|
|
|
|
@@ -5,7 +5,7 @@ Subject: [PATCH] Fakeplayer support
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
|
index 3095f4ef8aea1d47d0a8880fcfdaf9d124d83773..fc27cf0cf98a8640e2a451d3f06ac1216eb9686c 100644
|
|
|
|
|
index 3095f4ef8aea1d47d0a8880fcfdaf9d124d83773..d2087c9b06fac0c40a1eee3b5f4dfa167f9073fd 100644
|
|
|
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
|
@@ -126,6 +126,7 @@ import net.minecraft.util.profiling.metrics.profiling.ServerMetricsSamplersProvi
|
|
|
|
|
@@ -25,14 +25,11 @@ index 3095f4ef8aea1d47d0a8880fcfdaf9d124d83773..fc27cf0cf98a8640e2a451d3f06ac121
|
|
|
|
|
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
|
|
|
|
|
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
|
|
|
|
|
this.connection.acceptConnections();
|
|
|
|
|
@@ -942,6 +945,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
|
|
|
@@ -942,6 +945,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
|
|
|
MinecraftServer.LOGGER.info("Stopping server");
|
|
|
|
|
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Shutdown and don't bother finishing
|
|
|
|
|
MinecraftTimings.stopServer(); // Paper
|
|
|
|
|
+ // Leaves start - bot
|
|
|
|
|
+ top.leavesmc.leaves.bot.ServerBot.saveAllBot(); // Leaves - save
|
|
|
|
|
+ top.leavesmc.leaves.bot.ServerBot.removeAllBot(); // Leaves - remove all bot
|
|
|
|
|
+ // Leaves end - bot
|
|
|
|
|
+ top.leavesmc.leaves.bot.ServerBot.saveOrRemoveAllBot(); // Leaves - save or remove bot
|
|
|
|
|
// CraftBukkit start
|
|
|
|
|
if (this.server != null) {
|
|
|
|
|
this.server.disablePlugins();
|
|
|
|
|
@@ -332,7 +329,7 @@ index 1fb25e8a21b568864974cc81b452ba062890d593..816d78268db3d0be0a70ff3c78e74b52
|
|
|
|
|
public final String worldName;
|
|
|
|
|
diff --git a/src/main/java/top/leavesmc/leaves/bot/BotCommand.java b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..a572488cf07940fa760e8908973ba76cd1c7111f
|
|
|
|
|
index 0000000000000000000000000000000000000000..0507d8bfa1100863b5a448d7d36671b658804d21
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/main/java/top/leavesmc/leaves/bot/BotCommand.java
|
|
|
|
|
@@ -0,0 +1,222 @@
|
|
|
|
|
@@ -461,7 +458,7 @@ index 0000000000000000000000000000000000000000..a572488cf07940fa760e8908973ba76c
|
|
|
|
|
+ sender.sendMessage(ChatColor.RED + "Fakeplayer limit is full");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ServerBot.createBot(((Player) sender).getLocation(), args[1], args.length > 2 ? args[2] : null);
|
|
|
|
|
+ ServerBot.createBot(((Player) sender).getLocation(), args[1], args.length > 2 ? args[2] : null, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void onRemove(CommandSender sender, String @NotNull [] args) {
|
|
|
|
|
@@ -785,21 +782,28 @@ index 0000000000000000000000000000000000000000..07b688d376a4af88305e57519a5ae983
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/main/java/top/leavesmc/leaves/bot/BotUtil.java b/src/main/java/top/leavesmc/leaves/bot/BotUtil.java
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..406ca19c5cc1006e043873ffcb0db127f75f0f4c
|
|
|
|
|
index 0000000000000000000000000000000000000000..f3138e662d7cb58b083e202cd3c623d6ff3bc33d
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/main/java/top/leavesmc/leaves/bot/BotUtil.java
|
|
|
|
|
@@ -0,0 +1,102 @@
|
|
|
|
|
@@ -0,0 +1,141 @@
|
|
|
|
|
+package top.leavesmc.leaves.bot;
|
|
|
|
|
+
|
|
|
|
|
+import com.google.gson.JsonElement;
|
|
|
|
|
+import com.google.gson.JsonObject;
|
|
|
|
|
+import net.minecraft.core.NonNullList;
|
|
|
|
|
+import net.minecraft.nbt.CompoundTag;
|
|
|
|
|
+import net.minecraft.nbt.ListTag;
|
|
|
|
|
+import net.minecraft.nbt.NbtIo;
|
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
|
+import net.minecraft.world.entity.EquipmentSlot;
|
|
|
|
|
+import net.minecraft.world.item.ItemStack;
|
|
|
|
|
+import net.minecraft.world.level.storage.LevelResource;
|
|
|
|
|
+import org.bukkit.Bukkit;
|
|
|
|
|
+import org.bukkit.Location;
|
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+public class BotUtil {
|
|
|
|
|
@@ -865,6 +869,8 @@ index 0000000000000000000000000000000000000000..406ca19c5cc1006e043873ffcb0db127
|
|
|
|
|
+ float pitch = bot.getXRot();
|
|
|
|
|
+ String dimension = bot.getLocation().getWorld().getName();
|
|
|
|
|
+ String skin = bot.skinName == null ? "null" : bot.skinName;
|
|
|
|
|
+ String uuid = bot.getStringUUID();
|
|
|
|
|
+
|
|
|
|
|
+ JsonObject fakePlayer = new JsonObject();
|
|
|
|
|
+ fakePlayer.addProperty("pos_x", pos_x);
|
|
|
|
|
+ fakePlayer.addProperty("pos_y", pos_y);
|
|
|
|
|
@@ -873,6 +879,22 @@ index 0000000000000000000000000000000000000000..406ca19c5cc1006e043873ffcb0db127
|
|
|
|
|
+ fakePlayer.addProperty("pitch", pitch);
|
|
|
|
|
+ fakePlayer.addProperty("dimension", dimension);
|
|
|
|
|
+ fakePlayer.addProperty("skin", skin);
|
|
|
|
|
+ fakePlayer.addProperty("invuuid", uuid);
|
|
|
|
|
+
|
|
|
|
|
+ CompoundTag invnbt = new CompoundTag();
|
|
|
|
|
+ invnbt.put("Inventory", bot.getInventory().save(new ListTag()));
|
|
|
|
|
+
|
|
|
|
|
+ File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("fakeplayer/" + uuid + ".dat").toFile();
|
|
|
|
|
+ if (file.isFile()) {
|
|
|
|
|
+ file.delete();
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ file.createNewFile();
|
|
|
|
|
+ NbtIo.writeCompressed(invnbt, file);
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return fakePlayer;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
@@ -887,8 +909,22 @@ index 0000000000000000000000000000000000000000..406ca19c5cc1006e043873ffcb0db127
|
|
|
|
|
+ String dimension = fakePlayer.get("dimension").getAsString();
|
|
|
|
|
+ String skin = fakePlayer.get("skin").getAsString();
|
|
|
|
|
+ skin = skin.equals("null") ? null : skin;
|
|
|
|
|
+ ListTag inv = null;
|
|
|
|
|
+
|
|
|
|
|
+ if (fakePlayer.has("invuuid")) {
|
|
|
|
|
+ String uuid = fakePlayer.get("invuuid").getAsString();
|
|
|
|
|
+ File file = MinecraftServer.getServer().getWorldPath(LevelResource.ROOT).resolve("fakeplayer/" + uuid + ".dat").toFile();
|
|
|
|
|
+ try {
|
|
|
|
|
+ CompoundTag nbt = NbtIo.readCompressed(file);
|
|
|
|
|
+ inv = nbt.getList("Inventory", 10);
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ file.delete();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ServerBot.createBot(new Location(Bukkit.getWorld(dimension), pos_x, pos_y, pos_z, yaw, pitch),
|
|
|
|
|
+ username, skin);
|
|
|
|
|
+ username, skin, inv);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/main/java/top/leavesmc/leaves/bot/MojangAPI.java b/src/main/java/top/leavesmc/leaves/bot/MojangAPI.java
|
|
|
|
|
@@ -940,10 +976,10 @@ index 0000000000000000000000000000000000000000..d6466ee4db637106e1394bb462d875e5
|
|
|
|
|
+}
|
|
|
|
|
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..8208efc49c9d6e3395a5ca00995da343e57fa215
|
|
|
|
|
index 0000000000000000000000000000000000000000..fbdd0f051d933571c65ed032c679255fb31bb7a2
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/main/java/top/leavesmc/leaves/bot/ServerBot.java
|
|
|
|
|
@@ -0,0 +1,782 @@
|
|
|
|
|
@@ -0,0 +1,789 @@
|
|
|
|
|
+package top.leavesmc.leaves.bot;
|
|
|
|
|
+
|
|
|
|
|
+import com.google.common.collect.Lists;
|
|
|
|
|
@@ -954,6 +990,7 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+import com.mojang.authlib.properties.Property;
|
|
|
|
|
+import com.mojang.datafixers.util.Pair;
|
|
|
|
|
+import net.minecraft.Util;
|
|
|
|
|
+import net.minecraft.nbt.ListTag;
|
|
|
|
|
+import net.minecraft.network.Connection;
|
|
|
|
|
+import net.minecraft.network.PacketSendListener;
|
|
|
|
|
+import net.minecraft.network.protocol.Packet;
|
|
|
|
|
@@ -1077,7 +1114,7 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+ this.fauxSleeping = LeavesConfig.fakeplayerSkipSleep;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void createBot(Location loc, String name, String skinName) {
|
|
|
|
|
+ public static void createBot(Location loc, String name, String skinName, ListTag inv) {
|
|
|
|
|
+ String realName = LeavesConfig.fakeplayerPrefix + name + LeavesConfig.fakeplayerSuffix;
|
|
|
|
|
+ if (!isCreateLegal(realName)) {
|
|
|
|
|
+ return;
|
|
|
|
|
@@ -1085,15 +1122,15 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+ if (skinName != null) {
|
|
|
|
|
+ Bukkit.getScheduler().runTaskAsynchronously(MINECRAFT_PLUGIN, () -> {
|
|
|
|
|
+ String[] skin = MojangAPI.getSkin(skinName);
|
|
|
|
|
+ Bukkit.getScheduler().runTask(MINECRAFT_PLUGIN, () -> createBot(loc, realName, skin, skinName));
|
|
|
|
|
+ Bukkit.getScheduler().runTask(MINECRAFT_PLUGIN, () -> createBot(loc, realName, skin, skinName, inv));
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ createBot(loc, realName, null, null);
|
|
|
|
|
+ createBot(loc, realName, null, null, inv);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Nullable
|
|
|
|
|
+ public static ServerBot createBot(@NotNull Location loc, @NotNull String name, String[] skin, String skinName) {
|
|
|
|
|
+ public static ServerBot createBot(@NotNull Location loc, @NotNull String name, String[] skin, String skinName, ListTag inv) {
|
|
|
|
|
+ if (!isCreateLegal(name)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
@@ -1122,6 +1159,10 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+ Bukkit.broadcastMessage(event.getJoinMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (inv != null) {
|
|
|
|
|
+ bot.getInventory().load(inv);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bot.teleportTo(loc.getX(), loc.getY(), loc.getZ());
|
|
|
|
|
+ bot.setRot(loc.getYaw(), loc.getPitch());
|
|
|
|
|
+ bot.getBukkitEntity().setRotation(loc.getYaw(), loc.getPitch());
|
|
|
|
|
@@ -1656,7 +1697,7 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+ return bot;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void saveAllBot() {
|
|
|
|
|
+ public static void saveOrRemoveAllBot() {
|
|
|
|
|
+ if (LeavesConfig.fakeplayerSupport && LeavesConfig.fakeplayerResident) {
|
|
|
|
|
+ JsonObject fakePlayerList = new JsonObject();
|
|
|
|
|
+ bots.forEach((bot -> {
|
|
|
|
|
@@ -1676,6 +1717,8 @@ index 0000000000000000000000000000000000000000..8208efc49c9d6e3395a5ca00995da343
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ removeAllBot();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|