9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-28 11:29:12 +00:00
---------

Co-authored-by: MC-XiaoHei <xor7xiaohei@gmail.com>
Co-authored-by: violetc <58360096+s-yh-china@users.noreply.github.com>
Co-authored-by: Fortern <blueten.ki@gmail.com>
Co-authored-by: Helvetica Volubi <88063803+Suisuroru@users.noreply.github.com>
This commit is contained in:
Lumine1909
2025-07-21 06:08:20 -07:00
committed by violetc
parent b5793e809b
commit c5ecbe85d2
318 changed files with 6998 additions and 2715 deletions

View File

@@ -1,2 +1,7 @@
[*.java]
ij_java_use_fq_class_names = false
ij_java_if_brace_force = always
ij_java_do_while_brace_force = always
ij_java_for_brace_force = always
ij_java_while_brace_force = always
ij_java_use_fq_class_names = false
ij_java_packages_to_use_import_on_demand = org.leavesmc.leaves.bot.agent.actions.*, org.leavesmc.leaves.bot.agent.configs.*, org.leavesmc.leaves.entity.bot.action.*

View File

@@ -3,9 +3,7 @@ package org.leavesmc.leaves;
import com.destroystokyo.paper.util.SneakyThrow;
import io.papermc.paper.configuration.GlobalConfiguration;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.bukkit.command.Command;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -29,19 +27,17 @@ import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRule;
import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRules;
import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeature;
import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeatureSet;
import org.leavesmc.leaves.protocol.servux.logger.DataLogger;
import org.leavesmc.leaves.region.RegionFileFormat;
import org.leavesmc.leaves.util.ForcePeacefulModeSwitchType;
import org.leavesmc.leaves.util.MathUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import java.util.function.Predicate;
public final class LeavesConfig {
@@ -171,21 +167,12 @@ public final class LeavesConfig {
}
}
@GlobalConfig("always-send-data")
public boolean canSendDataAlways = true;
@GlobalConfig("resident-fakeplayer")
public boolean canResident = false;
@GlobalConfig("open-fakeplayer-inventory")
public boolean canOpenInventory = false;
@GlobalConfig("skip-sleep-check")
public boolean canSkipSleep = false;
@GlobalConfig("spawn-phantom")
public boolean canSpawnPhantom = false;
@GlobalConfig("use-action")
public boolean canUseAction = true;
@@ -198,8 +185,46 @@ public final class LeavesConfig {
@GlobalConfig(value = "cache-skin", lock = true)
public boolean useSkinCache = false;
@GlobalConfig(value = "tick-type")
public ServerBot.TickType tickType = ServerBot.TickType.NETWORK;
public InGameConfig inGame = new InGameConfig();
@GlobalConfigCategory("in-game")
public static class InGameConfig {
@RemovedConfig(name = "always-send-data", category = {"modify", "fakeplayer"}, transform = true)
@GlobalConfig("always-send-data")
public boolean canSendDataAlways = true;
@RemovedConfig(name = "skip-sleep-check", category = {"modify", "fakeplayer"}, transform = true)
@GlobalConfig("skip-sleep-check")
public boolean canSkipSleep = false;
@RemovedConfig(name = "spawn-phantom", category = {"modify", "fakeplayer"}, transform = true)
@GlobalConfig("spawn-phantom")
public boolean canSpawnPhantom = false;
@RemovedConfig(name = "tick-type", category = {"modify", "fakeplayer"}, transform = true)
@GlobalConfig("tick-type")
public ServerBot.TickType tickType = ServerBot.TickType.NETWORK;
@GlobalConfig(value = "simulation-distance", validator = BotSimulationDistanceValidator.class)
private int simulationDistance = -1;
public int getSimulationDistance(ServerBot bot) {
return this.simulationDistance == -1 ? bot.getBukkitEntity().getSimulationDistance() : this.simulationDistance;
}
public static class BotSimulationDistanceValidator extends IntConfigValidator {
@Override
public void verify(Integer old, Integer value) throws IllegalArgumentException {
if ((value < 2 && value != -1) || value > 32) {
throw new IllegalArgumentException("simulation-distance must be a number between 2 and 32, got: " + value);
}
}
}
@GlobalConfig("enable-locator-bar")
public boolean enableLocatorBar = false;
}
}
public MinecraftOLDConfig oldMC = new MinecraftOLDConfig();
@@ -354,6 +379,18 @@ public final class LeavesConfig {
@GlobalConfig("old-throwable-projectile-tick-order")
public boolean oldThrowableProjectileTickOrder = false;
@GlobalConfig("keep-leash-connect-when-use-firework")
public boolean keepLeashConnectWhenUseFirework = false;
@GlobalConfig("tnt-wet-explosion-no-item-damage")
public boolean tntWetExplosionNoItemDamage = false;
@GlobalConfig("old-projectile-explosion-behavior")
public boolean oldProjectileExplosionBehavior = false;
@GlobalConfig("ender-dragon-part-can-use-end-portal")
public boolean enderDragonPartCanUseEndPortal = false;
}
public ElytraAeronauticsConfig elytraAeronautics = new ElytraAeronauticsConfig();
@@ -425,16 +462,25 @@ public final class LeavesConfig {
}
}
public int shulkerBoxStackSize = 1;
@GlobalConfig(value = "stackable-shulker-boxes", validator = StackableShulkerValidator.class)
private String stackableShulkerBoxes = "false";
public ShulkerBoxConfig shulkerBox = new ShulkerBoxConfig();
private static class StackableShulkerValidator extends StringConfigValidator {
@Override
public void verify(String old, String value) throws IllegalArgumentException {
String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1";
LeavesConfig.modify.shulkerBoxStackSize = Integer.parseInt(realValue);
@GlobalConfigCategory("shulker-box")
public static class ShulkerBoxConfig {
public int shulkerBoxStackSize = 1;
@RemovedConfig(name = "stackable-shulker-boxes", category = "modify", transform = true)
@GlobalConfig(value = "stackable-shulker-boxes", validator = StackableShulkerValidator.class)
private String stackableShulkerBoxes = "false";
private static class StackableShulkerValidator extends StringConfigValidator {
@Override
public void verify(String old, String value) throws IllegalArgumentException {
String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1";
LeavesConfig.modify.shulkerBox.shulkerBoxStackSize = Integer.parseInt(realValue);
}
}
@GlobalConfig(value = "same-nbt-stackable")
public boolean sameNbtStackable = false;
}
@GlobalConfig(value = "force-void-trade", validator = ForceVoidTradeValidator.class)
@@ -846,6 +892,15 @@ public final class LeavesConfig {
@GlobalConfig("hud-metadata-protocol")
public boolean hudMetadataProtocol = false;
@GlobalConfig("hud-logger-protocol")
public boolean hudLoggerProtocol = false;
@GlobalConfig("hud-enabled-loggers")
public List<DataLogger.Type> hudEnabledLoggers = List.of(DataLogger.Type.TPS, DataLogger.Type.MOB_CAPS);
@GlobalConfig("hud-update-interval")
public int hudUpdateInterval = 1;
@GlobalConfig("hud-metadata-protocol-share-seed")
public boolean hudMetadataShareSeed = true;
@@ -956,7 +1011,7 @@ public final class LeavesConfig {
public String source = "application";
public static class DownloadSourceValidator extends StringConfigValidator {
private static final List<String> suggestSourceList = List.of("application", "cloud");
private static List<String> suggestSourceList = List.of("application", "cloud");
@Override
public List<String> valueSuggest() {
@@ -1117,17 +1172,14 @@ public final class LeavesConfig {
@GlobalConfig("vanilla-display-name")
public boolean vanillaDisplayName = false;
@GlobalConfig(value = "collision-behavior")
public CollisionBehavior collisionBehavior = CollisionBehavior.BLOCK_SHAPE_VANILLA;
public enum CollisionBehavior {
VANILLA, BLOCK_SHAPE_VANILLA, PAPER
}
@GlobalConfig("vanilla-portal-handle")
public boolean vanillaPortalHandle = false;
@GlobalConfig("vanilla-fluid-pushing")
public boolean vanillaFluidPushing = true;
@RemovedConfig(name = "collision-behavior", category = "fix")
@RemovedConfig(name = "spigot-EndPlatform-destroy", category = "fix")
private final boolean spigotEndPlatformDestroy = false;
private final boolean removed = false;
}
}

View File

@@ -7,9 +7,9 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.BotCreator;
import org.leavesmc.leaves.entity.CraftBot;
import org.leavesmc.leaves.entity.bot.Bot;
import org.leavesmc.leaves.entity.bot.BotCreator;
import org.leavesmc.leaves.entity.bot.CraftBot;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;

View File

@@ -5,10 +5,14 @@ import net.minecraft.core.UUIDUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.NbtIo;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.storage.LevelResource;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.TagValueInput;
import net.minecraft.world.level.storage.ValueInput;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.util.TagUtil;
import org.slf4j.Logger;
import java.io.File;
@@ -45,7 +49,7 @@ public class BotDataStorage implements IPlayerDataStorage {
public void save(Player player) {
boolean flag = true;
try {
CompoundTag nbt = player.saveWithoutId(new CompoundTag());
CompoundTag nbt = TagUtil.saveEntityWithoutId(player);
File file = new File(this.botDir, player.getStringUUID() + ".dat");
if (file.exists() && file.isFile()) {
@@ -73,10 +77,11 @@ public class BotDataStorage implements IPlayerDataStorage {
}
@Override
public Optional<CompoundTag> load(Player player) {
return this.load(player.getScoreboardName(), player.getStringUUID()).map((nbt) -> {
player.load(nbt);
return nbt;
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);
return valueInput;
});
}
@@ -100,6 +105,18 @@ public class BotDataStorage implements IPlayerDataStorage {
return Optional.empty();
}
public Optional<CompoundTag> read(String uuid) {
File file = new File(this.botDir, uuid + ".dat");
if (file.exists() && file.isFile()) {
try {
return Optional.of(NbtIo.readCompressed(file.toPath(), NbtAccounter.unlimitedHeap()));
} catch (Exception exception) {
BotDataStorage.LOGGER.warn("Failed to read fakeplayer data for {}", uuid);
}
}
return Optional.empty();
}
private void saveBotList() {
try {
if (this.botListFile.exists() && this.botListFile.isFile()) {

View File

@@ -14,12 +14,18 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.ValueInput;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.event.entity.EntityRemoveEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
@@ -30,10 +36,12 @@ import org.leavesmc.leaves.event.bot.BotRemoveEvent;
import org.leavesmc.leaves.event.bot.BotSpawnLocationEvent;
import org.slf4j.Logger;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -50,6 +58,7 @@ public class BotList {
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();
public BotList(MinecraftServer server) {
this.server = server;
@@ -94,15 +103,20 @@ public class BotList {
ServerBot bot = new ServerBot(this.server, this.server.getLevel(Level.OVERWORLD), new GameProfile(uuid, realName));
bot.connection = new ServerBotPacketListenerImpl(this.server, bot);
Optional<CompoundTag> optional = playerIO.load(bot);
Optional<ValueInput> optional;
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(bot.problemPath(), LOGGER)) {
optional = playerIO.load(bot, scopedCollector);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (optional.isEmpty()) {
return null;
}
CompoundTag nbt = optional.get();
ValueInput nbt = optional.get();
ResourceKey<Level> resourcekey = null;
if (nbt.contains("WorldUUIDMost") && nbt.contains("WorldUUIDLeast")) {
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();
@@ -116,8 +130,8 @@ public class BotList {
return this.placeNewBot(bot, world, bot.getLocation(), nbt);
}
public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, @Nullable CompoundTag save) {
Optional<CompoundTag> optional = Optional.ofNullable(save);
public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, ValueInput save) {
Optional<ValueInput> optional = Optional.ofNullable(save);
bot.isRealPlayer = true;
bot.loginTime = System.currentTimeMillis();
@@ -129,7 +143,7 @@ public class BotList {
location = event.getSpawnLocation();
bot.spawnIn(world);
bot.gameMode.setLevel(bot.serverLevel());
bot.gameMode.setLevel(bot.level());
bot.setPosRaw(location.getX(), location.getY(), location.getZ());
bot.setRot(location.getYaw(), location.getPitch());
@@ -158,8 +172,12 @@ public class BotList {
bot.renderAll();
bot.supressTrackerForLogin = false;
bot.serverLevel().getChunkSource().chunkMap.addEntity(bot);
BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.serverLevel().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ());
bot.level().getChunkSource().chunkMap.addEntity(bot);
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;
}
@@ -172,7 +190,7 @@ public class BotList {
this.server.server.getPluginManager().callEvent(event);
if (event.isCancelled() && event.getReason() != BotRemoveEvent.RemoveReason.INTERNAL) {
return event.isCancelled();
return true;
}
if (bot.removeTaskId != -1) {
@@ -180,10 +198,13 @@ public class BotList {
bot.removeTaskId = -1;
}
bot.disconnect();
if (event.shouldSave()) {
playerIO.save(bot);
} else {
bot.dropAll(true);
botsNameByWorldUuid.get(bot.level().uuid.toString()).remove(bot.getBukkitEntity().getRealName());
}
if (bot.isPassenger() && event.shouldSave()) {
@@ -191,8 +212,8 @@ public class BotList {
if (entity.hasExactlyOnePlayerPassenger()) {
bot.stopRiding();
entity.getPassengersAndSelf().forEach((entity1) -> {
if (entity1 instanceof net.minecraft.world.entity.npc.AbstractVillager villager) {
final net.minecraft.world.entity.player.Player human = villager.getTradingPlayer();
if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.voidTrade && entity1 instanceof AbstractVillager villager) {
final Player human = villager.getTradingPlayer();
if (human != null) {
villager.setTradingPlayer(null);
}
@@ -203,7 +224,15 @@ public class BotList {
}
bot.unRide();
bot.serverLevel().removePlayerImmediately(bot, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
for (ThrownEnderpearl thrownEnderpearl : bot.getEnderPearls()) {
if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) {
thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT);
} else {
thrownEnderpearl.setOwner(null);
}
}
bot.level().removePlayerImmediately(bot, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
this.bots.remove(bot);
this.botsByName.remove(bot.getScoreboardName().toLowerCase(Locale.ROOT));
@@ -214,9 +243,10 @@ public class BotList {
}
bot.removeTab();
for (ServerPlayer player : bot.serverLevel().players()) {
ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(bot.getId());
for (ServerPlayer player : bot.level().players()) {
if (!(player instanceof ServerBot)) {
player.connection.send(new ClientboundRemoveEntitiesPacket(bot.getId()));
player.connection.send(packet);
}
}
@@ -227,6 +257,15 @@ public class BotList {
return true;
}
public void removeAllIn(String worldUuid) {
for (String realName : this.botsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())) {
ServerBot bot = this.getBotByName(realName);
if (bot != null) {
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, LeavesConfig.modify.fakeplayer.canResident);
}
}
}
public void removeAll() {
for (ServerBot bot : this.bots) {
bot.resume = LeavesConfig.modify.fakeplayer.canResident;
@@ -234,16 +273,36 @@ public class BotList {
}
}
public void loadResume() {
if (LeavesConfig.modify.fakeplayer.enable && LeavesConfig.modify.fakeplayer.canResident) {
CompoundTag savedBotList = this.getSavedBotList().copy();
for (String realName : savedBotList.keySet()) {
CompoundTag nbt = savedBotList.getCompound(realName).orElseThrow();
if (nbt.getBoolean("resume").orElse(false)) {
this.loadNewBot(realName);
}
}
public void loadBotInfo() {
if (!LeavesConfig.modify.fakeplayer.enable || !LeavesConfig.modify.fakeplayer.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);
if (levelUuid == null) {
LOGGER.warn("Bot {} has no world UUID, skipping loading.", realName);
continue;
}
this.botsNameByWorldUuid
.computeIfAbsent(levelUuid.toString(), (k) -> new HashSet<>())
.add(realName);
}
}
public void loadResume(String worldUuid) {
if (!LeavesConfig.modify.fakeplayer.enable || !LeavesConfig.modify.fakeplayer.canResident) {
return;
}
Set<String> bots = this.botsNameByWorldUuid.get(worldUuid);
if (bots == null) {
return;
}
bots.forEach(this::loadNewBot);
}
public void networkTick() {

View File

@@ -2,12 +2,14 @@ package org.leavesmc.leaves.bot;
import com.google.common.base.Charsets;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import java.util.Optional;
import java.util.UUID;
public class BotUtil {
@@ -73,6 +75,21 @@ public class BotUtil {
return UUID.nameUUIDFromBytes(("Fakeplayer:" + realName).getBytes(Charsets.UTF_8));
}
public static UUID getBotLevel(@NotNull String realName, BotDataStorage botDataStorage) {
UUID uuid = BotUtil.getBotUUID(realName);
Optional<CompoundTag> tagOptional = botDataStorage.read(uuid.toString());
if (tagOptional.isEmpty()) {
return null;
}
CompoundTag tag = tagOptional.get();
Optional<Long> worldUUIDMost = tag.getLong("WorldUUIDMost");
Optional<Long> worldUUIDLeast = tag.getLong("WorldUUIDLeast");
if (worldUUIDMost.isEmpty() || worldUUIDLeast.isEmpty()) {
return null;
}
return new UUID(worldUUIDMost.get(), worldUUIDLeast.get());
}
public static String getFullName(String inputName) {
return LeavesConfig.modify.fakeplayer.prefix + inputName + LeavesConfig.modify.fakeplayer.suffix;
}

View File

@@ -1,7 +1,8 @@
package org.leavesmc.leaves.bot;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.storage.ValueInput;
import java.util.Optional;
@@ -9,5 +10,5 @@ public interface IPlayerDataStorage {
void save(Player player);
Optional<CompoundTag> load(Player player);
Optional<ValueInput> load(Player player, ProblemReporter reporter);
}

View File

@@ -3,10 +3,9 @@ package org.leavesmc.leaves.bot;
import com.google.common.collect.ImmutableMap;
import com.mojang.authlib.GameProfile;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.event.entity.EntityKnockbackEvent;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
@@ -31,16 +30,16 @@ import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.level.storage.ValueOutput;
import net.minecraft.world.phys.EntityHitResult;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -50,11 +49,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.LeavesLogger;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.Configs;
import org.leavesmc.leaves.entity.CraftBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.CraftBot;
import org.leavesmc.leaves.event.bot.BotActionScheduleEvent;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
import org.leavesmc.leaves.event.bot.BotDeathEvent;
@@ -73,7 +72,7 @@ import java.util.function.Predicate;
public class ServerBot extends ServerPlayer {
private final List<AbstractBotAction<?>> actions;
private final List<ServerBotAction<?>> actions;
private final Map<Configs<?>, AbstractBotConfig<?>> configs;
public boolean resume = false;
@@ -106,7 +105,8 @@ public class ServerBot extends ServerPlayer {
this.tracingRange = world.spigotConfig.playerTrackingRange * world.spigotConfig.playerTrackingRange;
this.notSleepTicks = 0;
this.fauxSleeping = LeavesConfig.modify.fakeplayer.canSkipSleep;
this.fauxSleeping = LeavesConfig.modify.fakeplayer.inGame.canSkipSleep;
this.getBukkitEntity().setSimulationDistance(LeavesConfig.modify.fakeplayer.inGame.getSimulationDistance(this));
this.setClientLoaded(true);
}
@@ -130,26 +130,18 @@ public class ServerBot extends ServerPlayer {
if (this.invulnerableTime > 0) {
this.invulnerableTime--;
}
if (this.spawnInvulnerableTime > 0) --this.spawnInvulnerableTime; // Leaves - spawn invulnerable time
if (this.spawnInvulnerableTime > 0) {
--this.spawnInvulnerableTime; // Leaves - spawn invulnerable time
}
// copy ServerPlayer end
if (this.getConfigValue(Configs.SPAWN_PHANTOM)) {
this.notSleepTicks++;
}
if (LeavesConfig.modify.fakeplayer.regenAmount > 0.0 && server.getTickCount() % 20 == 0) {
float health = getHealth();
float maxHealth = getMaxHealth();
if (LeavesConfig.modify.fakeplayer.regenAmount > 0.0 && getServer().getTickCount() % 20 == 0) {
float regenAmount = (float) (LeavesConfig.modify.fakeplayer.regenAmount * 20);
float amount;
if (health < maxHealth - regenAmount) {
amount = health + regenAmount;
} else {
amount = maxHealth;
}
this.setHealth(amount);
this.setHealth(Math.min(this.getHealth() + regenAmount, this.getMaxHealth()));
}
if (this.getConfigValue(Configs.TICK_TYPE) == TickType.ENTITY_LIST) {
@@ -194,7 +186,7 @@ public class ServerBot extends ServerPlayer {
this.updateIsUnderwater();
if (this.getConfigValue(Configs.TICK_TYPE) == TickType.NETWORK) {
this.server.scheduleOnMain(this::runAction);
this.getServer().scheduleOnMain(this::runAction);
}
this.livingEntityTick();
@@ -227,6 +219,11 @@ public class ServerBot extends ServerPlayer {
}
}
@Override
public boolean canSimulateMovement() {
return true;
}
@Override
public @Nullable ServerBot teleport(@NotNull TeleportTransition teleportTransition) {
if (this.isSleeping() || this.isRemoved()) {
@@ -236,7 +233,7 @@ public class ServerBot extends ServerPlayer {
this.removeVehicle();
}
ServerLevel fromLevel = this.serverLevel();
ServerLevel fromLevel = this.level();
ServerLevel toLevel = teleportTransition.newLevel();
if (toLevel.dimension() == fromLevel.dimension()) {
@@ -273,6 +270,14 @@ public class ServerBot extends ServerPlayer {
return this;
}
@Override
public void knockback(double strength, double x, double z, @Nullable Entity attacker, EntityKnockbackEvent.@NotNull Cause eventCause) {
if (!this.hurtMarked) {
return;
}
super.knockback(strength, x, z, attacker, eventCause);
}
@Override
public void onItemPickup(@NotNull ItemEntity item) {
super.onItemPickup(item);
@@ -296,7 +301,7 @@ public class ServerBot extends ServerPlayer {
if (LeavesConfig.modify.fakeplayer.canOpenInventory) {
if (player instanceof ServerPlayer player1 && player.getMainHandItem().isEmpty()) {
BotInventoryOpenEvent event = new BotInventoryOpenEvent(this.getBukkitEntity(), player1.getBukkitEntity());
this.server.server.getPluginManager().callEvent(event);
this.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;
@@ -306,49 +311,6 @@ public class ServerBot extends ServerPlayer {
return super.interact(player, hand);
}
@Override
public void checkFallDamage(double y, boolean onGround, @NotNull BlockState state, @NotNull BlockPos pos) {
ServerLevel serverLevel = this.serverLevel();
if (!this.isInWater() && y < 0.0) {
this.fallDistance -= (float) y;
}
if (onGround && this.fallDistance > 0.0F) {
this.onChangedBlock(serverLevel, pos);
double attributeValue = this.getAttributeValue(Attributes.SAFE_FALL_DISTANCE);
if (this.fallDistance > attributeValue && !state.isAir()) {
double x = this.getX();
double y1 = this.getY();
double z = this.getZ();
BlockPos blockPos = this.blockPosition();
if (pos.getX() != blockPos.getX() || pos.getZ() != blockPos.getZ()) {
double d = x - pos.getX() - 0.5;
double d1 = z - pos.getZ() - 0.5;
double max = Math.max(Math.abs(d), Math.abs(d1));
x = pos.getX() + 0.5 + d / max * 0.5;
z = pos.getZ() + 0.5 + d1 / max * 0.5;
}
float f = Mth.ceil(this.fallDistance - attributeValue);
double min = Math.min(0.2F + f / 15.0F, 2.5);
int i = (int) (150.0 * min);
serverLevel.sendParticlesSource(this, new BlockParticleOption(ParticleTypes.BLOCK, state), false, false, x, y1, z, i, 0.0, 0.0, 0.0, 0.15F);
}
}
if (onGround) {
if (this.fallDistance > 0.0F) {
state.getBlock().fallOn(serverLevel, state, pos, this, this.fallDistance);
serverLevel.gameEvent(GameEvent.HIT_GROUND, this.position(),
GameEvent.Context.of(this, this.mainSupportingBlockPos.map(supportingPos -> this.level().getBlockState(supportingPos)).orElse(state))
);
}
this.resetFallDistance();
} else if (y < 0.0D) {
this.fallDistance -= (float) y;
}
}
@Override
public void attack(@NotNull Entity target) {
super.attack(target);
@@ -356,7 +318,7 @@ public class ServerBot extends ServerPlayer {
}
@Override
public void addAdditionalSaveData(@NotNull CompoundTag nbt) {
public void addAdditionalSaveData(@NotNull ValueOutput nbt) {
super.addAdditionalSaveData(nbt);
nbt.putBoolean("isShiftKeyDown", this.isShiftKeyDown());
@@ -373,31 +335,29 @@ public class ServerBot extends ServerPlayer {
createNbt.put("skin", skin);
}
nbt.put("createStatus", createNbt);
nbt.store("createStatus", CompoundTag.CODEC, createNbt);
if (!this.actions.isEmpty()) {
ListTag actionNbt = new ListTag();
for (AbstractBotAction<?> action : this.actions) {
ValueOutput.TypedOutputList<CompoundTag> actionNbt = nbt.list("actions", CompoundTag.CODEC);
for (ServerBotAction<?> action : this.actions) {
actionNbt.add(action.save(new CompoundTag()));
}
nbt.put("actions", actionNbt);
}
if (!this.configs.isEmpty()) {
ListTag configNbt = new ListTag();
ValueOutput.TypedOutputList<CompoundTag> configNbt = nbt.list("configs", CompoundTag.CODEC);
for (AbstractBotConfig<?> config : this.configs.values()) {
configNbt.add(config.save(new CompoundTag()));
}
nbt.put("configs", configNbt);
}
}
@Override
public void readAdditionalSaveData(@NotNull CompoundTag nbt) {
public void readAdditionalSaveData(@NotNull ValueInput nbt) {
super.readAdditionalSaveData(nbt);
this.setShiftKeyDown(nbt.getBoolean("isShiftKeyDown").orElse(false));
this.setShiftKeyDown(nbt.getBooleanOr("isShiftKeyDown", false));
CompoundTag createNbt = nbt.getCompound("createStatus").orElseThrow();
CompoundTag createNbt = nbt.read("createStatus", CompoundTag.CODEC).orElseThrow();
BotCreateState.Builder createBuilder = BotCreateState.builder(createNbt.getString("realName").orElseThrow(), null).name(createNbt.getString("name").orElseThrow());
String[] skin = null;
@@ -416,23 +376,21 @@ public class ServerBot extends ServerPlayer {
this.gameProfile = new BotList.CustomGameProfile(this.getUUID(), this.createState.name(), this.createState.skin());
if (nbt.contains("actions")) {
ListTag actionNbt = nbt.getList("actions").orElseThrow();
for (int i = 0; i < actionNbt.size(); i++) {
CompoundTag actionTag = actionNbt.getCompound(i).orElseThrow();
AbstractBotAction<?> action = Actions.getForName(actionTag.getString("actionName").orElseThrow());
if (nbt.list("actions", CompoundTag.CODEC).isPresent()) {
ValueInput.TypedInputList<CompoundTag> actionNbt = nbt.list("actions", CompoundTag.CODEC).orElseThrow();
actionNbt.forEach(actionTag -> {
ServerBotAction<?> action = Actions.getForName(actionTag.getString("actionName").orElseThrow());
if (action != null) {
AbstractBotAction<?> newAction = action.create();
ServerBotAction<?> newAction = action.create();
newAction.load(actionTag);
this.actions.add(newAction);
}
}
});
}
if (nbt.contains("configs")) {
ListTag configNbt = nbt.getList("configs").orElseThrow();
for (int i = 0; i < configNbt.size(); i++) {
CompoundTag configTag = configNbt.getCompound(i).orElseThrow();
if (nbt.list("configs", CompoundTag.CODEC).isPresent()) {
ValueInput.TypedInputList<CompoundTag> configNbt = nbt.list("configs", CompoundTag.CODEC).orElseThrow();
for (CompoundTag configTag : configNbt) {
Configs<?> configKey = Configs.getConfig(configTag.getString("configName").orElseThrow());
if (configKey != null) {
this.configs.get(configKey).load(configTag);
@@ -441,11 +399,6 @@ public class ServerBot extends ServerPlayer {
}
}
@Override
public boolean isClientAuthoritative() {
return false;
}
public void sendPlayerInfo(ServerPlayer player) {
player.connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME), List.of(this)));
}
@@ -461,7 +414,7 @@ public class ServerBot extends ServerPlayer {
}
public void sendFakeData(ServerPlayerConnection playerConnection, boolean login) {
ChunkMap.TrackedEntity entityTracker = ((ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId());
ChunkMap.TrackedEntity entityTracker = this.level().getChunkSource().chunkMap.entityMap.get(this.getId());
if (entityTracker == null) {
LeavesLogger.LOGGER.warning("Fakeplayer cant get entity tracker for " + this.getId());
@@ -477,7 +430,7 @@ public class ServerBot extends ServerPlayer {
}
public void renderAll() {
this.server.getPlayerList().getPlayers().forEach(
this.getServer().getPlayerList().getPlayers().forEach(
player -> {
this.sendPlayerInfo(player);
this.sendFakeDataIfNeed(player, false);
@@ -486,16 +439,16 @@ public class ServerBot extends ServerPlayer {
}
private void sendPacket(Packet<?> packet) {
this.server.getPlayerList().getPlayers().forEach(player -> player.connection.send(packet));
this.getServer().getPlayerList().getPlayers().forEach(player -> player.connection.send(packet));
}
@Override
public void die(@NotNull DamageSource damageSource) {
boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
Component defaultMessage = this.getCombatTracker().getDeathMessage();
BotDeathEvent event = new BotDeathEvent(this.getBukkitEntity(), PaperAdventure.asAdventure(defaultMessage), flag);
this.server.server.getPluginManager().callEvent(event);
this.getServer().server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
if (this.getHealth() <= 0) {
@@ -508,10 +461,10 @@ 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())) {
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false);
this.getServer().getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false);
}
this.server.getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false);
this.getServer().getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false);
}
public void removeTab() {
@@ -578,11 +531,11 @@ public class ServerBot extends ServerPlayer {
private void runAction() {
if (LeavesConfig.modify.fakeplayer.canUseAction) {
this.actions.forEach(action -> action.tryTick(this));
this.actions.removeIf(AbstractBotAction::isCancelled);
this.actions.removeIf(ServerBotAction::isCancelled);
}
}
public boolean addBotAction(AbstractBotAction<?> action, CommandSender sender) {
public boolean addBotAction(ServerBotAction<?> action, CommandSender sender) {
if (!LeavesConfig.modify.fakeplayer.canUseAction) {
return false;
}
@@ -596,7 +549,7 @@ public class ServerBot extends ServerPlayer {
return true;
}
public List<AbstractBotAction<?>> getBotActions() {
public List<ServerBotAction<?>> getBotActions() {
return actions;
}

View File

@@ -1,14 +1,13 @@
package org.leavesmc.leaves.bot;
import io.netty.channel.ChannelFutureListener;
import net.minecraft.network.Connection;
import net.minecraft.network.DisconnectionDetails;
import net.minecraft.network.PacketSendListener;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import org.bukkit.event.player.PlayerKickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -19,19 +18,11 @@ public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl {
}
@Override
public void sendPacket(@NotNull Packet<?> packet) {
public void send(@NotNull Packet<?> packet, @Nullable ChannelFutureListener listener) {
}
@Override
public void send(@NotNull Packet<?> packet) {
}
@Override
public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener callbacks) {
}
@Override
public void disconnect(@NotNull DisconnectionDetails disconnectionInfo, PlayerKickEvent.@NotNull Cause cause) {
public void disconnect(@NotNull DisconnectionDetails disconnectionInfo) {
}
@Override
@@ -71,15 +62,7 @@ public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl {
}
@Override
public void send(@NotNull Packet<?> packet) {
}
@Override
public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
}
@Override
public void send(@NotNull Packet<?> packet, @Nullable PacketSendListener callbacks, boolean flush) {
public void send(@NotNull Packet<?> packet, @javax.annotation.Nullable ChannelFutureListener channelFutureListener, boolean flag) {
}
}
}

View File

@@ -3,23 +3,8 @@ package org.leavesmc.leaves.bot.agent;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.agent.actions.AttackAction;
import org.leavesmc.leaves.bot.agent.actions.BreakBlockAction;
import org.leavesmc.leaves.bot.agent.actions.DropAction;
import org.leavesmc.leaves.bot.agent.actions.FishAction;
import org.leavesmc.leaves.bot.agent.actions.JumpAction;
import org.leavesmc.leaves.bot.agent.actions.LookAction;
import org.leavesmc.leaves.bot.agent.actions.RotateAction;
import org.leavesmc.leaves.bot.agent.actions.RotationAction;
import org.leavesmc.leaves.bot.agent.actions.ShootAction;
import org.leavesmc.leaves.bot.agent.actions.SneakAction;
import org.leavesmc.leaves.bot.agent.actions.SwimAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOffHandAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOnAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemOnOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemToAction;
import org.leavesmc.leaves.bot.agent.actions.UseItemToOffhandAction;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.Collection;
import java.util.HashMap;
@@ -28,57 +13,62 @@ import java.util.Set;
public class Actions {
private static final Map<String, AbstractBotAction<?>> actions = new HashMap<>();
private static final Map<String, ServerBotAction<?>> actionsByName = new HashMap<>();
private static final Map<Class<?>, ServerBotAction<?>> actionsByClass = new HashMap<>();
public static void registerAll() {
register(new AttackAction());
register(new BreakBlockAction());
register(new DropAction());
register(new JumpAction());
register(new RotateAction());
register(new SneakAction());
register(new UseItemAction());
register(new UseItemOnAction());
register(new UseItemToAction());
register(new LookAction());
register(new FishAction());
register(new SwimAction());
register(new UseItemOffHandAction());
register(new UseItemOnOffhandAction());
register(new UseItemToOffhandAction());
register(new RotationAction());
register(new ShootAction());
register(new ServerAttackAction(), AttackAction.class);
register(new ServerBreakBlockAction(), BreakBlockAction.class);
register(new ServerDropAction(), DropAction.class);
register(new ServerJumpAction(), JumpAction.class);
register(new ServerSneakAction(), SneakAction.class);
register(new ServerUseItemAutoAction(), UseItemAutoAction.class);
register(new ServerUseItemAction(), UseItemAction.class);
register(new ServerUseItemOnAction(), UseItemOnAction.class);
register(new ServerUseItemToAction(), UseItemToAction.class);
register(new ServerUseItemOffhandAction(), UseItemOffhandAction.class);
register(new ServerUseItemOnOffhandAction(), UseItemOnOffhandAction.class);
register(new ServerUseItemToOffhandAction(), UseItemToOffhandAction.class);
register(new ServerLookAction.TO(), LookAction.class);
register(new ServerLookAction.ON(), LookAction.class);
register(new ServerFishAction(), FishAction.class);
register(new ServerSwimAction(), SwimAction.class);
register(new ServerRotationAction(), RotationAction.class);
register(new ServerMoveAction(), MoveAction.class);
}
public static boolean register(@NotNull AbstractBotAction<?> action) {
if (!actions.containsKey(action.getName())) {
actions.put(action.getName(), action);
public static boolean register(@NotNull ServerBotAction<?> action, Class<? extends BotAction<?>> type) {
if (!actionsByName.containsKey(action.getName())) {
actionsByName.put(action.getName(), action);
actionsByClass.put(type, action);
return true;
}
return false;
}
public static boolean unregister(@NotNull String name) {
if (actions.containsKey(name)) {
actions.remove(name);
return true;
}
return false;
// TODO add in custom action api
return true;
}
@NotNull
@Contract(pure = true)
public static Collection<AbstractBotAction<?>> getAll() {
return actions.values();
public static Collection<ServerBotAction<?>> getAll() {
return actionsByName.values();
}
@NotNull
public static Set<String> getNames() {
return actions.keySet();
return actionsByName.keySet();
}
@Nullable
public static AbstractBotAction<?> getForName(String name) {
return actions.get(name);
public static ServerBotAction<?> getForName(String name) {
return actionsByName.get(name);
}
@Nullable
public static ServerBotAction<?> getForClass(@NotNull Class<?> type) {
return actionsByClass.get(type);
}
}

View File

@@ -4,11 +4,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.configs.AlwaysSendDataConfig;
import org.leavesmc.leaves.bot.agent.configs.SimulationDistanceConfig;
import org.leavesmc.leaves.bot.agent.configs.SkipSleepConfig;
import org.leavesmc.leaves.bot.agent.configs.SpawnPhantomConfig;
import org.leavesmc.leaves.bot.agent.configs.TickTypeConfig;
import org.leavesmc.leaves.bot.agent.configs.*;
import java.util.Collection;
import java.util.HashMap;
@@ -25,6 +21,7 @@ public class Configs<E> {
public static final Configs<Boolean> SPAWN_PHANTOM = register(SpawnPhantomConfig.class, SpawnPhantomConfig::new);
public static final Configs<Integer> SIMULATION_DISTANCE = register(SimulationDistanceConfig.class, SimulationDistanceConfig::new);
public static final Configs<ServerBot.TickType> TICK_TYPE = register(TickTypeConfig.class, TickTypeConfig::new);
public static final Configs<Boolean> ENABLE_LOCATOR_BAR = register(LocatorBarConfig.class, LocatorBarConfig::new);
private final Class<? extends AbstractBotConfig<E>> configClass;
private final Supplier<? extends AbstractBotConfig<E>> configCreator;

View File

@@ -1,54 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.entity.botaction.BotActionType;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
public class CraftBotAction extends LeavesBotAction {
private final AbstractBotAction<?> handle;
public CraftBotAction(@NotNull AbstractBotAction<?> action) {
super(BotActionType.valueOf(action.getName()), action.getInitialTickInterval(), action.getNumberRemaining());
this.handle = action;
}
@Contract("_ -> new")
@NotNull
public static LeavesBotAction asAPICopy(AbstractBotAction<?> action) {
return new CraftBotAction(action);
}
@NotNull
public static AbstractBotAction<?> asInternalCopy(@NotNull LeavesBotAction action) {
AbstractBotAction<?> act = Actions.getForName(action.getActionName());
if (act == null) {
throw new IllegalArgumentException("Invalid action name!");
}
AbstractBotAction<?> newAction = null;
String[] args = new String[]{String.valueOf(action.getInitialTickDelay()), String.valueOf(action.getInitialTickInterval()), String.valueOf(action.getInitialNumber())};
try {
if (act instanceof CraftCustomBotAction customBotAction) {
newAction = customBotAction.createCraft(action.getActionPlayer(), args);
} else {
newAction = act.create();
newAction.loadCommand(action.getActionPlayer() == null ? null : ((CraftPlayer) action.getActionPlayer()).getHandle(), act.getArgument().parse(0, args));
}
} catch (IllegalArgumentException ignore) {
}
if (newAction == null) {
throw new IllegalArgumentException("Invalid action!"); // TODO look action
}
return newAction;
}
public AbstractBotAction<?> getHandle() {
return handle;
}
}

View File

@@ -1,54 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.entity.botaction.CustomBotAction;
public class CraftCustomBotAction extends AbstractBotAction<CraftCustomBotAction> {
private final CustomBotAction realAction;
public CraftCustomBotAction(String name, @NotNull CustomBotAction realAction) {
super(name, CommandArgument.EMPTY, null);
this.realAction = realAction;
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
throw new UnsupportedOperationException("Not supported.");
}
public CraftCustomBotAction createCraft(@Nullable Player player, String[] args) {
CustomBotAction newRealAction = realAction.getNew(player, args);
if (newRealAction != null) {
return new CraftCustomBotAction(this.getName(), newRealAction);
}
return null;
}
@Override
public int getInitialNumber() {
return realAction.getInitialNumber();
}
@Override
public int getInitialTickDelay() {
return realAction.getInitialTickDelay();
}
@Override
public int getInitialTickInterval() {
return realAction.getInitialTickInterval();
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
return realAction.doTick(bot.getBukkitEntity());
}
}

View File

@@ -1,17 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class DropAction extends AbstractTimerAction<DropAction> {
public DropAction() {
super("drop", DropAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.dropAll(false);
return true;
}
}

View File

@@ -1,21 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class JumpAction extends AbstractTimerAction<JumpAction> {
public JumpAction() {
super("jump", JumpAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.onGround()) {
bot.jumpFromGround();
return true;
} else {
return false;
}
}
}

View File

@@ -1,73 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import java.text.DecimalFormat;
import java.util.List;
public class LookAction extends AbstractBotAction<LookAction> {
private static final DecimalFormat DF = new DecimalFormat("0.0");
public LookAction() {
super("look", CommandArgument.of(CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE), LookAction::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "<X>") : Pair.of(List.of("0"), "<X>"));
this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "<Y>") : Pair.of(List.of("0"), "<Y>"));
this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "<Z>") : Pair.of(List.of("0"), "<Z>"));
}
private Vector pos;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) throws IllegalArgumentException {
Vector pos = result.readVector();
if (pos != null) {
this.setPos(pos).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
} else {
throw new IllegalArgumentException("pos?");
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putDouble("x", this.pos.getX());
nbt.putDouble("y", this.pos.getY());
nbt.putDouble("z", this.pos.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.setPos(
new Vector(
nbt.getDouble("x").orElse(0.0),
nbt.getDouble("y").orElse(0.0),
nbt.getDouble("z").orElse(0.0)
)
);
}
public LookAction setPos(Vector pos) {
this.pos = pos;
return this;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.look(pos.subtract(bot.getLocation().toVector()), false);
return true;
}
}

View File

@@ -1,51 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class RotateAction extends AbstractBotAction<RotateAction> {
public RotateAction() {
super("rotate", CommandArgument.EMPTY, RotateAction::new);
}
private ServerPlayer player;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setPlayer(player).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
}
public RotateAction setPlayer(ServerPlayer player) {
this.player = player;
return this;
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putString("actionName", "look"); // to player loc
nbt.putDouble("x", player.getX());
nbt.putDouble("y", player.getY());
nbt.putDouble("z", player.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.faceLocation(player.getBukkitEntity().getLocation());
return true;
}
}

View File

@@ -3,20 +3,27 @@ package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.actions.CraftAttackAction;
public class AttackAction extends AbstractTimerAction<AttackAction> {
public class ServerAttackAction extends ServerTimerBotAction<ServerAttackAction> {
public AttackAction() {
super("attack", AttackAction::new);
public ServerAttackAction() {
super("attack", ServerAttackAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, target -> target.isAttackable() && !target.skipAttackInteraction(bot));
if (entity != null) {
if (entity == null) {
return false;
} else {
bot.attack(entity);
return true;
}
return false;
}
@Override
public Object asCraft() {
return new CraftAttackAction(this);
}
}

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.bot.agent;
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.core.UUIDUtil;
import net.minecraft.nbt.CompoundTag;
@@ -6,7 +6,6 @@ import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
@@ -16,10 +15,11 @@ import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.List;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
//TODO onStop for fully terminate action (use, etc.)
public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
@SuppressWarnings("unchecked")
public abstract class ServerBotAction<E extends ServerBotAction<E>> {
private final String name;
private final CommandArgument argument;
@@ -34,20 +34,29 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
private int numberRemaining;
private boolean cancel;
public AbstractBotAction(String name, CommandArgument argument, Supplier<E> creator) {
private Consumer<E> onFail;
private Consumer<E> onSuccess;
private Consumer<E> onStop;
public ServerBotAction(String name, CommandArgument argument, Supplier<E> creator) {
this.name = name;
this.argument = argument;
this.uuid = UUID.randomUUID();
this.creator = creator;
this.cancel = false;
this.initialTickInterval = 20;
this.initialNumber = -1;
this.setStartDelayTick(0);
this.setDoIntervalTick(1);
this.setDoNumber(1);
}
public abstract boolean doTick(@NotNull ServerBot bot);
public abstract Object asCraft();
public void init() {
this.tickToNext = initialTickDelay;
this.numberRemaining = this.getInitialNumber();
this.numberRemaining = this.getDoNumber();
this.setCancelled(false);
}
@@ -57,18 +66,23 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
return;
}
if (this.cancel) {
this.stop(bot, BotActionStopEvent.Reason.PLUGIN);
return;
}
if (this.tickToNext <= 0) {
BotActionExecuteEvent event = new BotActionExecuteEvent(bot.getBukkitEntity(), name, uuid);
event.callEvent();
if (event.getResult() == BotActionExecuteEvent.Result.SOFT_CANCEL) {
this.tickToNext = this.getInitialTickInterval() - 1;
this.tickToNext = this.getDoIntervalTick() - 1;
return;
} else if (event.getResult() == BotActionExecuteEvent.Result.HARD_CANCEL) {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getInitialTickInterval() - 1;
this.tickToNext = this.getDoIntervalTick() - 1;
return;
}
@@ -76,7 +90,12 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
if (this.numberRemaining > 0) {
this.numberRemaining--;
}
this.tickToNext = this.getInitialTickInterval() - 1;
this.tickToNext = this.getDoIntervalTick() - 1;
if (this.onSuccess != null) {
this.onSuccess.accept((E) this);
}
} else if (this.onFail != null) {
this.onFail.accept((E) this);
}
} else {
this.tickToNext--;
@@ -113,24 +132,33 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
new BotActionStopEvent(bot.getBukkitEntity(), this.name, this.uuid, reason, null).callEvent();
this.setCancelled(true);
if (this.onStop != null) {
this.onStop.accept((E) this);
}
}
public abstract void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result);
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
}
public abstract boolean doTick(@NotNull ServerBot bot);
@SuppressWarnings("unchecked")
public E setSuggestion(int n, BiFunction<CommandSender, String, Pair<List<String>, String>> suggestion) {
public void setSuggestion(int n, BiFunction<CommandSender, String, Pair<List<String>, String>> suggestion) {
this.argument.setSuggestion(n, suggestion);
return (E) this;
}
public E setSuggestion(int n, Pair<List<String>, String> suggestion) {
return this.setSuggestion(n, (sender, arg) -> suggestion);
public void setSuggestion(int n, Pair<List<String>, String> suggestion) {
this.setSuggestion(n, (sender, arg) -> suggestion);
}
public E setSuggestion(int n, List<String> tabComplete) {
return this.setSuggestion(n, Pair.of(tabComplete, null));
public void setSuggestion(int n, List<String> tabComplete) {
this.setSuggestion(n, Pair.of(tabComplete, null));
}
@NotNull
public E create() {
return this.creator.get();
}
public CommandArgument getArgument() {
return this.argument;
}
public String getName() {
@@ -141,41 +169,35 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
return uuid;
}
@SuppressWarnings("unchecked")
public E setInitialTickDelay(int initialTickDelay) {
public void setStartDelayTick(int initialTickDelay) {
this.initialTickDelay = initialTickDelay;
return (E) this;
}
public int getInitialTickDelay() {
public int getStartDelayTick() {
return this.initialTickDelay;
}
public int getInitialTickInterval() {
public void setDoIntervalTick(int initialTickInterval) {
this.initialTickInterval = Math.max(1, initialTickInterval);
}
public int getDoIntervalTick() {
return this.initialTickInterval;
}
@SuppressWarnings("unchecked")
public E setInitialTickInterval(int initialTickInterval) {
this.initialTickInterval = Math.max(1, initialTickInterval);
return (E) this;
}
public int getInitialNumber() {
return this.initialNumber;
}
@SuppressWarnings("unchecked")
public E setInitialNumber(int initialNumber) {
public void setDoNumber(int initialNumber) {
this.initialNumber = Math.max(-1, initialNumber);
return (E) this;
}
public int getDoNumber() {
return this.initialNumber;
}
public int getTickToNext() {
return this.tickToNext;
}
public int getNumberRemaining() {
public int getDoNumberRemaining() {
return this.numberRemaining;
}
@@ -187,12 +209,27 @@ public abstract class AbstractBotAction<E extends AbstractBotAction<E>> {
this.cancel = cancel;
}
public CommandArgument getArgument() {
return this.argument;
public void setOnFail(Consumer<E> onFail) {
this.onFail = onFail;
}
@NotNull
public E create() {
return this.creator.get();
public Consumer<E> getOnFail() {
return onFail;
}
public void setOnSuccess(Consumer<E> onSuccess) {
this.onSuccess = onSuccess;
}
public Consumer<E> getOnSuccess() {
return onSuccess;
}
public void setOnStop(Consumer<E> onStop) {
this.onStop = onStop;
}
public Consumer<E> getOnStop() {
return onStop;
}
}

View File

@@ -7,11 +7,12 @@ import org.bukkit.block.Block;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.actions.CraftBreakBlockAction;
public class BreakBlockAction extends AbstractTimerAction<BreakBlockAction> {
public class ServerBreakBlockAction extends ServerTimerBotAction<ServerBreakBlockAction> {
public BreakBlockAction() {
super("break", BreakBlockAction::new);
public ServerBreakBlockAction() {
super("break", ServerBreakBlockAction::new);
}
private BlockPos lastPos = null;
@@ -72,4 +73,9 @@ public class BreakBlockAction extends AbstractTimerAction<BreakBlockAction> {
return f;
}
@Override
public Object asCraft() {
return new CraftBreakBlockAction(this);
}
}

View File

@@ -0,0 +1,23 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.actions.CraftDropAction;
public class ServerDropAction extends ServerTimerBotAction<ServerDropAction> {
public ServerDropAction() {
super("drop", ServerDropAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.dropAll(false);
return true;
}
@Override
public Object asCraft() {
return new CraftDropAction(this);
}
}

View File

@@ -7,11 +7,12 @@ import net.minecraft.world.item.FishingRodItem;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.actions.CraftFishAction;
public class FishAction extends AbstractTimerAction<FishAction> {
public class ServerFishAction extends ServerTimerBotAction<ServerFishAction> {
public FishAction() {
super("fish", FishAction::new);
public ServerFishAction() {
super("fish", ServerFishAction::new);
}
private static final int CATCH_ENTITY_DELAY = 20;
@@ -20,10 +21,9 @@ public class FishAction extends AbstractTimerAction<FishAction> {
private int tickToNextFish = 0;
@Override
public FishAction setInitialTickInterval(int initialTickInterval) {
super.setInitialTickInterval(1);
public void setDoIntervalTick(int initialTickInterval) {
super.setDoIntervalTick(1);
this.initialFishInterval = initialTickInterval;
return this;
}
@Override
@@ -72,4 +72,9 @@ public class FishAction extends AbstractTimerAction<FishAction> {
return false;
}
@Override
public Object asCraft() {
return new CraftFishAction(this);
}
}

View File

@@ -0,0 +1,27 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.entity.bot.actions.CraftJumpAction;
public class ServerJumpAction extends ServerTimerBotAction<ServerJumpAction> {
public ServerJumpAction() {
super("jump", ServerJumpAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (!bot.onGround()) {
return false;
} else {
bot.jumpFromGround();
}
return true;
}
@Override
public Object asCraft() {
return new CraftJumpAction(this);
}
}

View File

@@ -0,0 +1,126 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftLookAction;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
public abstract class ServerLookAction<T extends ServerLookAction<T>> extends ServerBotAction<T> {
private static final Vector ZERO_VECTOR = new Vector(0, 0, 0);
private Vector pos = ZERO_VECTOR;
private ServerPlayer target = null;
private ServerLookAction(String name, CommandArgument argument, Supplier<T> creator) {
super(name, argument, creator);
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
if (target != null) {
this.pos.setX(this.target.getX());
this.pos.setY(this.target.getY());
this.pos.setZ(this.target.getZ());
}
nbt.putDouble("x", this.pos.getX());
nbt.putDouble("y", this.pos.getY());
nbt.putDouble("z", this.pos.getZ());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.setPos(
new Vector(
nbt.getDouble("x").orElse(0.0),
nbt.getDouble("y").orElse(0.0),
nbt.getDouble("z").orElse(0.0)
)
);
}
public void setPos(Vector pos) {
this.pos = pos;
}
public Vector getPos() {
return this.pos;
}
public void setTarget(ServerPlayer player) {
this.target = player;
}
public ServerPlayer getTarget() {
return target;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (target != null) {
bot.faceLocation(target.getBukkitEntity().getLocation());
} else {
bot.look(pos.subtract(bot.getLocation().toVector()), false);
}
return true;
}
public static class TO extends ServerLookAction<TO> {
public TO() {
super("look_to", CommandArgument.of(CommandArgumentType.STRING), TO::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(Arrays.asList(player.getServer().getPlayerNames()), "<Player>") : Pair.of(List.of("0"), "<Player>"));
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
String name = result.readString(player.getScoreboardName());
ServerPlayer player1 = player.getServer().getPlayerList().getPlayerByName(name);
if (player1 == null) {
throw new IllegalArgumentException("No such player");
} else {
this.setTarget(player1);
}
}
}
public static class ON extends ServerLookAction<ON> {
private static final DecimalFormat DF = new DecimalFormat("0.0");
public ON() {
super("look_on", CommandArgument.of(CommandArgumentType.DOUBLE, CommandArgumentType.BOOLEAN, CommandArgumentType.BOOLEAN), ON::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "<X>") : Pair.of(List.of("0"), "<X>"));
this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "<Y>") : Pair.of(List.of("0"), "<Y>"));
this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "<Z>") : Pair.of(List.of("0"), "<Z>"));
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
Vector vector = result.readVector();
if (vector == null) {
throw new IllegalArgumentException("Invalid vector");
} else {
this.setPos(vector);
}
}
}
@Override
public Object asCraft() {
return new CraftLookAction(this);
}
}

View File

@@ -0,0 +1,71 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
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.List;
public class ServerMoveAction extends ServerStateBotAction<ServerMoveAction> {
private static final Pair<List<String>, String> suggestions = Pair.of(
Arrays.stream(MoveDirection.values()).map((it) -> it.name).toList(),
"<Direction>"
);
private MoveDirection direction = MoveDirection.FORWARD;
public ServerMoveAction() {
super("move", CommandArgument.of(CommandArgumentType.ofEnum(MoveDirection.class)), ServerMoveAction::new);
this.setSuggestion(0, (sender, arg) -> suggestions);
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
this.direction = result.read(MoveDirection.class);
if (direction == null) {
throw new IllegalArgumentException("Invalid direction");
}
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
switch (direction) {
case FORWARD, BACKWARD -> bot.zza = 0.0f;
case LEFT, RIGHT -> bot.xxa = 0.0f;
}
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
boolean isSneaking = bot.isShiftKeyDown();
float velocity = isSneaking ? 0.3f : 1.0f;
switch (direction) {
case FORWARD -> bot.zza = velocity;
case BACKWARD -> bot.zza = -velocity;
case LEFT -> bot.xxa = velocity;
case RIGHT -> bot.xxa = -velocity;
}
return true;
}
public MoveDirection getDirection() {
return direction;
}
public void setDirection(MoveDirection direction) {
this.direction = direction;
}
@Override
public Object asCraft() {
return new CraftMoveAction(this);
}
}

View File

@@ -4,46 +4,53 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftRotationAction;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Objects;
public class RotationAction extends AbstractBotAction<RotationAction> {
public class ServerRotationAction extends ServerBotAction<ServerRotationAction> {
private static final DecimalFormat DF = new DecimalFormat("0.00");
public RotationAction() {
super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), RotationAction::new);
public ServerRotationAction() {
super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), ServerRotationAction::new);
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getYRot())), "[yaw]") : Pair.of(List.of("0"), "<yaw>"));
this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getXRot())), "[pitch]") : Pair.of(List.of("0"), "<pitch>"));
this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getXRot())), "[pitch]") : Pair.of(List.of("0"), "<pitch>"));
}
private float yaw;
private float pitch;
private float yaw = 0.0f;
private float pitch = 0.0f;
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
if (player == null) {
return;
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
try {
this.yaw = result.readFloat(Objects.requireNonNull(player).getYRot());
this.pitch = result.readFloat(player.getXRot());
} catch (Exception e) {
throw new IllegalArgumentException("No valid rotation specified", e);
}
this.setYaw(result.readFloat(player.getYRot())).setPitch(result.readFloat(player.getXRot())).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
}
public RotationAction setYaw(float yaw) {
public void setYaw(float yaw) {
this.yaw = yaw;
return this;
}
public RotationAction setPitch(float pitch) {
public void setPitch(float pitch) {
this.pitch = pitch;
return this;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
@Override
@@ -58,7 +65,8 @@ public class RotationAction extends AbstractBotAction<RotationAction> {
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.setYaw(nbt.getFloat("yaw").orElseThrow()).setPitch(nbt.getFloat("pitch").orElseThrow());
this.setYaw(nbt.getFloat("yaw").orElseThrow());
this.setPitch(nbt.getFloat("pitch").orElseThrow());
}
@Override
@@ -66,4 +74,9 @@ public class RotationAction extends AbstractBotAction<RotationAction> {
bot.setRot(yaw, pitch);
return true;
}
@Override
public Object asCraft() {
return new CraftRotationAction(this);
}
}

View File

@@ -0,0 +1,35 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.actions.CraftSneakAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
public class ServerSneakAction extends ServerStateBotAction<ServerSneakAction> {
public ServerSneakAction() {
super("sneak", CommandArgument.EMPTY, ServerSneakAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isShiftKeyDown()) {
return false;
}
bot.setShiftKeyDown(true);
return true;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.setShiftKeyDown(false);
}
@Override
public Object asCraft() {
return new CraftSneakAction(this);
}
}

View File

@@ -0,0 +1,12 @@
package org.leavesmc.leaves.bot.agent.actions;
import org.leavesmc.leaves.command.CommandArgument;
import java.util.function.Supplier;
public abstract class ServerStateBotAction<E extends ServerStateBotAction<E>> extends ServerBotAction<E> {
public ServerStateBotAction(String name, CommandArgument argument, Supplier<E> creator) {
super(name, argument, creator);
this.setDoNumber(-1);
}
}

View File

@@ -0,0 +1,27 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.entity.bot.actions.CraftSwimAction;
public class ServerSwimAction extends ServerStateBotAction<ServerSwimAction> {
public ServerSwimAction() {
super("swim", CommandArgument.EMPTY, ServerSwimAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isInWater()) {
bot.addDeltaMovement(new Vec3(0, 0.03, 0));
}
return true;
}
@Override
public Object asCraft() {
return new CraftSwimAction(this);
}
}

View File

@@ -3,8 +3,6 @@ package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
@@ -13,13 +11,13 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
public abstract class AbstractTimerAction<E extends AbstractTimerAction<E>> extends AbstractBotAction<E> {
public abstract class ServerTimerBotAction<E extends ServerTimerBotAction<E>> extends ServerBotAction<E> {
public AbstractTimerAction(String name, Supplier<E> creator) {
public ServerTimerBotAction(String name, Supplier<E> creator) {
this(name, CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), creator);
}
public AbstractTimerAction(String name, CommandArgument argument, Supplier<E> creator) {
public ServerTimerBotAction(String name, CommandArgument argument, Supplier<E> creator) {
super(name, argument, creator);
this.setSuggestion(0, Pair.of(Collections.singletonList("0"), "[TickDelay]"));
this.setSuggestion(1, Pair.of(Collections.singletonList("20"), "[TickInterval]"));
@@ -27,7 +25,9 @@ public abstract class AbstractTimerAction<E extends AbstractTimerAction<E>> exte
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(result.readInt(0)).setInitialTickInterval(result.readInt(20)).setInitialNumber(result.readInt(1));
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setStartDelayTick(result.readInt(0));
this.setDoIntervalTick(result.readInt(20));
this.setDoNumber(result.readInt(1));
}
}

View File

@@ -0,0 +1,110 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Collections;
public class ServerUseItemAction extends ServerTimerBotAction<ServerUseItemAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemAction() {
super("use", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
boolean result = execute(bot);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putInt("useTick", this.useTick);
nbt.putInt("tickToRelease", this.tickToRelease);
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.useTick = nbt.getInt("useTick").orElseThrow();
this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow();
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}
boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemAction(this);
}
}

View File

@@ -0,0 +1,109 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.BlockHitResult;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemAutoAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Collections;
public class ServerUseItemAutoAction extends ServerTimerBotAction<ServerUseItemAutoAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemAutoAction() {
super("use_auto", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemAutoAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
boolean result = execute(bot);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public boolean execute(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}
Entity entity = bot.getTargetEntity(3, null);
BlockHitResult blockHitResult = (BlockHitResult) bot.getRayTrace(5, ClipContext.Fluid.NONE);
boolean mainSuccess, useTo = entity != null, useOn = !bot.level().getBlockState(blockHitResult.getBlockPos()).isAir();
if (useTo) {
mainSuccess = ServerUseItemToAction.execute(bot, entity) || ServerUseItemAction.execute(bot);
} else if (useOn) {
mainSuccess = ServerUseItemOnAction.execute(bot, blockHitResult) || ServerUseItemAction.execute(bot);
} else {
mainSuccess = ServerUseItemAction.execute(bot);
}
if (mainSuccess) {
return true;
}
if (useTo) {
return ServerUseItemToOffhandAction.execute(bot, entity) || ServerUseItemOffhandAction.execute(bot);
} else if (useOn) {
return ServerUseItemOnOffhandAction.execute(bot, blockHitResult) || ServerUseItemOffhandAction.execute(bot);
} else {
return ServerUseItemOffhandAction.execute(bot);
}
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemAutoAction(this);
}
}

View File

@@ -0,0 +1,110 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOffhandAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Collections;
public class ServerUseItemOffhandAction extends ServerTimerBotAction<ServerUseItemOffhandAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemOffhandAction() {
super("use_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOffhandAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
boolean result = execute(bot);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putInt("useTick", this.useTick);
nbt.putInt("tickToRelease", this.tickToRelease);
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.useTick = nbt.getInt("useTick").orElseThrow();
this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow();
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}
boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemOffhandAction(this);
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOnAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
import java.util.Collections;
public class ServerUseItemOnAction extends ServerTimerBotAction<ServerUseItemOnAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemOnAction() {
super("use_on", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOnAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
HitResult hitResult = bot.getRayTrace(5, ClipContext.Fluid.NONE);
boolean result = execute(bot, hitResult);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putInt("useTick", this.useTick);
nbt.putInt("tickToRelease", this.tickToRelease);
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.useTick = nbt.getInt("useTick").orElseThrow();
this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow();
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(@NotNull ServerBot bot, HitResult result) {
if (!(result instanceof BlockHitResult blockHitResult)) {
return false;
}
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
} else {
bot.swing(InteractionHand.MAIN_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
} else {
return false;
}
} else {
bot.updateItemInHand(InteractionHand.MAIN_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, blockHitResult).consumesAction();
}
}
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemOnAction(this);
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOnOffhandAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
import java.util.Collections;
public class ServerUseItemOnOffhandAction extends ServerTimerBotAction<ServerUseItemOnOffhandAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemOnOffhandAction() {
super("use_on_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOnOffhandAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
HitResult hitResult = bot.getRayTrace(5, ClipContext.Fluid.NONE);
boolean result = execute(bot, hitResult);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putInt("useTick", this.useTick);
nbt.putInt("tickToRelease", this.tickToRelease);
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.useTick = nbt.getInt("useTick").orElseThrow();
this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow();
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(ServerBot bot, HitResult result) {
if (!(result instanceof BlockHitResult blockHitResult)) {
return false;
}
BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
} else {
bot.swing(InteractionHand.OFF_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
} else {
return false;
}
} else {
bot.updateItemInHand(InteractionHand.OFF_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, blockHitResult).consumesAction();
}
}
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemOnOffhandAction(this);
}
}

View File

@@ -0,0 +1,95 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemToAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Collections;
public class ServerUseItemToAction extends ServerTimerBotAction<ServerUseItemToAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemToAction() {
super("use_to", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemToAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
Entity entity = bot.getTargetEntity(3, null);
boolean result = execute(bot, entity);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity == null) {
return false;
}
boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemToAction(this);
}
}

View File

@@ -0,0 +1,95 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import org.leavesmc.leaves.entity.bot.actions.CraftUseItemToOffhandAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import java.util.Collections;
public class ServerUseItemToOffhandAction extends ServerTimerBotAction<ServerUseItemToOffhandAction> {
private int useTick = -1;
private int tickToRelease = -1;
public ServerUseItemToOffhandAction() {
super("use_to_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemToOffhandAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]"));
}
@Override
public void init() {
super.init();
syncTickToRelease();
}
@Override
public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.useTick = result.readInt(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
tickToRelease--;
if (tickToRelease >= 0) {
Entity entity = bot.getTargetEntity(3, null);
boolean result = execute(bot, entity);
if (useTick >= 0) {
return false;
} else {
return result;
}
} else {
syncTickToRelease();
bot.releaseUsingItem();
return true;
}
}
private void syncTickToRelease() {
if (this.useTick >= 0) {
this.tickToRelease = this.useTick;
} else {
this.tickToRelease = Integer.MAX_VALUE;
}
}
public int getUseTick() {
return useTick;
}
public void setUseTick(int useTick) {
this.useTick = useTick;
}
public static boolean execute(ServerBot bot, Entity entity) {
if (entity == null) {
return false;
}
boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
@Override
public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) {
super.stop(bot, reason);
bot.completeUsingItem();
}
@Override
public Object asCraft() {
return new CraftUseItemToOffhandAction(this);
}
}

View File

@@ -1,80 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.Items;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
import org.leavesmc.leaves.command.CommandArgumentType;
import java.util.Collections;
public class ShootAction extends AbstractTimerAction<ShootAction> {
private int drawingTick;
private int tickToRelease = -1;
public ShootAction() {
super("shoot", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ShootAction::new);
this.setSuggestion(3, Pair.of(Collections.singletonList("20"), "[DrawingTick]"));
}
@Override
public void init() {
super.init();
tickToRelease = drawingTick;
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (!bot.getItemInHand(InteractionHand.MAIN_HAND).is(Items.BOW)) {
return false;
}
tickToRelease--;
if (tickToRelease >= 0) {
bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction();
bot.updateItemInHand(InteractionHand.MAIN_HAND);
return false;
} else {
bot.releaseUsingItem();
tickToRelease = drawingTick;
return true;
}
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
super.loadCommand(player, result);
this.setDrawingTick(result.readInt(20));
}
@Override
@NotNull
public CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putInt("drawingTick", this.drawingTick);
nbt.putInt("tickToRelease", this.tickToRelease);
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
super.load(nbt);
this.drawingTick = nbt.getInt("drawingTick").orElseThrow();
this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow();
}
public int getDrawingTick() {
return drawingTick;
}
public ShootAction setDrawingTick(int drawingTick) {
this.drawingTick = drawingTick;
return this;
}
}

View File

@@ -1,27 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class SneakAction extends AbstractBotAction<SneakAction> {
public SneakAction() {
super("sneak", CommandArgument.EMPTY, SneakAction::new);
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
bot.setShiftKeyDown(!bot.isShiftKeyDown());
return true;
}
}

View File

@@ -1,30 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentResult;
public class SwimAction extends AbstractBotAction<SwimAction> {
public SwimAction() {
super("swim", CommandArgument.EMPTY, SwimAction::new);
}
@Override
public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) {
this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(-1);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isInWater()) {
bot.addDeltaMovement(new Vec3(0, 0.03, 0));
}
return true;
}
}

View File

@@ -1,26 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemAction extends AbstractTimerAction<UseItemAction> {
public UseItemAction() {
super("use", UseItemAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}
boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
}

View File

@@ -1,26 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemOffHandAction extends AbstractTimerAction<UseItemOffHandAction> {
public UseItemOffHandAction() {
super("use_offhand", UseItemOffHandAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
if (bot.isUsingItem()) {
return false;
}
boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
}

View File

@@ -1,45 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class UseItemOnAction extends AbstractTimerAction<UseItemOnAction> {
public UseItemOnAction() {
super("use_on", UseItemOnAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
if (result instanceof BlockHitResult blockHitResult) {
BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
}
bot.swing(InteractionHand.MAIN_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
}
} else {
bot.updateItemInHand(InteractionHand.MAIN_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result).consumesAction();
}
}
return false;
}
}

View File

@@ -1,45 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.TrappedChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.plugin.MinecraftInternalPlugin;
public class UseItemOnOffhandAction extends AbstractTimerAction<UseItemOnOffhandAction> {
public UseItemOnOffhandAction() {
super("use_on_offhand", UseItemOnOffhandAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE);
if (result instanceof BlockHitResult blockHitResult) {
BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos());
if (state.isAir()) {
return false;
}
bot.swing(InteractionHand.OFF_HAND);
if (state.getBlock() == Blocks.TRAPPED_CHEST) {
BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos());
if (entity instanceof TrappedChestBlockEntity chestBlockEntity) {
chestBlockEntity.startOpen(bot);
Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1);
return true;
}
} else {
bot.updateItemInHand(InteractionHand.OFF_HAND);
return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, (BlockHitResult) result).consumesAction();
}
}
return false;
}
}

View File

@@ -1,27 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemToAction extends AbstractTimerAction<UseItemToAction> {
public UseItemToAction() {
super("use_to", UseItemToAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
if (entity != null) {
boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.MAIN_HAND);
bot.updateItemInHand(InteractionHand.MAIN_HAND);
}
return flag;
}
return false;
}
}

View File

@@ -1,27 +0,0 @@
package org.leavesmc.leaves.bot.agent.actions;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
public class UseItemToOffhandAction extends AbstractTimerAction<UseItemToOffhandAction> {
public UseItemToOffhandAction() {
super("use_to_offhand", UseItemToOffhandAction::new);
}
@Override
public boolean doTick(@NotNull ServerBot bot) {
Entity entity = bot.getTargetEntity(3, null);
if (entity != null) {
boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction();
if (flag) {
bot.swing(InteractionHand.OFF_HAND);
bot.updateItemInHand(InteractionHand.OFF_HAND);
}
return flag;
}
return false;
}
}

View File

@@ -17,7 +17,7 @@ public class AlwaysSendDataConfig extends AbstractBotConfig<Boolean> {
public AlwaysSendDataConfig() {
super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false")));
this.value = LeavesConfig.modify.fakeplayer.canSendDataAlways;
this.value = LeavesConfig.modify.fakeplayer.inGame.canSendDataAlways;
}
@Override
@@ -40,6 +40,6 @@ public class AlwaysSendDataConfig extends AbstractBotConfig<Boolean> {
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(nbt.getBoolean(NAME).orElseThrow());
this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSendDataAlways));
}
}

View File

@@ -0,0 +1,51 @@
package org.leavesmc.leaves.bot.agent.configs;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.waypoints.ServerWaypointManager;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentType;
import java.util.List;
public class LocatorBarConfig extends AbstractBotConfig<Boolean> {
public static final String NAME = "enable_locator_bar";
private boolean value;
public LocatorBarConfig() {
super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false")));
this.value = LeavesConfig.modify.fakeplayer.inGame.enableLocatorBar;
}
@Override
public Boolean getValue() {
return value;
}
@Override
public void setValue(Boolean value) throws IllegalArgumentException {
this.value = value;
ServerWaypointManager manager = this.bot.level().getWaypointManager();
if (value) {
manager.trackWaypoint(this.bot);
} else {
manager.untrackWaypoint(this.bot);
}
}
@Override
public @NotNull CompoundTag save(@NotNull CompoundTag nbt) {
super.save(nbt);
nbt.putBoolean(NAME, this.getValue());
return nbt;
}
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.enableLocatorBar));
}
}

View File

@@ -3,6 +3,7 @@ package org.leavesmc.leaves.bot.agent.configs;
import net.minecraft.nbt.CompoundTag;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentType;
@@ -40,6 +41,6 @@ public class SimulationDistanceConfig extends AbstractBotConfig<Integer> {
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(nbt.getInt(NAME).orElseThrow());
this.setValue(nbt.getIntOr(NAME, LeavesConfig.modify.fakeplayer.inGame.getSimulationDistance(this.bot)));
}
}

View File

@@ -2,6 +2,7 @@ package org.leavesmc.leaves.bot.agent.configs;
import net.minecraft.nbt.CompoundTag;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.bot.agent.AbstractBotConfig;
import org.leavesmc.leaves.command.CommandArgument;
import org.leavesmc.leaves.command.CommandArgumentType;
@@ -35,6 +36,6 @@ public class SkipSleepConfig extends AbstractBotConfig<Boolean> {
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(nbt.getBoolean(NAME).orElseThrow());
this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSkipSleep));
}
}

View File

@@ -17,7 +17,7 @@ public class SpawnPhantomConfig extends AbstractBotConfig<Boolean> {
public SpawnPhantomConfig() {
super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false")));
this.value = LeavesConfig.modify.fakeplayer.canSpawnPhantom;
this.value = LeavesConfig.modify.fakeplayer.inGame.canSpawnPhantom;
}
@Override
@@ -47,6 +47,6 @@ public class SpawnPhantomConfig extends AbstractBotConfig<Boolean> {
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(nbt.getBoolean(NAME).orElseThrow());
this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSpawnPhantom));
}
}

View File

@@ -19,7 +19,7 @@ public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType> {
public TickTypeConfig() {
super(NAME, CommandArgument.of(TICK_TYPE_ARGUMENT).setSuggestion(0, List.of("network", "entity_list")));
this.value = LeavesConfig.modify.fakeplayer.tickType;
this.value = LeavesConfig.modify.fakeplayer.inGame.tickType;
}
@Override
@@ -42,6 +42,6 @@ public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType> {
@Override
public void load(@NotNull CompoundTag nbt) {
this.setValue(TICK_TYPE_ARGUMENT.parse(nbt.getString(NAME).orElseThrow()));
this.setValue(TICK_TYPE_ARGUMENT.parse(nbt.getStringOr(NAME, LeavesConfig.modify.fakeplayer.inGame.tickType.name())));
}
}

View File

@@ -10,9 +10,8 @@ import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.command.LeavesSubcommand;
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
@@ -21,7 +20,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import static net.kyori.adventure.text.Component.text;
@@ -53,7 +51,7 @@ public class BotActionCommand implements LeavesSubcommand {
}
private void executeStart(ServerBot bot, CommandSender sender, String[] args) {
AbstractBotAction<?> action = Actions.getForName(args[2]);
ServerBotAction<?> action = Actions.getForName(args[2]);
if (action == null) {
sender.sendMessage(text("Invalid action", NamedTextColor.RED));
return;
@@ -67,23 +65,15 @@ public class BotActionCommand implements LeavesSubcommand {
}
String[] realArgs = Arrays.copyOfRange(args, 3, args.length);
AbstractBotAction<?> newAction;
ServerBotAction<?> newAction;
try {
if (action instanceof CraftCustomBotAction customBotAction) {
newAction = customBotAction.createCraft(player, realArgs);
} else {
newAction = action.create();
newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs));
}
newAction = action.create();
newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs));
} catch (IllegalArgumentException e) {
sender.sendMessage(text("Action create error, please check your arguments, " + e.getMessage(), NamedTextColor.RED));
return;
}
if (newAction == null) {
return;
}
if (bot.addBotAction(newAction, sender)) {
sender.sendMessage("Action " + action.getName() + " has been issued to " + bot.getName().getString());
}
@@ -97,15 +87,16 @@ public class BotActionCommand implements LeavesSubcommand {
String index = args[2];
if (index.equals("all")) {
Set<AbstractBotAction<?>> forRemoval = new HashSet<>();
Set<ServerBotAction<?>> forRemoval = new HashSet<>();
for (int i = 0; i < bot.getBotActions().size(); i++) {
AbstractBotAction<?> action = bot.getBotActions().get(i);
ServerBotAction<?> action = bot.getBotActions().get(i);
BotActionStopEvent event = new BotActionStopEvent(
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
);
event.callEvent();
if (!event.isCancelled()) {
forRemoval.add(action);
action.stop(bot, BotActionStopEvent.Reason.COMMAND);
}
}
bot.getBotActions().removeAll(forRemoval);
@@ -119,12 +110,13 @@ public class BotActionCommand implements LeavesSubcommand {
return;
}
AbstractBotAction<?> action = bot.getBotActions().get(i);
ServerBotAction<?> action = bot.getBotActions().get(i);
BotActionStopEvent event = new BotActionStopEvent(
bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender
);
event.callEvent();
if (!event.isCancelled()) {
action.stop(bot, BotActionStopEvent.Reason.COMMAND);
bot.getBotActions().remove(i);
sender.sendMessage(bot.getScoreboardName() + "'s " + action.getName() + " stopped.");
@@ -158,7 +150,7 @@ public class BotActionCommand implements LeavesSubcommand {
}
}
case 4, 5, 6, 7 -> {
AbstractBotAction<?> action = Actions.getForName(args[2]);
ServerBotAction<?> action = Actions.getForName(args[2]);
if (action == null) {
return;
}

View File

@@ -12,7 +12,7 @@ import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.command.LeavesSubcommand;
import org.leavesmc.leaves.command.LeavesSuggestionBuilder;
import org.leavesmc.leaves.entity.Bot;
import org.leavesmc.leaves.entity.bot.Bot;
import java.util.ArrayList;
import java.util.HashMap;

View File

@@ -1,6 +1,8 @@
package org.leavesmc.leaves.bytebuf;
import com.google.gson.JsonElement;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.JsonOps;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
@@ -226,7 +228,7 @@ public class WrappedBytebuf implements Bytebuf {
@Override
public Bytebuf writeComponentJson(JsonElement json) {
Component component = Component.Serializer.fromJson(json, RegistryAccess.EMPTY);
Component component = ComponentSerialization.CODEC.decode(JsonOps.INSTANCE, json).mapOrElse(Pair::getFirst, v -> null);
if (component == null) {
throw new IllegalArgumentException("Null can not be serialize to Minecraft chat component");
}
@@ -236,7 +238,7 @@ public class WrappedBytebuf implements Bytebuf {
@Override
public JsonElement readComponentJson() {
return Component.Serializer.serialize(ComponentSerialization.STREAM_CODEC.decode(new RegistryFriendlyByteBuf(buf, RegistryAccess.EMPTY)), RegistryAccess.EMPTY);
return ComponentSerialization.CODEC.encodeStart(JsonOps.INSTANCE, ComponentSerialization.STREAM_CODEC.decode(new RegistryFriendlyByteBuf(buf, RegistryAccess.EMPTY))).getOrThrow();
}
@Override

View File

@@ -54,6 +54,13 @@ public class CommandArgumentResult {
return new Vector(pos[0], pos[1], pos[2]);
}
public Object readObject() {
if (result.isEmpty()) {
return null;
}
return result.removeFirst();
}
public <T> T read(Class<T> tClass, T def) {
return Objects.requireNonNullElse(read(tClass), def);
}

View File

@@ -56,8 +56,11 @@ public class ReportCommand implements LeavesSubcommand {
if (provider instanceof SpigotPluginProvider) {
spigotPlugins.put(configuration.getDisplayName(), provider);
} else if (provider instanceof PaperPluginParent.PaperServerPluginProvider) {
if (provider.getMeta() instanceof LeavesPluginMeta) leavesPlugins.put(configuration.getDisplayName(), provider);
else paperPlugins.put(configuration.getDisplayName(), provider);
if (provider.getMeta() instanceof LeavesPluginMeta) {
leavesPlugins.put(configuration.getDisplayName(), provider);
} else {
paperPlugins.put(configuration.getDisplayName(), provider);
}
}
}

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.bot;
import com.google.common.base.Preconditions;
import org.bukkit.Location;
@@ -9,9 +9,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.actions.CraftBotAction;
import org.leavesmc.leaves.entity.botaction.LeavesBotAction;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import org.leavesmc.leaves.entity.bot.actions.CraftBotAction;
import org.leavesmc.leaves.event.bot.BotActionStopEvent;
import org.leavesmc.leaves.event.bot.BotRemoveEvent;
@@ -39,13 +39,16 @@ public class CraftBot extends CraftPlayer implements Bot {
}
@Override
public void addAction(@NotNull LeavesBotAction action) {
this.getHandle().addBotAction(CraftBotAction.asInternalCopy(action), null);
public <T extends BotAction<T>> void addAction(@NotNull T action) {
switch (action) {
case CraftBotAction act -> this.getHandle().addBotAction(act.getHandle(), null);
default -> throw new IllegalArgumentException("Action " + action.getClass().getName() + " is not a valid BotAction type!");
}
}
@Override
public LeavesBotAction getAction(int index) {
return CraftBotAction.asAPICopy(this.getHandle().getBotActions().get(index));
public BotAction<?> getAction(int index) {
return (BotAction<?>) this.getHandle().getBotActions().get(index).asCraft();
}
@Override
@@ -60,7 +63,7 @@ public class CraftBot extends CraftPlayer implements Bot {
@Override
public void stopAllActions() {
for (AbstractBotAction<?> action : this.getHandle().getBotActions()) {
for (ServerBotAction<?> action : this.getHandle().getBotActions()) {
action.stop(this.getHandle(), BotActionStopEvent.Reason.PLUGIN);
}
}
@@ -72,7 +75,7 @@ public class CraftBot extends CraftPlayer implements Bot {
}
@Override
public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag @NotNull ... flags) {
Preconditions.checkArgument(location != null, "location cannot be null");
Preconditions.checkState(location.getWorld().equals(this.getWorld()), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!");
return super.teleport(location, cause, flags);

View File

@@ -1,6 +1,5 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.bot;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Location;
@@ -9,10 +8,9 @@ import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.bot.BotCreateState;
import org.leavesmc.leaves.bot.BotList;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.AbstractBotAction;
import org.leavesmc.leaves.bot.agent.Actions;
import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction;
import org.leavesmc.leaves.entity.botaction.CustomBotAction;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import org.leavesmc.leaves.event.bot.BotCreateEvent;
import java.util.Collection;
@@ -26,7 +24,7 @@ public class CraftBotManager implements BotManager {
public CraftBotManager() {
this.botList = MinecraftServer.getServer().getBotList();
this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, bot -> bot.getBukkitEntity()));
this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, ServerBot::getBukkitEntity));
}
@Override
@@ -54,18 +52,19 @@ public class CraftBotManager implements BotManager {
return botViews;
}
@SuppressWarnings("unchecked")
@Override
public boolean registerCustomBotAction(String name, CustomBotAction action) {
return Actions.register(new CraftCustomBotAction(name, action));
}
@Override
public boolean unregisterCustomBotAction(String name) {
AbstractBotAction<?> action = Actions.getForName(name);
if (action instanceof CraftCustomBotAction) {
return Actions.unregister(name);
public <T extends BotAction<T>> T newAction(@NotNull Class<T> type) {
ServerBotAction<?> action = Actions.getForClass(type);
if (action == null) {
throw new IllegalArgumentException("No action registered for type: " + type.getName());
} else {
try {
return (T) action.create().asCraft();
} catch (Exception e) {
throw new RuntimeException("Failed to create action of type: " + type.getName(), e);
}
}
return false;
}
@Override

View File

@@ -0,0 +1,122 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftAttackAction extends CraftBotAction implements AttackAction {
private final ServerAttackAction serverAction;
private Consumer<AttackAction> onFail = null;
private Consumer<AttackAction> onSuccess = null;
private Consumer<AttackAction> onStop = null;
public CraftAttackAction(ServerAttackAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<AttackAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftAttackAction(it)));
}
@Override
public Consumer<AttackAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<AttackAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftAttackAction(it)));
}
@Override
public Consumer<AttackAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<AttackAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftAttackAction(it)));
}
@Override
public Consumer<AttackAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,7 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.leavesmc.leaves.bot.agent.actions.*;
public abstract class CraftBotAction {
public abstract ServerBotAction<?> getHandle();
}

View File

@@ -0,0 +1,122 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftBreakBlockAction extends CraftBotAction implements BreakBlockAction {
private final ServerBreakBlockAction serverAction;
private Consumer<BreakBlockAction> onFail = null;
private Consumer<BreakBlockAction> onSuccess = null;
private Consumer<BreakBlockAction> onStop = null;
public CraftBreakBlockAction(ServerBreakBlockAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<BreakBlockAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftBreakBlockAction(it)));
}
@Override
public Consumer<BreakBlockAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<BreakBlockAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftBreakBlockAction(it)));
}
@Override
public Consumer<BreakBlockAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<BreakBlockAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftBreakBlockAction(it)));
}
@Override
public Consumer<BreakBlockAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,122 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftDropAction extends CraftBotAction implements DropAction {
private final ServerDropAction serverAction;
private Consumer<DropAction> onFail = null;
private Consumer<DropAction> onSuccess = null;
private Consumer<DropAction> onStop = null;
public CraftDropAction(ServerDropAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<DropAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftDropAction(it)));
}
@Override
public Consumer<DropAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<DropAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftDropAction(it)));
}
@Override
public Consumer<DropAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<DropAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftDropAction(it)));
}
@Override
public Consumer<DropAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,122 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftFishAction extends CraftBotAction implements FishAction {
private final ServerFishAction serverAction;
private Consumer<FishAction> onFail = null;
private Consumer<FishAction> onSuccess = null;
private Consumer<FishAction> onStop = null;
public CraftFishAction(ServerFishAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<FishAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftFishAction(it)));
}
@Override
public Consumer<FishAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<FishAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftFishAction(it)));
}
@Override
public Consumer<FishAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<FishAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftFishAction(it)));
}
@Override
public Consumer<FishAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,122 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftJumpAction extends CraftBotAction implements JumpAction {
private final ServerJumpAction serverAction;
private Consumer<JumpAction> onFail = null;
private Consumer<JumpAction> onSuccess = null;
private Consumer<JumpAction> onStop = null;
public CraftJumpAction(ServerJumpAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<JumpAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftJumpAction(it)));
}
@Override
public Consumer<JumpAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<JumpAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftJumpAction(it)));
}
@Override
public Consumer<JumpAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<JumpAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftJumpAction(it)));
}
@Override
public Consumer<JumpAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,107 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftLookAction extends CraftBotAction implements LookAction {
private final ServerLookAction<?> serverAction;
private Consumer<LookAction> onFail = null;
private Consumer<LookAction> onSuccess = null;
private Consumer<LookAction> onStop = null;
public CraftLookAction(ServerLookAction<?> serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<LookAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftLookAction(it)));
}
@Override
public Consumer<LookAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<LookAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftLookAction(it)));
}
@Override
public Consumer<LookAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<LookAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftLookAction(it)));
}
@Override
public Consumer<LookAction> getOnStop() {
return onStop;
}
@Override
public LookAction setPos(Vector pos) {
serverAction.setPos(pos);
return this;
}
@Override
public Vector getPos() {
return serverAction.getPos();
}
@Override
public LookAction setTarget(Player player) {
serverAction.setTarget(((CraftPlayer) player).getHandle());
return this;
}
@Override
public Player getTarget() {
return serverAction.getTarget().getBukkitEntity();
}
}

View File

@@ -0,0 +1,93 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftMoveAction extends CraftBotAction implements MoveAction {
private final ServerMoveAction serverAction;
private Consumer<MoveAction> onFail = null;
private Consumer<MoveAction> onSuccess = null;
private Consumer<MoveAction> onStop = null;
public CraftMoveAction(ServerMoveAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<MoveAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftMoveAction(it)));
}
@Override
public Consumer<MoveAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<MoveAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftMoveAction(it)));
}
@Override
public Consumer<MoveAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<MoveAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftMoveAction(it)));
}
@Override
public Consumer<MoveAction> getOnStop() {
return onStop;
}
@Override
public MoveDirection getDirection() {
return serverAction.getDirection();
}
@Override
public MoveAction setDirection(MoveDirection direction) {
serverAction.setDirection(direction);
return this;
}
}

View File

@@ -0,0 +1,104 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftRotationAction extends CraftBotAction implements RotationAction {
private final ServerRotationAction serverAction;
private Consumer<RotationAction> onFail = null;
private Consumer<RotationAction> onSuccess = null;
private Consumer<RotationAction> onStop = null;
public CraftRotationAction(ServerRotationAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<RotationAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftRotationAction(it)));
}
@Override
public Consumer<RotationAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<RotationAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftRotationAction(it)));
}
@Override
public Consumer<RotationAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<RotationAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftRotationAction(it)));
}
@Override
public Consumer<RotationAction> getOnStop() {
return onStop;
}
@Override
public RotationAction setYaw(float yaw) {
serverAction.setYaw(yaw);
return this;
}
@Override
public RotationAction setPitch(float pitch) {
serverAction.setPitch(pitch);
return this;
}
@Override
public float getYaw() {
return serverAction.getYaw();
}
@Override
public float getPitch() {
return serverAction.getPitch();
}
}

View File

@@ -0,0 +1,82 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftSneakAction extends CraftBotAction implements SneakAction {
private final ServerSneakAction serverAction;
private Consumer<SneakAction> onFail = null;
private Consumer<SneakAction> onSuccess = null;
private Consumer<SneakAction> onStop = null;
public CraftSneakAction(ServerSneakAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<SneakAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftSneakAction(it)));
}
@Override
public Consumer<SneakAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<SneakAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftSneakAction(it)));
}
@Override
public Consumer<SneakAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<SneakAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftSneakAction(it)));
}
@Override
public Consumer<SneakAction> getOnStop() {
return onStop;
}
}

View File

@@ -0,0 +1,82 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftSwimAction extends CraftBotAction implements SwimAction {
private final ServerSwimAction serverAction;
private Consumer<SwimAction> onFail = null;
private Consumer<SwimAction> onSuccess = null;
private Consumer<SwimAction> onStop = null;
public CraftSwimAction(ServerSwimAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<SwimAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftSwimAction(it)));
}
@Override
public Consumer<SwimAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<SwimAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftSwimAction(it)));
}
@Override
public Consumer<SwimAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<SwimAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftSwimAction(it)));
}
@Override
public Consumer<SwimAction> getOnStop() {
return onStop;
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemAction extends CraftBotAction implements UseItemAction {
private final ServerUseItemAction serverAction;
private Consumer<UseItemAction> onFail = null;
private Consumer<UseItemAction> onSuccess = null;
private Consumer<UseItemAction> onStop = null;
public CraftUseItemAction(ServerUseItemAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemAction(it)));
}
@Override
public Consumer<UseItemAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemAction(it)));
}
@Override
public Consumer<UseItemAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemAction(it)));
}
@Override
public Consumer<UseItemAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemAutoAction extends CraftBotAction implements UseItemAutoAction {
private final ServerUseItemAutoAction serverAction;
private Consumer<UseItemAutoAction> onFail = null;
private Consumer<UseItemAutoAction> onSuccess = null;
private Consumer<UseItemAutoAction> onStop = null;
public CraftUseItemAutoAction(ServerUseItemAutoAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemAutoAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemAutoAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemAutoAction(it)));
}
@Override
public Consumer<UseItemAutoAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemAutoAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemAutoAction(it)));
}
@Override
public Consumer<UseItemAutoAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemAutoAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemAutoAction(it)));
}
@Override
public Consumer<UseItemAutoAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemOffhandAction extends CraftBotAction implements UseItemOffhandAction {
private final ServerUseItemOffhandAction serverAction;
private Consumer<UseItemOffhandAction> onFail = null;
private Consumer<UseItemOffhandAction> onSuccess = null;
private Consumer<UseItemOffhandAction> onStop = null;
public CraftUseItemOffhandAction(ServerUseItemOffhandAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemOffhandAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemOffhandAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOffhandAction(it)));
}
@Override
public Consumer<UseItemOffhandAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemOffhandAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOffhandAction(it)));
}
@Override
public Consumer<UseItemOffhandAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemOffhandAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOffhandAction(it)));
}
@Override
public Consumer<UseItemOffhandAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemOnAction extends CraftBotAction implements UseItemOnAction {
private final ServerUseItemOnAction serverAction;
private Consumer<UseItemOnAction> onFail = null;
private Consumer<UseItemOnAction> onSuccess = null;
private Consumer<UseItemOnAction> onStop = null;
public CraftUseItemOnAction(ServerUseItemOnAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemOnAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemOnAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOnAction(it)));
}
@Override
public Consumer<UseItemOnAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemOnAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOnAction(it)));
}
@Override
public Consumer<UseItemOnAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemOnAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOnAction(it)));
}
@Override
public Consumer<UseItemOnAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemOnOffhandAction extends CraftBotAction implements UseItemOnOffhandAction {
private final ServerUseItemOnOffhandAction serverAction;
private Consumer<UseItemOnOffhandAction> onFail = null;
private Consumer<UseItemOnOffhandAction> onSuccess = null;
private Consumer<UseItemOnOffhandAction> onStop = null;
public CraftUseItemOnOffhandAction(ServerUseItemOnOffhandAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemOnOffhandAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemOnOffhandAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOnOffhandAction(it)));
}
@Override
public Consumer<UseItemOnOffhandAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemOnOffhandAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOnOffhandAction(it)));
}
@Override
public Consumer<UseItemOnOffhandAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemOnOffhandAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOnOffhandAction(it)));
}
@Override
public Consumer<UseItemOnOffhandAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemToAction extends CraftBotAction implements UseItemToAction {
private final ServerUseItemToAction serverAction;
private Consumer<UseItemToAction> onFail = null;
private Consumer<UseItemToAction> onSuccess = null;
private Consumer<UseItemToAction> onStop = null;
public CraftUseItemToAction(ServerUseItemToAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemToAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemToAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemToAction(it)));
}
@Override
public Consumer<UseItemToAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemToAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemToAction(it)));
}
@Override
public Consumer<UseItemToAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemToAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemToAction(it)));
}
@Override
public Consumer<UseItemToAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -0,0 +1,133 @@
package org.leavesmc.leaves.entity.bot.actions;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.bot.ServerBot;
import org.leavesmc.leaves.bot.agent.actions.*;
import org.leavesmc.leaves.entity.bot.action.*;
import java.util.UUID;
import java.util.function.Consumer;
public class CraftUseItemToOffhandAction extends CraftBotAction implements UseItemToOffhandAction {
private final ServerUseItemToOffhandAction serverAction;
private Consumer<UseItemToOffhandAction> onFail = null;
private Consumer<UseItemToOffhandAction> onSuccess = null;
private Consumer<UseItemToOffhandAction> onStop = null;
public CraftUseItemToOffhandAction(ServerUseItemToOffhandAction serverAction) {
this.serverAction = serverAction;
}
public boolean doTick(@NotNull ServerBot bot) {
return serverAction.doTick(bot);
}
@Override
public int getUseTick() {
return serverAction.getUseTick();
}
@Override
public CraftUseItemToOffhandAction setUseTick(int useTick) {
serverAction.setUseTick(useTick);
return this;
}
@Override
public ServerBotAction<?> getHandle() {
return serverAction;
}
@Override
public String getName() {
return serverAction.getName();
}
@Override
public UUID getUUID() {
return serverAction.getUUID();
}
@Override
public void setCancelled(boolean cancel) {
serverAction.setCancelled(cancel);
}
@Override
public boolean isCancelled() {
return serverAction.isCancelled();
}
@Override
public void setOnFail(Consumer<UseItemToOffhandAction> onFail) {
this.onFail = onFail;
serverAction.setOnFail(it -> onFail.accept(new CraftUseItemToOffhandAction(it)));
}
@Override
public Consumer<UseItemToOffhandAction> getOnFail() {
return onFail;
}
@Override
public void setOnSuccess(Consumer<UseItemToOffhandAction> onSuccess) {
this.onSuccess = onSuccess;
serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemToOffhandAction(it)));
}
@Override
public Consumer<UseItemToOffhandAction> getOnSuccess() {
return onSuccess;
}
@Override
public void setOnStop(Consumer<UseItemToOffhandAction> onStop) {
this.onStop = onStop;
serverAction.setOnStop(it -> onStop.accept(new CraftUseItemToOffhandAction(it)));
}
@Override
public Consumer<UseItemToOffhandAction> getOnStop() {
return onStop;
}
@Override
public void setStartDelayTick(int delayTick) {
serverAction.setStartDelayTick(delayTick);
}
@Override
public int getStartDelayTick() {
return serverAction.getStartDelayTick();
}
@Override
public void setDoIntervalTick(int intervalTick) {
serverAction.setDoIntervalTick(intervalTick);
}
@Override
public int getDoIntervalTick() {
return serverAction.getDoIntervalTick();
}
@Override
public void setDoNumber(int doNumber) {
serverAction.setDoNumber(doNumber);
}
@Override
public int getDoNumber() {
return serverAction.getDoNumber();
}
@Override
public int getTickToNext() {
return serverAction.getTickToNext();
}
@Override
public int getDoNumberRemaining() {
return serverAction.getDoNumberRemaining();
}
}

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.photographer;
import net.minecraft.server.level.ServerPlayer;
import org.bukkit.craftbukkit.CraftServer;

View File

@@ -1,4 +1,4 @@
package org.leavesmc.leaves.entity;
package org.leavesmc.leaves.entity.photographer;
import com.google.common.collect.Lists;
import org.bukkit.Location;

View File

@@ -1,12 +1,16 @@
// Gale - Lithium - faster chunk serialization
package org.leavesmc.leaves.lithium.common.world.chunk;
import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.HashCommon;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.core.IdMap;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.VarInt;
import net.minecraft.world.level.chunk.MissingPaletteEntryException;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PaletteResize;
import org.jetbrains.annotations.NotNull;
@@ -17,8 +21,6 @@ import java.util.function.Predicate;
import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR;
// Powered by Gale(https://github.com/GaleMC/Gale)
/**
* Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling
* {@link LithiumHashPalette#idFor(Object)} through using a faster backing map and reducing pointer chasing.
@@ -30,11 +32,11 @@ public class LithiumHashPalette<T> implements Palette<T> {
private final PaletteResize<T> resizeHandler;
private final int indexBits;
private final Reference2IntMap<T> table;
private final Reference2IntOpenHashMap<T> table;
private T[] entries;
private int size = 0;
public LithiumHashPalette(IdMap<T> idList, PaletteResize<T> resizeHandler, int indexBits, T[] entries, Reference2IntMap<T> table, int size) {
private LithiumHashPalette(IdMap<T> idList, PaletteResize<T> resizeHandler, int indexBits, T[] entries, Reference2IntOpenHashMap<T> table, int size) {
this.idList = idList;
this.resizeHandler = resizeHandler;
this.indexBits = indexBits;
@@ -43,7 +45,7 @@ public class LithiumHashPalette<T> implements Palette<T> {
this.size = size;
}
public LithiumHashPalette(IdMap<T> idList, int bits, PaletteResize<T> resizeHandler, @NotNull List<T> list) {
public LithiumHashPalette(IdMap<T> idList, int bits, PaletteResize<T> resizeHandler, List<T> list) {
this(idList, bits, resizeHandler);
for (T t : list) {
@@ -120,14 +122,32 @@ public class LithiumHashPalette<T> implements Palette<T> {
}
@Override
public T valueFor(int id) {
public @NotNull T valueFor(int id) {
T[] entries = this.entries;
T entry = null;
if (id >= 0 && id < entries.length) {
return entries[id];
entry = entries[id];
}
return null;
if (entry != null) {
return entry;
} else {
throw this.missingPaletteEntryCrash(id);
}
}
private ReportedException missingPaletteEntryCrash(int id) {
try {
throw new MissingPaletteEntryException(id);
} catch (MissingPaletteEntryException e) {
CrashReport crashReport = CrashReport.forThrowable(e, "[Lithium] Getting Palette Entry");
CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk section");
crashReportCategory.setDetail("IndexBits", this.indexBits);
crashReportCategory.setDetail("Entries", this.entries.length + " Elements: " + Arrays.toString(this.entries));
crashReportCategory.setDetail("Table", this.table.size() + " Elements: " + this.table);
return new ReportedException(crashReport);
}
}
@Override
@@ -137,7 +157,7 @@ public class LithiumHashPalette<T> implements Palette<T> {
int entryCount = buf.readVarInt();
for (int i = 0; i < entryCount; ++i) {
this.addEntry(this.idList.byId(buf.readVarInt()));
this.addEntry(this.idList.byIdOrThrow(buf.readVarInt()));
}
}
@@ -167,10 +187,9 @@ public class LithiumHashPalette<T> implements Palette<T> {
return this.size;
}
@NotNull
@Override
public Palette<T> copy(@NotNull PaletteResize<T> resizeListener) {
return new LithiumHashPalette<>(this.idList, resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size);
public @NotNull Palette<T> copy(@NotNull PaletteResize<T> resizeHandler) {
return new LithiumHashPalette<>(this.idList, resizeHandler, this.indexBits, this.entries.clone(), this.table.clone(), this.size);
}
private void clear() {
@@ -180,17 +199,11 @@ public class LithiumHashPalette<T> implements Palette<T> {
}
public List<T> getElements() {
ImmutableList.Builder<T> builder = new ImmutableList.Builder<>();
for (T entry : this.entries) {
if (entry != null) {
builder.add(entry);
}
}
return builder.build();
T[] copy = Arrays.copyOf(this.entries, this.size);
return Arrays.asList(copy);
}
public static <A> Palette<A> create(int bits, IdMap<A> idList, PaletteResize<A> listener, List<A> list) {
return new LithiumHashPalette<>(idList, bits, listener, list);
}
}
}

View File

@@ -15,7 +15,9 @@ public class MixinConfiguration {
@PostProcess
public void postProcess() {
if (mixins.isEmpty()) return;
if (mixins.isEmpty()) {
return;
}
if (packageName == null) {
throw new IllegalStateException("Already define mixins: " + mixins + ", but no mixin package-name provided");
}

View File

@@ -8,6 +8,7 @@ import net.minecraft.world.level.GameRules;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.protocol.core.Context;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
@@ -16,6 +17,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@LeavesProtocol.Register(namespace = "appleskin")
public class AppleSkinProtocol implements LeavesProtocol {
@@ -32,7 +34,7 @@ public class AppleSkinProtocol implements LeavesProtocol {
private static final Map<ServerPlayer, Float> previousExhaustionLevels = new HashMap<>();
private static final Map<ServerPlayer, Boolean> previousNaturalRegeneration = new HashMap<>();
private static final Map<ServerPlayer, Set<String>> subscribedChannels = new HashMap<>();
private static final Map<UUID, Set<String>> subscribedChannels = new HashMap<>();
@Contract("_ -> new")
public static ResourceLocation id(String path) {
@@ -46,21 +48,24 @@ public class AppleSkinProtocol implements LeavesProtocol {
@ProtocolHandler.PlayerLeave
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
subscribedChannels.remove(player);
subscribedChannels.remove(player.getUUID());
resetPlayerData(player);
}
@ProtocolHandler.MinecraftRegister(onlyNamespace = true)
public static void onPlayerSubscribed(@NotNull ServerPlayer player, ResourceLocation id) {
subscribedChannels.computeIfAbsent(player, k -> new HashSet<>()).add(id.getPath());
public static void onPlayerSubscribed(@NotNull Context context, ResourceLocation id) {
subscribedChannels.computeIfAbsent(context.profile().getId(), k -> new HashSet<>()).add(id.getPath());
}
@ProtocolHandler.Ticker
public static void tick() {
for (Map.Entry<ServerPlayer, Set<String>> entry : subscribedChannels.entrySet()) {
ServerPlayer player = entry.getKey();
FoodData data = player.getFoodData();
for (Map.Entry<UUID, Set<String>> entry : subscribedChannels.entrySet()) {
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(entry.getKey());
if (player == null) {
continue;
}
FoodData data = player.getFoodData();
for (String channel : entry.getValue()) {
switch (channel) {
case "saturation" -> {
@@ -82,7 +87,7 @@ public class AppleSkinProtocol implements LeavesProtocol {
}
case "natural_regeneration" -> {
boolean regeneration = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION);
boolean regeneration = player.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION);
Boolean previousRegeneration = previousNaturalRegeneration.get(player);
if (previousRegeneration == null || regeneration != previousRegeneration) {
ProtocolUtils.sendBytebufPacket(player, NATURAL_REGENERATION_KEY, buf -> buf.writeBoolean(regeneration));

View File

@@ -134,7 +134,7 @@ public class BBORProtocol implements LeavesProtocol {
}
private static void sendStructureList(@NotNull ServerPlayer player) {
final Registry<Structure> structureRegistry = player.server.registryAccess().lookupOrThrow(Registries.STRUCTURE);
final Registry<Structure> structureRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.STRUCTURE);
final Set<String> structureIds = structureRegistry.entrySet().stream()
.map(e -> e.getKey().location().toString()).collect(Collectors.toSet());
ProtocolUtils.sendBytebufPacket(player, STRUCTURE_LIST_SYNC, buf -> {

View File

@@ -43,7 +43,7 @@ public class CarpetServerProtocol implements LeavesProtocol {
@ProtocolHandler.PayloadReceiver(payload = CarpetPayload.class)
private static void handleHello(@NotNull ServerPlayer player, @NotNull CarpetServerProtocol.CarpetPayload payload) {
if (payload.nbt.contains(HELLO)) {
LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with carpet " + payload.nbt.getString(HELLO));
LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with carpet " + payload.nbt.getString(HELLO).orElse("Unknown"));
CompoundTag data = new CompoundTag();
CarpetRules.write(data);
ProtocolUtils.sendPayloadPacket(player, new CarpetPayload(data));

View File

@@ -1,6 +1,5 @@
package org.leavesmc.leaves.protocol;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -10,6 +9,7 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.EnumProperty;
@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class LitematicaEasyPlaceProtocol {
@@ -51,9 +51,8 @@ public class LitematicaEasyPlaceProtocol {
BlockStateProperties.ROTATION_16
);
public static final ImmutableMap<Property<?>, ?> BLACKLISTED_PROPERTIES = ImmutableMap.of(
BlockStateProperties.WATERLOGGED, false,
BlockStateProperties.POWERED, false
public static final ImmutableSet<BiFunction<BlockState, BlockState, BlockState>> DYNAMIC_PROPERTIES = ImmutableSet.of(
(state, original) -> state.setValue(BlockStateProperties.WATERLOGGED, original.is(Blocks.WATER))
);
public static BlockState applyPlacementProtocol(BlockState state, BlockPlaceContext context) {
@@ -70,6 +69,14 @@ public class LitematicaEasyPlaceProtocol {
}
EnumProperty<Direction> property = CarpetAlternativeBlockPlacement.getFirstDirectionProperty(state);
BlockState original = context.getWorld().getBlockStateIfLoaded(context.pos);
if (original == null) {
return oldState;
}
for (var func : DYNAMIC_PROPERTIES) {
state = func.apply(state, original);
}
if (property != null && property != BlockStateProperties.VERTICAL_DIRECTION) {
state = applyDirectionProperty(state, context, property, protocolValue);
@@ -97,7 +104,7 @@ public class LitematicaEasyPlaceProtocol {
if (property != null && property.equals(p)) {
continue;
}
if (!WHITELISTED_PROPERTIES.contains(p) || BLACKLISTED_PROPERTIES.containsKey(p)) {
if (!WHITELISTED_PROPERTIES.contains(p)) {
continue;
}
@@ -129,12 +136,6 @@ public class LitematicaEasyPlaceProtocol {
LeavesLogger.LOGGER.warning("Exception trying to apply placement protocol value", e);
}
for (Map.Entry<Property<?>, ?> p : BLACKLISTED_PROPERTIES.entrySet()) {
if (state.hasProperty(p.getKey())) {
state = state.setValue((Property<T>) p.getKey(), (T) p.getValue());
}
}
if (state.canSurvive(context.getWorld(), context.getPos())) {
return state;
} else {

View File

@@ -31,6 +31,7 @@ import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
import org.leavesmc.leaves.util.TagUtil;
import java.util.HashMap;
import java.util.HashSet;
@@ -82,7 +83,7 @@ public class PcaSyncProtocol implements LeavesProtocol {
@ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class)
private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) {
BlockPos pos = payload.pos;
ServerLevel world = player.serverLevel();
ServerLevel world = player.level();
Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> {
BlockState blockState = world.getBlockState(pos);
@@ -122,7 +123,7 @@ public class PcaSyncProtocol implements LeavesProtocol {
private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) {
MinecraftServer server = MinecraftServer.getServer();
int entityId = payload.entityId;
ServerLevel world = player.serverLevel();
ServerLevel world = player.level();
Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> {
Entity entity = world.getEntity(entityId);
@@ -188,7 +189,7 @@ public class PcaSyncProtocol implements LeavesProtocol {
}
public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) {
CompoundTag nbt = entity.saveWithoutId(new CompoundTag());
CompoundTag nbt = TagUtil.saveEntity(entity);
ProtocolUtils.sendPayloadPacket(player, new UpdateEntityPayload(entity.level().dimension().location(), entity.getId(), nbt));
}

View File

@@ -0,0 +1,9 @@
package org.leavesmc.leaves.protocol.core;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.Connection;
import org.jetbrains.annotations.NotNull;
public record Context(@NotNull GameProfile profile, Connection connection) {
}

View File

@@ -0,0 +1,11 @@
package org.leavesmc.leaves.protocol.core;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.Nullable;
public record IdentifierSelector(@Nullable Context context, @Nullable ServerPlayer player) {
public Object select(ProtocolHandler.Stage stage) {
return stage == ProtocolHandler.Stage.CONFIGURATION ? context : player;
}
}

View File

@@ -218,27 +218,27 @@ public class LeavesProtocolManager {
codec.encode(ProtocolUtils.decorate(buf), payload);
}
public static void handlePayload(ServerPlayer player, LeavesCustomPayload payload) {
public static void handlePayload(IdentifierSelector selector, LeavesCustomPayload payload) {
PayloadReceiverInvokerHolder holder;
if ((holder = PAYLOAD_RECEIVERS.get(payload.getClass())) != null) {
holder.invoke(player, payload);
holder.invoke(selector, payload);
}
}
public static boolean handleBytebuf(ServerPlayer player, ResourceLocation location, ByteBuf buf) {
public static boolean handleBytebuf(IdentifierSelector selector, ResourceLocation location, ByteBuf buf) {
RegistryFriendlyByteBuf buf1 = ProtocolUtils.decorate(buf);
BytebufReceiverInvokerHolder holder;
if ((holder = STRICT_BYTEBUF_RECEIVERS.get(location.toString())) != null) {
holder.invoke(player, buf1);
holder.invoke(selector, buf1);
return true;
}
if ((holder = NAMESPACED_BYTEBUF_RECEIVERS.get(location.getNamespace())) != null) {
if (holder.invoke(player, buf1)) {
if (holder.invoke(selector, buf1)) {
return true;
}
}
for (var holder1 : GENERIC_BYTEBUF_RECEIVERS) {
if (holder1.invoke(player, buf1)) {
if (holder1.invoke(selector, buf1)) {
return true;
}
}
@@ -278,22 +278,22 @@ public class LeavesProtocolManager {
}
}
public static void handleMinecraftRegister(String channelId, ServerPlayer player) {
public static void handleMinecraftRegister(String channelId, IdentifierSelector selector) {
ResourceLocation location = ResourceLocation.tryParse(channelId);
if (location == null) {
return;
}
for (var wildHolder : WILD_MINECRAFT_REGISTER) {
wildHolder.invoke(player, location);
wildHolder.invoke(selector, location);
}
MinecraftRegisterInvokerHolder holder;
if ((holder = STRICT_MINECRAFT_REGISTER.get(location.toString())) != null) {
holder.invoke(player, location);
holder.invoke(selector, location);
}
if ((holder = NAMESPACED_MINECRAFT_REGISTER.get(location.getNamespace())) != null) {
holder.invoke(player, location);
holder.invoke(selector, location);
}
}

View File

@@ -1,5 +1,7 @@
package org.leavesmc.leaves.protocol.core;
import net.minecraft.server.level.ServerPlayer;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -16,6 +18,8 @@ public class ProtocolHandler {
@Retention(RetentionPolicy.RUNTIME)
public @interface PayloadReceiver {
Class<? extends LeavesCustomPayload> payload();
Stage stage() default Stage.GAME;
}
@Target(ElementType.METHOD)
@@ -24,6 +28,8 @@ public class ProtocolHandler {
String key() default "";
boolean onlyNamespace() default false;
Stage stage() default Stage.GAME;
}
@Target(ElementType.METHOD)
@@ -53,10 +59,27 @@ public class ProtocolHandler {
String key() default "";
boolean onlyNamespace() default false;
Stage stage() default Stage.CONFIGURATION;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReloadDataPack {
}
public enum Stage {
CONFIGURATION(Context.class),
GAME(ServerPlayer.class);
private final Class<?> identifier;
Stage(Class<?> identifier) {
this.identifier = identifier;
}
public Class<?> identifier() {
return identifier;
}
}
}

View File

@@ -11,7 +11,10 @@ import net.minecraft.network.protocol.common.custom.DiscardedPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -19,26 +22,50 @@ import java.util.function.Function;
public class ProtocolUtils {
private static final Function<ByteBuf, RegistryFriendlyByteBuf> bufDecorator = buf -> buf instanceof RegistryFriendlyByteBuf registry ? registry : new RegistryFriendlyByteBuf(buf, MinecraftServer.getServer().registryAccess());
private static final byte[] EMPTY = new byte[0];
public static String buildProtocolVersion(String protocol) {
return protocol + "-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE);
}
public static void sendEmptyPacket(ServerPlayer player, ResourceLocation id) {
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, null)));
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
}
public static void sendBytebufPacket(@NotNull ServerPlayer player, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
consumer.accept(buf);
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
}
public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) {
player.internalConnection.send(new ClientboundCustomPayloadPacket(payload));
player.connection.send(new ClientboundCustomPayloadPacket(payload));
}
public static void sendEmptyPacket(Context context, ResourceLocation id) {
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
}
public static void sendBytebufPacket(@NotNull Context context, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
consumer.accept(buf);
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
}
public static void sendPayloadPacket(Context context, CustomPacketPayload payload) {
context.connection().send(new ClientboundCustomPayloadPacket(payload));
}
public static RegistryFriendlyByteBuf decorate(ByteBuf buf) {
return bufDecorator.apply(buf);
}
public static IdentifierSelector createSelector(ServerCommonPacketListenerImpl common) {
ServerPlayer player = common instanceof ServerGamePacketListenerImpl game ? game.getPlayer() : null;
return new IdentifierSelector(new Context(common.profile, common.connection), player);
}
public static ByteBuf wrapNullable(byte @Nullable [] data) {
return data == null ? Unpooled.wrappedBuffer(EMPTY) : Unpooled.wrappedBuffer(data);
}
}

View File

@@ -14,6 +14,7 @@ public abstract class AbstractInvokerHolder<T> {
protected final T handler;
protected final Class<?> returnType;
protected final Class<?>[] parameterTypes;
protected final boolean isStatic;
protected AbstractInvokerHolder(LeavesProtocol owner, Method invoker, T handler, @Nullable Class<?> returnType, @NotNull Class<?>... parameterTypes) {
this.owner = owner;
@@ -21,6 +22,7 @@ public abstract class AbstractInvokerHolder<T> {
this.handler = handler;
this.returnType = returnType;
this.parameterTypes = parameterTypes;
this.isStatic = Modifier.isStatic(invoker.getModifiers());
validateMethodSignature();
}
@@ -58,7 +60,7 @@ public abstract class AbstractInvokerHolder<T> {
return null;
}
try {
if (Modifier.isStatic(invoker.getModifiers())) {
if (isStatic) {
return invoker.invoke(null, args);
} else {
return invoker.invoke(owner, args);

View File

@@ -1,7 +1,7 @@
package org.leavesmc.leaves.protocol.core.invoker;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
public class BytebufReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.BytebufReceiver> {
public BytebufReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.BytebufReceiver handler) {
super(owner, invoker, handler, null, ServerPlayer.class, FriendlyByteBuf.class);
super(owner, invoker, handler, null, handler.stage().identifier(), FriendlyByteBuf.class);
}
public boolean invoke(ServerPlayer player, FriendlyByteBuf buf) {
return invoke0(false, player, buf) instanceof Boolean b && b;
public boolean invoke(IdentifierSelector selector, FriendlyByteBuf buf) {
return invoke0(false, selector.select(handler.stage()), buf) instanceof Boolean b && b;
}
}
}

View File

@@ -1,7 +1,7 @@
package org.leavesmc.leaves.protocol.core.invoker;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
public class MinecraftRegisterInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.MinecraftRegister> {
public MinecraftRegisterInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.MinecraftRegister handler) {
super(owner, invoker, handler, null, ServerPlayer.class, ResourceLocation.class);
super(owner, invoker, handler, null, handler.stage().identifier(), ResourceLocation.class);
}
public void invoke(ServerPlayer player, ResourceLocation id) {
invoke0(false, player, id);
public void invoke(IdentifierSelector selector, ResourceLocation id) {
invoke0(false, selector.select(handler.stage()), id);
}
}

View File

@@ -1,6 +1,6 @@
package org.leavesmc.leaves.protocol.core.invoker;
import net.minecraft.server.level.ServerPlayer;
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
public class PayloadReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.PayloadReceiver> {
public PayloadReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.PayloadReceiver handler) {
super(owner, invoker, handler, null, ServerPlayer.class, handler.payload());
super(owner, invoker, handler, null, handler.stage().identifier(), handler.payload());
}
public void invoke(ServerPlayer player, LeavesCustomPayload payload) {
invoke0(false, player, payload);
public void invoke(IdentifierSelector selector, LeavesCustomPayload payload) {
invoke0(false, selector.select(handler.stage()), payload);
}
}

View File

@@ -92,7 +92,7 @@ import java.util.Set;
public class JadeProtocol implements LeavesProtocol {
public static final String PROTOCOL_ID = "jade";
public static final String PROTOCOL_VERSION = "7";
public static final String PROTOCOL_VERSION = "8";
public static final HierarchyLookup<IServerDataProvider<EntityAccessor>> entityDataProviders = new HierarchyLookup<>(Entity.class);
public static final PairHierarchyLookup<IServerDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
public static final WrappedHierarchyLookup<IServerExtensionProvider<ItemStack>> itemStorageProviders = WrappedHierarchyLookup.forAccessor();

View File

@@ -3,13 +3,13 @@ package org.leavesmc.leaves.protocol.jade.accessor;
import net.minecraft.nbt.Tag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamEncoder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.Nullable;
public interface Accessor<T extends HitResult> {
Level getLevel();
ServerLevel getLevel();
Player getPlayer();

View File

@@ -5,8 +5,8 @@ import net.minecraft.nbt.ByteArrayTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamEncoder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.HitResult;
import org.apache.commons.lang3.ArrayUtils;
@@ -14,20 +14,20 @@ import java.util.function.Supplier;
public abstract class AccessorImpl<T extends HitResult> implements Accessor<T> {
private final Level level;
private final ServerLevel level;
private final Player player;
private final Supplier<T> hit;
protected boolean verify;
private RegistryFriendlyByteBuf buffer;
public AccessorImpl(Level level, Player player, Supplier<T> hit) {
public AccessorImpl(ServerLevel level, Player player, Supplier<T> hit) {
this.level = level;
this.player = player;
this.hit = hit;
}
@Override
public Level getLevel() {
public ServerLevel getLevel() {
return level;
}

View File

@@ -1,8 +1,8 @@
package org.leavesmc.leaves.protocol.jade.accessor;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
@@ -23,7 +23,7 @@ public interface BlockAccessor extends Accessor<BlockHitResult> {
@ApiStatus.NonExtendable
interface Builder {
Builder level(Level level);
Builder level(ServerLevel level);
Builder player(Player player);

View File

@@ -6,10 +6,10 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -61,14 +61,14 @@ public class BlockAccessorImpl extends AccessorImpl<BlockHitResult> implements B
}
public static class Builder implements BlockAccessor.Builder {
private Level level;
private ServerLevel level;
private Player player;
private BlockHitResult hit;
private BlockState blockState = Blocks.AIR.defaultBlockState();
private Supplier<BlockEntity> blockEntity;
@Override
public Builder level(Level level) {
public Builder level(ServerLevel level) {
this.level = level;
return this;
}

Some files were not shown because too many files have changed in this diff Show More