diff --git a/patches/api/0003-Add-fakeplayer-api.patch b/patches/api/0003-Add-fakeplayer-api.patch index d72a46b4..c38a816b 100644 --- a/patches/api/0003-Add-fakeplayer-api.patch +++ b/patches/api/0003-Add-fakeplayer-api.patch @@ -4,6 +4,62 @@ Date: Wed, 27 Jul 2022 15:30:34 +0800 Subject: [PATCH] Add fakeplayer api +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index b243db56756c67cd2c41d7768898d01539f9260a..99a096e52775a58a38540dfd736b0f57236fd488 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -57,6 +57,7 @@ import org.jetbrains.annotations.Contract; + import org.jetbrains.annotations.NotNull; + import org.jetbrains.annotations.Nullable; + import io.papermc.paper.util.JarManifests; // Paper ++import top.leavesmc.leaves.entity.BotManager; + + /** + * Represents the Bukkit core, for version and Server singleton handling +@@ -2658,6 +2659,17 @@ public final class Bukkit { + } + // Paper end - Folia region threading API + ++ // Leaves start - Bot API ++ /** ++ * Returns a bot manager. ++ * ++ * @return Bot Manager ++ */ ++ public static @NotNull BotManager getBotManager() { ++ return server.getBotManager(); ++ } ++ // Leaves end - Bot API ++ + @NotNull + public static Server.Spigot spigot() { + return server.spigot(); +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index 3c4915b8dd1b6e802a5942658b15d3a9db472364..0bfe5628c8327e9cd5728cea7ae6c2ce1ec9541d 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -57,6 +57,7 @@ import org.bukkit.util.CachedServerIcon; + import org.jetbrains.annotations.Contract; + import org.jetbrains.annotations.NotNull; + import org.jetbrains.annotations.Nullable; ++import top.leavesmc.leaves.entity.BotManager; + + /** + * Represents a server implementation. +@@ -2321,4 +2322,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + */ + boolean isOwnedByCurrentRegion(@NotNull Entity entity); + // Paper end - Folia region threading API ++ ++ // Leaves start - Bot API ++ /** ++ * Returns a bot manager. ++ * ++ * @return Bot Manager ++ */ ++ @NotNull BotManager getBotManager(); ++ // Leaves end - Bot API + } diff --git a/src/main/java/top/leavesmc/leaves/entity/Bot.java b/src/main/java/top/leavesmc/leaves/entity/Bot.java new file mode 100644 index 0000000000000000000000000000000000000000..8057d1faa66540b8c4042a0f5c0f862e8a39eef1 @@ -37,6 +93,101 @@ index 0000000000000000000000000000000000000000..8057d1faa66540b8c4042a0f5c0f862e + @NotNull + public String getRealName(); +} +diff --git a/src/main/java/top/leavesmc/leaves/entity/BotManager.java b/src/main/java/top/leavesmc/leaves/entity/BotManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d9b2248ef7e080851bf5f1c4539aa6edb3927966 +--- /dev/null ++++ b/src/main/java/top/leavesmc/leaves/entity/BotManager.java +@@ -0,0 +1,89 @@ ++package top.leavesmc.leaves.entity; ++ ++import org.bukkit.Location; ++import org.bukkit.util.Consumer; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.util.Collection; ++import java.util.UUID; ++ ++/** ++ * Simple fakeplayer manager ++ */ ++public interface BotManager { ++ ++ /** ++ * Gets a fakeplayer object by the given uuid. ++ * ++ * @param uuid the uuid to look up ++ * @return a fakeplayer if one was found, null otherwise ++ */ ++ @Nullable ++ public Bot getBot(@NotNull UUID uuid); ++ ++ /** ++ * Gets a fakeplayer object by the given name. ++ * ++ * @param name the name to look up ++ * @return a fakeplayer if one was found, null otherwise ++ */ ++ @Nullable ++ public Bot getBot(@NotNull String name); ++ ++ /** ++ * Creates a fakeplayer with given param. ++ *

++ * prefix and suffix will not be added. ++ * ++ * @param name fakeplayer name ++ * @param realName fakeplayer real name ++ * @param skin fakeplayer skin arr ++ * @param skinName fakeplayer skin name ++ * @param location a location will create fakeplayer ++ * @return a fakeplayer if success, null otherwise ++ */ ++ @Nullable ++ public Bot createBot(@NotNull String name, @NotNull String realName, @Nullable String[] skin, @Nullable String skinName, @NotNull Location location); ++ ++ /** ++ * Creates a fakeplayer with given param. ++ * ++ * @param name fakeplayer name ++ * @param skinName fakeplayer skin name ++ * @param location a location will create fakeplayer ++ * @param consumer a consumer after create fakeplayer success ++ */ ++ public void createBot(@NotNull String name, @Nullable String skinName, @NotNull Location location, @Nullable Consumer consumer); ++ ++ /** ++ * Removes a fakeplayer object by the given name. ++ * ++ * @param name the name to look up ++ */ ++ public void removeBot(@NotNull String name); ++ ++ /** ++ * Removes a fakeplayer object by the given uuid. ++ * ++ * @param uuid the uuid to look up ++ */ ++ public void removeBot(@NotNull UUID uuid); ++ ++ /** ++ * Removes all fakeplayers. ++ */ ++ public void removeAllBots(); ++ ++ /** ++ * Save fakeplayers data if resident-fakeplayer is true, or remove all fakeplayer. ++ */ ++ public void saveOrRemoveAllBots(); ++ ++ /** ++ * Gets a view of all currently logged in fakeplayers. This view is a reused object, making some operations like Collection.size() zero-allocation. ++ * ++ * @return a view of fakeplayers. ++ */ ++ public Collection getBots(); ++} diff --git a/src/main/java/top/leavesmc/leaves/event/bot/BotCreateEvent.java b/src/main/java/top/leavesmc/leaves/event/bot/BotCreateEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..7cf1eb4eb3d2fe9310f9272ec53208632b87b49b diff --git a/patches/server/0008-Fakeplayer-support.patch b/patches/server/0008-Fakeplayer-support.patch index 02e238ca..9551122a 100644 --- a/patches/server/0008-Fakeplayer-support.patch +++ b/patches/server/0008-Fakeplayer-support.patch @@ -267,6 +267,38 @@ index 706b354ac9a1a6a4a1e61b2a109180d1dd22bbbd..f13f21dbd50f63a71276837abbcf82e0 private boolean tryItemClickBehaviourOverride(Player player, ClickAction clickType, Slot slot, ItemStack stack, ItemStack cursorStack) { FeatureFlagSet featureflagset = player.level().enabledFeatures(); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index a394fcb1afe37efda30893e06352941f1a049319..1be2fbe522fcf54ef4a9a0dd03aebf57ced5880c 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -259,6 +259,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor; + import org.yaml.snakeyaml.error.MarkedYAMLException; + + import net.md_5.bungee.api.chat.BaseComponent; // Spigot ++import top.leavesmc.leaves.entity.CraftBotManager; + + import javax.annotation.Nullable; // Paper + import javax.annotation.Nonnull; // Paper +@@ -304,6 +305,7 @@ public final class CraftServer implements Server { + public static Exception excessiveVelEx; // Paper - Velocity warnings + private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper + private final CraftPotionBrewer potionBrewer = new CraftPotionBrewer(); // Paper ++ private final CraftBotManager botManager = new CraftBotManager(); + + // Paper start - Folia region threading API + private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); +@@ -3088,4 +3090,11 @@ public final class CraftServer implements Server { + } + + // Paper end ++ ++ // Leaves start - Bot API ++ @Override ++ public CraftBotManager getBotManager() { ++ return botManager; ++ } ++ // Leaves end - Bot API + } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index fc0dc8e607cc24020106ea1af92b4421a5f9393d..81670f76c4d7ccec6f9e95465687c83b37c544bd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -295,7 +327,7 @@ index fc0dc8e607cc24020106ea1af92b4421a5f9393d..81670f76c4d7ccec6f9e95465687c83b } // Water Animals diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java -index 5ca9ffe8747ef9e8bd2936402e2f7201ec3a5762..4a919417ffefde2afdeaa3da222ca8f79f6567a9 100644 +index 28c18d02a1d04582e6f0badbc9917e6356bf8532..f621ae9f8a1c1488f4d4c3c98555cd3f4c769b87 100644 --- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java +++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java @@ -7,6 +7,9 @@ import org.bukkit.Bukkit; @@ -1028,10 +1060,10 @@ index 0000000000000000000000000000000000000000..daaece30b2a3983f1cc9ee9a851e8f37 +} diff --git a/src/main/java/top/leavesmc/leaves/bot/ServerBot.java b/src/main/java/top/leavesmc/leaves/bot/ServerBot.java new file mode 100644 -index 0000000000000000000000000000000000000000..e649d92c3c51a1087c0ff8b8b90e362bf57a8d29 +index 0000000000000000000000000000000000000000..a80777a9b2b6f5cb57671e722b29e60cd83b7a2f --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/bot/ServerBot.java -@@ -0,0 +1,630 @@ +@@ -0,0 +1,643 @@ +package top.leavesmc.leaves.bot; + +import com.google.common.collect.Lists; @@ -1102,12 +1134,14 @@ index 0000000000000000000000000000000000000000..e649d92c3c51a1087c0ff8b8b90e362b +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; ++import java.util.Collections; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; ++import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; + +// TODO remake all @@ -1131,7 +1165,7 @@ index 0000000000000000000000000000000000000000..e649d92c3c51a1087c0ff8b8b90e362b + + private final BotInventoryContainer container; + -+ private static final List bots = new ArrayList<>(); ++ private static final List bots = new CopyOnWriteArrayList<>(); + private static final Plugin MINECRAFT_PLUGIN = new MinecraftInternalPlugin(); + + private ServerBot(MinecraftServer server, ServerLevel world, GameProfile profile) { @@ -1593,6 +1627,17 @@ index 0000000000000000000000000000000000000000..e649d92c3c51a1087c0ff8b8b90e362b + return bot; + } + ++ public static ServerBot getBot(UUID uuid) { ++ ServerBot bot = null; ++ for (ServerBot b : bots) { ++ if (b.uuid == uuid) { ++ bot = b; ++ break; ++ } ++ } ++ return bot; ++ } ++ + public static void saveOrRemoveAllBot() { + if (LeavesConfig.fakeplayerSupport && LeavesConfig.fakeplayerResident) { + JsonObject fakePlayerList = new JsonObject(); @@ -1644,7 +1689,7 @@ index 0000000000000000000000000000000000000000..e649d92c3c51a1087c0ff8b8b90e362b + return true; + } + -+ public static List getBots() { // It needs unmodifiable ++ public static List getBots() { + return bots; + } + @@ -2511,6 +2556,95 @@ index 0000000000000000000000000000000000000000..7c436136a1f2a61978fbf992b90312a3 + return "CraftBot{" + "name=" + getName() + '}'; + } +} +diff --git a/src/main/java/top/leavesmc/leaves/entity/CraftBotManager.java b/src/main/java/top/leavesmc/leaves/entity/CraftBotManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..35a9c428432a65825a4712939574df5301bf2248 +--- /dev/null ++++ b/src/main/java/top/leavesmc/leaves/entity/CraftBotManager.java +@@ -0,0 +1,83 @@ ++package top.leavesmc.leaves.entity; ++ ++import com.google.common.base.Function; ++import com.google.common.collect.Lists; ++import org.bukkit.Location; ++import org.bukkit.util.Consumer; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import top.leavesmc.leaves.bot.ServerBot; ++ ++import java.util.Collection; ++import java.util.Collections; ++import java.util.List; ++import java.util.UUID; ++ ++public class CraftBotManager implements BotManager { ++ ++ private final Collection botViews = Collections.unmodifiableList(Lists.transform(ServerBot.getBots(), new Function() { ++ @Override ++ public CraftBot apply(ServerBot bot) { ++ return bot.getBukkitEntity(); ++ } ++ })); ++ ++ @Override ++ public @Nullable Bot getBot(@NotNull UUID uuid) { ++ return ServerBot.getBot(uuid).getBukkitPlayer(); ++ } ++ ++ @Override ++ public @Nullable Bot getBot(@NotNull String name) { ++ return ServerBot.getBot(name).getBukkitPlayer(); ++ } ++ ++ @Override ++ public @Nullable Bot createBot(@NotNull String name, @NotNull String realName, @Nullable String[] skin, @Nullable String skinName, @NotNull Location location) { ++ ServerBot bot = ServerBot.createBot(location, name, realName, skin, skinName); ++ if (bot != null) { ++ return bot.getBukkitPlayer(); ++ } ++ return null; ++ } ++ ++ @Override ++ public void createBot(@NotNull String name, @Nullable String skinName, @NotNull Location location, Consumer consumer) { ++ ServerBot.createBot(location, name, skinName, serverBot -> { ++ if (consumer != null) { ++ consumer.accept(serverBot.getBukkitPlayer()); ++ } ++ }); ++ } ++ ++ @Override ++ public void removeBot(@NotNull String name) { ++ ServerBot bot = ServerBot.getBot(name); ++ if (bot != null) { ++ bot.die(bot.damageSources().fellOutOfWorld()); ++ } ++ } ++ ++ @Override ++ public void removeBot(@NotNull UUID uuid) { ++ ServerBot bot = ServerBot.getBot(uuid); ++ if (bot != null) { ++ bot.die(bot.damageSources().fellOutOfWorld()); ++ } ++ } ++ ++ @Override ++ public void removeAllBots() { ++ ServerBot.removeAllBot(); ++ } ++ ++ @Override ++ public void saveOrRemoveAllBots() { ++ ServerBot.saveOrRemoveAllBot(); ++ } ++ ++ @Override ++ public Collection getBots() { ++ return botViews; ++ } ++} diff --git a/src/main/java/top/leavesmc/leaves/util/MathUtils.java b/src/main/java/top/leavesmc/leaves/util/MathUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..349cd0c0d2d9dc2c9c745ef3469e548a798931ba diff --git a/patches/server/0043-PCA-sync-protocol.patch b/patches/server/0043-PCA-sync-protocol.patch index 12999c4f..ef346075 100644 --- a/patches/server/0043-PCA-sync-protocol.patch +++ b/patches/server/0043-PCA-sync-protocol.patch @@ -343,10 +343,10 @@ index b7686fd63b7c5d88c3a12ec4ee9bc01a17f997e0..25a9c38c60d183bb65b14f4d7550ab98 public int[] getSlotsForFace(Direction side) { return ShulkerBoxBlockEntity.SLOTS; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index a394fcb1afe37efda30893e06352941f1a049319..31c7ec216108388954694c1ca0ae26d23c0c4c3c 100644 +index 1be2fbe522fcf54ef4a9a0dd03aebf57ced5880c..c1f0e7fe9eb7247fef6bb088c64ca49cce17a14e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -465,6 +465,7 @@ public final class CraftServer implements Server { +@@ -467,6 +467,7 @@ public final class CraftServer implements Server { MapPalette.setMapColorCache(new CraftMapColorCache(this.logger)); } datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper @@ -354,7 +354,7 @@ index a394fcb1afe37efda30893e06352941f1a049319..31c7ec216108388954694c1ca0ae26d2 } public boolean getCommandBlockOverride(String command) { -@@ -1057,6 +1058,13 @@ public final class CraftServer implements Server { +@@ -1059,6 +1060,13 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); top.leavesmc.leaves.LeavesConfig.init((File) console.options.valueOf("leaves-settings")); // Leaves - Server Config diff --git a/patches/server/0044-BBOR-Protocol.patch b/patches/server/0044-BBOR-Protocol.patch index 8f777ecd..1c5dd354 100644 --- a/patches/server/0044-BBOR-Protocol.patch +++ b/patches/server/0044-BBOR-Protocol.patch @@ -77,10 +77,10 @@ index cc224af0139a6e3adefd22cbfa0cd519735b7191..2c3ca05644bc97d505e8ca92e7a5f486 public Level getLevel() { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 31c7ec216108388954694c1ca0ae26d23c0c4c3c..6a8c524d401e421dbf6aa7a40d12e1e1b44f6110 100644 +index c1f0e7fe9eb7247fef6bb088c64ca49cce17a14e..19b68c4a1807342cbe08420380877680a2519054 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1065,6 +1065,13 @@ public final class CraftServer implements Server { +@@ -1067,6 +1067,13 @@ public final class CraftServer implements Server { top.leavesmc.leaves.protocol.PcaSyncProtocol.disablePcaSyncProtocolGlobal(); } // Leaves end - pca diff --git a/patches/server/0047-Jade-Protocol.patch b/patches/server/0047-Jade-Protocol.patch index deb844a8..d2e6e76b 100644 --- a/patches/server/0047-Jade-Protocol.patch +++ b/patches/server/0047-Jade-Protocol.patch @@ -45,10 +45,10 @@ index 4aeab90e778629c355189dfe79c39c4b21f5f5ac..fe8c9b7e7956837829b4fe3eb449b2c0 } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6a8c524d401e421dbf6aa7a40d12e1e1b44f6110..6888d0b096b665a10cf6b050a4e69be1b7d7928d 100644 +index 19b68c4a1807342cbe08420380877680a2519054..9fba7105b7e70ad05c243ee6cec27a8ebe875d83 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -466,6 +466,7 @@ public final class CraftServer implements Server { +@@ -468,6 +468,7 @@ public final class CraftServer implements Server { } datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper top.leavesmc.leaves.protocol.PcaSyncProtocol.init(); // Leaves - pca @@ -56,7 +56,7 @@ index 6a8c524d401e421dbf6aa7a40d12e1e1b44f6110..6888d0b096b665a10cf6b050a4e69be1 } public boolean getCommandBlockOverride(String command) { -@@ -1072,6 +1073,11 @@ public final class CraftServer implements Server { +@@ -1074,6 +1075,11 @@ public final class CraftServer implements Server { top.leavesmc.leaves.protocol.BBORProtocol.loggedOutAllPlayer(); } // Leaves end - bbor diff --git a/patches/server/0055-Appleskin-Protocol.patch b/patches/server/0055-Appleskin-Protocol.patch index 4926756b..390f3e04 100644 --- a/patches/server/0055-Appleskin-Protocol.patch +++ b/patches/server/0055-Appleskin-Protocol.patch @@ -37,10 +37,10 @@ index 3994583f24bd558e7b0f7649e27fcea79da32026..dc1c9c106593aed9ede4ea4a09dc085c ServerLevel worldserver = entityplayer.serverLevel(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6888d0b096b665a10cf6b050a4e69be1b7d7928d..e2fc4933f8e1faaed5837e54588a20582090dc65 100644 +index 9fba7105b7e70ad05c243ee6cec27a8ebe875d83..75c4b20c1637f4b2e1a77450d30a21b4d2db5af0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1078,6 +1078,13 @@ public final class CraftServer implements Server { +@@ -1080,6 +1080,13 @@ public final class CraftServer implements Server { top.leavesmc.leaves.protocol.JadeProtocol.enableAllPlayer(); } // Leaves end - Jade