Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5cc20ba9b | |||
| 46e7abe59c | |||
| 40df6b9dfb | |||
| 5559fa8bcc | |||
| 6319ddf78f | |||
| e74300a756 | |||
| d9674b4e7c | |||
| 6d02f00ac0 | |||
| 2960e7d24f | |||
| d950c6d3e8 | |||
| 357c351b95 | |||
| a780b13fcc | |||
| cf80fc6a86 | |||
| 20acc9ccf5 | |||
| e49ab25111 | |||
| eed4457419 | |||
| 429a0345d9 | |||
| 670d4e39c9 | |||
| 5d4ddb9a6b | |||
| 0ad90dc36e | |||
| 284810dfb8 | |||
| 0f67f445b9 | |||
| 018cc61204 | |||
| b9c3d8deea | |||
| 0d5b289d65 | |||
| 5b20ad2e2c | |||
| 9fcce731d0 | |||
| 0783c97224 | |||
| 300e891906 | |||
| a3e0a3ee1a | |||
| b3703e2069 | |||
| d3c8da4edb | |||
| bed0bfff06 | |||
| 238231b28b |
@@ -74,11 +74,11 @@ body:
|
||||
All config files on your server.
|
||||
例如以下文件(或者文件夹):
|
||||
Example files (or folders):
|
||||
- \spigot.yml
|
||||
- \bukkit.yml
|
||||
- \config\\\*
|
||||
- \lophine_config\\\*
|
||||
- \luminol_config\\\*
|
||||
- \spigot.yml
|
||||
- \bukkit.yml
|
||||
- \config\\\*
|
||||
- \lophine_config\\\*
|
||||
- \luminol_config\\\*
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit
|
||||
fetch-depth: 0 # a full history is required for pull request analysis
|
||||
- name: 'Qodana Scan'
|
||||
uses: JetBrains/qodana-action@v2025.3
|
||||
uses: JetBrains/qodana-action@latest
|
||||
with:
|
||||
pr-mode: false
|
||||
env:
|
||||
|
||||
+3
-5
@@ -6,12 +6,10 @@ build
|
||||
|
||||
/run
|
||||
|
||||
/lightingluminol-server/build.gradle.kts
|
||||
/lightingluminol-api/build.gradle.kts
|
||||
/luminol-server/build.gradle.kts
|
||||
/luminol-server/src/minecraft
|
||||
/lophine-server/build.gradle.kts
|
||||
/lophine-api/build.gradle.kts
|
||||
/lophine-server/src/minecraft
|
||||
/paper-server
|
||||
/luminol-api/build.gradle.kts
|
||||
/paper-api
|
||||
/paper-api-generator
|
||||
|
||||
|
||||
+2
-2
@@ -4,10 +4,10 @@ mcVersion=1.21.11
|
||||
# This is the current API version for use in (paper-)plugin.yml files
|
||||
# During snapshot cycles this should be the anticipated version of the release target
|
||||
apiVersion=1.21.11
|
||||
release=1
|
||||
release=2
|
||||
# 0 for skip release, 1 for pre-release, 2 for release
|
||||
|
||||
luminolRef=db42c568c4fb9addf797d797710fc8ad49daf3ba
|
||||
luminolRef=78a3b89f5850f71ddb5b1d1adeccda47f5762a1b
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -39,9 +39,9 @@ public interface Bot extends Player {
|
||||
/**
|
||||
* Gets the fakeplayer name without prefix and suffix
|
||||
*
|
||||
* @return fakeplayer real name
|
||||
* @return fakeplayer raw name
|
||||
*/
|
||||
@NotNull String getRealName();
|
||||
@NotNull String getRawName();
|
||||
|
||||
/**
|
||||
* Gets the creator's UUID of the fakeplayer
|
||||
@@ -91,4 +91,13 @@ public interface Bot extends Player {
|
||||
* @return success
|
||||
*/
|
||||
boolean remove(boolean save);
|
||||
|
||||
/**
|
||||
* Remove the fakeplayer
|
||||
*
|
||||
* @param save should save
|
||||
* @param resume should resume at next server start
|
||||
* @return success
|
||||
*/
|
||||
boolean remove(boolean save, boolean resume);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ import java.util.function.Consumer;
|
||||
|
||||
public interface BotCreator {
|
||||
|
||||
static BotCreator of(String realName, Location location) {
|
||||
return Bukkit.getBotManager().botCreator(realName, location);
|
||||
static BotCreator of(String rawName, Location location) {
|
||||
return Bukkit.getBotManager().botCreator(rawName, location);
|
||||
}
|
||||
|
||||
BotCreator name(String name);
|
||||
|
||||
@@ -61,5 +61,5 @@ public interface BotManager {
|
||||
*/
|
||||
<T extends BotAction<T>> T newAction(@NotNull Class<T> type);
|
||||
|
||||
BotCreator botCreator(@NotNull String realName, @NotNull Location location);
|
||||
BotCreator botCreator(@NotNull String rawName, @NotNull Location location);
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@
|
||||
- implementation(project(":luminol-api")) // Luminol
|
||||
+ implementation(project(":lophine-api")) // Lophine
|
||||
// Luminol start - Dependenices insert
|
||||
implementation("io.netty:netty-all:4.2.9.Final") // used for io_uring
|
||||
implementation("com.electronwill.night-config:toml:3.8.3") // Night config
|
||||
implementation("com.github.luben:zstd-jni:1.5.4-1")
|
||||
@@ -272,14 +_,14 @@
|
||||
@@ -273,14 +_,14 @@
|
||||
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
@@ -70,7 +70,7 @@
|
||||
"Build-Number" to (build ?: ""),
|
||||
"Build-Time" to buildTime.toString(),
|
||||
"Git-Branch" to gitBranch,
|
||||
@@ -431,7 +_,7 @@
|
||||
@@ -432,7 +_,7 @@
|
||||
}
|
||||
|
||||
fill {
|
||||
|
||||
@@ -17,15 +17,15 @@ index 0bebc2cc87fb9c1c526e4de4f3bc157552307a72..cb1657939b86c039fcfe6403d3f202c2
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
index df5d926fb4401dd93d658fe14ae4d9d58cff68f9..b6d84fea596cfa78032151ab2f206b6b3d5dd197 100644
|
||||
index e4022494b050b68d54bac3cde87bdfc9e908859c..a4188ef831825764c0756b826651e2e7a9f99c5b 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
@@ -8,7 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
@ConfigClassInfo(category = EnumConfigCategory.MISC, name = "server_mod_name")
|
||||
public class ServerModNameConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "name")
|
||||
@ConfigInfo(name = "name", comments = "Decides the server mod name shown in your F3 debug screen.")
|
||||
- public static String serverModName = "Luminol";
|
||||
+ public static String serverModName = "Lophine";
|
||||
|
||||
@ConfigInfo(name = "vanilla_spoof")
|
||||
@ConfigInfo(name = "vanilla_spoof", comments = "Ignore any plugin's modification and server mod name set in this config block, only force sending brand name of vanilla")
|
||||
public static boolean fakeVanilla = false;
|
||||
|
||||
@@ -5,26 +5,36 @@ Subject: [PATCH] Transformed Configs
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
index 4051384e82dba0416838c3c9889a6e368367b601..a5535b479cdcca870d0c8be6ed6fbcb32f266ac2 100644
|
||||
index ad2ba680bedb2336de24146676e70a1f64fd9c5a..f81581782bf684bbcf4719e9b268efa3c6385325 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
@@ -11,6 +11,7 @@ public class CommandConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "enable", directory = {"experiment", "force_the_data_command_to_be_enabled"})
|
||||
@@ -13,6 +13,7 @@ public class CommandConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enable_data_command")
|
||||
@HotReloadUnsupported
|
||||
public static boolean data = false;
|
||||
+ @TransformedConfig(name = "command_block_enabled", directory = {"experiment", "command"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "enabled", directory = {"experiment", "force_enable_command_block_command_execution"})
|
||||
@ConfigInfo(name = "enable_command_block", comments = """
|
||||
Force to enable command blocks.
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
index 35e6014f04093050a9a62b895b43e5c5d8c6a28e..11abfb884f972fd73ca4c13a6e309de1bcd23fd5 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
@@ -8,6 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.OPTIMIZATIONS, name = "force_disable_packet_limiter_of_paper")
|
||||
@@ -20,6 +21,9 @@ public class CommandConfig implements IConfigModule {
|
||||
DO NOT ENABLE UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
""")
|
||||
public static boolean commandBlock = false;
|
||||
+ @TransformedConfig(name = "enable-waypoint", directory = {"experiment", "waypoint bar"})
|
||||
+ @TransformedConfig(name = "enable-waypoint", directory = {"experiment", "waypoint_bar"})
|
||||
+ @TransformedConfig(name = "waypoint_command_enabled", directory = {"experiment", "command"})
|
||||
@ConfigInfo(name = "enable_waypoints_and_waypoint_command", comments = """
|
||||
Enable waypoint and waypoint command.
|
||||
WARN: Still under testing
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
|
||||
index ce190737de22438d5de86b0ee0e8158954fdca18..0a175e87f3cb5b23480abefd70ee2e84e876b0d4 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
|
||||
@@ -11,6 +11,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
"has negative impacts on security"
|
||||
)
|
||||
public class PaperPacketLimiterConfig implements IConfigModule {
|
||||
+ @TransformedConfig(name = "unlimit-packet", directory = {"misc", "network"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "force_disable", directory = {"misc", "force_disable_packet_limiter_of_paper"})
|
||||
@TransformedConfig(name = "force_disable", directory = {"optimizations", "force_disable_packet_limiter_of_paper"})
|
||||
@ConfigInfo(name = "force_disable")
|
||||
public static boolean forceDisable = false;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 18 Feb 2026 00:15:08 +0800
|
||||
Subject: [PATCH] Leaves: Fakeplayer
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java b/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
|
||||
index 14cf379decfd46c4719bc192a1467bbbd6835417..20970844de2e64ca213384e53003e80020165770 100644
|
||||
--- a/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
|
||||
+++ b/src/main/java/me/earthme/luminol/utils/FoliaServerWaypointManager.java
|
||||
@@ -38,6 +38,12 @@ public class FoliaServerWaypointManager implements WaypointManager<@NotNull Wayp
|
||||
return;
|
||||
}
|
||||
|
||||
+ // Leaves start - fakeplayer
|
||||
+ if (waypoint instanceof org.leavesmc.leaves.bot.ServerBot bot && !bot.getConfigValue(org.leavesmc.leaves.bot.agent.Configs.ENABLE_LOCATOR_BAR)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
+
|
||||
this.waypoints.add(waypoint);
|
||||
|
||||
for (ServerPlayer toCreateFor : this.trackingPlayers) {
|
||||
@@ -91,6 +97,12 @@ public class FoliaServerWaypointManager implements WaypointManager<@NotNull Wayp
|
||||
public void addPlayer(ServerPlayer player) {
|
||||
this.trackingPlayers.add(player);
|
||||
|
||||
+ // Leaves start - fakeplayer
|
||||
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
+
|
||||
for (WaypointTransmitter waypointTransmitter : this.waypoints) {
|
||||
this.createConnection(player, waypointTransmitter);
|
||||
}
|
||||
+7
-7
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Sun, 3 Aug 2025 14:26:37 +0800
|
||||
Subject: [PATCH] Add configs to disable some check for operators
|
||||
Subject: [PATCH] Add config to disable some check for operators
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 718a10b442997c8225a7de27ff92c1f36b809a9e..5757832ca91c42b417a95a2536a282a24eef0ef7 100644
|
||||
index bd344bbebc867f89061694edc0feeab9d679c90c..6d0bb9868e2c2ef516de7630442808c04ba47b39 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -391,7 +391,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -392,7 +392,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.tickCount++;
|
||||
this.knownMovePacketCount = this.receivedMovePacketCount;
|
||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
||||
@@ -17,7 +17,7 @@ index 718a10b442997c8225a7de27ff92c1f36b809a9e..5757832ca91c42b417a95a2536a282a2
|
||||
// LOGGER.warn("{} was kicked for floating too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
|
||||
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_PLAYER); // Paper - use configurable kick message & kick event cause
|
||||
return true;
|
||||
@@ -410,7 +410,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -411,7 +411,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.vehicleLastGoodY = this.lastVehicle.getY();
|
||||
this.vehicleLastGoodZ = this.lastVehicle.getZ();
|
||||
if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) {
|
||||
@@ -26,7 +26,7 @@ index 718a10b442997c8225a7de27ff92c1f36b809a9e..5757832ca91c42b417a95a2536a282a2
|
||||
// LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getPlainTextName()); // Paper - Logging moved to net.minecraft.server.network.ServerCommonPacketListenerImpl.disconnect()
|
||||
this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_VEHICLE); // Paper - use configurable kick message & kick event cause
|
||||
return true;
|
||||
@@ -661,7 +661,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -662,7 +662,7 @@ public class ServerGamePacketListenerImpl
|
||||
d5 = d2 - rootVehicle.getZ();
|
||||
d7 = d3 * d3 + d4 * d4 + d5 * d5;
|
||||
boolean flag1 = false;
|
||||
@@ -35,7 +35,7 @@ index 718a10b442997c8225a7de27ff92c1f36b809a9e..5757832ca91c42b417a95a2536a282a2
|
||||
flag1 = true; // Paper - diff on change, this should be moved wrongly
|
||||
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getPlainTextName(), this.player.getPlainTextName(), Math.sqrt(d7));
|
||||
}
|
||||
@@ -1563,7 +1563,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1564,7 +1564,7 @@ public class ServerGamePacketListenerImpl
|
||||
// Paper start - Add fail move event
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
|
||||
toX, toY, toZ, toYaw, toPitch, true);
|
||||
@@ -44,7 +44,7 @@ index 718a10b442997c8225a7de27ff92c1f36b809a9e..5757832ca91c42b417a95a2536a282a2
|
||||
if (event.getLogWarning()) {
|
||||
LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getPlainTextName(), d3, d4, d5);
|
||||
}
|
||||
@@ -1642,7 +1642,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -1643,7 +1643,7 @@ public class ServerGamePacketListenerImpl
|
||||
// Paper start - Add fail move event
|
||||
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY,
|
||||
toX, toY, toZ, toYaw, toPitch, true);
|
||||
+7
-7
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable cross region damage trace
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 338ad851814e0d15ac2c20c9f13895f52557e130..93bc76af4d0abbe1c526434991e74c4465764ac6 100644
|
||||
index 08e0dde0aa5ff94b72127abcd7da2a63d5701db8..e311502c156076842c5dcd91c70a94e414312100 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1447,6 +1447,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -1445,6 +1445,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.awardStat(Stats.ENTITY_KILLED_BY.get(killCredit.getType()));
|
||||
killCredit.awardKillScore(this, damageSource);
|
||||
this.createWitherRose(killCredit);
|
||||
@@ -22,7 +22,7 @@ index 338ad851814e0d15ac2c20c9f13895f52557e130..93bc76af4d0abbe1c526434991e74c44
|
||||
}
|
||||
|
||||
this.level().broadcastEntityEvent(this, EntityEvent.DEATH);
|
||||
@@ -1470,6 +1477,24 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -1468,6 +1475,24 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
// Leaves end - exp fix
|
||||
|
||||
@@ -48,10 +48,10 @@ index 338ad851814e0d15ac2c20c9f13895f52557e130..93bc76af4d0abbe1c526434991e74c44
|
||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||
this.level()
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 372fb8a7f06e87c5694b972e3b726e52903ef1e3..ad497cc5a01662e86d6c3d0a7d51b86cfc764f53 100644
|
||||
index c67c29278ea63ab8b936d53bf654089f2dba2eef..88d532d11c29bd8cfe5b6b02847d960b07cf0a38 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1960,6 +1960,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -1975,6 +1975,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
final LivingEntity killer = this.getKillCredit();
|
||||
if (killer != null) {
|
||||
killer.awardKillScore(this, damageSource);
|
||||
@@ -65,7 +65,7 @@ index 372fb8a7f06e87c5694b972e3b726e52903ef1e3..ad497cc5a01662e86d6c3d0a7d51b86c
|
||||
}
|
||||
}); // Paper end
|
||||
this.postDeathDropItems(deathEvent); // Paper
|
||||
@@ -1970,6 +1977,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -1985,6 +1992,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
return deathEvent; // Paper
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ index 372fb8a7f06e87c5694b972e3b726e52903ef1e3..ad497cc5a01662e86d6c3d0a7d51b86c
|
||||
protected void dropEquipment(ServerLevel level) {
|
||||
}
|
||||
protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
||||
@@ -2597,6 +2616,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -2612,6 +2631,18 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@ index bca2c5410aa543d2bb421e53893e9163508b3568..fdccb06c918d387e46c29ede7337159d
|
||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
if (rangeY != -1) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 532a628de2d5eda29b503274bc323d71a57cf1cb..0f213d1cfab6066f6713c5b2124b76409510454c 100644
|
||||
index 040c0f8d26554ba583ecf370e2df3690d8f48dd6..22e68cabb4554c3e21e6f4ef316186f60ec77511 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -152,7 +152,7 @@ import org.jetbrains.annotations.Contract;
|
||||
@@ -30,7 +30,7 @@ index 532a628de2d5eda29b503274bc323d71a57cf1cb..0f213d1cfab6066f6713c5b2124b7640
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
static boolean isLevelAtLeast(ValueInput input, int level) {
|
||||
@@ -6536,4 +6536,46 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
@@ -6442,4 +6442,46 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
// Paper end - Expose entity id counter
|
||||
|
||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
@@ -92,7 +92,7 @@ index 0590d5723854a03a59fe9471710802f4e64e50b8..4f8ff2c024d6f2e67c5fa38fe2e660ba
|
||||
public EntityType(
|
||||
EntityType.EntityFactory<T> factory,
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 5b19dba8c978feafa5d3d956359188e2de2257a5..3a8ac0765b8a988c281a2ded8c40ec044781cda2 100644
|
||||
index 67c0f4027a1e8b364694b5ed8b71965f2fe9b359..0f6e1428cc71c370af45db3e2a4f47c66e5d8628 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -189,6 +189,25 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to enable function command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index b4976ac6a609c24a43375d6c945e2412b00ab627..ddde2c3e7c8d9105202a7ff32e444f85485cdb7f 100644
|
||||
index 9c0c3835776bda3bab08f0abaffc89a72bba0bfc..b95d144dd479d339cc4b0f92cc4c3bade9af4927 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -215,7 +215,9 @@ public class Commands {
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 16 Jan 2026 02:34:43 +0800
|
||||
Subject: [PATCH] Add config to enable save-all command
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 17108636a5728efe98a064001e00e3ca098b1f51..7748e9ac04fbd3f5259d92fc908d90889cba86c8 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -350,6 +350,8 @@ public final class RegionizedServer {
|
||||
// tick player ping sample
|
||||
this.tickPlayerSample();
|
||||
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.checkTimeout(); // Lophine - save-all fix
|
||||
+
|
||||
// tick worlds
|
||||
for (final ServerLevel world : this.worlds) {
|
||||
this.globalTick(world, tickCount);
|
||||
diff --git a/io/papermc/paper/threadedregions/TickRegions.java b/io/papermc/paper/threadedregions/TickRegions.java
|
||||
index 02c004bc7f9a0203523ce4b27cd766d6bdc478c0..3d86e21198f2888422330b6f7c27712f40a6aabc 100644
|
||||
--- a/io/papermc/paper/threadedregions/TickRegions.java
|
||||
+++ b/io/papermc/paper/threadedregions/TickRegions.java
|
||||
@@ -190,6 +190,8 @@ public final class TickRegions implements ThreadedRegionizer.RegionCallbacks<Tic
|
||||
public final ThreadedRegionizer.ThreadedRegion<TickRegionData, TickRegionSectionData> region;
|
||||
public final ServerLevel world;
|
||||
|
||||
+ public long lastSavedTime = 0; // Lophine - save-all fix
|
||||
+
|
||||
// generic regionised data
|
||||
private final Reference2ReferenceOpenHashMap<RegionizedData<?>, Object> regionizedData = new Reference2ReferenceOpenHashMap<>();
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 6cb0d4daf0f275b95d5ca09275e40ab32258eb39..48628174299f8f18170198df1834d6174bd1fafa 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -294,7 +294,11 @@ public class Commands {
|
||||
PardonCommand.register(this.dispatcher);
|
||||
PardonIpCommand.register(this.dispatcher);
|
||||
//PerfCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
- //SaveAllCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ // Lophine start - Add a config to enable save all command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.saveAll) {
|
||||
+ SaveAllCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+ }
|
||||
+ // Lophine end - Add a config to enable save all command
|
||||
SaveOffCommand.register(this.dispatcher);
|
||||
SaveOnCommand.register(this.dispatcher);
|
||||
SetPlayerIdleTimeoutCommand.register(this.dispatcher);
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 4be383909addfebc0ca3b007d4ef2ec30ed445f7..fa60388376e9dafc5e1b71b6e78550bb6cd4009b 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1656,6 +1656,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia start - region threading
|
||||
public void tickServer(long startTime, long scheduledEnd, long targetBuffer,
|
||||
io.papermc.paper.threadedregions.TickRegions.TickRegionData region) {
|
||||
+ // Lophine start - save-all fix
|
||||
+ if (fun.bm.lophine.utils.SaveAllUtil.isSaving()) {
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.postRegionSave(region);
|
||||
+ }
|
||||
+ // Lophine end - save-all fix
|
||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler(); // Folia - profiler
|
||||
// Folia end - region threading
|
||||
org.spigotmc.WatchdogThread.tick(); // Spigot
|
||||
diff --git a/net/minecraft/server/commands/SaveAllCommand.java b/net/minecraft/server/commands/SaveAllCommand.java
|
||||
index e37b71402179c73146ff67babc228ccfb996f8f4..cfdb60bd89d83282f2202a5585bac22a6002e138 100644
|
||||
--- a/net/minecraft/server/commands/SaveAllCommand.java
|
||||
+++ b/net/minecraft/server/commands/SaveAllCommand.java
|
||||
@@ -21,7 +21,9 @@ public class SaveAllCommand {
|
||||
}
|
||||
|
||||
private static int saveAll(CommandSourceStack source, boolean flush) throws CommandSyntaxException {
|
||||
- source.sendSuccess(() -> Component.translatable("commands.save.saving"), false);
|
||||
+ // Lophine start - save all
|
||||
+ fun.bm.lophine.utils.SaveAllUtil.preSaveAll(source, flush);
|
||||
+/* source.sendSuccess(() -> Component.translatable("commands.save.saving"), false);
|
||||
MinecraftServer server = source.getServer();
|
||||
boolean flag = server.saveEverything(true, flush, true);
|
||||
if (!flag) {
|
||||
@@ -29,6 +31,12 @@ public class SaveAllCommand {
|
||||
} else {
|
||||
source.sendSuccess(() -> Component.translatable("commands.save.success"), true);
|
||||
return 1;
|
||||
- }
|
||||
+ }*/
|
||||
+ return 1;
|
||||
}
|
||||
+
|
||||
+ public static SimpleCommandExceptionType getErrorFailed() {
|
||||
+ return ERROR_FAILED;
|
||||
+ }
|
||||
+ // Lophine end - save all
|
||||
}
|
||||
+2
-2
@@ -5,11 +5,11 @@ Subject: [PATCH] Add config to enable scoreboard command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index c347830fbd8fccbf3b6b536beaba818fb7c6be32..8d77d6f165a5883e997122d1c2f231287e0caebe 100644
|
||||
index 097e5b6a14fd148c93ca3894295a4a6b1e9aa870..bd8d98aa813b575e83138e79726bd3143268913c 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -241,7 +241,11 @@ public class Commands {
|
||||
//RotateCommand.register(this.dispatcher); // Folia - region threading - TODO later // Luminol - Disable not correctly disabled unsupported commands
|
||||
RotateCommand.register(this.dispatcher);
|
||||
SayCommand.register(this.dispatcher);
|
||||
//ScheduleCommand.register(this.dispatcher); // Folia - region threading
|
||||
- //ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
+16
-16
@@ -1,11 +1,11 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Thu, 1 May 2025 22:43:08 +0800
|
||||
Date: Wed, 21 Jan 2026 21:28:21 +0800
|
||||
Subject: [PATCH] Add config to enable tick command
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index b3bc39ebe8d2f48d976de9cd4fcae46095523514..6df2b8cf3b902bb157ed5fa9eaf9ca062d9e5a39 100644
|
||||
index 7748e9ac04fbd3f5259d92fc908d90889cba86c8..80b5d151e0dd6fa44794187875b4b80519839d81 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -332,6 +332,11 @@ public final class RegionizedServer {
|
||||
@@ -20,7 +20,7 @@ index b3bc39ebe8d2f48d976de9cd4fcae46095523514..6df2b8cf3b902bb157ed5fa9eaf9ca06
|
||||
// expire invalid click command callbacks
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick
|
||||
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue((int)this.tickCount); // Paper // Folia - region threading - moved to global tick
|
||||
@@ -355,6 +360,13 @@ public final class RegionizedServer {
|
||||
@@ -357,6 +362,13 @@ public final class RegionizedServer {
|
||||
this.globalTick(world, tickCount);
|
||||
}
|
||||
|
||||
@@ -34,20 +34,20 @@ index b3bc39ebe8d2f48d976de9cd4fcae46095523514..6df2b8cf3b902bb157ed5fa9eaf9ca06
|
||||
// tick connections
|
||||
this.tickConnections();
|
||||
|
||||
@@ -488,7 +500,7 @@ public final class RegionizedServer {
|
||||
@@ -492,7 +504,7 @@ public final class RegionizedServer {
|
||||
}
|
||||
|
||||
private void tickTime(final ServerLevel world, final int tickCount) {
|
||||
private void tickTime(final ServerLevel world, final long tickCount) {
|
||||
- if (world.tickTime) {
|
||||
+ if ((!fun.bm.lophine.config.modules.experiment.CommandConfig.tick || world.tickRateManager().runsNormally()) && world.tickTime) { // Luminol - Add a config to enable tick command
|
||||
if (world.getGameRules().get(GameRules.ADVANCE_TIME)) {
|
||||
world.setDayTime(world.levelData.getDayTime() + (long)tickCount);
|
||||
world.setDayTime(world.levelData.getDayTime() + tickCount);
|
||||
}
|
||||
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
index e3df94bfd26b118cb8a7bdece75d611aaf27c606..bae2385b725c0ce551768f22945393ccf6e1e432 100644
|
||||
index 0f4e8ee9438135e24e0f61a1390c59573b9e9c3f..65699d2ad66c686a8b7d1b951787ddd766800a94 100644
|
||||
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
|
||||
@@ -39,8 +39,8 @@ public final class TickRegionScheduler {
|
||||
@@ -40,8 +40,8 @@ public final class TickRegionScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,14 +58,14 @@ index e3df94bfd26b118cb8a7bdece75d611aaf27c606..bae2385b725c0ce551768f22945393cc
|
||||
// Folia start - watchdog
|
||||
public static final FoliaWatchdogThread WATCHDOG_THREAD = new FoliaWatchdogThread();
|
||||
static {
|
||||
@@ -447,8 +447,23 @@ public final class TickRegionScheduler {
|
||||
@@ -448,8 +448,23 @@ public final class TickRegionScheduler {
|
||||
final long cpuStart = MEASURE_CPU_TIME ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : 0L;
|
||||
final long tickStart = System.nanoTime();
|
||||
|
||||
- // use max(), don't assume that tickStart >= scheduledStart
|
||||
- final int tickCount = Math.max(1, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
- final long tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ // Luminol start - Add a config to enable tick command
|
||||
+ final int tickCount;
|
||||
+ final long tickCount;
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.tick) {
|
||||
+ if (MinecraftServer.tickRateManager.isSprinting() && MinecraftServer.tickRateManager.checkShouldSprintThisTick()) {
|
||||
+ TICK_RATE = net.minecraft.server.commands.TickCommand.MAX_TICKRATE;
|
||||
@@ -74,17 +74,17 @@ index e3df94bfd26b118cb8a7bdece75d611aaf27c606..bae2385b725c0ce551768f22945393cc
|
||||
+ } else {
|
||||
+ TICK_RATE = MinecraftServer.tickRateManager.tickrate();
|
||||
+ TIME_BETWEEN_TICKS = (long) (1_000_000_000L / TICK_RATE);
|
||||
+ tickCount = Math.max(1, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ }
|
||||
+ } else {
|
||||
+ // use max(), don't assume that tickStart >= scheduledStart
|
||||
+ tickCount = Math.max(1, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ tickCount = Math.max(1L, this.tickSchedule.getPeriodsAhead(TIME_BETWEEN_TICKS, tickStart));
|
||||
+ }
|
||||
+ // Luminol end - Add tick command support
|
||||
|
||||
if (!this.tryMarkTicking()) {
|
||||
if (!this.cancelled.get()) {
|
||||
@@ -497,6 +512,11 @@ public final class TickRegionScheduler {
|
||||
@@ -498,6 +513,11 @@ public final class TickRegionScheduler {
|
||||
try {
|
||||
// next start isn't updated until the end of this tick
|
||||
this.tickRegion(tickCount, tickStart, scheduledEnd);
|
||||
@@ -97,7 +97,7 @@ index e3df94bfd26b118cb8a7bdece75d611aaf27c606..bae2385b725c0ce551768f22945393cc
|
||||
this.scheduler.regionFailed(this, false, thr);
|
||||
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 8d77d6f165a5883e997122d1c2f231287e0caebe..23f047a47cdccc90a96153cc52bdedf91cd15db9 100644
|
||||
index bd8d98aa813b575e83138e79726bd3143268913c..65f200381f486146ce8d893378f0591a82f6076b 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -262,7 +262,11 @@ public class Commands {
|
||||
@@ -114,7 +114,7 @@ index 8d77d6f165a5883e997122d1c2f231287e0caebe..23f047a47cdccc90a96153cc52bdedf9
|
||||
TitleCommand.register(this.dispatcher, context);
|
||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 1627a8f3ebf7bf1a750a62802f1187ad8c1a6a0f..6e18d988104c121d9683eb57e77a78acfdee3907 100644
|
||||
index 76098a4f44f8d82bebf832fa5e240adf25fbe80a..644c49730fc08a7c680f8114136db00ee8f81378 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -270,7 +270,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
-170
@@ -1,170 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 7 Jul 2025 18:19:00 +0800
|
||||
Subject: [PATCH] Add config to enable waypoint command & bar
|
||||
|
||||
use concurrent method to fix it (now, they are thread safe)
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 23f047a47cdccc90a96153cc52bdedf91cd15db9..9cfcac44b4d51cb5f122d7e1fa980791a23dd38f 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -270,7 +270,11 @@ public class Commands {
|
||||
TimeCommand.register(this.dispatcher);
|
||||
TitleCommand.register(this.dispatcher, context);
|
||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
- //WaypointCommand.register(this.dispatcher, context); // Folia - region threading - TODO later
|
||||
+ // Lophine start - unsafe waypoint bar
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) {
|
||||
+ WaypointCommand.register(this.dispatcher, context); // Folia - region threading - TODO later
|
||||
+ }
|
||||
+ // Lophine end - unsafe waypoint bar
|
||||
WeatherCommand.register(this.dispatcher);
|
||||
WorldBorderCommand.register(this.dispatcher);
|
||||
if (JvmProfiler.INSTANCE.isAvailable()) {
|
||||
diff --git a/net/minecraft/server/waypoints/ServerWaypointManager.java b/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
index 1cbc46e480cc7d109c6128f109a1a9e38bf1a193..d2c0b532200f274e44f18147d294dfe5d3f52d1d 100644
|
||||
--- a/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
+++ b/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
@@ -16,22 +16,31 @@ import net.minecraft.world.waypoints.WaypointManager;
|
||||
import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||
|
||||
public class ServerWaypointManager implements WaypointManager<WaypointTransmitter> {
|
||||
- private final Set<WaypointTransmitter> waypoints = new HashSet<>();
|
||||
- private final Set<ServerPlayer> players = new HashSet<>();
|
||||
- private final Table<ServerPlayer, WaypointTransmitter, WaypointTransmitter.Connection> connections = HashBasedTable.create();
|
||||
+ private final Set<WaypointTransmitter> waypoints = new java.util.concurrent.CopyOnWriteArraySet<>(); // Lophine - concurrent
|
||||
+ private final Set<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArraySet<>(); // Lophine - concurrent
|
||||
+ private final fun.bm.lophine.utils.concurrent.AbstractConcurrentTable<ServerPlayer, WaypointTransmitter, WaypointTransmitter.Connection> connections = fun.bm.lophine.config.modules.optimizations.WayPointOptimizedTableConfig.optimizedTable ? new fun.bm.lophine.utils.concurrent.OptimizedConcurrentTable<>() : new fun.bm.lophine.utils.concurrent.ConcurrentTable<>(); // Lophine - concurrent
|
||||
|
||||
@Override
|
||||
public void trackWaypoint(WaypointTransmitter waypoint) {
|
||||
- // Folia - region threading
|
||||
+ // Lophine start - unsafe waypoint bar
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ this.waypoints.add(waypoint);
|
||||
+
|
||||
+ for (ServerPlayer serverPlayer : this.players) {
|
||||
+ this.createConnection(serverPlayer, waypoint);
|
||||
+ }
|
||||
+ // Lophine end - unsafe waypoint bar
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateWaypoint(WaypointTransmitter waypoint) {
|
||||
if (this.waypoints.contains(waypoint)) {
|
||||
- Map<ServerPlayer, WaypointTransmitter.Connection> map = Tables.transpose(this.connections).row(waypoint);
|
||||
- SetView<ServerPlayer> set = Sets.difference(this.players, map.keySet());
|
||||
+ java.util.List<Entry<ServerPlayer, WaypointTransmitter.Connection>> map = this.connections.getXZ(waypoint); // Lophine - concurrent
|
||||
+ Set<ServerPlayer> players1 = new HashSet<>(); // Lophine - concurrent
|
||||
+ map.forEach((entry) -> players1.add(entry.getKey())); // Lophine - concurrent
|
||||
+ SetView<ServerPlayer> set = Sets.difference(this.players, players1); // Lophine - concurrent
|
||||
|
||||
- for (Entry<ServerPlayer, WaypointTransmitter.Connection> entry : ImmutableSet.copyOf(map.entrySet())) {
|
||||
+ for (Entry<ServerPlayer, WaypointTransmitter.Connection> entry : map) { // Lophine - concurrent
|
||||
this.updateConnection(entry.getKey(), waypoint, entry.getValue());
|
||||
}
|
||||
|
||||
@@ -43,26 +52,60 @@ public class ServerWaypointManager implements WaypointManager<WaypointTransmitte
|
||||
|
||||
@Override
|
||||
public void untrackWaypoint(WaypointTransmitter waypoint) {
|
||||
- this.connections.column(waypoint).forEach((serverPlayer, connection) -> connection.disconnect());
|
||||
- Tables.transpose(this.connections).row(waypoint).clear();
|
||||
+ this.connections.getXZ(waypoint).forEach((entry) -> entry.getKey().disconnect()); // Lophine - concurrent
|
||||
+ this.connections.clearXZ(waypoint); // Lophine - concurrent
|
||||
this.waypoints.remove(waypoint);
|
||||
}
|
||||
|
||||
public void addPlayer(ServerPlayer player) {
|
||||
// Folia - region threading
|
||||
+ // Lophine start - unsafe waypoint bar
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ this.players.add(player);
|
||||
+
|
||||
+ for (WaypointTransmitter waypointTransmitter : this.waypoints) {
|
||||
+ this.createConnection(player, waypointTransmitter);
|
||||
+ }
|
||||
+
|
||||
+ if (player.isTransmittingWaypoint()) {
|
||||
+ this.trackWaypoint((WaypointTransmitter)player);
|
||||
+ }
|
||||
+ // Lophine end - unsafe waypoint bar
|
||||
}
|
||||
|
||||
public void updatePlayer(ServerPlayer player) {
|
||||
// Folia - region threading
|
||||
+ // Lophine start - unsafe waypoint bar
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ java.util.List<Entry<WaypointTransmitter, WaypointTransmitter.Connection>> map = this.connections.getYZ(player); // Lophine - concurrent
|
||||
+ Set<WaypointTransmitter> waypoints1 = new HashSet<>();// Lophine - concurrent
|
||||
+ map.forEach((entry) -> waypoints1.add(entry.getKey()));// Lophine - concurrent
|
||||
+ SetView<WaypointTransmitter> set = Sets.difference(this.waypoints, waypoints1); // Lophine - concurrent
|
||||
+
|
||||
+ for (Entry<WaypointTransmitter, WaypointTransmitter.Connection> entry : map) { // Lophine - concurrent
|
||||
+ this.updateConnection(player, entry.getKey(), entry.getValue());
|
||||
+ }
|
||||
+
|
||||
+ for (WaypointTransmitter waypointTransmitter : set) {
|
||||
+ this.createConnection(player, waypointTransmitter);
|
||||
+ }
|
||||
+ // Lophine end - unsafe waypoint bar
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayer player) {
|
||||
// Folia - region threading
|
||||
+ // Lophine start - unsafe waypoint bar
|
||||
+ if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ this.connections.getYZ(player).forEach((entry) -> entry.getValue().disconnect()); // Lophine - concurrent
|
||||
+ this.connections.clearYZ(player); // Lophine - concurrent
|
||||
+ this.untrackWaypoint((WaypointTransmitter)player);
|
||||
+ this.players.remove(player);
|
||||
+ // Lophine end - unsafe waypoint bar
|
||||
}
|
||||
|
||||
public void breakAllConnections() {
|
||||
- this.connections.values().forEach(WaypointTransmitter.Connection::disconnect);
|
||||
- this.connections.clear();
|
||||
+ this.connections.getAllZ().forEach(WaypointTransmitter.Connection::disconnect); // Lophine - concurrent
|
||||
+ this.connections.clearAll(); // Lophine - concurrent
|
||||
}
|
||||
|
||||
public void remakeConnections(WaypointTransmitter waypoint) {
|
||||
@@ -83,13 +126,18 @@ public class ServerWaypointManager implements WaypointManager<WaypointTransmitte
|
||||
if (player != waypoint) {
|
||||
if (isLocatorBarEnabledFor(player)) {
|
||||
waypoint.makeWaypointConnectionWith(player).ifPresentOrElse(connection -> {
|
||||
- this.connections.put(player, waypoint, connection);
|
||||
+ this.connections.putOrUpdate(player, waypoint, connection);
|
||||
connection.connect();
|
||||
}, () -> {
|
||||
- WaypointTransmitter.Connection connection = this.connections.remove(player, waypoint);
|
||||
- if (connection != null) {
|
||||
- connection.disconnect();
|
||||
- }
|
||||
+ // Lophine start - concurrent
|
||||
+ java.util.List<WaypointTransmitter.Connection> c = this.connections.getZ(player, waypoint);
|
||||
+ c.forEach((connection) -> {
|
||||
+ this.connections.remove(player, waypoint, connection);
|
||||
+ if (connection != null) {
|
||||
+ connection.disconnect();
|
||||
+ }
|
||||
+ });
|
||||
+ // Lophine end - concurrent
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -103,10 +151,11 @@ public class ServerWaypointManager implements WaypointManager<WaypointTransmitte
|
||||
} else {
|
||||
waypoint.makeWaypointConnectionWith(player).ifPresentOrElse(connection1 -> {
|
||||
connection1.connect();
|
||||
- this.connections.put(player, waypoint, connection1);
|
||||
+ this.connections.putOrUpdate(player, waypoint, connection1);
|
||||
}, () -> {
|
||||
connection.disconnect();
|
||||
- this.connections.remove(player, waypoint);
|
||||
+ java.util.List<WaypointTransmitter.Connection> c = this.connections.getZ(player, waypoint); // Lophine - concurrent
|
||||
+ c.forEach((connection1) -> this.connections.remove(player, waypoint, connection1)); // Lophine - concurrent
|
||||
});
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,10 +5,10 @@ Subject: [PATCH] Fix datapack command save function
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 2f91e80f8c3df2775a793aa3c648c50007543192..6230c08d001aebc119900906aa557247261985a3 100644
|
||||
index d7d22806c010636d8c1471f0fd1d64ef54e92c97..8d96d2130cf3383427047fee97fa49155164e337 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2430,6 +2430,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2431,6 +2431,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 6df2b8cf3b902bb157ed5fa9eaf9ca062d9e5a39..057f60cd24876bf44cf3efccbc8a61b030a2a381 100644
|
||||
index 80b5d151e0dd6fa44794187875b4b80519839d81..8d32d906f87a1cb866a7497ee0de3045e9adce2c 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -367,6 +367,8 @@ public final class RegionizedServer {
|
||||
@@ -369,6 +369,8 @@ public final class RegionizedServer {
|
||||
}
|
||||
// Luminol end - Add a config to enable tick command
|
||||
|
||||
@@ -129,7 +129,7 @@ index 0bf2173c5445de021090c2d0264afc440b005bdc..076bfe7a7b57f8d3b29ef0aaad117707
|
||||
this.connection.setReadOnly();
|
||||
// CraftBukkit - Don't wait
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index fe58993c3fb98189141120f849c7750ce1e24ebd..d9b20f3b099eea4862774da79929bb71f8dede53 100644
|
||||
index d2b2bf35b3f5704f3bca94d0fe3b70206c2fbf96..c8be04b8a50bac52150a1fdd238634e630e1765e 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -315,6 +315,8 @@ public abstract class PlayerList {
|
||||
|
||||
+3
-3
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index a60c70550c217bccda6695dc7b7165de8e97e5cd..6aad6024dc121eae63b7fde92a89cbea29fcafb3 100644
|
||||
index d0b5bc9da450d881534abdbd8ff786e1fbc7d418..674450fb2e600236f99550febf276d093308b8d8 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -3015,7 +3015,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -3030,7 +3030,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Spigot start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
// Paper start - Fix merchant inventory not closing on entity removal
|
||||
@@ -21,7 +21,7 @@ index a60c70550c217bccda6695dc7b7165de8e97e5cd..6aad6024dc121eae63b7fde92a89cbea
|
||||
}
|
||||
// Paper end - Fix merchant inventory not closing on entity removal
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index a8a034ad5895ad1b833754c91c3a370c3b9b3744..35d51c727ce9229a174c45e9ea838fa9e3c3d80a 100644
|
||||
index c8be04b8a50bac52150a1fdd238634e630e1765e..2eb551390aa66d89988df9ca23cf0dd7ccfd6577 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -555,7 +555,7 @@ public abstract class PlayerList {
|
||||
|
||||
@@ -41,10 +41,10 @@ index 1281eadb2d0c5b4ce5e3afd51d8205f9a4ef011c..b1446dfb4689174ee9f55cec6080622e
|
||||
if (count > i) {
|
||||
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName()));
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 5757832ca91c42b417a95a2536a282a24eef0ef7..df6ad5831f83fcc869b0b4ed844a73b3cb81c469 100644
|
||||
index 6d0bb9868e2c2ef516de7630442808c04ba47b39..1a749d9bee139975fa249839df93c3a1e48bf102 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3126,7 +3126,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -3162,7 +3162,7 @@ public class ServerGamePacketListenerImpl
|
||||
} else if (slot.mayPlace(cursor)) {
|
||||
if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) {
|
||||
int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1;
|
||||
@@ -53,7 +53,7 @@ index 5757832ca91c42b417a95a2536a282a24eef0ef7..df6ad5831f83fcc869b0b4ed844a73b3
|
||||
toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount());
|
||||
if (toPlace == 1) {
|
||||
action = InventoryAction.PLACE_ONE;
|
||||
@@ -3162,7 +3162,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -3198,7 +3198,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
} else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) {
|
||||
if (clickedItem.getCount() >= 0) {
|
||||
@@ -62,7 +62,7 @@ index 5757832ca91c42b417a95a2536a282a24eef0ef7..df6ad5831f83fcc869b0b4ed844a73b3
|
||||
// As of 1.5, this is result slots only
|
||||
action = InventoryAction.PICKUP_ALL;
|
||||
}
|
||||
@@ -3379,6 +3379,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -3415,6 +3415,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.player.containerMenu.broadcastFullState();
|
||||
} else {
|
||||
this.player.containerMenu.broadcastChanges();
|
||||
@@ -70,7 +70,7 @@ index 5757832ca91c42b417a95a2536a282a24eef0ef7..df6ad5831f83fcc869b0b4ed844a73b3
|
||||
}
|
||||
if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots
|
||||
if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
|
||||
@@ -3490,7 +3491,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -3526,7 +3527,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45;
|
||||
@@ -79,7 +79,7 @@ index 5757832ca91c42b417a95a2536a282a24eef0ef7..df6ad5831f83fcc869b0b4ed844a73b3
|
||||
if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot
|
||||
// CraftBukkit start - Call click event
|
||||
org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView();
|
||||
@@ -3532,6 +3533,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -3568,6 +3569,7 @@ public class ServerGamePacketListenerImpl
|
||||
this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack);
|
||||
this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack);
|
||||
this.player.inventoryMenu.broadcastChanges();
|
||||
@@ -229,7 +229,7 @@ index 44276ba9c7aab306cfd12833a834ebe61cf64e7c..0a19a7782f3fa27c41e02393e887ba7c
|
||||
|
||||
default @Nullable SlotAccess getChestVehicleSlot(final int slot) {
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6fd57a4574 100644
|
||||
index 3b1c6a2397950ceb167890961b635cc69aaf8950..e7ea8849e8fa942709f505145e8076f064476206 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -292,6 +292,13 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -255,7 +255,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
int min1 = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemStack) + i2, min);
|
||||
count -= min1 - i2;
|
||||
// slot1.setByPlayer(itemStack.copyWithCount(min1));
|
||||
@@ -560,7 +567,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -556,7 +563,7 @@ public abstract class AbstractContainerMenu {
|
||||
slot.setByPlayer(carried2);
|
||||
}
|
||||
} else if (ItemStack.isSameItemSameComponents(carried, carried2)) {
|
||||
@@ -264,7 +264,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
optional1.ifPresent(itemStack2 -> {
|
||||
carried2.grow(itemStack2.getCount());
|
||||
slot.onTake(player, itemStack2);
|
||||
@@ -622,7 +629,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -618,7 +625,7 @@ public abstract class AbstractContainerMenu {
|
||||
Slot slot2 = this.slots.get(slotIndex);
|
||||
if (slot2.hasItem()) {
|
||||
ItemStack itemStack = slot2.getItem();
|
||||
@@ -273,7 +273,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
}
|
||||
} else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotIndex >= 0) {
|
||||
Slot slot2 = this.slots.get(slotIndex);
|
||||
@@ -657,15 +664,15 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -653,15 +660,15 @@ public abstract class AbstractContainerMenu {
|
||||
int maxStackSize = button == 0 ? 1 : -1;
|
||||
|
||||
for (int i3 = 0; i3 < 2; i3++) {
|
||||
@@ -292,7 +292,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
itemStack.grow(itemStack1.getCount());
|
||||
}
|
||||
}
|
||||
@@ -767,7 +774,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -763,7 +770,7 @@ public abstract class AbstractContainerMenu {
|
||||
i = endIndex - 1;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) {
|
||||
Slot slot = this.slots.get(i);
|
||||
ItemStack item = slot.getItem();
|
||||
@@ -868,7 +875,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -864,7 +871,7 @@ public abstract class AbstractContainerMenu {
|
||||
public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) {
|
||||
boolean flag = slot == null || !slot.hasItem();
|
||||
return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem())
|
||||
@@ -310,7 +310,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
: flag;
|
||||
}
|
||||
|
||||
@@ -876,7 +883,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -872,7 +879,7 @@ public abstract class AbstractContainerMenu {
|
||||
return switch (type) {
|
||||
case 0 -> Mth.floor((float)stack.getCount() / slots.size());
|
||||
case 1 -> 1;
|
||||
@@ -319,7 +319,7 @@ index b090b74c845cd5944c9a8e35e899ad35063770d3..8e28afcfda7b180def81122e35920f6f
|
||||
default -> stack.getCount();
|
||||
};
|
||||
}
|
||||
@@ -899,7 +906,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -895,7 +902,7 @@ public abstract class AbstractContainerMenu {
|
||||
for (int i = 0; i < container.getContainerSize(); i++) {
|
||||
ItemStack item = container.getItem(i);
|
||||
if (!item.isEmpty()) {
|
||||
@@ -355,7 +355,7 @@ index 2b7e245ebf3bb471a1d817c4b5d56a64790cbab7..00083df87439ff0fa56e09853931b605
|
||||
|
||||
public @Nullable Identifier getNoItemIcon() {
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index 5489302acb5bceac2cae71079a8356b455cf1304..a688da5bc71799c13548d390ab58645da9128229 100644
|
||||
index ed2971b54afbebe37a7ff61798778a4249b79856..73a97f4f62fe7d27b441cab58c6c86ffce011060 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -174,7 +174,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
@@ -420,7 +420,7 @@ index c5fe15844d405a27cdae18c903dd481c25b437de..3faa541c4a4623e915269d6241e1a3a3
|
||||
org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack);
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index 8176c0b35852fb0753339a92f1bbae41a5ae6782..9ada04588b8d30d307a91d93c48e6dca25b8d484 100644
|
||||
index 9346f2deca8eeca29fa2fced416247fd1609249e..07236e86638faa3231917af507cdd37ac49b1270 100644
|
||||
--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -412,7 +412,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f2
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
||||
index c8fa9a9ae29ecf9b2d6234e7efee61d05c8bc0ae..336daa3f7e2c957286d245746af47603a98438bc 100644
|
||||
index 08a1be57e1057a9e961eeb8f59cd12e98ed52bab..33ee967d8a7d4ce2c455db9ffaac740cd589e6f3 100644
|
||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||
@@ -717,6 +717,7 @@ public class ServerExplosion implements Explosion {
|
||||
|
||||
@@ -24,7 +24,7 @@ index 80f17f33f670018240c854df589cf90cdeab6e70..c9af615ff9120c07787f436dbb6024e5
|
||||
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
|
||||
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
|
||||
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
|
||||
index 4deb9e4688a04b25e862572b70bf91e3ace9841e..2f31fae204dbeeeec1d188b6908aec5ad937e62e 100644
|
||||
index dcdd6f230ff153a7b58d13b963d32376b1905b72..be9c78f2cf121e8ae55c1b18685877637a25ec80 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raid.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raid.java
|
||||
@@ -264,7 +264,7 @@ public class Raid {
|
||||
@@ -167,7 +167,7 @@ index 4deb9e4688a04b25e862572b70bf91e3ace9841e..2f31fae204dbeeeec1d188b6908aec5a
|
||||
+ // Leaves end - old FindSpawnPosition
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||
index 29ddff87216069cdf423f96f3fe835e0802d9ab5..18c4dffb5942b17dc1f2e9d9124c4f3ba3271360 100644
|
||||
index 5e8245e6dd8a07ece83dd1bc20e351a92044e7a0..2b7894a4104d4cb237746a3e66d4368b6f8f3c1e 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||
@@ -127,6 +127,43 @@ public abstract class Raider extends PatrollingMonster {
|
||||
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
|
||||
index 8cf3e51e12f9cf98836657e722edb23943f9e866..5fd5e9fd4e1a79dd1a9d62a5cf0c308805979420 100644
|
||||
index 5e25ddf78f72ada318ef28d29199de9b93fe667e..6f48162a25e20d2439935e8995cede9497626322 100644
|
||||
--- a/net/minecraft/world/item/ShearsItem.java
|
||||
+++ b/net/minecraft/world/item/ShearsItem.java
|
||||
@@ -80,7 +80,10 @@ public class ShearsItem extends Item {
|
||||
|
||||
@@ -23,10 +23,10 @@ index 95f6b1cbd5e33151c326689bc72292ff38a48803..e1974bbebbd10b75ea02955d9ced198d
|
||||
+ // Leaves end - servux
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 6aad6024dc121eae63b7fde92a89cbea29fcafb3..90e363a310936830788aee6484a63a989aa316e7 100644
|
||||
index 674450fb2e600236f99550febf276d093308b8d8..f5bf8ed6e741823078ab93eac47636fcebcdfe2d 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2442,6 +2442,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2463,6 +2463,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
this.server.updateEffectiveRespawnData();
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] LeavesHooks
|
||||
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
index d9fd093f59987f471627ff20cfd2eb1a3c0dea64..78c6d425589b8147c33583ac46d6f21ec5dbefaa 100644
|
||||
index faf62f8c9453f8e7a21b1e141577f1f4539cd2f9..4e5985a3e4969f466980558190324350019ba8af 100644
|
||||
--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
+++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java
|
||||
@@ -29,7 +29,7 @@ import net.minecraft.world.phys.AABB;
|
||||
|
||||
+3
-3
@@ -6,10 +6,10 @@ Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index ad497cc5a01662e86d6c3d0a7d51b86cfc764f53..67faf1ed52806ee2c1e2ea080b39959ad9ae986d 100644
|
||||
index 5bae274f5ee869e540e4330e03af671b6b18313d..3fe9afe55b4d61db8030479d3d74b8656679cb10 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1225,6 +1225,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -1240,6 +1240,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ index ad497cc5a01662e86d6c3d0a7d51b86cfc764f53..67faf1ed52806ee2c1e2ea080b39959a
|
||||
if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
|
||||
return !effectInstance.is(MobEffects.INFESTED);
|
||||
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
|
||||
index 18c4dffb5942b17dc1f2e9d9124c4f3ba3271360..2a2078ff7e353f5c94145ae700d58771a602a7ff 100644
|
||||
index 2b7894a4104d4cb237746a3e66d4368b6f8f3c1e..03e3290367790add702a5856aaff3be465ea548c 100644
|
||||
--- a/net/minecraft/world/entity/raid/Raider.java
|
||||
+++ b/net/minecraft/world/entity/raid/Raider.java
|
||||
@@ -157,7 +157,7 @@ public abstract class Raider extends PatrollingMonster {
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18
|
||||
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 3c27af5cf768eaa0591846923590a88606dee589..66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85 100644
|
||||
index 2eb551390aa66d89988df9ca23cf0dd7ccfd6577..0d322ef4aa3e70c9edbb9fa8ba368bef916eb93d 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -963,6 +963,10 @@ public abstract class PlayerList {
|
||||
@@ -23,7 +23,7 @@ index 3c27af5cf768eaa0591846923590a88606dee589..66e7b62a57eada0f0db7d9cc1be6362a
|
||||
|
||||
// Paper start - whitelist verify event / login event
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 3a8ac0765b8a988c281a2ded8c40ec044781cda2..1e3ac806c3f111ee0a4f8ef47134941ec85fbe6e 100644
|
||||
index 0f6e1428cc71c370af45db3e2a4f47c66e5d8628..83612969b6058f444fc17e360cdcc4a8846f79aa 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -179,6 +179,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
|
||||
@@ -26,7 +26,7 @@ index 7b9e2a1a208b46a69c16e6afd8b502259893574f..c300ae4363298fecef8fa9bf739f01c0
|
||||
loadFromJson(resourceAsStream, output);
|
||||
} catch (JsonParseException | IOException var7) {
|
||||
diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
|
||||
index 2d5309cc9386ef1bddf0bd4e153269fea1e75d60..ffa479f3743571bd198b1e3694301d73953a4eaa 100644
|
||||
index f41c70c6cb2e9fae43bad9dd66546417fe38f14a..0bb0877011cac3184b881bfa35f10ef83d7341de 100644
|
||||
--- a/net/minecraft/server/Main.java
|
||||
+++ b/net/minecraft/server/Main.java
|
||||
@@ -151,6 +151,8 @@ public class Main {
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Old zombie reinforcement
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/monster/zombie/Zombie.java b/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
index 1f359cf31dfd1a7bb9e1a9c8c830a4a4aa88ed00..206b725c9d1dffb185a466746544324135b14f23 100644
|
||||
index 7a9394d4555464312418964f1a7a5d2581496774..3fcd32cc77458ce196ce0e468c1a99f456a57604 100644
|
||||
--- a/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
+++ b/net/minecraft/world/entity/monster/zombie/Zombie.java
|
||||
@@ -314,7 +314,7 @@ public class Zombie extends Monster {
|
||||
|
||||
@@ -5,14 +5,14 @@ Subject: [PATCH] Spawn invulnerable time
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 93bc76af4d0abbe1c526434991e74c4465764ac6..1a43bdcb4c37df4ad1c4dfe6ebb84470832e910f 100644
|
||||
index ec34282744c71c881392ff278a8b03af90de8151..f0d45cb70af62b747c9235941f3fc45221b3b8e6 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -240,6 +240,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private int lastSentFood = -99999999;
|
||||
private boolean lastFoodSaturationZero = true;
|
||||
public int lastSentExp = -99999999;
|
||||
+ private int spawnInvulnerableTime = 60; // Lophine - spawn invulnerable time
|
||||
+ protected int spawnInvulnerableTime = 60; // Lophine - spawn invulnerable time
|
||||
private ChatVisiblity chatVisibility = ChatVisiblity.FULL;
|
||||
public ParticleStatus particleStatus = ParticleStatus.ALL;
|
||||
private boolean canChatColor = true;
|
||||
@@ -24,7 +24,7 @@ index 93bc76af4d0abbe1c526434991e74c4465764ac6..1a43bdcb4c37df4ad1c4dfe6ebb84470
|
||||
if (this.invulnerableTime > 0) {
|
||||
this.invulnerableTime--;
|
||||
}
|
||||
@@ -1538,6 +1540,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -1536,6 +1538,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
if (this.isInvulnerableTo(level, damageSource)) {
|
||||
return false;
|
||||
} else {
|
||||
|
||||
@@ -20,7 +20,7 @@ index 368a9d33f93c2e85abe4cf10df5a85c09fb03dd6..2b78040daeb3b09c08494cbc1d4a9d36
|
||||
Set<CriterionTrigger.Listener<T>> set = (Set) advancements.criterionData.get(this); // Paper - fix PlayerAdvancements leak
|
||||
if (set != null && !set.isEmpty()) {
|
||||
diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
|
||||
index d5e604bf18a223aa434bc9f78274e1f3ff7f203d..715976a49ca621ba40d9353b18d41d342315afd4 100644
|
||||
index 9f444988d40208a1bfa9f147ef80489f81115e93..ab2fa0b86564622501238305714fff014e2b2a56 100644
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -74,7 +74,7 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@@ -33,7 +33,7 @@ index d5e604bf18a223aa434bc9f78274e1f3ff7f203d..715976a49ca621ba40d9353b18d41d34
|
||||
private boolean encrypted;
|
||||
private final java.util.concurrent.atomic.AtomicBoolean disconnectionHandled = new java.util.concurrent.atomic.AtomicBoolean(false); // Folia - region threading - may be called concurrently during configuration stage
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4d2197da3 100644
|
||||
index 8d96d2130cf3383427047fee97fa49155164e337..dfcf8eb7dc422a55d94d6eb9eb1451c7c14a1d56 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -425,6 +425,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -45,7 +45,7 @@ index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
AtomicReference<S> atomicReference = new AtomicReference<>();
|
||||
@@ -1052,6 +1054,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1050,6 +1052,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia end - region threading
|
||||
|
||||
public void stopServer() {
|
||||
@@ -57,7 +57,7 @@ index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4
|
||||
// Folia start - region threading
|
||||
// halt scheduler
|
||||
// don't wait, we may be on a scheduler thread
|
||||
@@ -1665,7 +1672,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1668,7 +1675,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
int i = this.pauseWhenEmptySeconds() * 20;
|
||||
this.removeDisabledPluginsBlockingSleep(); // Paper - API to allow/disallow tick sleeping
|
||||
if (false && i > 0) { // Folia - region threading - this is complicated to implement, and even if done correctly is messy
|
||||
@@ -66,7 +66,15 @@ index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4
|
||||
this.emptyTicks++;
|
||||
} else {
|
||||
this.emptyTicks = 0;
|
||||
@@ -2020,6 +2027,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1801,6 +1808,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.isSaving = true;
|
||||
if (playerSaveInterval > 0) {
|
||||
this.playerList.saveAll(playerSaveInterval);
|
||||
+ org.leavesmc.leaves.bot.BotList.INSTANCE.saveAllResumeBots(playerSaveInterval); // Leaves - resident fakeplayer
|
||||
}
|
||||
for (final ServerLevel level : (region == null ? this.getAllLevels() : Arrays.asList(region.world))) { // Folia - region threading
|
||||
if (level.paperConfig().chunks.autoSaveInterval.value() > 0) {
|
||||
@@ -2021,6 +2029,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
public void tickConnection() {
|
||||
this.getConnection().tick();
|
||||
@@ -74,7 +82,7 @@ index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4
|
||||
}
|
||||
|
||||
private void synchronizeTime(ServerLevel level) {
|
||||
@@ -3154,6 +3162,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -3155,6 +3164,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.debugSubscribers;
|
||||
}
|
||||
|
||||
@@ -92,7 +100,7 @@ index e4d1f0ae66aec2cdc625e3140da094c99350687d..324f9d259c6e0fd814ffe11b62d07fb4
|
||||
@Override
|
||||
public void close() {
|
||||
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
|
||||
index 98004b77b7f40d315f41be82105df6d4b9000e33..cd968c6971d054d9b66a0eaea4753a51ebb75b02 100644
|
||||
index c9e6cd428e4c74b14a992de9ffe85a5a707c4e6b..5bf7eb5b906cefa57a1dfcf828ff7872dbceac4f 100644
|
||||
--- a/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -166,6 +166,11 @@ public class PlayerAdvancements {
|
||||
@@ -125,7 +133,7 @@ index d92492bca62fb02fe7a9e4e220cb8651c4d1e16d..7d0752f9a6a90cf389a9cb5829ab0260
|
||||
return banIp(source, playerByName.getIpAddress(), reason);
|
||||
} else {
|
||||
diff --git a/net/minecraft/server/commands/BanPlayerCommands.java b/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
index 978ef2e996a78e907f959bfe99d47de832427011..b34a077449f1c7bb8a0b5c94fdeb072dcc103797 100644
|
||||
index 978ef2e996a78e907f959bfe99d47de832427011..9644e68ba2c295fcda2d4a3034277520ade91bca 100644
|
||||
--- a/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
+++ b/net/minecraft/server/commands/BanPlayerCommands.java
|
||||
@@ -45,7 +45,15 @@ public class BanPlayerCommands {
|
||||
@@ -135,7 +143,7 @@ index 978ef2e996a78e907f959bfe99d47de832427011..b34a077449f1c7bb8a0b5c94fdeb072d
|
||||
+ boolean hasBot = false; // Leaves - disable kick
|
||||
for (NameAndId nameAndId : players) {
|
||||
+ // Leaves start - disable ban
|
||||
+ if (org.leavesmc.leaves.bot.BotList.INSTANCE.getBot(nameAndId.id()) != null) {
|
||||
+ if (nameAndId.isBot()) {
|
||||
+ source.sendFailure(Component.literal("Permission denied"));
|
||||
+ hasBot = true;
|
||||
+ continue;
|
||||
@@ -197,19 +205,19 @@ index 5f78d629bab84acb2fa43a9fcc1cec52b4e91ae3..1c6059bd23afdd555d2dc8c533a5b027
|
||||
return i;
|
||||
}
|
||||
diff --git a/net/minecraft/server/commands/OpCommand.java b/net/minecraft/server/commands/OpCommand.java
|
||||
index 07332a86e6e0441bafacb020f27ec36a277f1486..3798c1ea92ead20b3b7e67d88d2405f29e324d2c 100644
|
||||
index 07332a86e6e0441bafacb020f27ec36a277f1486..590891d70a71ab30ceae3a3cf1923745e7c20b26 100644
|
||||
--- a/net/minecraft/server/commands/OpCommand.java
|
||||
+++ b/net/minecraft/server/commands/OpCommand.java
|
||||
@@ -43,6 +43,7 @@ public class OpCommand {
|
||||
int i = 0;
|
||||
|
||||
for (NameAndId nameAndId : players) {
|
||||
+ if (org.leavesmc.leaves.bot.BotList.INSTANCE.getBot(nameAndId.id()) != null) continue; // Leaves - disable op
|
||||
+ if (nameAndId.isBot()) continue; // Leaves - disable op
|
||||
if (!playerList.isOp(nameAndId)) {
|
||||
playerList.op(nameAndId);
|
||||
i++;
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 5fbcb5eac1d5449247da77b6120edbe2f2dd1d58..00285e2e68b00d627e91f292da46e9058255ea52 100644
|
||||
index 5fbcb5eac1d5449247da77b6120edbe2f2dd1d58..69cc67b7618d38e65ccb1f4c58013ef116886ad2 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -252,6 +252,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@@ -224,7 +232,7 @@ index 5fbcb5eac1d5449247da77b6120edbe2f2dd1d58..00285e2e68b00d627e91f292da46e905
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
me.earthme.luminol.config.ConfigManager.loadConfigFiles(); // Luminol - load config file
|
||||
fun.bm.lophine.utils.ServerI18nUtil.init(); // Lophine - I18n support
|
||||
+ this.getBotList().loadBotInfo(); // Leaves - load resident bot info
|
||||
+ this.getBotList().loadResumeBotInfo(); // Leaves - load resident bot info
|
||||
if (false) this.server.spark.enableEarlyIfRequested(); // Paper - spark // Luminol - Force disable builtin spark
|
||||
// Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save
|
||||
if (this.convertOldUsers()) {
|
||||
@@ -247,7 +255,7 @@ index fdccb06c918d387e46c29ede7337159db8c5d9ca..4cd5c5659ac098c3b7ff95efb94b1987
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 90e363a310936830788aee6484a63a989aa316e7..c09af6b81987df8e681689ecce9932a2e39af1a3 100644
|
||||
index f5bf8ed6e741823078ab93eac47636fcebcdfe2d..14516c3ebd092e6f230804145a60dc851f34230b 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -220,6 +220,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -266,7 +274,7 @@ index 90e363a310936830788aee6484a63a989aa316e7..c09af6b81987df8e681689ecce9932a2
|
||||
}
|
||||
|
||||
// Folia start - region threading
|
||||
@@ -2469,6 +2471,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2490,6 +2492,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
return this.players;
|
||||
}
|
||||
|
||||
@@ -279,7 +287,7 @@ index 90e363a310936830788aee6484a63a989aa316e7..c09af6b81987df8e681689ecce9932a2
|
||||
@Override
|
||||
public void updatePOIOnBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
Optional<Holder<PoiType>> optional = PoiTypes.forState(oldState);
|
||||
@@ -2942,6 +2950,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2963,6 +2971,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
@@ -291,7 +299,7 @@ index 90e363a310936830788aee6484a63a989aa316e7..c09af6b81987df8e681689ecce9932a2
|
||||
if (serverPlayer.isReceivingWaypoints()) {
|
||||
ServerLevel.this.getWaypointManager().addPlayer(serverPlayer);
|
||||
}
|
||||
@@ -3029,6 +3042,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -3044,6 +3057,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
@@ -304,7 +312,7 @@ index 90e363a310936830788aee6484a63a989aa316e7..c09af6b81987df8e681689ecce9932a2
|
||||
ServerLevel.this.updateSleepingPlayerList();
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 1a43bdcb4c37df4ad1c4dfe6ebb84470832e910f..daff493e4ea944afa91ce99a3596931a487304a3 100644
|
||||
index f0d45cb70af62b747c9235941f3fc45221b3b8e6..132645758827ee4d332909e701dde24e69699beb 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -227,7 +227,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -316,15 +324,6 @@ index 1a43bdcb4c37df4ad1c4dfe6ebb84470832e910f..daff493e4ea944afa91ce99a3596931a
|
||||
private final PlayerAdvancements advancements;
|
||||
private final ServerStatsCounter stats;
|
||||
private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE;
|
||||
@@ -240,7 +240,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private int lastSentFood = -99999999;
|
||||
private boolean lastFoodSaturationZero = true;
|
||||
public int lastSentExp = -99999999;
|
||||
- private int spawnInvulnerableTime = 60; // Lophine - spawn invulnerable time
|
||||
+ public int spawnInvulnerableTime = 60; // Lophine - spawn invulnerable time
|
||||
private ChatVisiblity chatVisibility = ChatVisiblity.FULL;
|
||||
public ParticleStatus particleStatus = ParticleStatus.ALL;
|
||||
private boolean canChatColor = true;
|
||||
@@ -248,7 +248,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
private @Nullable Entity camera;
|
||||
public boolean isChangingDimension;
|
||||
@@ -334,26 +333,16 @@ index 1a43bdcb4c37df4ad1c4dfe6ebb84470832e910f..daff493e4ea944afa91ce99a3596931a
|
||||
private @Nullable Vec3 levitationStartPos;
|
||||
private int levitationStartTime;
|
||||
private boolean disconnected;
|
||||
@@ -440,6 +440,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
private final ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder viewDistanceHolder = new ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.ViewDistanceHolder();
|
||||
+ // Leaves start - player operation limiter
|
||||
+ private int instaBreakCountPerTick = 0;
|
||||
+ private int placeBlockCountPerTick = 0;
|
||||
+ // Leaves end - player operation limiter
|
||||
@@ -1495,7 +1495,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
// Luminol End - Cross Region Damage trace
|
||||
|
||||
@Override
|
||||
public final boolean moonrise$isRealPlayer() {
|
||||
@@ -897,6 +901,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
}
|
||||
// CraftBukkit end
|
||||
this.connection.tickClientLoadTimeout();
|
||||
+ this.resetOperationCountPerTick(); // Leaves - player operation limiter
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
if (this.spawnInvulnerableTime > 0) --this.spawnInvulnerableTime; // Lophine - spawn invulnerable time
|
||||
@@ -2134,6 +2139,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
- private void tellNeutralMobsThatIDied() {
|
||||
+ protected void tellNeutralMobsThatIDied() { // Leaves private -> protected
|
||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||
this.level()
|
||||
.getEntitiesOfClass(Mob.class, aabb, EntitySelector.NO_SPECTATORS)
|
||||
@@ -2132,6 +2132,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
this.teleportSpectators(teleportTransition, serverLevel);
|
||||
@@ -365,40 +354,73 @@ index 1a43bdcb4c37df4ad1c4dfe6ebb84470832e910f..daff493e4ea944afa91ce99a3596931a
|
||||
// CraftBukkit start
|
||||
org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld());
|
||||
this.level().getCraftServer().getPluginManager().callEvent(changeEvent);
|
||||
@@ -3728,4 +3738,31 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity();
|
||||
diff --git a/net/minecraft/server/players/CachedUserNameToIdResolver.java b/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
index 345bdb0ff82b8cd8c63e5ff1f2dabb68a1e54b77..c9a7c1c37155e0d339b880179a5988c9a6cb3797 100644
|
||||
--- a/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
+++ b/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
@@ -122,6 +122,12 @@ public class CachedUserNameToIdResolver implements UserNameToIdResolver {
|
||||
|
||||
@Override
|
||||
public Optional<NameAndId> get(String name) {
|
||||
+ // Leaves start - fix bot
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = org.leavesmc.leaves.bot.BotList.INSTANCE.getBotByName(name);
|
||||
+ if (bot != null) {
|
||||
+ return Optional.of(bot.nameAndId());
|
||||
+ }
|
||||
+ // Leaves end - fix bot
|
||||
String string = name.toLowerCase(Locale.ROOT);
|
||||
boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
CachedUserNameToIdResolver.GameProfileInfo gameProfileInfo = this.profilesByName.get(string);
|
||||
diff --git a/net/minecraft/server/players/NameAndId.java b/net/minecraft/server/players/NameAndId.java
|
||||
index 05b4a75f6597e8613c91344d100bb7f005d169a7..9a5006362c12e972d031c48be4d30362d88d1c00 100644
|
||||
--- a/net/minecraft/server/players/NameAndId.java
|
||||
+++ b/net/minecraft/server/players/NameAndId.java
|
||||
@@ -8,18 +8,22 @@ import java.util.UUID;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
-public record NameAndId(UUID id, String name) {
|
||||
+public record NameAndId(UUID id, String name, boolean isBot) { // Leaves - fakeplayer
|
||||
public static final Codec<NameAndId> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(UUIDUtil.STRING_CODEC.fieldOf("id").forGetter(NameAndId::id), Codec.STRING.fieldOf("name").forGetter(NameAndId::name))
|
||||
.apply(instance, NameAndId::new)
|
||||
);
|
||||
|
||||
public NameAndId(GameProfile profile) {
|
||||
- this(profile.id(), profile.name());
|
||||
+ this(profile.id(), profile.name(), com.google.common.collect.Iterables.getFirst(profile.properties().get("is_bot"), "false").equals("true")); // Leaves - fakeplayer
|
||||
}
|
||||
// CraftBukkit end
|
||||
+
|
||||
+ // Leaves start - player operation limiter
|
||||
+ protected void resetOperationCountPerTick() {
|
||||
+ instaBreakCountPerTick = 0;
|
||||
+ placeBlockCountPerTick = 0;
|
||||
|
||||
public NameAndId(com.mojang.authlib.yggdrasil.response.NameAndId nameAndId) {
|
||||
- this(nameAndId.id(), nameAndId.name());
|
||||
+ this(nameAndId.id(), nameAndId.name(), false); // Leaves - fakeplayer
|
||||
+ }
|
||||
+
|
||||
+ public int getInstaBreakCountPerTick() {
|
||||
+ return instaBreakCountPerTick;
|
||||
+ }
|
||||
+
|
||||
+ public int getPlaceBlockCountPerTick() {
|
||||
+ return placeBlockCountPerTick;
|
||||
+ }
|
||||
+
|
||||
+ public void addInstaBreakCountPerTick() {
|
||||
+ ++instaBreakCountPerTick;
|
||||
+ }
|
||||
+
|
||||
+ public void addPlaceBlockCountPerTick() {
|
||||
+ ++placeBlockCountPerTick;
|
||||
+ }
|
||||
+
|
||||
+ public boolean allowOperation() {
|
||||
+ return (instaBreakCountPerTick == 0 || placeBlockCountPerTick == 0) && (instaBreakCountPerTick <= 1 && placeBlockCountPerTick <= 2);
|
||||
+ }
|
||||
+ // Leaves end - player operation limiter
|
||||
}
|
||||
+ public NameAndId(UUID uuid, String name) {
|
||||
+ this(uuid, name, false); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
public static @Nullable NameAndId fromJson(JsonObject json) {
|
||||
@@ -33,7 +37,7 @@ public record NameAndId(UUID id, String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
- return new NameAndId(uuid, json.get("name").getAsString());
|
||||
+ return new NameAndId(uuid, json.get("name").getAsString(), false); // Leaves - fakeplayer
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -46,7 +50,7 @@ public record NameAndId(UUID id, String name) {
|
||||
|
||||
public static NameAndId createOffline(String name) {
|
||||
UUID uuid = UUIDUtil.createOfflinePlayerUUID(name);
|
||||
- return new NameAndId(uuid, name);
|
||||
+ return new NameAndId(uuid, name, false); // Leaves - fakeplayer
|
||||
}
|
||||
|
||||
// Paper start - utility method for common conversion back to the game profile
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3c96739a6 100644
|
||||
index 0d322ef4aa3e70c9edbb9fa8ba368bef916eb93d..3a5319739f0687fc6f09b2ac8ee31716593fe0de 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -317,6 +317,19 @@ public abstract class PlayerList {
|
||||
@@ -409,7 +431,7 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
|
||||
+ if (bot != null) {
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, true);
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
|
||||
+ }
|
||||
+ this.server.getBotList().bots.forEach(bot1 -> {
|
||||
+ bot1.sendPlayerInfo(player);
|
||||
@@ -421,7 +443,7 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
||||
|
||||
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
|
||||
@@ -791,6 +804,13 @@ public abstract class PlayerList {
|
||||
@@ -791,6 +804,12 @@ public abstract class PlayerList {
|
||||
).callEvent();
|
||||
// Paper end
|
||||
|
||||
@@ -430,12 +452,11 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
+ this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(serverPlayer, true)); // Leaves - render bot
|
||||
+ }
|
||||
+ // Leaves end - bot support
|
||||
+
|
||||
+
|
||||
return serverPlayer;
|
||||
}
|
||||
|
||||
@@ -892,11 +912,16 @@ public abstract class PlayerList {
|
||||
@@ -892,11 +911,16 @@ public abstract class PlayerList {
|
||||
|
||||
public String[] getPlayerNamesArray() {
|
||||
List<ServerPlayer> players = new java.util.ArrayList<>(this.players); // Folia - region threading
|
||||
@@ -453,7 +474,7 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
|
||||
return strings;
|
||||
}
|
||||
@@ -1016,7 +1041,14 @@ public abstract class PlayerList {
|
||||
@@ -1016,7 +1040,14 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayerByName(String username) {
|
||||
@@ -469,7 +490,7 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
}
|
||||
|
||||
public void broadcast(@Nullable Player except, double x, double y, double z, double radius, ResourceKey<Level> dimension, Packet<?> packet) {
|
||||
@@ -1353,7 +1385,13 @@ public abstract class PlayerList {
|
||||
@@ -1353,7 +1384,13 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayer(UUID playerUUID) {
|
||||
@@ -484,39 +505,11 @@ index 66e7b62a57eada0f0db7d9cc1be6362ac1e3ee85..95e7d3245bb38bf33a401648143522d3
|
||||
}
|
||||
|
||||
public @Nullable ServerPlayer getPlayer(String name) {
|
||||
diff --git a/net/minecraft/server/waypoints/ServerWaypointManager.java b/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
index d2c0b532200f274e44f18147d294dfe5d3f52d1d..55133071b97400dfb3ed6615c30006003de492c5 100644
|
||||
--- a/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
+++ b/net/minecraft/server/waypoints/ServerWaypointManager.java
|
||||
@@ -24,6 +24,11 @@ public class ServerWaypointManager implements WaypointManager<WaypointTransmitte
|
||||
public void trackWaypoint(WaypointTransmitter waypoint) {
|
||||
// Lophine start - unsafe waypoint bar
|
||||
if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ // Leaves start - fakeplayer
|
||||
+ if (waypoint instanceof org.leavesmc.leaves.bot.ServerBot bot && !bot.getConfigValue(org.leavesmc.leaves.bot.agent.Configs.ENABLE_LOCATOR_BAR)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
this.waypoints.add(waypoint);
|
||||
|
||||
for (ServerPlayer serverPlayer : this.players) {
|
||||
@@ -61,6 +66,11 @@ public class ServerWaypointManager implements WaypointManager<WaypointTransmitte
|
||||
// Folia - region threading
|
||||
// Lophine start - unsafe waypoint bar
|
||||
if (!fun.bm.lophine.config.modules.experiment.CommandConfig.waypoint) return;
|
||||
+ // Leaves start - fakeplayer
|
||||
+ if (player instanceof org.leavesmc.leaves.bot.ServerBot) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - fakeplayer
|
||||
this.players.add(player);
|
||||
|
||||
for (WaypointTransmitter waypointTransmitter : this.waypoints) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 0f213d1cfab6066f6713c5b2124b76409510454c..5bcf646ef600a2aae7633453d3331fde2f141aff 100644
|
||||
index 32299faedd89a848ca00288672ce85cad707dca0..3e44a61bd982dc822437f647a02a95affd988cdb 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1252,7 +1252,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
@@ -1235,7 +1235,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
|
||||
BlockPos onPosLegacy = this.getOnPosLegacy();
|
||||
BlockState blockState = this.level().getBlockState(onPosLegacy);
|
||||
@@ -525,7 +518,7 @@ index 0f213d1cfab6066f6713c5b2124b76409510454c..5bcf646ef600a2aae7633453d3331fde
|
||||
this.checkFallDamage(vec3.y, this.onGround(), blockState, onPosLegacy);
|
||||
}
|
||||
|
||||
@@ -1577,7 +1577,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
@@ -1570,7 +1570,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
}
|
||||
|
||||
// Paper start - optimise collisions
|
||||
@@ -535,10 +528,10 @@ index 0f213d1cfab6066f6713c5b2124b76409510454c..5bcf646ef600a2aae7633453d3331fde
|
||||
final boolean yZero = movement.y == 0.0;
|
||||
final boolean zZero = movement.z == 0.0;
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 67faf1ed52806ee2c1e2ea080b39959ad9ae986d..f80f5533c1c3c64ee1b8b2c43e2bc2dea8ab567f 100644
|
||||
index 3fe9afe55b4d61db8030479d3d74b8656679cb10..c0ebd700caa950948c58846eaf164afc14f87f09 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3304,7 +3304,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -3319,7 +3319,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
private void travelRidden(Player player, Vec3 travelVector) {
|
||||
Vec3 riddenInput = this.getRiddenInput(player, travelVector);
|
||||
this.tickRidden(player, riddenInput);
|
||||
@@ -547,16 +540,16 @@ index 67faf1ed52806ee2c1e2ea080b39959ad9ae986d..f80f5533c1c3c64ee1b8b2c43e2bc2de
|
||||
this.setSpeed(this.getRiddenSpeed(player));
|
||||
this.travel(riddenInput);
|
||||
} else {
|
||||
@@ -4213,7 +4213,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -4228,7 +4228,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
// Paper start - lag compensate eating
|
||||
// we add 1 to the expected time to avoid lag compensating when we should not
|
||||
final boolean shouldLagCompensate = this.useItem.has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1L + this.totalEatTimeTicks) * 50L * (1000L * 1000L));
|
||||
- if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level().isClientSide() && !usingItem.useOnRelease()) {
|
||||
+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !(this instanceof org.leavesmc.leaves.bot.ServerBot) && !this.level().isClientSide() && !usingItem.useOnRelease()) { // Leaves - Fakeplayer skip this check
|
||||
+ if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !(this instanceof org.leavesmc.leaves.bot.ServerBot) && !this.level().isClientSide() && !usingItem.useOnRelease()) {
|
||||
this.useItemRemaining = 0;
|
||||
// Paper end - lag compensate eating
|
||||
this.completeUsingItem();
|
||||
@@ -4397,6 +4397,23 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
@@ -4413,6 +4413,23 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
this.stopUsingItem();
|
||||
}
|
||||
|
||||
@@ -581,7 +574,7 @@ index 67faf1ed52806ee2c1e2ea080b39959ad9ae986d..f80f5533c1c3c64ee1b8b2c43e2bc2de
|
||||
if (!this.level().isClientSide()) {
|
||||
boolean isUsingItem = this.isUsingItem();
|
||||
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
||||
index 1e3ac806c3f111ee0a4f8ef47134941ec85fbe6e..52c41d1e526dc0d42dde3773ab20ee7252737e5d 100644
|
||||
index 83612969b6058f444fc17e360cdcc4a8846f79aa..29ca31b05ec5636243b13fee8b3399d5e21808b4 100644
|
||||
--- a/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -168,7 +168,7 @@ public abstract class Player extends Avatar implements ContainerUser {
|
||||
@@ -668,7 +661,7 @@ index fc1b3501114108d0166256c514a225337955e461..56bc87fefc82c77077bfed50accbde77
|
||||
return switch (this.getStatus()) {
|
||||
case IN_WATER, UNDER_WATER, UNDER_FLOWING_WATER -> SoundEvents.BOAT_PADDLE_WATER;
|
||||
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
index 8e28afcfda7b180def81122e35920f6fd57a4574..f42697374461ab2e1c610b8c3250d3c03c0821b4 100644
|
||||
index e7ea8849e8fa942709f505145e8076f064476206..4935234fba5977246aa303bf8162404813b5491e 100644
|
||||
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
|
||||
@@ -404,6 +404,7 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -679,7 +672,7 @@ index 8e28afcfda7b180def81122e35920f6fd57a4574..f42697374461ab2e1c610b8c3250d3c0
|
||||
if (clickType == ClickType.QUICK_CRAFT) {
|
||||
int i = this.quickcraftStatus;
|
||||
this.quickcraftStatus = getQuickcraftHeader(button);
|
||||
@@ -682,6 +683,22 @@ public abstract class AbstractContainerMenu {
|
||||
@@ -678,6 +679,22 @@ public abstract class AbstractContainerMenu {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -703,7 +696,7 @@ index 8e28afcfda7b180def81122e35920f6fd57a4574..f42697374461ab2e1c610b8c3250d3c0
|
||||
FeatureFlagSet featureFlagSet = player.level().enabledFeatures();
|
||||
return carriedItem.isItemEnabled(featureFlagSet) && carriedItem.overrideStackedOnOther(slot, action, player)
|
||||
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
|
||||
index a688da5bc71799c13548d390ab58645da9128229..e63cca6f7f63a2b5f249ae01033167186e710fdb 100644
|
||||
index 73a97f4f62fe7d27b441cab58c6c86ffce011060..ea6285b7f53f391c84519aa7ae39164cf5740b81 100644
|
||||
--- a/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/net/minecraft/world/item/ItemStack.java
|
||||
@@ -456,7 +456,7 @@ public final class ItemStack implements DataComponentHolder, ChangePublisher<net
|
||||
@@ -737,7 +730,7 @@ index a688da5bc71799c13548d390ab58645da9128229..e63cca6f7f63a2b5f249ae0103316718
|
||||
return this.getItem().useOnRelease(this);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
index adc8c8a7b8a02cf395e919eb51aefc47ff6ed9ab..225fedb32b100a0f24e001e442c0bae44acb0284 100644
|
||||
index 557ea70254a8d6dd87c656098c5632bdcbe3df8f..1d60054146f970ec24054d2c76a27e2d8620ec67 100644
|
||||
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||||
@@ -145,7 +145,7 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
||||
@@ -778,16 +771,3 @@ index bef794c3f58c41d910aa0bcc63fbdeea7225fddf..a601da588e6973cc5b87d3e3eeba49b5
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index b8ef50bc3d07890c9da2c98d5f009a3adc52f4b0..f37de9384005f53631cc3e122c74e4793dff4be0 100644
|
||||
--- a/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -19,7 +19,7 @@ import net.minecraft.util.datafix.DataFixTypes;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public class PlayerDataStorage {
|
||||
+public class PlayerDataStorage implements org.leavesmc.leaves.bot.IPlayerDataStorage {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final File playerDir;
|
||||
protected final DataFixer fixerUpper;
|
||||
|
||||
@@ -9,7 +9,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index df6ad5831f83fcc869b0b4ed844a73b3cb81c469..5c81be29f7ecc3389b5b578f85774035def96e26 100644
|
||||
index 1a749d9bee139975fa249839df93c3a1e48bf102..d81e22fe65cded98c201a7bbae8a51b22c6a20b4 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -338,9 +338,12 @@ public class ServerGamePacketListenerImpl
|
||||
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 173a55715b9c459eeb93cdc065c69e64fc704b43..b2694cb60505766877398fa526b9bfe60e6b6404 100644
|
||||
index 435acf0fe5e80ca371d1145befc2cfaa917a89e3..77577d0df9b14a7ad55b2866c2ac31863226458b 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -758,6 +758,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 13:33:19 +0800
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Fri, 13 Feb 2026 16:17:36 +0800
|
||||
Subject: [PATCH] Leaves: Jade Protocol
|
||||
|
||||
This patch is Powered by Jade(https://github.com/Snownee/Jade)
|
||||
@@ -9,10 +9,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index daff493e4ea944afa91ce99a3596931a487304a3..f79735abf21b6eecc02e5b5f1ce3140dfef3ede9 100644
|
||||
index 132645758827ee4d332909e701dde24e69699beb..3efce8ae3cba85019aea7453f97a72939baef7f6 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1458,7 +1458,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -1451,7 +1451,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
} else if (fun.bm.lophine.config.modules.experiment.EntityDamageSourceTraceConfig.enabled) {
|
||||
final LivingEntity entitylivingnew = this.getKillCreditOrigin();
|
||||
if (entitylivingnew != null) {
|
||||
@@ -22,18 +22,18 @@ index daff493e4ea944afa91ce99a3596931a487304a3..f79735abf21b6eecc02e5b5f1ce3140d
|
||||
// Luminol End - Cross Region Damage trace
|
||||
}
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 5c81be29f7ecc3389b5b578f85774035def96e26..98d641b2e8ca340cb10fe0448f8a8b4f8446f616 100644
|
||||
index d81e22fe65cded98c201a7bbae8a51b22c6a20b4..43e9fd5684d15f8643524132e60266071c6dc454 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3798,7 +3798,7 @@ public class ServerGamePacketListenerImpl
|
||||
} else if (this.clientLoadedTimeoutTimer == 1) markClientLoaded(); // Paper - Add PlayerLoadedWorldEvent - decrement by calling #markClientLoaded which will set the value to 0 *and* call the event.
|
||||
@@ -3835,7 +3835,7 @@ public class ServerGamePacketListenerImpl
|
||||
}
|
||||
|
||||
@Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add PlayerLoadedWorldEvent
|
||||
- private void markClientLoaded() {
|
||||
+ public void markClientLoaded() { // Lophine - private -> public
|
||||
// Paper start - Add PlayerLoadedWorldEvent
|
||||
if (!hasClientLoaded()) {
|
||||
final io.papermc.paper.event.player.PlayerClientLoadedWorldEvent event = new io.papermc.paper.event.player.PlayerClientLoadedWorldEvent(this.player.getBukkitEntity(), true);
|
||||
this.markClientLoaded(false);
|
||||
}
|
||||
diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
index 901e4e9897e76cd4158d7f8bb8ec829df8ff8196..59b9373c7a14e42d9e5f691354a7616d16856215 100644
|
||||
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
|
||||
@@ -8,13 +8,13 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 95e7d3245bb38bf33a401648143522d3c96739a6..98f2ced8e6afdf0074ade94e0bbf5498bd6c505f 100644
|
||||
index 3a5319739f0687fc6f09b2ac8ee31716593fe0de..36cd1a0307ff1a734eb5f4f3cc013781692e7ad8 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1127,6 +1127,7 @@ public abstract class PlayerList {
|
||||
player.connection.send(new ClientboundSetChunkCacheRadiusPacket(level.spigotConfig.viewDistance));
|
||||
player.connection.send(new ClientboundSetSimulationDistancePacket(level.spigotConfig.simulationDistance));
|
||||
// Paper end
|
||||
@@ -1126,6 +1126,7 @@ public abstract class PlayerList {
|
||||
//player.connection.send(new ClientboundSetChunkCacheRadiusPacket(io.papermc.paper.FeatureHooks.getViewDistance(level))); // Paper - rewrite chunk system
|
||||
//player.connection.send(new ClientboundSetSimulationDistancePacket(io.papermc.paper.FeatureHooks.getSimulationDistance(level))); // Paper - rewrite chunk system
|
||||
// Paper end - view distances
|
||||
+ org.leavesmc.leaves.protocol.XaeroMapProtocol.onSendWorldInfo(player); // Leaves - xaero map protocol
|
||||
if (level.isRaining()) {
|
||||
// CraftBukkit start - handle player weather
|
||||
|
||||
@@ -10,7 +10,7 @@ Licensed under: MIT
|
||||
This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 6a51bace3151646afae9de820d9c8977a0221df4..8dd50507bbc9f61c9ae019eecc5e9338d20addff 100644
|
||||
index 6a51bace3151646afae9de820d9c8977a0221df4..474ca0ce0d3095fc586f8f9e9a584ed4f7c91471 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -229,8 +229,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -72,7 +72,7 @@ index 6a51bace3151646afae9de820d9c8977a0221df4..8dd50507bbc9f61c9ae019eecc5e9338
|
||||
+ for (int i = 0; i < container.getContainerSize(); ++i) {
|
||||
+ if (!container.getItem(i).isEmpty()) {
|
||||
+ ItemStack itemstack = container.getItem(i);
|
||||
+ org.leavesmc.leaves.util.HopperCounter.getCounter(woolColor).add(level, itemstack);
|
||||
+ org.leavesmc.leaves.util.HopperCounter.getCounter(woolColor).add(level.getServer(), itemstack);
|
||||
+ container.setItem(i, ItemStack.EMPTY);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+3
-3
@@ -13,10 +13,10 @@ MasaGadget(https://github.com/plusls/MasaGadget)
|
||||
litematica(https://github.com/maruohon/litematica)
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 98d641b2e8ca340cb10fe0448f8a8b4f8446f616..878f5c5801b68e3a6d01d63caf44737841387600 100644
|
||||
index 43e9fd5684d15f8643524132e60266071c6dc454..62db0ba9c824959f953d452ab7aafcde01b10bcd 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2128,7 +2128,7 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -2134,7 +2134,7 @@ public class ServerGamePacketListenerImpl
|
||||
if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(this.player.level(), blockPos.getX() >> 4, blockPos.getZ() >> 4, 8) && this.player.isWithinBlockInteractionRange(blockPos, 1.0)) { // Folia - do not allow players to interact with blocks outside the current region
|
||||
Vec3 vec3 = location.subtract(Vec3.atCenterOf(blockPos));
|
||||
double d = 1.0000001;
|
||||
@@ -60,7 +60,7 @@ index d75c95d728efc0b4064f562ca80b68b23883feaf..be685383b8e7c8111e976fc560f16d43
|
||||
blockState = blockState1;
|
||||
break;
|
||||
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
|
||||
index 13f06f1fbdf77b88493333b481b951d729579f11..e0ab4f7372ed11c9d17b341c8a24a82350c714fa 100644
|
||||
index 492b1615d96133c5082e0f16015f114299f8082f..fb47a2acb0e4232359f5da061c1620a7b1d6c476 100644
|
||||
--- a/net/minecraft/world/level/block/Block.java
|
||||
+++ b/net/minecraft/world/level/block/Block.java
|
||||
@@ -489,6 +489,32 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
|
||||
@@ -84,10 +84,10 @@ index af71e0e1eb1c93745f3e4954ecc8fbd2ad4808a3..f3829564681faff3ae8971ed90b947b4
|
||||
players.add(serverPlayer1);
|
||||
if (players.size() >= resultLimit) {
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a465408bf341a 100644
|
||||
index dfcf8eb7dc422a55d94d6eb9eb1451c7c14a1d56..9130f1fbf15500f2149418b73ae2a374bba22eee 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1894,7 +1894,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1896,7 +1896,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
private ServerStatus.Players buildPlayerStatus() {
|
||||
@@ -96,7 +96,7 @@ index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a4654
|
||||
int maxPlayers = this.getMaxPlayers();
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
|
||||
@@ -2103,7 +2103,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2105,7 +2105,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
@@ -105,7 +105,7 @@ index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a4654
|
||||
}
|
||||
|
||||
public String[] getPlayerNames() {
|
||||
@@ -2307,7 +2307,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2309,7 +2309,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
@@ -114,7 +114,7 @@ index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a4654
|
||||
serverPlayer.getBukkitEntity().taskScheduler.schedule((ServerPlayer player) -> { // Folia - region threading
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
org.bukkit.event.player.PlayerGameModeChangeEvent event = player.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null); // Folia - region threading
|
||||
@@ -2492,7 +2492,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2494,7 +2494,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (Thread.currentThread() != this.serverThread) return; // Paper
|
||||
// Paper start - we don't need to save everything, just advancements
|
||||
// this.getPlayerList().saveAll();
|
||||
@@ -123,7 +123,7 @@ index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a4654
|
||||
player.getAdvancements().save();
|
||||
}
|
||||
// Paper end - we don't need to save everything, just advancements
|
||||
@@ -2630,7 +2630,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2632,7 +2632,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
PlayerList playerList = this.getPlayerList();
|
||||
UserWhiteList whiteList = playerList.getWhiteList();
|
||||
|
||||
@@ -133,7 +133,7 @@ index 324f9d259c6e0fd814ffe11b62d07fb4d2197da3..9d334ed3307f3c4c82bb5300219a4654
|
||||
serverPlayer.connection.disconnect(net.kyori.adventure.text.Component.text(org.spigotmc.SpigotConfig.whitelistMessage), org.bukkit.event.player.PlayerKickEvent.Cause.WHITELIST); // Paper - use configurable message & kick event cause
|
||||
}
|
||||
diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java
|
||||
index cd968c6971d054d9b66a0eaea4753a51ebb75b02..9525d77c379264289db4256e8275378d9cfa9f63 100644
|
||||
index 5bf7eb5b906cefa57a1dfcf828ff7872dbceac4f..85923708c32a0597e98e028eeec501f2ea07b63b 100644
|
||||
--- a/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -167,7 +167,7 @@ public class PlayerAdvancements {
|
||||
@@ -146,7 +146,7 @@ index cd968c6971d054d9b66a0eaea4753a51ebb75b02..9525d77c379264289db4256e8275378d
|
||||
}
|
||||
// Leaves end - bot can't get advancement
|
||||
diff --git a/net/minecraft/server/ServerScoreboard.java b/net/minecraft/server/ServerScoreboard.java
|
||||
index a938ae0f340aaece1fdbe3f6d517809563b1b0f5..e9f2c50c0e87b32627ad16910e1f4a816f4efc5f 100644
|
||||
index 04a62e5ab9c0d0b9b7959280b0e0ea3ff388c017..e4260ec1938a43d41e007ad67a2b5be96a00227c 100644
|
||||
--- a/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -249,7 +249,7 @@ public class ServerScoreboard extends Scoreboard {
|
||||
@@ -181,7 +181,7 @@ index e7c778a7f292fd0749cbd5e6586ad1b93ac7f29e..024b56405bb58801b17a6adad7fec7a4
|
||||
org.bukkit.entity.Player sender = (org.bukkit.entity.Player) source.getBukkitSender();
|
||||
playersTemp = playersTemp.stream().filter((ep) -> sender.canSee(ep.getBukkitEntity())).collect(java.util.stream.Collectors.toList());
|
||||
diff --git a/net/minecraft/server/commands/OpCommand.java b/net/minecraft/server/commands/OpCommand.java
|
||||
index 3798c1ea92ead20b3b7e67d88d2405f29e324d2c..922383a284c8fb3c183d8a15dc41d813451adfb3 100644
|
||||
index 590891d70a71ab30ceae3a3cf1923745e7c20b26..0ede1e5c73a0071e854de70f81ae1fc6a1d6dc59 100644
|
||||
--- a/net/minecraft/server/commands/OpCommand.java
|
||||
+++ b/net/minecraft/server/commands/OpCommand.java
|
||||
@@ -25,7 +25,7 @@ public class OpCommand {
|
||||
@@ -284,10 +284,10 @@ index 5a8cd3e6b448a4472092690cf589bca10b142126..158593b1a6384db635a1f224919b24c1
|
||||
|
||||
this.setListData(list);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index c09af6b81987df8e681689ecce9932a2e39af1a3..b3c593474e889d254f59813e7f42299b7b77d9ce 100644
|
||||
index 14516c3ebd092e6f230804145a60dc851f34230b..bd33a381490ec3f03af9d22c9337f5d686014d85 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2951,7 +2951,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2972,7 +2972,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
// Leaves start - skip
|
||||
@@ -296,7 +296,7 @@ index c09af6b81987df8e681689ecce9932a2e39af1a3..b3c593474e889d254f59813e7f42299b
|
||||
ServerLevel.this.realPlayers.add(serverPlayer);
|
||||
}
|
||||
// Leaves end - skip
|
||||
@@ -3043,7 +3043,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -3058,7 +3058,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
// Leaves start - skip
|
||||
@@ -306,7 +306,7 @@ index c09af6b81987df8e681689ecce9932a2e39af1a3..b3c593474e889d254f59813e7f42299b
|
||||
}
|
||||
// Leaves end - skip
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index f79735abf21b6eecc02e5b5f1ce3140dfef3ede9..04a600d96f4ae7c08d06dc4fb8f71b3f0eb1be07 100644
|
||||
index 3efce8ae3cba85019aea7453f97a72939baef7f6..0741dc695c0b22a6edd9a51a9dcdec0cdd545326 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -202,7 +202,7 @@ import org.jspecify.annotations.Nullable;
|
||||
@@ -318,7 +318,7 @@ index f79735abf21b6eecc02e5b5f1ce3140dfef3ede9..04a600d96f4ae7c08d06dc4fb8f71b3f
|
||||
public static final long LAST_SAVE_ABSENT = Long.MIN_VALUE; public long lastSave = LAST_SAVE_ABSENT; // Paper // Folia - threaded regions - changed to nanoTime
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
|
||||
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
|
||||
@@ -673,7 +673,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
@@ -669,7 +669,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
this.loadGameTypes(input);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ index f79735abf21b6eecc02e5b5f1ce3140dfef3ede9..04a600d96f4ae7c08d06dc4fb8f71b3f
|
||||
if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
|
||||
this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 98f2ced8e6afdf0074ade94e0bbf5498bd6c505f..4dcb90709200b33fc9155f6dea4281ed32427889 100644
|
||||
index 36cd1a0307ff1a734eb5f4f3cc013781692e7ad8..0c3e6c1f70289c63bfe424a49374602f25ff5c0b 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -130,6 +130,7 @@ public abstract class PlayerList {
|
||||
@@ -356,7 +356,7 @@ index 98f2ced8e6afdf0074ade94e0bbf5498bd6c505f..4dcb90709200b33fc9155f6dea4281ed
|
||||
+
|
||||
+ LevelData worlddata = worldserver1.getLevelData();
|
||||
+
|
||||
+ player.loadGameTypes(null);
|
||||
+ //player.loadGameTypes(null); // simply fix for https://github.com/MC-XiaoHei/ISeeYou/issues/70
|
||||
+ ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, CommonListenerCookie.createInitial(player.gameProfile, false));
|
||||
+ GameRules gamerules = worldserver1.getGameRules();
|
||||
+ boolean flag = gamerules.get(GameRules.IMMEDIATE_RESPAWN);
|
||||
@@ -405,7 +405,7 @@ index 98f2ced8e6afdf0074ade94e0bbf5498bd6c505f..4dcb90709200b33fc9155f6dea4281ed
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
|
||||
+ if (bot != null) {
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false);
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, false);
|
||||
+ }
|
||||
+ this.server.getBotList().bots.forEach(bot1 -> {
|
||||
+ bot1.sendPlayerInfo(player);
|
||||
@@ -532,7 +532,7 @@ index 98f2ced8e6afdf0074ade94e0bbf5498bd6c505f..4dcb90709200b33fc9155f6dea4281ed
|
||||
this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
|
||||
this.server.getCustomBossEvents().onPlayerDisconnect(player);
|
||||
UUID uuid = player.getUUID();
|
||||
@@ -911,15 +1070,15 @@ public abstract class PlayerList {
|
||||
@@ -910,15 +1069,15 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public String[] getPlayerNamesArray() {
|
||||
@@ -553,7 +553,7 @@ index 98f2ced8e6afdf0074ade94e0bbf5498bd6c505f..4dcb90709200b33fc9155f6dea4281ed
|
||||
// Leaves end - fakeplayer support
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index f80f5533c1c3c64ee1b8b2c43e2bc2dea8ab567f..aa9cbb5f02b87789fd94521792aefac5c840c95a 100644
|
||||
index c0ebd700caa950948c58846eaf164afc14f87f09..e4ae4354e81f34f0db410333fc9b8e17383a5f41 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -262,7 +262,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
|
||||
+34
-21
@@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Sat, 15 Nov 2025 01:06:20 +0800
|
||||
Date: Sat, 7 Feb 2026 23:57:50 +0800
|
||||
Subject: [PATCH] Leaves: Catch update suppression crash
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/network/PacketProcessor.java b/net/minecraft/network/PacketProcessor.java
|
||||
index e07e5eced7e32d1c3a0ac14e8639c1f19b0f641a..fe7483581e5c3f5cb523601b394750a94a178e10 100644
|
||||
index cf162ec136309d05c5aa03042652ab3932935917..469ffd54eb5af980f49061bbec0a72f4e888f8a3 100644
|
||||
--- a/net/minecraft/network/PacketProcessor.java
|
||||
+++ b/net/minecraft/network/PacketProcessor.java
|
||||
@@ -107,7 +107,20 @@ public class PacketProcessor implements AutoCloseable {
|
||||
@@ -46,10 +46,10 @@ index ab80a66646a7ebe2862221ac342b06c14fcfc734..7834f3da4d0ff4a5cdec46b023d73483
|
||||
fillCrashReport(reportedException.getReport(), packetListener, packet);
|
||||
return reportedException;
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 9d334ed3307f3c4c82bb5300219a465408bf341a..f2f57cfcd7739a951123c81f82cac1c2bbd3a3bd 100644
|
||||
index 9130f1fbf15500f2149418b73ae2a374bba22eee..eef40103bcec3b836ffb50154fb05926b9757723 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1973,8 +1973,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1975,11 +1975,27 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
try {
|
||||
profiler.startTimer(serverLevel.tickTimerId); try { // Folia - profiler
|
||||
serverLevel.tick(hasTimeLeft, region); // Folia - region threading
|
||||
@@ -59,19 +59,32 @@ index 9d334ed3307f3c4c82bb5300219a465408bf341a..f2f57cfcd7739a951123c81f82cac1c2
|
||||
+ exception.consume();
|
||||
} finally { profiler.stopTimer(serverLevel.tickTimerId); } // Folia - profiler
|
||||
} catch (Throwable var7) {
|
||||
+ if (var7.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.provideLevel(serverLevel);
|
||||
+ exception.consume();
|
||||
- CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
- serverLevel.fillReportDetails(crashReport);
|
||||
- throw new ReportedException(crashReport);
|
||||
+ org.leavesmc.leaves.util.UpdateSuppressionException updateSuppressionException = null;
|
||||
+ if (var7 instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ updateSuppressionException = exception;
|
||||
+ } else if (var7.getCause() instanceof org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ updateSuppressionException = exception;
|
||||
+ }
|
||||
+ // Leaves end - update suppression crash fix
|
||||
CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
serverLevel.fillReportDetails(crashReport);
|
||||
throw new ReportedException(crashReport);
|
||||
+ if (updateSuppressionException != null) {
|
||||
+ updateSuppressionException.provideLevel(serverLevel);
|
||||
+ updateSuppressionException.consume();
|
||||
+ } else {
|
||||
+ // Leaves end - update suppression crash fix
|
||||
+ CrashReport crashReport = CrashReport.forThrowable(var7, "Exception ticking world");
|
||||
+ serverLevel.fillReportDetails(crashReport);
|
||||
+ throw new ReportedException(crashReport);
|
||||
+ }
|
||||
}
|
||||
|
||||
profilerFiller.pop();
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index b3c593474e889d254f59813e7f42299b7b77d9ce..b878f5a8316dfee582180a6bbe7122a78581fae2 100644
|
||||
index bd33a381490ec3f03af9d22c9337f5d686014d85..284bd9703b11804f51273ecfaa5cd44925726f5f 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -878,7 +878,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -894,7 +894,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Kaiiju end
|
||||
|
||||
profilerFiller.push("tick");
|
||||
@@ -79,7 +92,7 @@ index b3c593474e889d254f59813e7f42299b7b77d9ce..b878f5a8316dfee582180a6bbe7122a7
|
||||
+ // Lophine start - update suppression crash fix
|
||||
+ if (fun.bm.lophine.config.modules.fixes.UpdateSuppressionCrashFixConfig.enabled) {
|
||||
+ try {
|
||||
+ this.tickNonPassenger(entity); // Lophine changed
|
||||
+ this.guardEntityTick(this::tickNonPassenger, entity); // Lophine changed
|
||||
+ // Leaves start - update suppression crash fix - for dragon dupe
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
+ exception.provideLevel(this);
|
||||
@@ -94,12 +107,12 @@ index b3c593474e889d254f59813e7f42299b7b77d9ce..b878f5a8316dfee582180a6bbe7122a7
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||
index 04a600d96f4ae7c08d06dc4fb8f71b3f0eb1be07..45e4e3243c72b01d94dc440b26230a48b3909367 100644
|
||||
index 0741dc695c0b22a6edd9a51a9dcdec0cdd545326..3fc09529159d202ce6201626be535d791818fa4a 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1115,6 +1115,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
((org.bukkit.craftbukkit.CraftWorldBorder) this.getBukkitEntity().getWorldBorder()).getHandle().tick();
|
||||
}
|
||||
@@ -1108,6 +1108,12 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
||||
|
||||
// Folia - region threading - move to main tick loop where we can detect duplicates
|
||||
// CraftBukkit end
|
||||
+ // Leaves start - update suppression crash fix
|
||||
+ } catch (org.leavesmc.leaves.util.UpdateSuppressionException exception) {
|
||||
@@ -111,10 +124,10 @@ index 04a600d96f4ae7c08d06dc4fb8f71b3f0eb1be07..45e4e3243c72b01d94dc440b26230a48
|
||||
CrashReport crashReport = CrashReport.forThrowable(var4, "Ticking player");
|
||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Player being ticked");
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 5bcf646ef600a2aae7633453d3331fde2f141aff..5d5c3694e821954e6ede4d5c3de8844a84f71f45 100644
|
||||
index 3e44a61bd982dc822437f647a02a95affd988cdb..28ae21b08e42edcc031ace2404b9d213589c28e8 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1434,9 +1434,19 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
@@ -1427,9 +1427,19 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
||||
this.walkingStepSound(pos, state);
|
||||
}
|
||||
|
||||
@@ -181,7 +194,7 @@ index c020d1944a25e2cd247e30a97c35bf93731d694a..74967f20099ea58cea1f9fc0f2387d8c
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index b2694cb60505766877398fa526b9bfe60e6b6404..7c354894f48a5540eb2554d8b1428306e8929066 100644
|
||||
index 77577d0df9b14a7ad55b2866c2ac31863226458b..5551d80a81c2878136f96b3e695c4888c7105a49 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -383,7 +383,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Instant Block Updater
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index 56e09b99c2901882483c5f2b3216bf0a11406e2e..1480bd04597001cd7c54e53ded46d7f75908a65a 100644
|
||||
index c7f578c117baccb10c0c15b05a6c04e073f15da8..aee3f98173de1b2c5a5278919a5d21b4bca03b7b 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -468,7 +468,7 @@ public final class RegionizedWorldData {
|
||||
@@ -472,7 +472,7 @@ public final class RegionizedWorldData {
|
||||
public long lastMidTickExecuteFailure;
|
||||
// From Level
|
||||
public boolean populating;
|
||||
@@ -17,7 +17,7 @@ index 56e09b99c2901882483c5f2b3216bf0a11406e2e..1480bd04597001cd7c54e53ded46d7f7
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
public final Map<BlockPos, CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
@@ -527,7 +527,7 @@ public final class RegionizedWorldData {
|
||||
@@ -531,7 +531,7 @@ public final class RegionizedWorldData {
|
||||
this.world = world;
|
||||
this.blockLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, true);
|
||||
this.fluidLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, false);
|
||||
@@ -27,10 +27,10 @@ index 56e09b99c2901882483c5f2b3216bf0a11406e2e..1480bd04597001cd7c54e53ded46d7f7
|
||||
this.wireHandler = new alternate.current.wire.WireHandler(world);
|
||||
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index b878f5a8316dfee582180a6bbe7122a78581fae2..a906e7a34d048369f9357b0371339b4cccac5f25 100644
|
||||
index 284bd9703b11804f51273ecfaa5cd44925726f5f..9756caff0b7403c212987e58c08a2da09bdeb962 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -911,12 +911,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -927,12 +927,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Paper - rewrite chunk system
|
||||
profilerFiller.pop();
|
||||
profilerFiller.push("debugSynchronizers");
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 8d28b29348c255c901375af161210a2041de1985..86f7cfd5816917bd03aca0a796f1eaca938d65aa 100644
|
||||
index 3301e521a79adbc6dd76be05e69cce1c97f8697e..8dc1db0e6bafba19e07a7fa78f3920d572d38466 100644
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -386,7 +386,18 @@ public class ServerPlayerGameMode {
|
||||
|
||||
+3
-3
@@ -553,7 +553,7 @@ index d1dbfc821f068f14bf975842f66251816ea5c985..fe13504a7d2d685e43183dd7b3219f16
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
if (!movedByPiston) {
|
||||
diff --git a/net/minecraft/world/level/block/SculkSensorBlock.java b/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
index 5ef593a61c74af7077d02f4b18d936bf9b2507b9..a94d69927b78089b2e9eb0ee74f693821c3d93fc 100644
|
||||
index 80e6ba8f026a6565696f18304507b2d0a347650c..593fab3d2a70bcd6832dd777afa4973f22abbaeb 100644
|
||||
--- a/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
+++ b/net/minecraft/world/level/block/SculkSensorBlock.java
|
||||
@@ -128,6 +128,18 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg
|
||||
@@ -732,7 +732,7 @@ index b369e80a4fc371a3762e34e7d4d180b86d1d190f..0b412e360b090dc85d1726eb8f51c69b
|
||||
protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) {
|
||||
BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 10f9f617123e7ef582707038230f43350d5c5810..d96385dc19b7d6409d65ae37549b6d8f3f955cd2 100644
|
||||
index 418517faeaf40ae2f7dea5635e4232cd89db3ead..0de2f6627fb6295d7927ac3e37026f4daf68cfd3 100644
|
||||
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -171,6 +171,15 @@ public abstract class BlockBehaviour implements FeatureElement, org.leavesmc.lea
|
||||
@@ -765,7 +765,7 @@ index 10f9f617123e7ef582707038230f43350d5c5810..d96385dc19b7d6409d65ae37549b6d8f
|
||||
this.getBlock().affectNeighborsAfterRemoval(this.asState(), level, pos, movedByPiston);
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 7c354894f48a5540eb2554d8b1428306e8929066..de82e9a7f0cc190f8cf8c66eee9dc178241f6a27 100644
|
||||
index 5551d80a81c2878136f96b3e695c4888c7105a49..73dd8e67938fbfff745b189c06a93174976ba1bf 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -406,22 +406,28 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ index a5d3caab2072b2c9bf8fdcbdb7c52c2dee16cfaf..4bb36d2965785fadf628a9bfac4fa2aa
|
||||
// CraftBukkit start
|
||||
if (bukkitState != null) {
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index de82e9a7f0cc190f8cf8c66eee9dc178241f6a27..f5b128a993fab7af71a098b2128537ac749edc2f 100644
|
||||
index 73dd8e67938fbfff745b189c06a93174976ba1bf..8e56c2237f9d49d0b09b62c0933283f77aaae679 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -1001,12 +1001,14 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Global Entities Counter
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index 1480bd04597001cd7c54e53ded46d7f75908a65a..c49be29a91422bea393f0acd6daa6ef948bd77ec 100644
|
||||
index aee3f98173de1b2c5a5278919a5d21b4bca03b7b..24a8ea9a709ed9637a8e3814c6f8fe9f9f9dedff 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -521,6 +521,9 @@ public final class RegionizedWorldData {
|
||||
@@ -525,6 +525,9 @@ public final class RegionizedWorldData {
|
||||
public final Map<Long, ChunkSectionItemEntityMovementTracker> itemEntityMovementTrackerMap = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>();
|
||||
// Luminol end
|
||||
|
||||
@@ -18,7 +18,7 @@ index 1480bd04597001cd7c54e53ded46d7f75908a65a..c49be29a91422bea393f0acd6daa6ef9
|
||||
public final TickRegions.TickRegionData regionData;
|
||||
|
||||
public RegionizedWorldData(final ServerLevel world, final TickRegions.TickRegionData regionData) {
|
||||
@@ -533,6 +536,15 @@ public final class RegionizedWorldData {
|
||||
@@ -537,6 +540,15 @@ public final class RegionizedWorldData {
|
||||
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
||||
this.regionData = regionData;
|
||||
|
||||
@@ -97,10 +97,10 @@ index f4c9c551fc39bae38e283ccbbc3cd116f0536a64..db13211b24208d8addd3c210155bc244
|
||||
NaturalSpawner.spawnForChunk(this.level, chunk, spawnState, spawnCategories);
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index a906e7a34d048369f9357b0371339b4cccac5f25..b5be74243607fb34812dcbad26aad76e44bf0b19 100644
|
||||
index 9756caff0b7403c212987e58c08a2da09bdeb962..4acd4718628b160c482b04da6ba905687b61bbad 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -763,6 +763,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -765,6 +765,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
public void tick(BooleanSupplier hasTimeLeft, io.papermc.paper.threadedregions.TickRegions.TickRegionData region) { // Folia - regionised ticking
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ Subject: [PATCH] Add null check in RegionizedWorldData >> conections
|
||||
some of our function patches will crash because of get null in conn.getPlayer(), then when we process player.chunkPosition() will get NPE, so we need to fix it.
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index c49be29a91422bea393f0acd6daa6ef948bd77ec..9b25483472a606168e6860e0a96f05b78d3e5b02 100644
|
||||
index 24a8ea9a709ed9637a8e3814c6f8fe9f9f9dedff..35f8bcb5569987e4096ea06bab4e6693dfb97695 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -229,14 +229,17 @@ public final class RegionizedWorldData {
|
||||
@@ -41,7 +41,7 @@ index c49be29a91422bea393f0acd6daa6ef948bd77ec..9b25483472a606168e6860e0a96f05b7
|
||||
}
|
||||
for (final Entity entity : from.allEntities) {
|
||||
final ChunkPos pos = entity.chunkPosition();
|
||||
@@ -581,6 +591,7 @@ public final class RegionizedWorldData {
|
||||
@@ -585,6 +595,7 @@ public final class RegionizedWorldData {
|
||||
private static void cleanUpConnection(final Connection conn) {
|
||||
// note: ALL connections HERE have a player
|
||||
final ServerPlayer player = conn.getPlayer();
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Tue, 13 Jan 2026 21:04:59 +0800
|
||||
Subject: [PATCH] Add removed check before all checks start in addEffect
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index e4ae4354e81f34f0db410333fc9b8e17383a5f41..fc8833655102ca98bb331782a624af79cbef414f 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1186,6 +1186,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
public boolean addEffect(MobEffectInstance effectInstance, @Nullable Entity entity, EntityPotionEffectEvent.Cause cause, boolean fireEvent) {
|
||||
// Paper end - Don't fire sync event during generation
|
||||
// org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot // Paper - move to API
|
||||
+ if (this.isRemoved()) return false; // Lophine - shouldn't be possible to add effects to removed entity
|
||||
if (!this.hasNullCallback()) ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread(this, "Cannot add effects to entities asynchronously"); // Folia - region threading
|
||||
if (this.isTickingEffects) {
|
||||
this.effectsToProcess.add(new ProcessableEffect(effectInstance, cause));
|
||||
@@ -35,27 +35,20 @@ index fcdfd4f6de5e1c2d5e80c7f3d8cb0b33a62d257d..6eaa4e9bd1ecbfa531313ce1f470d55e
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
|
||||
Map<String, Map<String, Integer>> map = new HashMap<>();
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
index 22125dbe1765f930fe10fe420be1c275ec553139..d5b070d1a3d84e228960dacd614e0f1abe968e79 100644
|
||||
index a5f2e4454258886536251288c3694f58386c7420..28371ecf31d5fc280aaa03ed9a86f5b565cf32f6 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
|
||||
@@ -35,7 +35,7 @@ public class PaperVersionFetcher implements VersionFetcher {
|
||||
private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
@@ -40,8 +40,8 @@ public class PaperVersionFetcher implements VersionFetcher {
|
||||
private static final ComponentLogger COMPONENT_LOGGER = ComponentLogger.logger(LogManager.getRootLogger().getName());
|
||||
private static final int DISTANCE_ERROR = -1;
|
||||
private static final int DISTANCE_UNKNOWN = -2;
|
||||
- private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Luminol"; //Luminol
|
||||
+ private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Lophine"; //Luminol // Lophine
|
||||
|
||||
@Override
|
||||
public long getCacheTime() {
|
||||
@@ -49,7 +49,7 @@ public class PaperVersionFetcher implements VersionFetcher {
|
||||
if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) {
|
||||
updateMessage = text("You are running a development version without access to version information", color(0xFF5300));
|
||||
} else {
|
||||
- updateMessage = getUpdateStatusMessage("LuminolMC/Luminol", build); // Folia // Luminol
|
||||
+ updateMessage = getUpdateStatusMessage("LuminolMC/Lophine", build); // Folia // Luminol // Lophine
|
||||
}
|
||||
final @Nullable Component history = this.getHistory();
|
||||
|
||||
- private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Luminol"; // Luminol
|
||||
- private static final String REPOSITORY = "LuminolMC/Luminol"; // Luminol
|
||||
+ private static final String DOWNLOAD_PAGE = "https://github.com/LuminolMC/Lophine"; // Luminol // Lophine
|
||||
+ private static final String REPOSITORY = "LuminolMC/Lophine"; // Luminol // Lophine
|
||||
private static final ServerBuildInfo BUILD_INFO = ServerBuildInfo.buildInfo();
|
||||
private static final String USER_AGENT = BUILD_INFO.brandName() + "/" + BUILD_INFO.asString(VERSION_SIMPLE) + " (https://papermc.io)";
|
||||
private static final Gson GSON = new Gson();
|
||||
diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
||||
index 4ada790812957657d580cb748077c4961987d0cb..3a539df860305e777e85ed6dc72b5effe76734b4 100644
|
||||
--- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java
|
||||
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 92de192c7b420ebb4510354f347003127595e141..e28c7043c04a4df34733b9bfc5fd55ee6082d010 100644
|
||||
index 507204301b5e3cd545e66c510842c0a6391f0241..dfcfc83474443638e30f87d54472e5a38947dfad 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -485,6 +485,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
@@ -53,7 +53,7 @@ index 21d594a39d09b2d17f05c40ce5323d57949d0b0b..46859fc70795097366f02dba48fdaab8
|
||||
if (nmsEntity.level() != this.getHandle().getLevel()) {
|
||||
throw new IllegalArgumentException(entity + " wasn't created with this world, you must create the entity with the world you want to add it to.");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index e28c7043c04a4df34733b9bfc5fd55ee6082d010..3b179b11441a9295698fa55cc4a020b4c1652616 100644
|
||||
index dfcfc83474443638e30f87d54472e5a38947dfad..973f064fc5e089dc892d4b4077a807517fd199b5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -305,6 +305,7 @@ public final class CraftServer implements Server {
|
||||
@@ -96,10 +96,10 @@ index e28c7043c04a4df34733b9bfc5fd55ee6082d010..3b179b11441a9295698fa55cc4a020b4
|
||||
/**
|
||||
* Gets the TPS from the region which owns the specified location, or {@code null} if no region owns
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index a1a79a18673c94218288f32345195b80139ad879..acddc62380f65f50779786296dec265de4a647db 100644
|
||||
index dcd32c1e32fd67ec13bb7fca8af20aa665407594..b7f83e66227b5a1f5ad9b424e425eee118cc0692 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -249,7 +249,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -247,7 +247,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public int getPlayerCount() {
|
||||
@@ -108,7 +108,7 @@ index a1a79a18673c94218288f32345195b80139ad879..acddc62380f65f50779786296dec265d
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1122,9 +1122,9 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -1121,9 +1121,9 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public List<Player> getPlayers() {
|
||||
@@ -120,7 +120,7 @@ index a1a79a18673c94218288f32345195b80139ad879..acddc62380f65f50779786296dec265d
|
||||
HumanEntity bukkitEntity = human.getBukkitEntity();
|
||||
|
||||
if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) {
|
||||
@@ -1626,7 +1626,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -1622,7 +1622,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public void playSound(final net.kyori.adventure.sound.Sound sound) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
final long seed = sound.seed().orElseGet(this.world.getRandom()::nextLong);
|
||||
@@ -129,7 +129,7 @@ index a1a79a18673c94218288f32345195b80139ad879..acddc62380f65f50779786296dec265d
|
||||
player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player.getX(), player.getY(), player.getZ(), seed, null));
|
||||
}
|
||||
}
|
||||
@@ -1654,7 +1654,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -1650,7 +1650,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper
|
||||
final long seed = sound.seed().orElseGet(this.getHandle().getRandom()::nextLong);
|
||||
if (emitter == net.kyori.adventure.sound.Sound.Emitter.self()) {
|
||||
@@ -138,7 +138,7 @@ index a1a79a18673c94218288f32345195b80139ad879..acddc62380f65f50779786296dec265d
|
||||
player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player, seed, null));
|
||||
}
|
||||
} else if (emitter instanceof CraftEntity craftEntity) {
|
||||
@@ -1795,7 +1795,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@@ -1791,7 +1791,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||
}
|
||||
this.getHandle().sendParticlesSource(
|
||||
@@ -161,7 +161,7 @@ index e6cd1c4a50b32b74f70a264e869b1ab4ac9b9eb0..6867064de52d810f1fd3869463ae2786
|
||||
if (entity instanceof EnderDragonPart complexPart) {
|
||||
if (complexPart.parentMob instanceof EnderDragon) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 3d465c857b3560a2cd57825c9cbd0a3c9029e6d3..a41b5eeb1e82725948c448c7c3c4f5b2d1e06af6 100644
|
||||
index 0429ffda4aa4410f6f53bd163be8dee71b134637..9274f4ef639ed9b3028321566173d6612663082b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1014,7 +1014,11 @@ public class CraftEventFactory {
|
||||
|
||||
@@ -21,7 +21,7 @@ index e1f456b31ffda9370b63e51f343847d6f9f62263..8a0f85241cc1530aacccc8b6ea24b9de
|
||||
}
|
||||
// Leaves end - skip bot
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 401f977483b6e809b9b10c601900e35110ae7396..030a9cf9a95fcea1410e825df76f817f73d4db78 100644
|
||||
index 973f064fc5e089dc892d4b4077a807517fd199b5..06766a9058595aeee25e8fd3e3d01aeec2a55116 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -306,6 +306,7 @@ public final class CraftServer implements Server {
|
||||
@@ -66,10 +66,10 @@ index 6867064de52d810f1fd3869463ae27868ed0fb07..69a0de762cfde089e8aaa6e6be79a8c8
|
||||
// Special case complex part, since there is no extra entity type for them
|
||||
if (entity instanceof EnderDragonPart complexPart) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index a8838e45dd7d44c25442c14d49b53583f9f2a2d2..effb56daac89b7cc3106ed4b394a6c583b654735 100644
|
||||
index 6e745c7ddf417ec2fdcf102edd6a592047b5f73e..2f59107642d43719159872d5df37107d8a1a5b97 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2091,7 +2091,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
|
||||
@@ -2085,7 +2085,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
|
||||
|
||||
@Override
|
||||
public boolean canSee(Player player) {
|
||||
@@ -79,10 +79,10 @@ index a8838e45dd7d44c25442c14d49b53583f9f2a2d2..effb56daac89b7cc3106ed4b394a6c58
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index dcec69554213bfb8608b77341819b09e31a96e09..5dce7416f42902de34bff6398cf402c610be600c 100644
|
||||
index 6f608ad5d1151925ad0f38596dfe15290d20d753..9c1a48dd4a8957200d8c05cf7e142c621132bb74 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -338,7 +338,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
@@ -344,7 +344,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Error saving advancement " + key, ex);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,5 +4,5 @@ import com.mojang.logging.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class LophineLogger {
|
||||
public static final Logger LOGGER = LogUtils.getClassLogger(); // only provided for some Logger can not be initialized
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package fun.bm.lophine.command.counter;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.LiteralNode;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class DisplayCommand extends CounterSubCommand {
|
||||
}
|
||||
|
||||
public static void displayCounter(CommandContext context, @NotNull HopperCounter counter, boolean realTime) {
|
||||
for (Component component : counter.format(MinecraftServer.getServer(), context.getSource().getLevel(), realTime)) {
|
||||
for (Component component : counter.format(MinecraftServer.getServer(), realTime)) {
|
||||
context.getSender().sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import fun.bm.lophine.command.counter.CounterSubCommand;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.ArgumentNode;
|
||||
@@ -27,7 +28,7 @@ public class ResetCommand extends CounterSubCommand {
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
HopperCounter.resetAll(context.getSource().getLevel(), false);
|
||||
HopperCounter.resetAll(MinecraftServer.getServer(), false);
|
||||
context.getSender().sendMessage(Component.text("Restarted all counters."));
|
||||
return true;
|
||||
}
|
||||
@@ -41,14 +42,14 @@ public class ResetCommand extends CounterSubCommand {
|
||||
protected boolean execute(@NotNull CommandContext context) {
|
||||
String color0 = context.getArgument(DyeColorArg.class);
|
||||
if (color0.equals("all")) {
|
||||
HopperCounter.resetAll(context.getSource().getLevel(), false);
|
||||
HopperCounter.resetAll(MinecraftServer.getServer(), false);
|
||||
context.getSender().sendMessage(Component.text("Restarted all counters."));
|
||||
return true;
|
||||
}
|
||||
DyeColor color = DyeColor.byName(color0, null);
|
||||
if (color == null) return true;
|
||||
HopperCounter counter = HopperCounter.getCounter(color);
|
||||
counter.reset(context.getSource().getLevel());
|
||||
counter.reset(MinecraftServer.getServer());
|
||||
context.getSender().sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Restarted "),
|
||||
Component.text(color.getName(), TextColor.color(color.getTextColor())),
|
||||
|
||||
+11
-1
@@ -22,11 +22,21 @@ public class CommandConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "enable-waypoint", directory = {"experiment", "waypoint_bar"})
|
||||
@ConfigInfo(name = "waypoint_command_enabled", comments =
|
||||
"""
|
||||
Allow to use waypoint command""")
|
||||
Allow to use waypoint command and locator bar""")
|
||||
public static boolean waypoint = false;
|
||||
|
||||
@ConfigInfo(name = "scoreboard_command_enabled", comments =
|
||||
"""
|
||||
Allow to use scoreboard command""")
|
||||
public static boolean scoreboard = false;
|
||||
|
||||
@ConfigInfo(name = "enabled", directory = {"save_all_command"}, comments =
|
||||
"""
|
||||
Allow to use save-all command""")
|
||||
public static boolean saveAll = false;
|
||||
|
||||
@ConfigInfo(name = "log_all_process", directory = {"save_all_command"}, comments =
|
||||
"""
|
||||
Log all process of save-all command to console""")
|
||||
public static boolean logAllProcess = false;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package fun.bm.lophine.config.modules.function;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import fun.bm.lophine.utils.RandomProfilePool;
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.HotReloadUnsupported;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "replay-api")
|
||||
public class ReplayAPIConfig implements IConfigModule {
|
||||
@HotReloadUnsupported
|
||||
@ConfigInfo(name = "enable-cache")
|
||||
public static boolean enableCache = true;
|
||||
|
||||
@HotReloadUnsupported
|
||||
@ConfigInfo(name = "cache-photographer-time", comments = """
|
||||
Time to cache photographer profile(in seconds)""")
|
||||
public static int cachePhotographerTime = 3600;
|
||||
|
||||
@HotReloadUnsupported
|
||||
@ConfigInfo(name = "cache-photographer-size", comments = """
|
||||
Maximum size of cache photographer profile""")
|
||||
public static int cachePhotographerSize = 100;
|
||||
|
||||
@Override
|
||||
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> e) {
|
||||
RandomProfilePool.init();
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package fun.bm.lophine.config.modules.optimizations;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.HotReloadUnsupported;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.OPTIMIZATIONS, name = "waypoint")
|
||||
public class WayPointOptimizedTableConfig implements IConfigModule {
|
||||
@HotReloadUnsupported
|
||||
@ConfigInfo(name = "optimizedTable", comments = """
|
||||
Should use optimized table instead of normal concurrent table for waypoints.
|
||||
May improve performance when there are many waypoints and players.
|
||||
When enabled, more memory is needed to store data.""")
|
||||
public static boolean optimizedTable = false;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
|
||||
public class RemovedConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "optimizedTable", directory = {"optimizations", "waypoint"}, transform = false)
|
||||
@TransformedConfig(name = "enabled", directory = {"fixes", "end-void-ring"}, transform = false)
|
||||
@TransformedConfig(name = "enabled", directory = {"gameplay", "end_void_rings"}, transform = false)
|
||||
@TransformedConfig(name = "datapack_command_enabled", directory = {"experiment", "command"}, transform = false)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package fun.bm.lophine.utils;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import fun.bm.lophine.config.modules.function.ReplayAPIConfig;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RandomProfilePool {
|
||||
private static int lastUsedId = 0;
|
||||
private static final Object lock = new Object();
|
||||
private static Cache<Integer, GameProfile> cache;
|
||||
private static final Object lockCache = new Object();
|
||||
|
||||
public static void init() {
|
||||
if (ReplayAPIConfig.enableCache) {
|
||||
cache = CacheBuilder.newBuilder()
|
||||
.maximumSize(ReplayAPIConfig.cachePhotographerSize)
|
||||
.expireAfterWrite(ReplayAPIConfig.cachePhotographerTime, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
public static GameProfile getRandomProfile(String id) {
|
||||
if (ReplayAPIConfig.enableCache) {
|
||||
synchronized (lockCache) {
|
||||
for (Map.Entry<Integer, GameProfile> entry : cache.asMap().entrySet()) {
|
||||
int key = entry.getKey();
|
||||
cache.invalidate(key);
|
||||
GameProfile gp = entry.getValue();
|
||||
return new GameProfile(gp.id(), id, gp.properties());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new GameProfile(UUID.randomUUID(), id);
|
||||
}
|
||||
|
||||
public static void putProfile(GameProfile profile) {
|
||||
if (ReplayAPIConfig.enableCache) {
|
||||
synchronized (lockCache) {
|
||||
cache.put(getNextId(), profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int getNextId() {
|
||||
synchronized (lock) {
|
||||
int newId = lastUsedId + 1;
|
||||
while (cache.getIfPresent(newId) != null) {
|
||||
newId++;
|
||||
}
|
||||
lastUsedId = newId;
|
||||
return newId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package fun.bm.lophine.utils;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import fun.bm.lophine.config.modules.experiment.CommandConfig;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.commands.SaveAllCommand;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class SaveAllUtil {
|
||||
private static final long TIMEOUT = 1000 * 30; // 30 seconds
|
||||
public static final Object lock = new Object();
|
||||
public static volatile long lastSaveAllTime = 0;
|
||||
private static volatile Pair<CommandSourceStack, Boolean> currentSaveAll = null;
|
||||
private static volatile int regionCount = 0;
|
||||
private static final AtomicInteger savedRegionCount = new AtomicInteger(0);
|
||||
private static final AtomicBoolean withError = new AtomicBoolean(false);
|
||||
|
||||
public static void preSaveAll(CommandSourceStack source, boolean flush) {
|
||||
synchronized (lock) {
|
||||
if (isSaving()) {
|
||||
source.sendFailure(Component.literal("Server is already in saving! Please wait..."));
|
||||
} else {
|
||||
source.sendSuccess(() -> Component.translatable("commands.save.saving"), false);
|
||||
currentSaveAll = Pair.of(source, flush);
|
||||
// we need to count how many regions we need to save
|
||||
AtomicInteger count = new AtomicInteger();
|
||||
for (ServerLevel world : source.getServer().getAllLevels()) {
|
||||
world.regioniser.computeForAllRegions(unused -> {
|
||||
count.getAndIncrement();
|
||||
});
|
||||
}
|
||||
regionCount = count.get();
|
||||
savedRegionCount.set(0);
|
||||
withError.set(false);
|
||||
lastSaveAllTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void postRegionSave(io.papermc.paper.threadedregions.TickRegions.TickRegionData region) {
|
||||
Pair<CommandSourceStack, Boolean> currentSaveAll = SaveAllUtil.currentSaveAll;
|
||||
synchronized (lock) {
|
||||
if (lastSaveAllTime < region.lastSavedTime) return; // already saved
|
||||
}
|
||||
try {
|
||||
region.world.moonrise$getChunkTaskScheduler().chunkHolderManager.saveAllChunksRegionised(currentSaveAll.getSecond(), false, CommandConfig.logAllProcess, false, false, true, false);
|
||||
currentSaveAll.getFirst().getServer().getPlayerList().saveAll();
|
||||
MinecraftServer.LOGGER.info("Saved chunks in region around chunk {} in world '{}'", region.region.getCenterChunk(), region.region.regioniser.world.getWorld().getName());
|
||||
} catch (final Throwable thr) {
|
||||
CommandSyntaxException error = SaveAllCommand.getErrorFailed().create();
|
||||
currentSaveAll.getFirst().sendFailure(Component.literal(error.getMessage()));
|
||||
MinecraftServer.LOGGER.error(error.getMessage(), thr);
|
||||
withError.set(true);
|
||||
}
|
||||
region.lastSavedTime = System.currentTimeMillis();
|
||||
int saved;
|
||||
synchronized (savedRegionCount) {
|
||||
saved = savedRegionCount.incrementAndGet();
|
||||
}
|
||||
if (saved >= regionCount) {
|
||||
if (withError.get()) {
|
||||
currentSaveAll.getFirst().sendFailure(Component.literal("At least one region failed to save!"));
|
||||
} else if (saved == regionCount) {
|
||||
currentSaveAll.getFirst().sendSuccess(() -> Component.translatable("commands.save.success"), true);
|
||||
SaveAllUtil.currentSaveAll = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTimeout() {
|
||||
Pair<CommandSourceStack, Boolean> currentSaveAll = SaveAllUtil.currentSaveAll;
|
||||
if (!isSaving()) return;
|
||||
if (System.currentTimeMillis() - lastSaveAllTime > TIMEOUT) {
|
||||
currentSaveAll.getFirst().sendFailure(Component.literal("At least one region save data timeout!"));
|
||||
currentSaveAll.getFirst().sendFailure(Component.literal("Regions need to save expect is " + regionCount + ", but only " + savedRegionCount.get() + " saved!"));
|
||||
SaveAllUtil.currentSaveAll = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSaving() {
|
||||
synchronized (lock) {
|
||||
return currentSaveAll != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class ServerI18nUtil {
|
||||
}
|
||||
langPath = BASE_PATH + "lang/" + LanguageConfig.lang + ".json";
|
||||
langJsonPath = "minecraft/lang/" + LanguageConfig.lang + ".json";
|
||||
lophineLangPath = "/assets/Lophine/lang/" + LanguageConfig.lang + ".json";
|
||||
lophineLangPath = "/assets/lophine/lang/" + LanguageConfig.lang + ".json";
|
||||
logger.info("Starting load language: {}", LanguageConfig.lang);
|
||||
preloadTask.thenAcceptAsync(v -> loadI18n(LanguageConfig.lang, 2));
|
||||
}
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractConcurrentTable<X, Y, Z> {
|
||||
public abstract void putOrUpdate(X x, Y y, Z z);
|
||||
|
||||
public abstract void put(X x, Y y, Z z);
|
||||
|
||||
public abstract void remove(X x, Y y, Z z);
|
||||
|
||||
public abstract List<Z> getZ(X x, Y y);
|
||||
|
||||
public abstract List<Y> getY(X x, Z z);
|
||||
|
||||
public abstract List<X> getX(Y y, Z z);
|
||||
|
||||
public abstract List<Map.Entry<X, Y>> getXY(Z z);
|
||||
|
||||
public abstract List<Map.Entry<Y, Z>> getYZ(X x);
|
||||
|
||||
public abstract List<Map.Entry<X, Z>> getXZ(Y y);
|
||||
|
||||
public abstract List<X> getAllX();
|
||||
|
||||
public abstract List<Y> getAllY();
|
||||
|
||||
public abstract List<Z> getAllZ();
|
||||
|
||||
public abstract void clearXY(Z z);
|
||||
|
||||
public abstract void clearYZ(X x);
|
||||
|
||||
public abstract void clearXZ(Y y);
|
||||
|
||||
public abstract void clearAll();
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ConcurrentTable<X, Y, Z> extends AbstractConcurrentTable<X, Y, Z> {
|
||||
protected final ConcurrentLinkedDeque<TableEntry<X, Y, Z>> data = new ConcurrentLinkedDeque<>();
|
||||
|
||||
@Override
|
||||
public void putOrUpdate(X x, Y y, Z z) {
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (entry.getX().equals(x) && entry.getY().equals(y)) {
|
||||
entry.setZ(z);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.put(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(X x, Y y, Z z) {
|
||||
data.add(new TableEntry<>(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(X x, Y y, Z z) {
|
||||
data.removeIf(entry -> entry.getX().equals(x) && entry.getY().equals(y) && entry.getZ().equals(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getZ(X x, Y y) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getX().equals(x) && entry.getY().equals(y),
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getY(X x, Z z) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getX().equals(x) && entry.getZ().equals(z),
|
||||
TableEntry::getY
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getX(Y y, Z z) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getY().equals(y) && entry.getZ().equals(z),
|
||||
TableEntry::getX
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<X, Y>> getXY(Z z) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getZ().equals(z),
|
||||
TableEntry::getX,
|
||||
TableEntry::getY
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<Y, Z>> getYZ(X x) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getX().equals(x),
|
||||
TableEntry::getY,
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<X, Z>> getXZ(Y y) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getY().equals(y),
|
||||
TableEntry::getX,
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getAllX() {
|
||||
return collectAll(TableEntry::getX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getAllY() {
|
||||
return collectAll(TableEntry::getY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getAllZ() {
|
||||
return collectAll(TableEntry::getZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXY(Z z) {
|
||||
data.removeIf(entry -> entry.getZ().equals(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearYZ(X x) {
|
||||
data.removeIf(entry -> entry.getX().equals(x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXZ(Y y) {
|
||||
data.removeIf(entry -> entry.getY().equals(y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAll() {
|
||||
data.clear();
|
||||
}
|
||||
|
||||
private <T> List<T> filterAndCollect(Predicate<TableEntry<X, Y, Z>> filter,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, T> mapper) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (filter.test(entry)) {
|
||||
result.add(mapper.apply(entry));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private <K, V> List<Map.Entry<K, V>> filterAndMap(Predicate<TableEntry<X, Y, Z>> filter,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, K> keyMapper,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, V> valueMapper) {
|
||||
List<Map.Entry<K, V>> list = new ArrayList<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (filter.test(entry)) {
|
||||
list.add(new AbstractMap.SimpleEntry<>(keyMapper.apply(entry), valueMapper.apply(entry)));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private <T> List<T> collectAll(java.util.function.Function<TableEntry<X, Y, Z>, T> mapper) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
result.add(mapper.apply(entry));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
-197
@@ -1,197 +0,0 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class OptimizedConcurrentTable<X, Y, Z> extends ConcurrentTable<X, Y, Z> {
|
||||
private final ConcurrentHashMap<X, ConcurrentHashMap<Y, Set<Z>>> xyIndex = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Y, ConcurrentHashMap<Z, Set<X>>> yzIndex = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Z, ConcurrentHashMap<X, Set<Y>>> zxIndex = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void putOrUpdate(X x, Y y, Z z) {
|
||||
boolean updated = false;
|
||||
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (entry.getX().equals(x) && entry.getY().equals(y)) {
|
||||
removeFromIndex(xyIndex, entry.getX(), entry.getY(), entry.getZ());
|
||||
removeFromIndex(yzIndex, entry.getY(), entry.getZ(), entry.getX());
|
||||
removeFromIndex(zxIndex, entry.getZ(), entry.getX(), entry.getY());
|
||||
|
||||
entry.setZ(z);
|
||||
|
||||
putData(x, y, z);
|
||||
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!updated) {
|
||||
this.put(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
private void putData(X x, Y y, Z z) {
|
||||
xyIndex.computeIfAbsent(x, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(y, k -> ConcurrentHashMap.newKeySet()).add(z);
|
||||
yzIndex.computeIfAbsent(y, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(z, k -> ConcurrentHashMap.newKeySet()).add(x);
|
||||
zxIndex.computeIfAbsent(z, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(x, k -> ConcurrentHashMap.newKeySet()).add(y);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void put(X x, Y y, Z z) {
|
||||
super.put(x, y, z);
|
||||
putData(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(X x, Y y, Z z) {
|
||||
super.remove(x, y, z);
|
||||
removeFromIndex(xyIndex, x, y, z);
|
||||
removeFromIndex(yzIndex, y, z, x);
|
||||
removeFromIndex(zxIndex, z, x, y);
|
||||
}
|
||||
|
||||
private <K, V, T> void removeFromIndex(ConcurrentHashMap<K, ConcurrentHashMap<V, Set<T>>> index,
|
||||
K key1, V key2, T value) {
|
||||
index.computeIfPresent(key1, (k, map) -> {
|
||||
map.computeIfPresent(key2, (k2, set) -> {
|
||||
set.remove(value);
|
||||
return set.isEmpty() ? null : set;
|
||||
});
|
||||
return map.isEmpty() ? null : map;
|
||||
});
|
||||
}
|
||||
|
||||
public void removeAll(Predicate<TableEntry<X, Y, Z>> predicate) {
|
||||
data.removeIf(entry -> {
|
||||
boolean shouldRemove = predicate.test(entry);
|
||||
if (shouldRemove) {
|
||||
removeFromIndex(xyIndex, entry.getX(), entry.getY(), entry.getZ());
|
||||
removeFromIndex(yzIndex, entry.getY(), entry.getZ(), entry.getX());
|
||||
removeFromIndex(zxIndex, entry.getZ(), entry.getX(), entry.getY());
|
||||
}
|
||||
return shouldRemove;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean putIfAbsent(X x, Y y, Z z) {
|
||||
if (data.stream().anyMatch(entry ->
|
||||
Objects.equals(entry.getX(), x) &&
|
||||
Objects.equals(entry.getY(), y) &&
|
||||
Objects.equals(entry.getZ(), z))) {
|
||||
return false;
|
||||
}
|
||||
put(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getZ(X x, Y y) {
|
||||
Set<Z> result = xyIndex.getOrDefault(x, new ConcurrentHashMap<>()).get(y);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getY(X x, Z z) {
|
||||
Set<Y> result = zxIndex.getOrDefault(z, new ConcurrentHashMap<>()).get(x);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<X> getX(Y y, Z z) {
|
||||
Set<X> result = yzIndex.getOrDefault(y, new ConcurrentHashMap<>()).get(z);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<X, Y>> getXY(Z z) {
|
||||
return buildDataFromIndex(zxIndex.get(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<Y, Z>> getYZ(X x) {
|
||||
return buildDataFromIndex(xyIndex.get(x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map.Entry<X, Z>> getXZ(Y y) {
|
||||
return reverseDataFromIndex(yzIndex.get(y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getAllX() {
|
||||
Set<X> resultSet = new HashSet<>(xyIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getAllY() {
|
||||
Set<Y> resultSet = new HashSet<>(yzIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getAllZ() {
|
||||
Set<Z> resultSet = new HashSet<>(zxIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearXY(Z z) {
|
||||
super.clearXY(z);
|
||||
zxIndex.remove(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearYZ(X x) {
|
||||
super.clearYZ(x);
|
||||
xyIndex.remove(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXZ(Y y) {
|
||||
super.clearXZ(y);
|
||||
yzIndex.remove(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAll() {
|
||||
super.clearAll();
|
||||
xyIndex.clear();
|
||||
yzIndex.clear();
|
||||
zxIndex.clear();
|
||||
}
|
||||
|
||||
|
||||
private <K, V, R> List<R> buildEntriesFromIndex(ConcurrentHashMap<K, Set<V>> indexMap,
|
||||
BiFunction<K, V, R> entryCreator) {
|
||||
List<R> result = new ArrayList<>();
|
||||
if (indexMap != null) {
|
||||
for (Map.Entry<K, Set<V>> entry : indexMap.entrySet()) {
|
||||
K key = entry.getKey();
|
||||
Set<V> valueSet = entry.getValue();
|
||||
if (valueSet != null && !valueSet.isEmpty()) {
|
||||
for (V value : valueSet) {
|
||||
result.add(entryCreator.apply(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private <K, V> List<Map.Entry<K, V>> buildDataFromIndex(ConcurrentHashMap<K, Set<V>> indexMap) {
|
||||
return buildEntriesFromIndex(indexMap, AbstractMap.SimpleEntry::new);
|
||||
}
|
||||
|
||||
private <K, V> List<Map.Entry<V, K>> reverseDataFromIndex(ConcurrentHashMap<K, Set<V>> indexMap) {
|
||||
return buildEntriesFromIndex(indexMap, (key, value) -> new AbstractMap.SimpleEntry<>(value, key));
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
public class TableEntry<X, Y, Z> {
|
||||
private final X x;
|
||||
private final Y y;
|
||||
private Z z;
|
||||
|
||||
public TableEntry(X x, Y y, Z z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public X getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public Y getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public Z getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(Z z) {
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package org.leavesmc.leaves.bot;
|
||||
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -33,7 +32,7 @@ import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public record BotCreateState(String realName, String name, String skinName, String[] skin, Location location,
|
||||
public record BotCreateState(String rawName, String fullName, String skinName, String[] skin, Location location,
|
||||
BotCreateEvent.CreateReason createReason, CommandSender creator) {
|
||||
|
||||
private static final MinecraftServer server = MinecraftServer.getServer();
|
||||
@@ -43,15 +42,15 @@ public record BotCreateState(String realName, String name, String skinName, Stri
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Builder builder(@NotNull String realName, @Nullable Location location) {
|
||||
return new Builder(realName, location);
|
||||
public static Builder builder(@NotNull String rawName, @Nullable Location location) {
|
||||
return new Builder(rawName, location);
|
||||
}
|
||||
|
||||
public static class Builder implements BotCreator {
|
||||
|
||||
private final String realName;
|
||||
private final String rawName; // For internal calculation, use it as little as possible
|
||||
|
||||
private String name;
|
||||
private String fullName;
|
||||
private Location location;
|
||||
|
||||
private String skinName;
|
||||
@@ -60,14 +59,14 @@ public record BotCreateState(String realName, String name, String skinName, Stri
|
||||
private BotCreateEvent.CreateReason createReason;
|
||||
private CommandSender creator;
|
||||
|
||||
private Builder(@NotNull String realName, @Nullable Location location) {
|
||||
Objects.requireNonNull(realName);
|
||||
private Builder(@NotNull String rawName, @Nullable Location location) {
|
||||
Objects.requireNonNull(rawName);
|
||||
|
||||
this.realName = realName;
|
||||
this.rawName = rawName;
|
||||
this.location = location;
|
||||
|
||||
this.name = FakeplayerConfig.prefix + realName + FakeplayerConfig.suffix;
|
||||
this.skinName = this.realName;
|
||||
this.fullName = BotUtil.getFullName(rawName);
|
||||
this.skinName = this.rawName;
|
||||
this.skin = null;
|
||||
this.createReason = BotCreateEvent.CreateReason.UNKNOWN;
|
||||
this.creator = null;
|
||||
@@ -75,7 +74,7 @@ public record BotCreateState(String realName, String name, String skinName, Stri
|
||||
|
||||
public Builder name(@NotNull String name) {
|
||||
Objects.requireNonNull(name);
|
||||
this.name = name;
|
||||
this.fullName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -113,31 +112,24 @@ public record BotCreateState(String realName, String name, String skinName, Stri
|
||||
}
|
||||
|
||||
public BotCreateState build() {
|
||||
return new BotCreateState(realName, name, skinName, skin, location, createReason, creator);
|
||||
return new BotCreateState(rawName, fullName, skinName, skin, location, createReason, creator);
|
||||
}
|
||||
|
||||
public void spawnWithSkin(Consumer<Bot> consumer) {
|
||||
Bukkit.getRegionScheduler().execute(
|
||||
MinecraftInternalPlugin.INSTANCE,
|
||||
location.getWorld(),
|
||||
location.getBlockX() >> 4,
|
||||
location.getBlockZ() >> 4,
|
||||
() -> {
|
||||
this.mojangAPISkin();
|
||||
Bukkit.getRegionScheduler().execute(
|
||||
MinecraftInternalPlugin.INSTANCE,
|
||||
location.getWorld(),
|
||||
location.getBlockX() >> 4,
|
||||
location.getBlockZ() >> 4,
|
||||
() -> {
|
||||
CraftBot bot = this.spawn();
|
||||
if (bot != null && consumer != null) {
|
||||
consumer.accept(bot);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
Bukkit.getAsyncScheduler().runNow(MinecraftInternalPlugin.INSTANCE, (task0) -> {
|
||||
this.mojangAPISkin();
|
||||
Bukkit.getRegionScheduler().execute(
|
||||
MinecraftInternalPlugin.INSTANCE,
|
||||
location.getWorld(),
|
||||
location.getBlockX() >> 4,
|
||||
location.getBlockZ() >> 4,
|
||||
() -> {
|
||||
CraftBot bot = this.spawn();
|
||||
if (bot != null && consumer != null) {
|
||||
consumer.accept(bot);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -36,10 +36,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BotDataStorage implements IPlayerDataStorage {
|
||||
|
||||
private static final LevelResource BOT_DATA_DIR = new LevelResource("fakeplayerdata");
|
||||
private static final LevelResource BOT_LIST_FILE = new LevelResource("fakeplayer.dat");
|
||||
public class BotDataStorage {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final File botDir;
|
||||
@@ -47,9 +44,9 @@ public class BotDataStorage implements IPlayerDataStorage {
|
||||
|
||||
private CompoundTag savedBotList;
|
||||
|
||||
public BotDataStorage(LevelStorageSource.@NotNull LevelStorageAccess session) {
|
||||
this.botDir = session.getLevelPath(BOT_DATA_DIR).toFile();
|
||||
this.botListFile = session.getLevelPath(BOT_LIST_FILE).toFile();
|
||||
public BotDataStorage(LevelStorageSource.@NotNull LevelStorageAccess session, String dataDir, String listFileName) {
|
||||
this.botDir = session.getLevelPath(new LevelResource(dataDir)).toFile();
|
||||
this.botListFile = session.getLevelPath(new LevelResource(listFileName)).toFile();
|
||||
this.botDir.mkdirs();
|
||||
|
||||
this.savedBotList = new CompoundTag();
|
||||
@@ -62,7 +59,6 @@ public class BotDataStorage implements IPlayerDataStorage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Player player) {
|
||||
boolean flag = true;
|
||||
try {
|
||||
@@ -85,22 +81,27 @@ public class BotDataStorage implements IPlayerDataStorage {
|
||||
|
||||
if (flag && player instanceof ServerBot bot) {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putString("name", bot.createState.name());
|
||||
nbt.putString("name", bot.createState.fullName());
|
||||
nbt.store("uuid", UUIDUtil.CODEC, bot.getUUID());
|
||||
nbt.putBoolean("resume", bot.resume);
|
||||
this.savedBotList.put(bot.createState.realName(), nbt);
|
||||
this.savedBotList.put(bot.createState.fullName(), nbt);
|
||||
this.saveBotList();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<ValueInput> load(Player player, ProblemReporter reporter) {
|
||||
return this.load(player.getScoreboardName(), player.getStringUUID()).map(nbt -> {
|
||||
ValueInput valueInput = TagValueInput.create(reporter, player.registryAccess(), nbt);
|
||||
player.load(valueInput);
|
||||
|
||||
public Optional<ValueInput> load(@NotNull ServerBot bot, ProblemReporter reporter) {
|
||||
return this.load(bot.nameAndId().name(), bot.nameAndId().id().toString()).map(nbt -> {
|
||||
ValueInput valueInput = TagValueInput.create(reporter, bot.registryAccess(), nbt);
|
||||
bot.load(valueInput);
|
||||
return valueInput;
|
||||
});
|
||||
}
|
||||
|
||||
public void removeSavedData(@NotNull ServerBot bot) {
|
||||
this.load(bot.nameAndId().name(), bot.nameAndId().id().toString());
|
||||
}
|
||||
|
||||
private Optional<CompoundTag> load(String name, String uuid) {
|
||||
File file = new File(this.botDir, uuid + ".dat");
|
||||
|
||||
|
||||
@@ -21,13 +21,14 @@ import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import fun.bm.lophine.config.modules.function.OldFeatureConfig;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.profile.MutablePropertyMap;
|
||||
import io.papermc.paper.threadedregions.RegionizedServer;
|
||||
import io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -46,10 +47,10 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.event.bot.*;
|
||||
@@ -68,23 +69,48 @@ public class BotList {
|
||||
private final MinecraftServer server;
|
||||
|
||||
public final List<ServerBot> bots = new CopyOnWriteArrayList<>();
|
||||
private final BotDataStorage dataStorage;
|
||||
private final BotDataStorage manualSaveDataStorage;
|
||||
private final BotDataStorage resumeDataStorage;
|
||||
|
||||
private final Map<UUID, ServerBot> botsByUUID = Maps.newHashMap();
|
||||
private final Map<String, ServerBot> botsByName = Maps.newHashMap();
|
||||
private final Map<String, Set<String>> botsNameByWorldUuid = Maps.newHashMap();
|
||||
private final Map<String, Set<String>> legacyBotsNameByWorldUuid = Maps.newHashMap();
|
||||
|
||||
public boolean forceShutdown = false;
|
||||
|
||||
public BotList(MinecraftServer server) {
|
||||
public BotList(@NotNull MinecraftServer server) {
|
||||
this.server = server;
|
||||
this.dataStorage = new BotDataStorage(server.storageSource);
|
||||
this.manualSaveDataStorage = new BotDataStorage(server.storageSource, "fakeplayerdata", "fakeplayer.dat");
|
||||
this.resumeDataStorage = new BotDataStorage(server.storageSource, "resume_fakeplayerdata", "resume_fakeplayer.dat");
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public ServerBot createNewBot(BotCreateState state) {
|
||||
BotCreateEvent event = new BotCreateEvent(state.name(), state.skinName(), state.location(), state.createReason(), state.creator());
|
||||
event.setCancelled(!BotUtil.isCreateLegal(state.name()));
|
||||
public void saveAllResumeBots(final int interval) {
|
||||
MCUtil.ensureMain("Save Bots", () -> {
|
||||
final long now = System.currentTimeMillis() / 50;
|
||||
for (ServerBot bot : bots) {
|
||||
if (interval == -1 || now - bot.lastSave >= interval) {
|
||||
this.resumeDataStorage.save(bot);
|
||||
bot.lastSave = now;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public void saveAllResumeBots() {
|
||||
if (!FakeplayerConfig.enable || !FakeplayerConfig.canResident) {
|
||||
return;
|
||||
}
|
||||
for (ServerBot bot : this.bots) {
|
||||
this.resumeDataStorage.save(bot);
|
||||
}
|
||||
}
|
||||
|
||||
public ServerBot createNewBot(@NotNull BotCreateState state) {
|
||||
BotCreateEvent event = new BotCreateEvent(state.fullName(), state.skinName(), state.location(), state.createReason(), state.creator());
|
||||
event.setCancelled(!BotUtil.isCreateLegal(state.fullName()));
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
@@ -94,7 +120,7 @@ public class BotList {
|
||||
Location location = event.getCreateLocation();
|
||||
ServerLevel world = ((CraftWorld) location.getWorld()).getHandle();
|
||||
|
||||
GameProfile profile = setProfile(BotUtil.getBotUUID(state), state.name(), state.skin());
|
||||
GameProfile profile = createBotProfile(BotUtil.getBotUUID(state), state.fullName(), state.skin());
|
||||
ServerBot bot = new ServerBot(this.server, world, profile);
|
||||
bot.createState = state;
|
||||
if (event.getCreator() instanceof org.bukkit.entity.Player player) {
|
||||
@@ -104,56 +130,58 @@ public class BotList {
|
||||
return this.placeNewBot(bot, world, location, null);
|
||||
}
|
||||
|
||||
public ServerBot loadNewBot(String realName) {
|
||||
try {
|
||||
return this.loadNewBot(realName, this.dataStorage);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to load bot {}", realName, e);
|
||||
return null;
|
||||
}
|
||||
public ServerBot loadNewManualSavedBot(String fullName) {
|
||||
return this.loadNewBot(fullName, this.manualSaveDataStorage);
|
||||
}
|
||||
|
||||
public ServerBot loadNewBot(String realName, IPlayerDataStorage playerIO) {
|
||||
UUID uuid = BotUtil.getBotUUID(realName);
|
||||
public ServerBot loadNewResumeBot(String fullName) {
|
||||
return this.loadNewBot(fullName, this.resumeDataStorage);
|
||||
}
|
||||
|
||||
BotLoadEvent event = new BotLoadEvent(realName, uuid);
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
public ServerBot loadNewBot(String fullName, BotDataStorage storage) {
|
||||
if (botsByName.containsKey(fullName)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
UUID uuid = BotUtil.getBotUUID(fullName);
|
||||
|
||||
ServerBot bot = new ServerBot(this.server, this.server.getLevel(Level.OVERWORLD), new GameProfile(uuid, realName));
|
||||
bot.connection = new ServerBotPacketListenerImpl(this.server, bot, new ServerBotPacketListenerImpl.BotConnection());
|
||||
bot.connection.markClientLoaded();
|
||||
Optional<ValueInput> optional;
|
||||
if (playerIO instanceof BotDataStorage botIO) {
|
||||
BotLoadEvent event = new BotLoadEvent(fullName, uuid);
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerBot bot = new ServerBot(this.server, this.server.getLevel(Level.OVERWORLD), new GameProfile(uuid, fullName));
|
||||
bot.connection = new ServerBotPacketListenerImpl(this.server, bot);
|
||||
Optional<ValueInput> optional;
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(bot.problemPath(), LOGGER)) {
|
||||
optional = botIO.load(bot, scopedCollector);
|
||||
optional = storage.load(bot, scopedCollector);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
optional = Optional.empty();
|
||||
}
|
||||
|
||||
if (optional.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
ValueInput nbt = optional.get();
|
||||
|
||||
ResourceKey<Level> resourcekey = null;
|
||||
if (nbt.getLong("WorldUUIDMost").isPresent() && nbt.getLong("WorldUUIDLeast").isPresent()) {
|
||||
World bWorld = Bukkit.getServer().getWorld(new UUID(nbt.getLong("WorldUUIDMost").orElseThrow(), nbt.getLong("WorldUUIDLeast").orElseThrow()));
|
||||
if (bWorld != null) {
|
||||
resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
|
||||
if (optional.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (resourcekey == null) {
|
||||
ValueInput nbt = optional.get();
|
||||
|
||||
ResourceKey<Level> resourcekey = null;
|
||||
if (nbt.getLong("WorldUUIDMost").isPresent() && nbt.getLong("WorldUUIDLeast").isPresent()) {
|
||||
org.bukkit.World bWorld = Bukkit.getServer().getWorld(new UUID(nbt.getLong("WorldUUIDMost").orElseThrow(), nbt.getLong("WorldUUIDLeast").orElseThrow()));
|
||||
if (bWorld != null) {
|
||||
resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
|
||||
}
|
||||
}
|
||||
if (resourcekey == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerLevel world = this.server.getLevel(resourcekey);
|
||||
return this.placeNewBot(bot, world, bot.getLocation(), nbt);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to load bot {}", fullName, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
ServerLevel world = this.server.getLevel(resourcekey);
|
||||
return this.placeNewBot(bot, world, bot.getLocation(), nbt);
|
||||
}
|
||||
|
||||
public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, ValueInput save) {
|
||||
@@ -161,7 +189,7 @@ public class BotList {
|
||||
|
||||
bot.isRealPlayer = true;
|
||||
bot.loginTime = System.currentTimeMillis();
|
||||
bot.connection = new ServerBotPacketListenerImpl(this.server, bot, new ServerBotPacketListenerImpl.BotConnection());
|
||||
bot.connection = new ServerBotPacketListenerImpl(this.server, bot);
|
||||
bot.connection.markClientLoaded();
|
||||
bot.setServerLevel(world);
|
||||
|
||||
@@ -183,65 +211,60 @@ public class BotList {
|
||||
|
||||
bot.suppressTrackerForLogin = true;
|
||||
|
||||
optional.ifPresent(nbt -> {
|
||||
bot.loadAndSpawnEnderPearls(nbt);
|
||||
bot.loadAndSpawnParentVehicle(nbt);
|
||||
});
|
||||
Runnable task = () -> {
|
||||
optional.ifPresent(nbt -> {
|
||||
bot.loadAndSpawnEnderPearls(nbt);
|
||||
bot.loadAndSpawnParentVehicle(nbt);
|
||||
});
|
||||
world.getCurrentWorldData().connections.add(bot.connection.connection);
|
||||
world.addNewPlayer(bot);
|
||||
BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)));
|
||||
this.server.server.getPluginManager().callEvent(event1);
|
||||
|
||||
net.kyori.adventure.text.Component joinMessage = event1.joinMessage();
|
||||
if (joinMessage != null && !joinMessage.equals(net.kyori.adventure.text.Component.empty())) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(joinMessage), false);
|
||||
}
|
||||
|
||||
bot.renderInfo();
|
||||
bot.suppressTrackerForLogin = false;
|
||||
|
||||
bot.level().getChunkSource().chunkMap.addEntity(bot);
|
||||
bot.renderData();
|
||||
bot.initInventoryMenu();
|
||||
botsNameByWorldUuid
|
||||
.computeIfAbsent(bot.level().uuid.toString(), (k) -> new HashSet<>())
|
||||
.add(bot.getBukkitEntity().getName());
|
||||
BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.level().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ());
|
||||
};
|
||||
if (TickThread.isTickThreadFor(world, location.blockX() >> 4, location.blockZ() >> 4)) {
|
||||
summonBot(bot, world);
|
||||
task.run();
|
||||
} else {
|
||||
RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
|
||||
world, location.getBlockX() >> 4, location.blockZ() >> 4,
|
||||
() -> summonBot(bot, world));
|
||||
task);
|
||||
}
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
private ServerBot summonBot(ServerBot bot, ServerLevel world) {
|
||||
world.getCurrentWorldData().connections.add(bot.connection.connection);
|
||||
world.addNewPlayer(bot);
|
||||
|
||||
BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)));
|
||||
this.server.server.getPluginManager().callEvent(event1);
|
||||
|
||||
net.kyori.adventure.text.Component joinMessage = event1.joinMessage();
|
||||
if (joinMessage != null && !joinMessage.equals(net.kyori.adventure.text.Component.empty())) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(joinMessage), false);
|
||||
}
|
||||
|
||||
bot.renderInfo();
|
||||
bot.suppressTrackerForLogin = false;
|
||||
|
||||
bot.level().getChunkSource().chunkMap.addEntity(bot);
|
||||
bot.renderData();
|
||||
bot.initInventoryMenu();
|
||||
botsNameByWorldUuid
|
||||
.computeIfAbsent(bot.level().uuid.toString(), (k) -> new HashSet<>())
|
||||
.add(bot.getBukkitEntity().getRealName());
|
||||
BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.level().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ());
|
||||
return bot;
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if async
|
||||
*/
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved, boolean async) {
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean save, boolean resume, boolean async) {
|
||||
if (async && !TickThread.isTickThreadFor(bot.level(), bot.getX(), bot.getZ())) {
|
||||
bot.getBukkitEntity().taskScheduler.schedule((Entity unused) -> this.removeBot(bot, reason, remover, saved), null, 1L);
|
||||
return true;
|
||||
bot.getBukkitEntity().taskScheduler.schedule((Entity unused) -> this.removeBot(bot, reason, remover, save, resume), null, 1L);
|
||||
return true; // async always return true
|
||||
}
|
||||
this.removeBot(bot, reason, remover, saved);
|
||||
return false;
|
||||
return this.removeBot(bot, remover, reason, save, resume);
|
||||
}
|
||||
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved) {
|
||||
return this.removeBot(bot, reason, remover, saved, this.dataStorage);
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean save, boolean resume) {
|
||||
return this.removeBot(bot, reason, remover, save, resume, true);
|
||||
}
|
||||
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved, IPlayerDataStorage playerIO) {
|
||||
BotRemoveEvent event = new BotRemoveEvent(bot.getBukkitEntity(), reason, remover, PaperAdventure.asAdventure(Component.translatable("multiplayer.player.left", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)), saved);
|
||||
public boolean removeBot(@NotNull ServerBot bot, @Nullable CommandSender remover, @NotNull BotRemoveEvent.RemoveReason reason, boolean save, boolean resume) {
|
||||
BotRemoveEvent event = new BotRemoveEvent(bot.getBukkitEntity(), reason, remover, PaperAdventure.asAdventure(Component.translatable("multiplayer.player.left", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)), save);
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled() && event.getReason() != BotRemoveEvent.RemoveReason.INTERNAL) {
|
||||
@@ -255,11 +278,16 @@ public class BotList {
|
||||
|
||||
bot.disconnect();
|
||||
|
||||
this.resumeDataStorage.removeSavedData(bot);
|
||||
if (event.shouldSave()) {
|
||||
playerIO.save(bot);
|
||||
if (resume) {
|
||||
this.resumeDataStorage.save(bot);
|
||||
} else {
|
||||
this.manualSaveDataStorage.save(bot);
|
||||
}
|
||||
} else {
|
||||
bot.dropAll(true);
|
||||
botsNameByWorldUuid.getOrDefault(bot.level().uuid.toString(), new HashSet<>()).remove(bot.getBukkitEntity().getRealName());
|
||||
botsNameByWorldUuid.getOrDefault(bot.level().uuid.toString(), new HashSet<>()).remove(bot.getBukkitEntity().getName());
|
||||
}
|
||||
|
||||
if (bot.isPassenger() && event.shouldSave()) {
|
||||
@@ -267,7 +295,7 @@ public class BotList {
|
||||
if (entity.hasExactlyOnePlayerPassenger()) {
|
||||
bot.stopRiding();
|
||||
entity.getPassengersAndSelf().forEach((entity1) -> {
|
||||
if (entity1 instanceof AbstractVillager villager) {
|
||||
if (!OldFeatureConfig.villagerVoidTrade && entity1 instanceof AbstractVillager villager) {
|
||||
final Player human = villager.getTradingPlayer();
|
||||
if (human != null) {
|
||||
villager.setTradingPlayer(null);
|
||||
@@ -312,15 +340,14 @@ public class BotList {
|
||||
if (removeMessage != null && !removeMessage.equals(net.kyori.adventure.text.Component.empty())) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(removeMessage), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeAllIn(String worldUuid) {
|
||||
for (String realName : this.botsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())) {
|
||||
ServerBot bot = this.getBotByName(realName);
|
||||
for (String fullName : this.botsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())) {
|
||||
ServerBot bot = this.getBotByName(fullName);
|
||||
if (bot != null) {
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident, FakeplayerConfig.canResident);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,7 +359,7 @@ public class BotList {
|
||||
for (ServerBot bot : this.bots) {
|
||||
bot.resume = FakeplayerConfig.canResident;
|
||||
if (TickThread.isTickThreadFor(bot.level(), bot.getX(), bot.getZ())) {
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident, FakeplayerConfig.canResident);
|
||||
} else {
|
||||
finished = false;
|
||||
check.getAndIncrement();
|
||||
@@ -349,7 +376,7 @@ public class BotList {
|
||||
}
|
||||
counter.getAndIncrement();
|
||||
try {
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident, FakeplayerConfig.canResident);
|
||||
received.getAndIncrement();
|
||||
} catch (Exception e) {
|
||||
this.removeBot(bot, check, received, counter);
|
||||
@@ -361,24 +388,39 @@ public class BotList {
|
||||
}, null, 1L);
|
||||
}
|
||||
|
||||
public void loadBotInfo() {
|
||||
public void loadResumeBotInfo() {
|
||||
if (!FakeplayerConfig.enable || !FakeplayerConfig.canResident) {
|
||||
return;
|
||||
}
|
||||
CompoundTag savedBotList = this.getSavedBotList().copy();
|
||||
for (String realName : savedBotList.keySet()) {
|
||||
CompoundTag nbt = savedBotList.getCompound(realName).orElseThrow();
|
||||
if (!nbt.getBoolean("resume").orElse(false)) {
|
||||
continue;
|
||||
}
|
||||
UUID levelUuid = BotUtil.getBotLevel(realName, this.dataStorage);
|
||||
CompoundTag savedBotList = this.getResumeBotList().copy();
|
||||
for (String fullName : savedBotList.keySet()) {
|
||||
UUID levelUuid = BotUtil.getBotLevel(fullName, this.resumeDataStorage);
|
||||
if (levelUuid == null) {
|
||||
LOGGER.warn("Bot {} has no world UUID, skipping loading.", realName);
|
||||
LOGGER.warn("Bot {} has no world UUID, skipping loading.", fullName);
|
||||
continue;
|
||||
}
|
||||
this.botsNameByWorldUuid
|
||||
.computeIfAbsent(levelUuid.toString(), (k) -> new HashSet<>())
|
||||
.add(realName);
|
||||
.add(fullName);
|
||||
}
|
||||
loadLegacyResumeBotInfo();
|
||||
}
|
||||
|
||||
private void loadLegacyResumeBotInfo() {
|
||||
CompoundTag savedBotList = this.getManualSavedBotList().copy();
|
||||
for (String fullName : savedBotList.keySet()) {
|
||||
CompoundTag nbt = savedBotList.getCompound(fullName).orElseThrow();
|
||||
if (!nbt.getBoolean("resume").orElse(false)) {
|
||||
continue;
|
||||
}
|
||||
UUID levelUuid = BotUtil.getBotLevel(fullName, this.manualSaveDataStorage);
|
||||
if (levelUuid == null) {
|
||||
LOGGER.warn("Bot {} has no world UUID, skipping loading.", fullName);
|
||||
continue;
|
||||
}
|
||||
this.legacyBotsNameByWorldUuid
|
||||
.computeIfAbsent(levelUuid.toString(), (k) -> new HashSet<>())
|
||||
.add(fullName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,23 +428,19 @@ public class BotList {
|
||||
if (!FakeplayerConfig.enable || !FakeplayerConfig.canResident) {
|
||||
return;
|
||||
}
|
||||
Set<String> bots = this.botsNameByWorldUuid.get(worldUuid);
|
||||
if (bots == null) {
|
||||
return;
|
||||
}
|
||||
Set<String> botsCopy = new HashSet<>(bots);
|
||||
botsCopy.forEach(this::loadNewBot);
|
||||
new HashSet<>(this.botsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())).forEach(this::loadNewResumeBot);
|
||||
new HashSet<>(this.legacyBotsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())).forEach(this::loadNewManualSavedBot);
|
||||
}
|
||||
|
||||
public void updateBotLevel(ServerBot bot, ServerLevel level) {
|
||||
public void updateBotLevel(@NotNull ServerBot bot, @NotNull ServerLevel level) {
|
||||
String prevUuid = bot.level().uuid.toString();
|
||||
String newUuid = level.uuid.toString();
|
||||
this.botsNameByWorldUuid
|
||||
.computeIfAbsent(newUuid, (k) -> new HashSet<>())
|
||||
.add(bot.getBukkitEntity().getRealName());
|
||||
.add(bot.getBukkitEntity().getName());
|
||||
this.botsNameByWorldUuid
|
||||
.computeIfAbsent(prevUuid, (k) -> new HashSet<>())
|
||||
.remove(bot.getBukkitEntity().getRealName());
|
||||
.remove(bot.getBukkitEntity().getName());
|
||||
}
|
||||
|
||||
public void networkTick() {
|
||||
@@ -419,15 +457,25 @@ public class BotList {
|
||||
return this.botsByName.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public CompoundTag getSavedBotList() {
|
||||
return this.dataStorage.getSavedBotList();
|
||||
public CompoundTag getManualSavedBotList() {
|
||||
return this.getSavedBotList(this.manualSaveDataStorage);
|
||||
}
|
||||
|
||||
public GameProfile setProfile(UUID uuid, String name, String[] skin) {
|
||||
GameProfile profile = new GameProfile(uuid, name);
|
||||
if (skin == null) return profile;
|
||||
PropertyMap profileMap = new MutablePropertyMap(profile.properties());
|
||||
profileMap.put("textures", new Property("textures", skin[0], skin[1]));
|
||||
return new GameProfile(uuid, name, profileMap);
|
||||
public CompoundTag getResumeBotList() {
|
||||
return this.getSavedBotList(this.resumeDataStorage);
|
||||
}
|
||||
|
||||
public CompoundTag getSavedBotList(@NotNull BotDataStorage storage) {
|
||||
return storage.getSavedBotList();
|
||||
}
|
||||
|
||||
@Contract("_, _, _ -> new")
|
||||
public static @NotNull GameProfile createBotProfile(UUID uuid, String name, String[] skin) {
|
||||
GameProfile profile = new GameProfile(uuid, name, new MutablePropertyMap());
|
||||
profile.properties().put("is_bot", new Property("is_bot", "true"));
|
||||
if (skin != null) {
|
||||
profile.properties().put("textures", new Property("textures", skin[0], skin[1]));
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.minecraft.stats.ServerStatsCounter;
|
||||
import net.minecraft.stats.Stat;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -44,7 +45,7 @@ public class BotStatsCounter extends ServerStatsCounter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(@NotNull DataFixer dataFixer, @NotNull JsonElement json) {
|
||||
public void parse(@NonNull DataFixer fixerUpper, @NonNull JsonElement json) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,15 +85,15 @@ public class BotUtil {
|
||||
|
||||
@NotNull
|
||||
public static UUID getBotUUID(@NotNull BotCreateState state) {
|
||||
return getBotUUID(state.realName());
|
||||
return getBotUUID(state.fullName());
|
||||
}
|
||||
|
||||
public static UUID getBotUUID(@NotNull String realName) {
|
||||
return UUID.nameUUIDFromBytes(("Fakeplayer:" + realName).getBytes(Charsets.UTF_8));
|
||||
public static UUID getBotUUID(@NotNull String fullName) {
|
||||
return UUID.nameUUIDFromBytes(("Fakeplayer:" + fullName).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public static UUID getBotLevel(@NotNull String realName, BotDataStorage botDataStorage) {
|
||||
UUID uuid = BotUtil.getBotUUID(realName);
|
||||
public static UUID getBotLevel(@NotNull String fullName, BotDataStorage botDataStorage) {
|
||||
UUID uuid = getBotUUID(fullName);
|
||||
Optional<CompoundTag> tagOptional = botDataStorage.read(uuid.toString());
|
||||
if (tagOptional.isEmpty()) {
|
||||
return null;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.bot;
|
||||
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
public interface IPlayerDataStorage {
|
||||
|
||||
void save(Player player);
|
||||
|
||||
// Optional<ValueInput> load(Player player, ProblemReporter reporter);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package org.leavesmc.leaves.bot;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.LophineLogger;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.event.entity.EntityKnockbackEvent;
|
||||
@@ -77,16 +77,16 @@ import org.leavesmc.leaves.entity.bot.CraftBot;
|
||||
import org.leavesmc.leaves.event.bot.*;
|
||||
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
|
||||
import org.leavesmc.leaves.util.MathUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static net.minecraft.server.MinecraftServer.getServer;
|
||||
|
||||
public class ServerBot extends ServerPlayer {
|
||||
|
||||
private final List<AbstractBotAction<?>> actions;
|
||||
private final Map<String, AbstractBotConfig<?, ?, ?>> configs;
|
||||
private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
private final Map<String, AbstractBotConfig<?, ?>> configs;
|
||||
|
||||
public boolean resume = false;
|
||||
public BotCreateState createState;
|
||||
@@ -108,8 +108,8 @@ public class ServerBot extends ServerPlayer {
|
||||
this.gameMode = new ServerBotGameMode(this);
|
||||
|
||||
this.actions = new ArrayList<>();
|
||||
ImmutableMap.Builder<String, AbstractBotConfig<?, ?, ?>> configBuilder = ImmutableMap.builder();
|
||||
for (AbstractBotConfig<?, ?, ?> config : Configs.getConfigs()) {
|
||||
ImmutableMap.Builder<String, AbstractBotConfig<?, ?>> configBuilder = ImmutableMap.builder();
|
||||
for (AbstractBotConfig<?, ?> config : Configs.getConfigs()) {
|
||||
configBuilder.put(config.getName(), config.create().setBot(this));
|
||||
}
|
||||
this.configs = configBuilder.build();
|
||||
@@ -139,7 +139,7 @@ public class ServerBot extends ServerPlayer {
|
||||
this.joining = false;
|
||||
}
|
||||
|
||||
this.resetOperationCountPerTick(); // Leaves - player operation limiter
|
||||
// this.resetOperationCountPerTick(); // Leaves - player operation limiter
|
||||
this.wardenSpawnTracker.tick();
|
||||
if (this.invulnerableTime > 0) {
|
||||
this.invulnerableTime--;
|
||||
@@ -213,17 +213,7 @@ public class ServerBot extends ServerPlayer {
|
||||
this.updateIsUnderwater();
|
||||
|
||||
if (this.getConfigValue(Configs.TICK_TYPE) == TickType.NETWORK) {
|
||||
try {
|
||||
Bukkit.getRegionScheduler().execute(
|
||||
MinecraftInternalPlugin.INSTANCE,
|
||||
this.level().getWorld(),
|
||||
this.getBlockX() >> 4,
|
||||
this.getBlockZ() >> 4,
|
||||
this::runAction
|
||||
);
|
||||
} catch (Exception e) {
|
||||
this.runAction();
|
||||
}
|
||||
getServer().scheduleOnMain(this::runAction);
|
||||
}
|
||||
|
||||
this.livingEntityTick();
|
||||
@@ -305,6 +295,18 @@ public class ServerBot extends ServerPlayer {
|
||||
teleportTransition.postTeleportTransition().onTransition(this);
|
||||
this.isChangingDimension = false;
|
||||
|
||||
// Lophine - We don't have this
|
||||
/* if (LeavesConfig.modify.netherPortalFix) {
|
||||
final ResourceKey<Level> fromDim = fromLevel.dimension();
|
||||
final ResourceKey<Level> toDim = level().dimension();
|
||||
if (!((fromDim != Level.OVERWORLD || toDim != Level.NETHER) && (fromDim != Level.NETHER || toDim != Level.OVERWORLD))) {
|
||||
BlockPos fromPortal = org.leavesmc.leaves.util.ReturnPortalManager.findPortalAt(this, fromDim, lastPos);
|
||||
BlockPos toPos = this.blockPosition();
|
||||
if (fromPortal != null) {
|
||||
org.leavesmc.leaves.util.ReturnPortalManager.storeReturnPortal(this, toDim, toPos, fromPortal);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
if (this.isBlocking()) {
|
||||
this.stopUsingItem();
|
||||
}
|
||||
@@ -350,7 +352,7 @@ public class ServerBot extends ServerPlayer {
|
||||
if (FakeplayerConfig.canOpenInventory) {
|
||||
if (player instanceof ServerPlayer player1 && player.getMainHandItem().isEmpty()) {
|
||||
BotInventoryOpenEvent event = new BotInventoryOpenEvent(this.getBukkitEntity(), player1.getBukkitEntity());
|
||||
MinecraftServer.getServer().server.getPluginManager().callEvent(event);
|
||||
getServer().server.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, this.container), this.getDisplayName()));
|
||||
return InteractionResult.SUCCESS;
|
||||
@@ -372,8 +374,8 @@ public class ServerBot extends ServerPlayer {
|
||||
nbt.putBoolean("isShiftKeyDown", this.isShiftKeyDown());
|
||||
|
||||
CompoundTag createNbt = new CompoundTag();
|
||||
createNbt.putString("realName", this.createState.realName());
|
||||
createNbt.putString("name", this.createState.name());
|
||||
createNbt.putString("rawName", this.createState.rawName());
|
||||
createNbt.putString("name", this.createState.fullName());
|
||||
|
||||
createNbt.putString("skinName", this.createState.skinName());
|
||||
if (this.createState.skin() != null) {
|
||||
@@ -395,7 +397,7 @@ public class ServerBot extends ServerPlayer {
|
||||
|
||||
if (!this.configs.isEmpty()) {
|
||||
ValueOutput.TypedOutputList<CompoundTag> configNbt = nbt.list("configs", CompoundTag.CODEC);
|
||||
for (AbstractBotConfig<?, ?, ?> config : this.configs.values()) {
|
||||
for (AbstractBotConfig<?, ?> config : this.configs.values()) {
|
||||
configNbt.add(config.save(new CompoundTag()));
|
||||
}
|
||||
}
|
||||
@@ -407,7 +409,11 @@ public class ServerBot extends ServerPlayer {
|
||||
this.setShiftKeyDown(nbt.getBooleanOr("isShiftKeyDown", false));
|
||||
|
||||
CompoundTag createNbt = nbt.read("createStatus", CompoundTag.CODEC).orElseThrow();
|
||||
BotCreateState.Builder createBuilder = BotCreateState.builder(createNbt.getString("realName").orElseThrow(), null).name(createNbt.getString("name").orElseThrow());
|
||||
BotCreateState.Builder createBuilder = BotCreateState
|
||||
.builder(createNbt.getString("rawName")
|
||||
.orElseGet(() -> createNbt.getString("realName")
|
||||
.orElseThrow()), null) // Convert from legacy version, consider to use ca.spottedleaf.dataconverter.minecraft.MCDataConverter instead for release version
|
||||
.name(createNbt.getString("name").orElseThrow());
|
||||
|
||||
String[] skin = null;
|
||||
if (createNbt.contains("skin")) {
|
||||
@@ -422,7 +428,7 @@ public class ServerBot extends ServerPlayer {
|
||||
createBuilder.createReason(BotCreateEvent.CreateReason.INTERNAL).creator(null);
|
||||
|
||||
this.createState = createBuilder.build();
|
||||
this.gameProfile = BotList.INSTANCE.setProfile(this.getUUID(), this.createState.name(), this.createState.skin());
|
||||
this.gameProfile = BotList.createBotProfile(this.getUUID(), this.createState.fullName(), this.createState.skin());
|
||||
|
||||
|
||||
if (nbt.list("actions", CompoundTag.CODEC).isPresent()) {
|
||||
@@ -440,8 +446,9 @@ public class ServerBot extends ServerPlayer {
|
||||
if (nbt.list("configs", CompoundTag.CODEC).isPresent()) {
|
||||
ValueInput.TypedInputList<CompoundTag> configNbt = nbt.list("configs", CompoundTag.CODEC).orElseThrow();
|
||||
for (CompoundTag configTag : configNbt) {
|
||||
AbstractBotConfig<?, ?, ?> config = Configs.getConfig(configTag.getString("configName").orElseThrow());
|
||||
AbstractBotConfig<?, ?> config = Configs.getConfig(configTag.getString("configName").orElseThrow());
|
||||
if (config != null) {
|
||||
config.setBot(this);
|
||||
config.load(configTag);
|
||||
}
|
||||
}
|
||||
@@ -466,30 +473,30 @@ public class ServerBot extends ServerPlayer {
|
||||
ChunkMap.TrackedEntity entityTracker = this.moonrise$getTrackedEntity();
|
||||
|
||||
if (entityTracker == null) {
|
||||
LOGGER.warn("Fakeplayer cant get entity tracker for {}", this.getId());
|
||||
LophineLogger.LOGGER.warn("Fakeplayer cant get entity tracker for {}", this.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
playerConnection.send(this.getAddEntityPacket(entityTracker.serverEntity));
|
||||
if (login) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(MinecraftInternalPlugin.INSTANCE, (unused) -> playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))), 10);
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(MinecraftInternalPlugin.INSTANCE, (task) -> playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f))), 10);
|
||||
} else {
|
||||
playerConnection.send(new ClientboundRotateHeadPacket(this, (byte) ((getYRot() * 256f) / 360f)));
|
||||
}
|
||||
}
|
||||
|
||||
public void renderInfo() {
|
||||
MinecraftServer.getServer().getPlayerList().getPlayers().forEach(this::sendPlayerInfo);
|
||||
getServer().getPlayerList().getPlayers().forEach(this::sendPlayerInfo);
|
||||
}
|
||||
|
||||
public void renderData() {
|
||||
MinecraftServer.getServer().getPlayerList().getPlayers().forEach(
|
||||
getServer().getPlayerList().getPlayers().forEach(
|
||||
player -> this.sendFakeDataIfNeed(player, false)
|
||||
);
|
||||
}
|
||||
|
||||
private void sendPacket(Packet<?> packet) {
|
||||
MinecraftServer.getServer().getPlayerList().getPlayers().forEach(player -> player.connection.send(packet));
|
||||
getServer().getPlayerList().getPlayers().forEach(player -> player.connection.send(packet));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -498,7 +505,7 @@ public class ServerBot extends ServerPlayer {
|
||||
Component defaultMessage = this.getCombatTracker().getDeathMessage();
|
||||
|
||||
BotDeathEvent event = new BotDeathEvent(this.getBukkitEntity(), PaperAdventure.asAdventure(defaultMessage), flag);
|
||||
MinecraftServer.getServer().server.getPluginManager().callEvent(event);
|
||||
getServer().server.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
if (this.getHealth() <= 0) {
|
||||
@@ -511,18 +518,23 @@ public class ServerBot extends ServerPlayer {
|
||||
|
||||
net.kyori.adventure.text.Component deathMessage = event.deathMessage();
|
||||
if (event.isSendDeathMessage() && deathMessage != null && !deathMessage.equals(net.kyori.adventure.text.Component.empty())) {
|
||||
MinecraftServer.getServer().getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false);
|
||||
getServer().getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false);
|
||||
}
|
||||
|
||||
MinecraftServer.getServer().getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false);
|
||||
// TODO: separate die and remove logic, call super.die here
|
||||
this.removeEntitiesOnShoulder();
|
||||
if (this.level().getGameRules().get(GameRules.FORGIVE_DEAD_PLAYERS)) {
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
getServer().getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startRiding(Entity entity, boolean force, boolean triggerEvents) {
|
||||
if (super.startRiding(entity, force, triggerEvents)) {
|
||||
if (entity.getControllingPassenger() == this) { // see net.minecraft.server.networkServerGamePacketListenerImpl#handleMoveVehicle
|
||||
public boolean startRiding(@NotNull Entity vehicle, boolean force, boolean sendGameEvent) {
|
||||
if (super.startRiding(vehicle, force, sendGameEvent)) {
|
||||
if (vehicle.getControllingPassenger() == this) { // see net.minecraft.server.networkServerGamePacketListenerImpl#handleMoveVehicle
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
this.setYRot(entity.yRotO);
|
||||
this.setYRot(vehicle.yRotO);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
@@ -669,15 +681,15 @@ public class ServerBot extends ServerPlayer {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <O, I, E extends AbstractBotConfig<O, I, E>> AbstractBotConfig<O, I, E> getConfig(@NotNull AbstractBotConfig<O, I, E> config) {
|
||||
return (AbstractBotConfig<O, I, E>) Objects.requireNonNull(this.configs.get(config.getName()));
|
||||
public <T, E extends AbstractBotConfig<T, E>> AbstractBotConfig<T, E> getConfig(@NotNull AbstractBotConfig<T, E> config) {
|
||||
return (AbstractBotConfig<T, E>) Objects.requireNonNull(this.configs.get(config.getName()));
|
||||
}
|
||||
|
||||
public Collection<AbstractBotConfig<?, ?, ?>> getAllConfigs() {
|
||||
public Collection<AbstractBotConfig<?, ?>> getAllConfigs() {
|
||||
return configs.values();
|
||||
}
|
||||
|
||||
public <O, I, E extends AbstractBotConfig<O, I, E>> O getConfigValue(@NotNull AbstractBotConfig<O, I, E> config) {
|
||||
public <T, E extends AbstractBotConfig<T, E>> T getConfigValue(@NotNull AbstractBotConfig<T, E> config) {
|
||||
return this.getConfig(config).getValue();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class ServerBotGameMode extends ServerPlayerGameMode {
|
||||
this.level.sendBlockUpdated(pos, blockState, blockState, 3);
|
||||
return false;
|
||||
} else {
|
||||
BlockState blockState1 = block.playerWillDestroy(this.level, pos, blockState, this.player); // Leaves - no block update
|
||||
BlockState blockState1 = /*isNoBlockUpdate() ? blockState : */block.playerWillDestroy(this.level, pos, blockState, this.player); // Leaves - no block update
|
||||
boolean flag = this.level.removeBlock(pos, false);
|
||||
if (flag) {
|
||||
block.destroy(this.level, pos, blockState1);
|
||||
|
||||
+4
-5
@@ -29,12 +29,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl {
|
||||
public final Connection fakeConnection;
|
||||
|
||||
public ServerBotPacketListenerImpl(MinecraftServer server, ServerBot bot, BotConnection botConnection) {
|
||||
super(server, botConnection, bot, CommonListenerCookie.createInitial(bot.gameProfile, false));
|
||||
this.fakeConnection = botConnection;
|
||||
this.fakeConnection.packetListener = this;
|
||||
public ServerBotPacketListenerImpl(MinecraftServer server, ServerBot bot) {
|
||||
super(server, BotConnection.INSTANCE, bot, CommonListenerCookie.createInitial(bot.gameProfile, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,6 +53,8 @@ public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl {
|
||||
|
||||
public static class BotConnection extends Connection {
|
||||
|
||||
private static final BotConnection INSTANCE = new BotConnection();
|
||||
|
||||
public BotConnection() {
|
||||
super(PacketFlow.SERVERBOUND);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"unused"})
|
||||
public class Configs {
|
||||
private static final Map<Class<?>, AbstractBotConfig<?, ?, ?>> configs = new HashMap<>();
|
||||
private static final Map<Class<?>, AbstractBotConfig<?, ?>> configs = new HashMap<>();
|
||||
|
||||
public static final SkipSleepConfig SKIP_SLEEP = register(new SkipSleepConfig());
|
||||
public static final AlwaysSendDataConfig ALWAYS_SEND_DATA = register(new AlwaysSendDataConfig());
|
||||
@@ -38,7 +38,7 @@ public class Configs {
|
||||
public static final LocatorBarConfig ENABLE_LOCATOR_BAR = register(new LocatorBarConfig());
|
||||
|
||||
@Nullable
|
||||
public static AbstractBotConfig<?, ?, ?> getConfig(String name) {
|
||||
public static AbstractBotConfig<?, ?> getConfig(String name) {
|
||||
return configs.values().stream()
|
||||
.filter(config -> config.getName().equals(name))
|
||||
.findFirst()
|
||||
@@ -47,12 +47,12 @@ public class Configs {
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public static Collection<AbstractBotConfig<?, ?, ?>> getConfigs() {
|
||||
public static Collection<AbstractBotConfig<?, ?>> getConfigs() {
|
||||
return configs.values();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <Value, Type, E extends AbstractBotConfig<Value, Type, E>> @NotNull E register(AbstractBotConfig<Value, Type, E> instance) {
|
||||
private static <T, E extends AbstractBotConfig<T, E>> @NotNull E register(AbstractBotConfig<T, E> instance) {
|
||||
configs.put(instance.getClass(), instance);
|
||||
return (E) instance;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.leavesmc.leaves.bot.agent;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record ExtraData(List<Pair<String, String>> raw) {
|
||||
public void add(String key, String value) {
|
||||
raw.add(Pair.of(key, value));
|
||||
}
|
||||
}
|
||||
+12
-22
@@ -19,18 +19,18 @@ package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.LophineLogger;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.WrappedArgument;
|
||||
import org.leavesmc.leaves.event.bot.BotActionExecuteEvent;
|
||||
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
|
||||
import org.leavesmc.leaves.util.UpdateSuppressionException;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
@@ -56,7 +56,6 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
|
||||
private Consumer<E> onFail;
|
||||
private Consumer<E> onSuccess;
|
||||
private Consumer<E> onStop;
|
||||
private static final Logger LOGGER = LogUtils.getClassLogger();
|
||||
|
||||
public AbstractBotAction(String name, Supplier<E> creator) {
|
||||
this.name = name;
|
||||
@@ -74,13 +73,12 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
|
||||
|
||||
public abstract Object asCraft();
|
||||
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
public String getActionDataString() {
|
||||
return getActionDataString(new ExtraData(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public String getActionDataString() {
|
||||
ActionData data = new ActionData(new ArrayList<>());
|
||||
provideActionData(data);
|
||||
return data.raw.stream()
|
||||
public String getActionDataString(@NotNull ExtraData data) {
|
||||
return data.raw().stream()
|
||||
.map(pair -> pair.getLeft() + "=" + pair.getRight())
|
||||
.reduce((a, b) -> a + ", " + b)
|
||||
.orElse("No arguments");
|
||||
@@ -141,7 +139,7 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
|
||||
e.providePlayer(bot);
|
||||
e.consume();
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("An error occurred while executing bot " + bot.displayName + ", action " + this.name, e);
|
||||
LophineLogger.LOGGER.error("An error occurred while executing bot {}, action {}", bot.displayName, this.name, e);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
@@ -179,12 +177,12 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
this.uuid = nbt.read("actionUUID", UUIDUtil.CODEC).orElse(UUID.randomUUID());
|
||||
|
||||
this.initialTickDelay = nbt.getInt("initialTickDelay").orElse(0);
|
||||
this.initialTickInterval = nbt.getInt("initialTickInterval").orElse(0);
|
||||
this.initialNumber = nbt.getInt("initialNumber").orElse(0);
|
||||
this.initialTickDelay = nbt.getIntOr("initialTickDelay", 0);
|
||||
this.initialTickInterval = nbt.getIntOr("initialTickInterval", 0);
|
||||
this.initialNumber = nbt.getIntOr("initialNumber", 0);
|
||||
|
||||
this.tickToNext = nbt.getInt("tickToNext").orElse(0);
|
||||
this.numberRemaining = nbt.getInt("numberRemaining").orElse(0);
|
||||
this.tickToNext = nbt.getIntOr("tickToNext", 0);
|
||||
this.numberRemaining = nbt.getIntOr("numberRemaining", 0);
|
||||
}
|
||||
|
||||
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
|
||||
@@ -263,12 +261,4 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
|
||||
public void setOnStop(Consumer<E> onStop) {
|
||||
this.onStop = onStop;
|
||||
}
|
||||
|
||||
public record ActionData(
|
||||
List<Pair<String, String>> raw
|
||||
) {
|
||||
public void add(String key, String value) {
|
||||
raw.add(Pair.of(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -20,7 +20,6 @@ package org.leavesmc.leaves.bot.agent.actions;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AbstractStateBotAction<E extends AbstractStateBotAction<E>> extends AbstractBotAction<E> {
|
||||
|
||||
public AbstractStateBotAction(String name, Supplier<E> creator) {
|
||||
super(name, creator);
|
||||
this.setDoNumber(-1);
|
||||
|
||||
+5
-8
@@ -19,6 +19,7 @@ package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
@@ -30,12 +31,8 @@ public abstract class AbstractTimerBotAction<E extends AbstractTimerBotAction<E>
|
||||
|
||||
public AbstractTimerBotAction(String name, Supplier<E> creator) {
|
||||
super(name, creator);
|
||||
this.addArgument("delay", integer(0))
|
||||
.suggests(strings("0", "5", "10", "20"))
|
||||
.setOptional(true);
|
||||
this.addArgument("interval", integer(0))
|
||||
.suggests(strings("20", "0", "5", "10"))
|
||||
.setOptional(true);
|
||||
this.addArgument("delay", integer(0)).suggests(strings("0", "5", "10", "20")).setOptional(true);
|
||||
this.addArgument("interval", integer(0)).suggests(strings("20", "0", "5", "10")).setOptional(true);
|
||||
this.addArgument("do_number", integer(-1))
|
||||
.suggests(((context, builder) -> builder.suggest("-1", Component.literal("do infinite times"))))
|
||||
.setOptional(true);
|
||||
@@ -49,11 +46,11 @@ public abstract class AbstractTimerBotAction<E extends AbstractTimerBotAction<E>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
super.provideActionData(data);
|
||||
public String getActionDataString(@NotNull ExtraData data) {
|
||||
data.add("delay", String.valueOf(this.getStartDelayTick()));
|
||||
data.add("interval", String.valueOf(this.getDoIntervalTick()));
|
||||
data.add("do_number", String.valueOf(this.getDoNumber()));
|
||||
data.add("remaining_do_number", String.valueOf(this.getDoNumberRemaining()));
|
||||
return super.getActionDataString(data);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -22,6 +22,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
|
||||
|
||||
@@ -115,10 +116,10 @@ public abstract class AbstractUseBotAction<T extends AbstractUseBotAction<T>> ex
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
super.provideActionData(data);
|
||||
public String getActionDataString(@NotNull ExtraData data) {
|
||||
data.add("use_timeout", String.valueOf(this.useTickTimeout));
|
||||
data.add("already_used_tick", String.valueOf(this.alreadyUsedTick));
|
||||
return super.getActionDataString(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,9 +134,9 @@ public abstract class AbstractUseBotAction<T extends AbstractUseBotAction<T>> ex
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
this.useTickTimeout = nbt.getInt("useTick").orElseThrow();
|
||||
this.useTickTimeout = nbt.getIntOr("useTick", this.useTickTimeout);
|
||||
this.alreadyUsedTick = nbt.getInt("alreadyUsedTick").orElseGet(
|
||||
() -> this.useTickTimeout - nbt.getInt("tickToRelease").orElseThrow()
|
||||
() -> nbt.getInt("tickToRelease").map(tickToRelease -> this.useTickTimeout - tickToRelease).orElse(this.alreadyUsedTick)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@ public class ServerFishAction extends AbstractTimerBotAction<ServerFishAction> {
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
this.initialFishInterval = nbt.getInt("initialFishInterval").orElseThrow();
|
||||
this.tickToNextFish = nbt.getInt("tickToNextFish").orElseThrow();
|
||||
this.initialFishInterval = nbt.getIntOr("initialFishInterval", this.initialFishInterval);
|
||||
this.tickToNextFish = nbt.getIntOr("tickToNextFish", this.tickToNextFish);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+22
-39
@@ -18,15 +18,15 @@
|
||||
package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.EntityArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.Coordinates;
|
||||
import net.minecraft.commands.arguments.coordinates.Vec3Argument;
|
||||
import net.minecraft.commands.arguments.selector.EntitySelector;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
|
||||
import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver;
|
||||
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
@@ -42,35 +42,28 @@ public class ServerLookAction extends AbstractBotAction<ServerLookAction> {
|
||||
|
||||
public ServerLookAction() {
|
||||
super("look", ServerLookAction::new);
|
||||
declarePlayerBranch();
|
||||
declareLocationBranch();
|
||||
}
|
||||
|
||||
private void declarePlayerBranch() {
|
||||
this.fork(0);
|
||||
this.addArgument("player", EntityArgument.player())
|
||||
.setOptional(true);
|
||||
}
|
||||
|
||||
private void declareLocationBranch() {
|
||||
this.addArgument("player", ArgumentTypes.player()).setOptional(true);
|
||||
this.fork(1);
|
||||
this.addArgument("location", Vec3Argument.vec3(false));
|
||||
this.addArgument("location", ArgumentTypes.finePosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommand(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
EntitySelector selector = context.getArgumentOrDefault("player", EntitySelector.class, null);
|
||||
Coordinates location = context.getArgumentOrDefault("location", Coordinates.class, null);
|
||||
PlayerSelectorArgumentResolver playerSelectorResolver = context.getArgumentOrDefault("player", PlayerSelectorArgumentResolver.class, null);
|
||||
FinePositionResolver positionResolver = context.getArgumentOrDefault("location", FinePositionResolver.class, null);
|
||||
CommandSourceStack source = context.getSource();
|
||||
if (selector == null && location == null) {
|
||||
Entity sender = source.getEntityOrException();
|
||||
this.setPos(new Vector(sender.getX(), sender.getY(), sender.getZ()));
|
||||
} else if (selector != null) {
|
||||
ServerPlayer player = selector.findSinglePlayer(source);
|
||||
this.setTarget(player);
|
||||
if (playerSelectorResolver == null && positionResolver == null) {
|
||||
CommandSender sender = context.getSender();
|
||||
if (sender instanceof Entity entity) {
|
||||
this.setPos(entity.getLocation().toVector());
|
||||
} else {
|
||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().create();
|
||||
}
|
||||
} else if (playerSelectorResolver != null) {
|
||||
CraftPlayer player = (CraftPlayer) playerSelectorResolver.resolve(source).getFirst();
|
||||
this.setTarget(player.getHandle());
|
||||
} else {
|
||||
Vec3 vector = location.getPosition(source);
|
||||
this.setPos(new Vector(vector.x, vector.y, vector.z));
|
||||
this.setPos(positionResolver.resolve(source).toVector());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,16 +108,6 @@ public class ServerLookAction extends AbstractBotAction<ServerLookAction> {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
super.provideActionData(data);
|
||||
if (target != null) {
|
||||
data.add("target", target.getName().getString());
|
||||
} else {
|
||||
data.add("position", String.format("(%.2f, %.2f, %.2f)", pos.getX(), pos.getY(), pos.getZ()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doTick(@NotNull ServerBot bot) {
|
||||
if (target != null) {
|
||||
|
||||
+7
-11
@@ -17,9 +17,8 @@
|
||||
|
||||
package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.entity.CraftVehicle;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
@@ -39,14 +38,17 @@ public class ServerMountAction extends AbstractBotAction<ServerMountAction> {
|
||||
Location center = bot.getBukkitEntity().getLocation();
|
||||
List<Vehicle> vehicles = center.getNearbyEntitiesByType(
|
||||
Vehicle.class,
|
||||
4,
|
||||
vehicle -> manhattanDistance(bot, ((CraftEntity) vehicle).getHandle()) <= 3
|
||||
bot.entityInteractionRange()
|
||||
).stream().sorted(Comparator.comparingDouble(
|
||||
(vehicle) -> center.distanceSquared(vehicle.getLocation())
|
||||
)).toList();
|
||||
|
||||
for (Vehicle vehicle : vehicles) {
|
||||
if (bot.startRiding(((CraftEntity) vehicle).getHandle(), false, true)) {
|
||||
CraftVehicle craftVehicle = (CraftVehicle) vehicle;
|
||||
if (!bot.hasLineOfSight(craftVehicle.getHandle())) {
|
||||
continue;
|
||||
}
|
||||
if (bot.startRiding(craftVehicle.getHandle())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -58,10 +60,4 @@ public class ServerMountAction extends AbstractBotAction<ServerMountAction> {
|
||||
public Object asCraft() {
|
||||
return new CraftMountAction(this);
|
||||
}
|
||||
|
||||
private double manhattanDistance(@NotNull Entity entity1, @NotNull Entity entity2) {
|
||||
return Math.abs(entity1.getX() - entity2.getX()) +
|
||||
Math.abs(entity1.getY() - entity2.getY()) +
|
||||
Math.abs(entity1.getZ() - entity2.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
+7
-27
@@ -17,46 +17,26 @@
|
||||
|
||||
package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.arguments.EnumArgumentType;
|
||||
import org.leavesmc.leaves.entity.bot.action.MoveAction.MoveDirection;
|
||||
import org.leavesmc.leaves.entity.bot.actions.CraftMoveAction;
|
||||
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static org.leavesmc.leaves.command.ArgumentNode.ArgumentSuggestions.strings;
|
||||
|
||||
public class ServerMoveAction extends AbstractStateBotAction<ServerMoveAction> {
|
||||
private static final Map<String, MoveDirection> NAME_TO_DIRECTION = Arrays.stream(MoveDirection.values()).collect(toMap(
|
||||
it -> it.name,
|
||||
it -> it
|
||||
));
|
||||
private MoveDirection direction = MoveDirection.FORWARD;
|
||||
|
||||
public ServerMoveAction() {
|
||||
super("move", ServerMoveAction::new);
|
||||
this.addArgument("direction", StringArgumentType.word())
|
||||
.suggests(strings(
|
||||
Arrays.stream(MoveDirection.values())
|
||||
.map((it) -> it.name)
|
||||
.toList()
|
||||
));
|
||||
this.addArgument("direction", EnumArgumentType.fromEnum(MoveDirection.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommand(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
String raw = context.getArgument("direction", String.class);
|
||||
MoveDirection direction = NAME_TO_DIRECTION.get(raw);
|
||||
if (direction == null) {
|
||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
|
||||
}
|
||||
this.direction = direction;
|
||||
public void loadCommand(@NotNull CommandContext context) {
|
||||
this.direction = context.getArgument("direction", MoveDirection.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,9 +62,9 @@ public class ServerMoveAction extends AbstractStateBotAction<ServerMoveAction> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
super.provideActionData(data);
|
||||
public String getActionDataString(@NotNull ExtraData data) {
|
||||
data.add("direction", direction.name);
|
||||
return super.getActionDataString(data);
|
||||
}
|
||||
|
||||
public MoveDirection getDirection() {
|
||||
|
||||
+31
-14
@@ -18,11 +18,13 @@
|
||||
package org.leavesmc.leaves.bot.agent.actions;
|
||||
|
||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.entity.bot.actions.CraftRotationAction;
|
||||
|
||||
@@ -35,16 +37,26 @@ public class ServerRotationAction extends AbstractBotAction<ServerRotationAction
|
||||
public ServerRotationAction() {
|
||||
super("rotation", ServerRotationAction::new);
|
||||
this.addArgument("yaw", FloatArgumentType.floatArg(-180, 180))
|
||||
.suggests((context, builder) -> builder.suggest(
|
||||
DF.format(context.getSource().getEntityOrException().getYRot()),
|
||||
Component.literal("current player yaw")
|
||||
))
|
||||
.suggests((context, builder) -> {
|
||||
CommandSender sender = context.getSender();
|
||||
if (sender instanceof Entity entity) {
|
||||
builder.suggest(
|
||||
DF.format(entity.getYaw()),
|
||||
Component.literal("current player yaw")
|
||||
);
|
||||
}
|
||||
})
|
||||
.setOptional(true);
|
||||
this.addArgument("pitch", FloatArgumentType.floatArg(-90, 90))
|
||||
.suggests((context, builder) -> builder.suggest(
|
||||
DF.format(context.getSource().getEntityOrException().getXRot()),
|
||||
Component.literal("current player pitch")
|
||||
))
|
||||
.suggests((context, builder) -> {
|
||||
CommandSender sender = context.getSender();
|
||||
if (sender instanceof Entity entity) {
|
||||
builder.suggest(
|
||||
DF.format(entity.getPitch()),
|
||||
Component.literal("current player pitch")
|
||||
);
|
||||
}
|
||||
})
|
||||
.setOptional(true);
|
||||
}
|
||||
|
||||
@@ -52,9 +64,14 @@ public class ServerRotationAction extends AbstractBotAction<ServerRotationAction
|
||||
private float pitch = 0.0f;
|
||||
|
||||
@Override
|
||||
public void loadCommand(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
this.yaw = context.getFloatOrDefault("yaw", context.getSource().getEntityOrException().getYRot());
|
||||
this.pitch = context.getFloatOrDefault("pitch", context.getSource().getEntityOrException().getXRot());
|
||||
public void loadCommand(@NotNull CommandContext context) {
|
||||
CommandSender sender = context.getSender();
|
||||
if (sender instanceof Entity entity) {
|
||||
this.yaw = entity.getYaw();
|
||||
this.pitch = entity.getPitch();
|
||||
}
|
||||
this.yaw = context.getFloatOrDefault("yaw", this.yaw);
|
||||
this.pitch = context.getFloatOrDefault("pitch", this.pitch);
|
||||
}
|
||||
|
||||
public void setYaw(float yaw) {
|
||||
@@ -74,10 +91,10 @@ public class ServerRotationAction extends AbstractBotAction<ServerRotationAction
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideActionData(@NotNull ActionData data) {
|
||||
super.provideActionData(data);
|
||||
public String getActionDataString(@NotNull ExtraData data) {
|
||||
data.add("yaw", DF.format(this.yaw));
|
||||
data.add("pitch", DF.format(this.pitch));
|
||||
return super.getActionDataString(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+24
-28
@@ -21,29 +21,27 @@ import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.WrappedArgument;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.event.HoverEvent.showText;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
|
||||
|
||||
public abstract class AbstractBotConfig<Value, Type, E extends AbstractBotConfig<Value, Type, E>> {
|
||||
public abstract class AbstractBotConfig<T, E extends AbstractBotConfig<T, E>> {
|
||||
private final String name;
|
||||
private final WrappedArgument<Type> argument;
|
||||
private final WrappedArgument<T> argument;
|
||||
private final Supplier<E> creator;
|
||||
|
||||
protected ServerBot bot;
|
||||
|
||||
public AbstractBotConfig(String name, ArgumentType<Type> type, Supplier<E> creator) {
|
||||
public AbstractBotConfig(String name, ArgumentType<T> type, Supplier<E> creator) {
|
||||
this.name = name;
|
||||
this.argument = new WrappedArgument<>(name, type);
|
||||
if (shouldApplySuggestions()) {
|
||||
@@ -56,7 +54,7 @@ public abstract class AbstractBotConfig<Value, Type, E extends AbstractBotConfig
|
||||
public void applySuggestions(final CommandContext context, final SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
}
|
||||
|
||||
public AbstractBotConfig<Value, Type, E> setBot(ServerBot bot) {
|
||||
public AbstractBotConfig<T, E> setBot(ServerBot bot) {
|
||||
this.bot = bot;
|
||||
return this;
|
||||
}
|
||||
@@ -65,34 +63,32 @@ public abstract class AbstractBotConfig<Value, Type, E extends AbstractBotConfig
|
||||
return creator.get();
|
||||
}
|
||||
|
||||
public abstract Value getValue();
|
||||
public abstract T getValue();
|
||||
|
||||
public abstract void setValue(Value value) throws CommandSyntaxException;
|
||||
public abstract void setValue(T value) throws CommandSyntaxException;
|
||||
|
||||
public abstract Value loadFromCommand(@NotNull CommandContext context) throws CommandSyntaxException;
|
||||
|
||||
public List<Pair<String, String>> getExtraData() {
|
||||
return List.of();
|
||||
}
|
||||
public abstract T loadFromCommand(@NotNull CommandContext context) throws CommandSyntaxException;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Component getNameComponent() {
|
||||
Component result = text(getName(), AQUA);
|
||||
if (!getExtraData().isEmpty()) {
|
||||
result = result.hoverEvent(showText(
|
||||
getExtraData().stream()
|
||||
.map(pair -> text(pair.getKey() + "=" + pair.getValue()))
|
||||
.reduce((a, b) -> a.append(text(", ")).append(b))
|
||||
.orElseGet(() -> text(""))
|
||||
));
|
||||
}
|
||||
return result;
|
||||
return Component.text(getName(), NamedTextColor.AQUA).hoverEvent(HoverEvent.showText(Component.text(getExtraDataString())));
|
||||
}
|
||||
|
||||
public WrappedArgument<Type> getArgument() {
|
||||
public String getExtraDataString() {
|
||||
return getExtraDataString(new ExtraData(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public String getExtraDataString(@NotNull ExtraData data) {
|
||||
return data.raw().stream()
|
||||
.map(pair -> pair.getLeft() + "=" + pair.getRight())
|
||||
.reduce((a, b) -> a + ", " + b)
|
||||
.orElse("No data");
|
||||
}
|
||||
|
||||
public WrappedArgument<T> getArgument() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
public class AlwaysSendDataConfig extends AbstractBotConfig<Boolean, Boolean, AlwaysSendDataConfig> {
|
||||
public class AlwaysSendDataConfig extends AbstractBotConfig<Boolean, AlwaysSendDataConfig> {
|
||||
private boolean value;
|
||||
|
||||
public AlwaysSendDataConfig() {
|
||||
|
||||
+18
-13
@@ -18,17 +18,18 @@
|
||||
package org.leavesmc.leaves.bot.agent.configs;
|
||||
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import fun.bm.lophine.LophineLogger;
|
||||
import fun.bm.lophine.config.modules.experiment.CommandConfig;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.FoliaServerWaypointManager;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.waypoints.ServerWaypointManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
public class LocatorBarConfig extends AbstractBotConfig<Boolean, Boolean, LocatorBarConfig> {
|
||||
public class LocatorBarConfig extends AbstractBotConfig<Boolean, LocatorBarConfig> {
|
||||
private boolean value;
|
||||
|
||||
public LocatorBarConfig() {
|
||||
@@ -43,20 +44,24 @@ public class LocatorBarConfig extends AbstractBotConfig<Boolean, Boolean, Locato
|
||||
|
||||
@Override
|
||||
public void setValue(@NotNull Boolean value) throws IllegalArgumentException {
|
||||
if (bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> setValue(value), 20);
|
||||
} else {
|
||||
setValue(value, this.bot);
|
||||
}
|
||||
setValue(value, 0);
|
||||
}
|
||||
|
||||
public void setValue(@NotNull Boolean value, ServerBot bot) throws IllegalArgumentException {
|
||||
this.value = value;
|
||||
ServerWaypointManager manager = bot.level().getWaypointManager();
|
||||
if (value) {
|
||||
manager.trackWaypoint(bot);
|
||||
public void setValue(@NotNull Boolean value, int count) throws IllegalArgumentException {
|
||||
if (count > 60) {
|
||||
LophineLogger.LOGGER.error("Failed to set locator bar for a fakeplayer after 60 attempts");
|
||||
return;
|
||||
}
|
||||
if (this.bot != null) {
|
||||
this.value = value;
|
||||
FoliaServerWaypointManager manager = this.bot.level().getWaypointManager(); // Lophine - waypoint for adapt of luminol ver
|
||||
if (value) {
|
||||
manager.trackWaypoint(this.bot);
|
||||
} else {
|
||||
manager.untrackWaypoint(this.bot);
|
||||
}
|
||||
} else {
|
||||
manager.untrackWaypoint(bot);
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task0) -> setValue(value, count + 1), 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-4
@@ -19,6 +19,7 @@ package org.leavesmc.leaves.bot.agent.configs;
|
||||
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import fun.bm.lophine.LophineLogger;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -28,7 +29,7 @@ import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
import static net.minecraft.network.chat.Component.literal;
|
||||
|
||||
public class SimulationDistanceConfig extends AbstractBotConfig<Integer, Integer, SimulationDistanceConfig> {
|
||||
public class SimulationDistanceConfig extends AbstractBotConfig<Integer, SimulationDistanceConfig> {
|
||||
|
||||
public SimulationDistanceConfig() {
|
||||
super("simulation_distance", IntegerArgumentType.integer(2, 32), SimulationDistanceConfig::new);
|
||||
@@ -68,10 +69,18 @@ public class SimulationDistanceConfig extends AbstractBotConfig<Integer, Integer
|
||||
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
if (this.bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> load(nbt), 20);
|
||||
} else {
|
||||
load(nbt, 0);
|
||||
}
|
||||
|
||||
public void load(@NotNull CompoundTag nbt, int count) {
|
||||
if (count > 60) {
|
||||
LophineLogger.LOGGER.error("Failed to load simulation distance for a fakeplayer after 60 attempts");
|
||||
return;
|
||||
}
|
||||
if (this.bot != null) {
|
||||
this.setValue(nbt.getIntOr(getName(), FakeplayerConfig.getSimulationDistance(this.bot)));
|
||||
} else {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task0) -> load(nbt, count + 1), 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-10
@@ -18,15 +18,15 @@
|
||||
package org.leavesmc.leaves.bot.agent.configs;
|
||||
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import fun.bm.lophine.LophineLogger;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
public class SkipSleepConfig extends AbstractBotConfig<Boolean, Boolean, SkipSleepConfig> {
|
||||
public class SkipSleepConfig extends AbstractBotConfig<Boolean, SkipSleepConfig> {
|
||||
|
||||
public SkipSleepConfig() {
|
||||
super("skip_sleep", BoolArgumentType.bool(), SkipSleepConfig::new);
|
||||
@@ -38,16 +38,20 @@ public class SkipSleepConfig extends AbstractBotConfig<Boolean, Boolean, SkipSle
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(@NotNull Boolean value) throws IllegalArgumentException {
|
||||
if (bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> setValue(value), 20);
|
||||
} else {
|
||||
setValue(value, this.bot);
|
||||
}
|
||||
public void setValue(Boolean value) throws IllegalArgumentException {
|
||||
setValue(value, 0);
|
||||
}
|
||||
|
||||
public void setValue(@NotNull Boolean value, ServerBot bot) throws IllegalArgumentException {
|
||||
bot.fauxSleeping = value;
|
||||
public void setValue(Boolean value, int count) throws IllegalArgumentException {
|
||||
if (count > 60) {
|
||||
LophineLogger.LOGGER.error("Failed to set skip sleep config for a fakeplayer after 60 attempts.");
|
||||
return;
|
||||
}
|
||||
if (this.bot != null) {
|
||||
bot.fauxSleeping = value;
|
||||
} else {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task0) -> setValue(value, count + 1), 20);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-6
@@ -20,13 +20,11 @@ package org.leavesmc.leaves.bot.agent.configs;
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.agent.ExtraData;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SpawnPhantomConfig extends AbstractBotConfig<Boolean, Boolean, SpawnPhantomConfig> {
|
||||
public class SpawnPhantomConfig extends AbstractBotConfig<Boolean, SpawnPhantomConfig> {
|
||||
private boolean value;
|
||||
|
||||
public SpawnPhantomConfig() {
|
||||
@@ -45,8 +43,9 @@ public class SpawnPhantomConfig extends AbstractBotConfig<Boolean, Boolean, Spaw
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getExtraData() {
|
||||
return List.of(Pair.of("not_sleeping_ticks", String.valueOf(bot.notSleepTicks)));
|
||||
public String getExtraDataString(@NotNull ExtraData data) {
|
||||
data.add("not_sleeping_ticks", String.valueOf(bot.notSleepTicks));
|
||||
return super.getExtraDataString(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-20
@@ -17,37 +17,26 @@
|
||||
|
||||
package org.leavesmc.leaves.bot.agent.configs;
|
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.arguments.EnumArgumentType;
|
||||
|
||||
public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType, String, TickTypeConfig> {
|
||||
import java.util.Locale;
|
||||
|
||||
public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType, TickTypeConfig> {
|
||||
private ServerBot.TickType value;
|
||||
|
||||
public TickTypeConfig() {
|
||||
super("tick_type", StringArgumentType.word(), TickTypeConfig::new);
|
||||
super("tick_type", EnumArgumentType.fromEnum(ServerBot.TickType.class), TickTypeConfig::new);
|
||||
this.value = FakeplayerConfig.tickType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySuggestions(CommandContext context, @NotNull SuggestionsBuilder builder) {
|
||||
builder.suggest("network");
|
||||
builder.suggest("entity_list");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerBot.TickType loadFromCommand(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
String raw = context.getString(getName());
|
||||
return switch (raw) {
|
||||
case "network" -> ServerBot.TickType.NETWORK;
|
||||
case "entity_list" -> ServerBot.TickType.ENTITY_LIST;
|
||||
default -> throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
|
||||
};
|
||||
public ServerBot.TickType loadFromCommand(@NotNull CommandContext context) {
|
||||
return context.getArgument("tick_type", ServerBot.TickType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,14 +53,14 @@ public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType, String
|
||||
@NotNull
|
||||
public CompoundTag save(@NotNull CompoundTag nbt) {
|
||||
super.save(nbt);
|
||||
nbt.putString(getName(), this.getValue().toString());
|
||||
nbt.putString(getName(), this.getValue().toString().toLowerCase(Locale.ROOT));
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
String raw = nbt.getStringOr(getName(), FakeplayerConfig.tickType.name());
|
||||
this.setValue(switch (raw.toLowerCase()) {
|
||||
this.setValue(switch (raw.toLowerCase(Locale.ROOT)) {
|
||||
case "network" -> ServerBot.TickType.NETWORK;
|
||||
case "entity_list" -> ServerBot.TickType.ENTITY_LIST;
|
||||
default -> throw new IllegalStateException("Unexpected bot tick type value: " + raw);
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.command.arguments;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BotArgumentType implements CustomArgumentType.Converted<@NotNull ServerBot, @NotNull String> {
|
||||
|
||||
private BotArgumentType() {
|
||||
}
|
||||
|
||||
public static @NotNull BotArgumentType bot() {
|
||||
return new BotArgumentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> @NotNull CompletableFuture<Suggestions> listSuggestions(com.mojang.brigadier.context.@NotNull CommandContext<S> context, @NotNull SuggestionsBuilder builder) {
|
||||
Collection<ServerBot> bots = BotList.INSTANCE.bots;
|
||||
if (bots.isEmpty()) {
|
||||
return builder
|
||||
.suggest("<NO BOT EXISTS>", Component.literal("There are no bots in the server, create one first."))
|
||||
.buildFuture();
|
||||
}
|
||||
bots.stream().map(ServerBot::getScoreboardName).forEach(builder::suggest);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerBot convert(String nativeType) throws CommandSyntaxException {
|
||||
ServerBot bot = BotList.INSTANCE.getBotByName(nativeType);
|
||||
if (bot == null) {
|
||||
throw new CommandSyntaxException(
|
||||
CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument(),
|
||||
Component.literal("Bot with name '" + nativeType + "' does not exist")
|
||||
);
|
||||
}
|
||||
return bot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArgumentType<@NotNull String> getNativeType() {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.command.arguments;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public final class EnumArgumentType<T extends Enum<T>> implements CustomArgumentType.Converted<@NotNull T, @NotNull String> {
|
||||
private final Class<T> enumClass;
|
||||
|
||||
@Contract(value = "_ -> new", pure = true)
|
||||
public static <T extends Enum<T>> @NotNull EnumArgumentType<T> fromEnum(Class<T> enumClass) {
|
||||
return new EnumArgumentType<>(enumClass);
|
||||
}
|
||||
|
||||
private EnumArgumentType(Class<T> enumClass) {
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull T convert(@NotNull String nativeType) throws CommandSyntaxException {
|
||||
try {
|
||||
return Enum.valueOf(enumClass, nativeType.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> @NotNull CompletableFuture<Suggestions> listSuggestions(@NotNull CommandContext<S> context, @NotNull SuggestionsBuilder builder) {
|
||||
for (Enum<?> value : enumClass.getEnumConstants()) {
|
||||
String name = value.name().toLowerCase();
|
||||
if (name.startsWith(builder.getRemainingLowerCase())) {
|
||||
builder.suggest(name);
|
||||
}
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArgumentType<@NotNull String> getNativeType() {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
|
||||
public Class<T> enumClass() {
|
||||
return enumClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || obj.getClass() != this.getClass()) {
|
||||
return false;
|
||||
}
|
||||
EnumArgumentType<?> that = (EnumArgumentType<?>) obj;
|
||||
return Objects.equals(this.enumClass, that.enumClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(enumClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EnumArgumentType[" +
|
||||
"enumClass=" + enumClass + ']';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package org.leavesmc.leaves.command.bot;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.CustomArgumentType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BotArgument implements CustomArgumentType<ServerBot, String> {
|
||||
@Override
|
||||
public ArgumentType<String> getBaseArgumentType() {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerBot transform(String value) throws CommandSyntaxException {
|
||||
ServerBot bot = BotList.INSTANCE.getBotByName(value);
|
||||
if (bot == null) {
|
||||
throw new CommandSyntaxException(
|
||||
CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument(),
|
||||
Component.literal("Bot with name '" + value + "' does not exist")
|
||||
);
|
||||
}
|
||||
return bot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Suggestions> getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException {
|
||||
Collection<ServerBot> bots = BotList.INSTANCE.bots;
|
||||
if (bots.isEmpty()) {
|
||||
return builder
|
||||
.suggest("<NO BOT EXISTS>", Component.literal("There are no bots in the server, create one first."))
|
||||
.buildFuture();
|
||||
}
|
||||
bots.stream().map(ServerBot::getScoreboardName).forEach(builder::suggest);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
package org.leavesmc.leaves.command.bot;
|
||||
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.RootNode;
|
||||
@@ -52,7 +52,7 @@ public class BotCommand extends RootNode {
|
||||
return sender.hasPermission(PERM_BASE);
|
||||
}
|
||||
|
||||
public static boolean hasPermission(@NotNull CommandSender sender, String... subcommand) {
|
||||
return hasPermission(PERM_BASE, sender, subcommand);
|
||||
public static boolean hasPermission(@NotNull CommandSender sender, String subcommand) {
|
||||
return sender.hasPermission(PERM_BASE) || sender.hasPermission(PERM_BASE + "." + subcommand);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user