mirror of
https://github.com/tanyaofei/minecraft-fakeplayer.git
synced 2025-09-14 11:16:46 +08:00
Merge branch '0.2.0' of github.com:tanyaofei/minecraft-fakeplayer into 0.2.0
# Conflicts: # fakeplayer-api/src/main/java/io/github/hello09x/fakeplayer/api/action/ActionType.java # fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/command/CommandRegistry.java # fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/command/impl/ConfigCommand.java # fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/command/impl/RotationCommand.java # fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/listener/RefillListener.java # fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/repository/model/Config.java
This commit is contained in:
commit
cda96bd262
@ -49,8 +49,9 @@ public enum ActionType implements Translatable {
|
||||
|
||||
final String translationKey;
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull String translationKey() {
|
||||
return translationKey;
|
||||
return this.translationKey;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,9 @@ package io.github.hello09x.fakeplayer.api.action;
|
||||
import io.github.hello09x.fakeplayer.api.action.impl.*;
|
||||
import io.github.hello09x.fakeplayer.api.spi.Action;
|
||||
import io.github.hello09x.fakeplayer.api.spi.ActionTicker;
|
||||
import io.github.hello09x.fakeplayer.api.spi.VersionSupport;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSBridge;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -18,14 +17,14 @@ public abstract class BaseActionTicker implements ActionTicker {
|
||||
protected ActionSetting setting;
|
||||
|
||||
public BaseActionTicker(@NotNull Player player, @NotNull ActionType action, @NotNull ActionSetting setting) {
|
||||
var versionSupport = Objects.requireNonNull(VersionSupport.getInstance());
|
||||
var bridge = Objects.requireNonNull(NMSBridge.getInstance());
|
||||
this.setting = setting;
|
||||
this.action = switch (action) {
|
||||
case JUMP -> new JumpAction(versionSupport.player(player));
|
||||
case LOOK_AT_NEAREST_ENTITY -> new LookAtEntityAction(versionSupport.player(player));
|
||||
case DROP_ITEM -> new DropItemAction(versionSupport.player(player));
|
||||
case DROP_STACK -> new DropStackAction(versionSupport.player(player));
|
||||
case DROP_INVENTORY -> new DropInventoryAction(versionSupport.player(player));
|
||||
case JUMP -> new JumpAction(bridge.player(player));
|
||||
case LOOK_AT_NEAREST_ENTITY -> new LookAtEntityAction(bridge.player(player));
|
||||
case DROP_ITEM -> new DropItemAction(bridge.player(player));
|
||||
case DROP_STACK -> new DropStackAction(bridge.player(player));
|
||||
case DROP_INVENTORY -> new DropInventoryAction(bridge.player(player));
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
@ -11,14 +11,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
public interface VersionSupport {
|
||||
public interface NMSBridge {
|
||||
|
||||
static @Nullable VersionSupport getInstance() {
|
||||
static @Nullable NMSBridge getInstance() {
|
||||
return ServiceLoader
|
||||
.load(VersionSupport.class, VersionSupport.class.getClassLoader())
|
||||
.load(NMSBridge.class, NMSBridge.class.getClassLoader())
|
||||
.stream()
|
||||
.map(ServiceLoader.Provider::get)
|
||||
.filter(VersionSupport::isSupported)
|
||||
.filter(NMSBridge::isSupported)
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package io.github.hello09x.fakeplayer.api.spi;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface NMSGamePacketListener {
|
||||
|
||||
int MESSAGE_HISTORY_SIZE = 50;
|
||||
|
||||
/**
|
||||
* @return 获取最后一条消息
|
||||
*/
|
||||
@Nullable ReceivedMessage getLastMessage();
|
||||
|
||||
/**
|
||||
* 获取最近消息消息
|
||||
*
|
||||
* @return 最近消息
|
||||
*/
|
||||
@NotNull List<ReceivedMessage> getRecentMessages();
|
||||
|
||||
record ReceivedMessage(
|
||||
int id,
|
||||
Component content
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -15,7 +15,7 @@ public interface NMSNetwork {
|
||||
* @param player 假人玩家
|
||||
* @param address 虚拟地址
|
||||
*/
|
||||
void bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address);
|
||||
@NotNull NMSGamePacketListener bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address);
|
||||
|
||||
/**
|
||||
* 绑定一个虚拟的登陆连接
|
||||
|
@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface NMSServerPlayer {
|
||||
|
||||
|
||||
/**
|
||||
* @return 返回 bukkit 的 Player 对象
|
||||
*/
|
||||
|
@ -0,0 +1,35 @@
|
||||
package io.github.hello09x.fakeplayer.api.utils;
|
||||
|
||||
import io.github.hello09x.bedrock.util.LazyInit;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
public abstract class ClientboundSystemChatPackets {
|
||||
|
||||
private final static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
private final static LazyInit<MethodHandle> ADVENTURE$CONTENT = new LazyInit<>();
|
||||
|
||||
public static @Nullable Component getAdventureContent(@NotNull Object packet) {
|
||||
var adventure$content = ADVENTURE$CONTENT.computeIfAbsent(() -> {
|
||||
try {
|
||||
return LOOKUP.findVirtual(packet.getClass(), "adventure$content", MethodType.methodType(Component.class));
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}, true);
|
||||
|
||||
if (adventure$content != null) {
|
||||
try {
|
||||
return (Component) adventure$content.invoke(packet);
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -3,7 +3,7 @@ package io.github.hello09x.fakeplayer.core;
|
||||
import io.github.hello09x.bedrock.i18n.I18n;
|
||||
import io.github.hello09x.bedrock.i18n.I18nSupported;
|
||||
import io.github.hello09x.bedrock.util.RegistrablePlugin;
|
||||
import io.github.hello09x.fakeplayer.api.spi.VersionSupport;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSBridge;
|
||||
import io.github.hello09x.fakeplayer.core.command.CommandRegistry;
|
||||
import io.github.hello09x.fakeplayer.core.config.FakeplayerConfig;
|
||||
import io.github.hello09x.fakeplayer.core.listener.FakeplayerListener;
|
||||
@ -23,14 +23,14 @@ public final class Main extends RegistrablePlugin implements I18nSupported {
|
||||
private static Main instance;
|
||||
|
||||
@Getter
|
||||
private static VersionSupport versionSupport;
|
||||
private static NMSBridge bridge;
|
||||
|
||||
private I18n i18n;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
versionSupport = VersionSupport.getInstance();
|
||||
if (versionSupport == null) {
|
||||
bridge = NMSBridge.getInstance();
|
||||
if (bridge == null) {
|
||||
throw new ExceptionInInitializerError("Unsupported Minecraft version: " + Bukkit.getMinecraftVersion());
|
||||
}
|
||||
this.i18n = new I18n(this, "message/message");
|
||||
|
@ -3,6 +3,7 @@ package io.github.hello09x.fakeplayer.core.command;
|
||||
import dev.jorel.commandapi.CommandPermission;
|
||||
import io.github.hello09x.bedrock.command.Usage;
|
||||
import io.github.hello09x.bedrock.i18n.I18n;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionSetting;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionType;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import io.github.hello09x.fakeplayer.core.command.impl.*;
|
||||
@ -22,6 +23,7 @@ public class CommandRegistry {
|
||||
|
||||
private final static I18n i18n = Main.i18n();
|
||||
|
||||
|
||||
public static void register() {
|
||||
command("fakeplayer")
|
||||
.withAliases("fp")
|
||||
@ -107,21 +109,6 @@ public class CommandRegistry {
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executesPlayer(DistanceCommand.instance::distance),
|
||||
command("drop")
|
||||
.withPermission(Permission.drop)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executes(DropCommand.instance.drop()),
|
||||
command("dropstack")
|
||||
.withPermission(Permission.dropstack)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executes(DropCommand.instance.dropstack()),
|
||||
command("dropinv")
|
||||
.withPermission(Permission.dropinv)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executes(DropCommand.instance.dropinv()),
|
||||
command("skin")
|
||||
.withPermission(Permission.skin)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
@ -174,30 +161,60 @@ public class CommandRegistry {
|
||||
.withPermission(Permission.tp)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executesPlayer(TpCommand.instance::tp),
|
||||
.executesPlayer(TeleportCommand.instance::tp),
|
||||
command("tphere")
|
||||
.withPermission(Permission.tphere)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executesPlayer(TpCommand.instance::tphere),
|
||||
.executesPlayer(TeleportCommand.instance::tphere),
|
||||
command("tps")
|
||||
.withPermission(Permission.tps)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(target("name"))
|
||||
.executesPlayer(TpCommand.instance::tps),
|
||||
.executesPlayer(TeleportCommand.instance::tps),
|
||||
|
||||
command("attack")
|
||||
.withPermission(Permission.attack)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.ATTACK)),
|
||||
.withSubcommands(newActionCommands(ActionType.ATTACK))
|
||||
.executes(ActionCommand.instance.action(ActionType.ATTACK, ActionSetting.once())),
|
||||
command("mine")
|
||||
.withPermission(Permission.mine)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.MINE)),
|
||||
.withSubcommands(newActionCommands(ActionType.MINE))
|
||||
.executes(ActionCommand.instance.action(ActionType.MINE, ActionSetting.once())),
|
||||
command("use")
|
||||
.withPermission(Permission.use)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.USE)),
|
||||
.withSubcommands(newActionCommands(ActionType.USE))
|
||||
.executes(ActionCommand.instance.action(ActionType.USE, ActionSetting.once())),
|
||||
command("jump")
|
||||
.withPermission(Permission.jump)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.JUMP))
|
||||
.executes(ActionCommand.instance.action(ActionType.JUMP, ActionSetting.once())),
|
||||
command("drop")
|
||||
.withPermission(Permission.drop)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.DROP_ITEM))
|
||||
.executes(ActionCommand.instance.action(ActionType.DROP_ITEM, ActionSetting.once())),
|
||||
command("dropstack")
|
||||
.withPermission(Permission.dropstack)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.DROP_STACK))
|
||||
.executes(ActionCommand.instance.action(ActionType.DROP_STACK, ActionSetting.once())),
|
||||
command("dropinv")
|
||||
.withPermission(Permission.dropinv)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.DROP_INVENTORY))
|
||||
.executes(ActionCommand.instance.action(ActionType.DROP_INVENTORY, ActionSetting.once())),
|
||||
command("sneak")
|
||||
.withPermission(Permission.sneak)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(
|
||||
target("name"),
|
||||
literals("sneaking", List.of("true", "false")))
|
||||
.executes(SneakCommand.instance::sneak),
|
||||
command("refill")
|
||||
.withPermission(RefillCommand.PERMISSION)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
@ -206,17 +223,6 @@ public class CommandRegistry {
|
||||
literals("enabled", List.of("true", "false"))
|
||||
)
|
||||
.executes(RefillCommand.instance::refill),
|
||||
command("jump")
|
||||
.withPermission(Permission.jump)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withSubcommands(newActionCommands(ActionType.JUMP)),
|
||||
command("sneak")
|
||||
.withPermission(Permission.sneak)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
.withOptionalArguments(
|
||||
literals("sneaking", List.of("true", "false")),
|
||||
target("name"))
|
||||
.executes(SneakCommand.instance::sneak),
|
||||
command("look")
|
||||
.withPermission(Permission.look)
|
||||
.withRequirement(CommandSupports::hasTarget)
|
||||
@ -306,7 +312,8 @@ public class CommandRegistry {
|
||||
Usage.of("left", i18n.asString("fakeplayer.command.move.left.description")),
|
||||
Usage.of("right", i18n.asString("fakeplayer.command.move.right.description"))
|
||||
)
|
||||
),
|
||||
)
|
||||
.executes(MoveCommand.instance.move(1, 0)),
|
||||
|
||||
command("ride")
|
||||
.withPermission(Permission.ride)
|
||||
@ -364,6 +371,14 @@ public class CommandRegistry {
|
||||
command("killall")
|
||||
.withPermission(CommandPermission.OP)
|
||||
.executes(KillallCommand.instance::killall),
|
||||
command("msg")
|
||||
.withPermission(CommandPermission.OP)
|
||||
.withOptionalArguments(
|
||||
int32("size", 1),
|
||||
int32("skip", 0),
|
||||
target("name")
|
||||
)
|
||||
.executes(MsgCommand.instance::msg),
|
||||
command("reload")
|
||||
.withPermission(CommandPermission.OP)
|
||||
.executes(ReloadCommand.instance::reload)
|
||||
|
@ -4,6 +4,7 @@ import dev.jorel.commandapi.CommandAPI;
|
||||
import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException;
|
||||
import dev.jorel.commandapi.executors.CommandArguments;
|
||||
import dev.jorel.commandapi.wrappers.CommandResult;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.core.command.Permission;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -11,8 +12,12 @@ import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.Component.textOfChildren;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class CmdCommand extends AbstractCommand {
|
||||
@ -28,15 +33,28 @@ public class CmdCommand extends AbstractCommand {
|
||||
throw CommandAPI.failWithString(i18n.asString("fakeplayer.command.cmd.error.no-permission"));
|
||||
}
|
||||
|
||||
if (name.equals("fakeplayer") || name.equals("fp")) {
|
||||
if (!sender.isOp() && (name.equals("fakeplayer") || name.equals("fp"))) {
|
||||
throw CommandAPI.failWithString(i18n.asString("fakeplayer.command.cmd.error.no-permission"));
|
||||
}
|
||||
|
||||
var messageId = Optional.ofNullable(fakeplayerManager.getLastMessage(target))
|
||||
.map(NMSGamePacketListener.ReceivedMessage::id)
|
||||
.orElse(-1);
|
||||
if (!command.execute(target)) {
|
||||
throw CommandAPI.failWithString(i18n.asString("fakeplayer.command.cmd.error.execute-failed"));
|
||||
}
|
||||
|
||||
sender.sendMessage(i18n.translate("fakeplayer.command.cmd.success.execute", GRAY));
|
||||
var message = fakeplayerManager.getLastMessage(target);
|
||||
if (message != null && message.id() != messageId) {
|
||||
sender.sendMessage(textOfChildren(
|
||||
text(">> ", GRAY),
|
||||
text(target.getName(), WHITE),
|
||||
text(": ", GRAY),
|
||||
message.content()
|
||||
));
|
||||
} else {
|
||||
sender.sendMessage(i18n.translate("fakeplayer.command.cmd.success.execute", GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class ConfigCommand extends AbstractCommand {
|
||||
manager.setConfig(sender, config, value);
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.config.set.success") + "</gray>",
|
||||
Placeholder.component("option", i18n.translate(config, GOLD)),
|
||||
Placeholder.component("option", i18n.translate(config.translationKey(), GOLD)),
|
||||
Placeholder.component("value", text(value.toString(), WHITE))
|
||||
));
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ public class DistanceCommand extends AbstractCommand {
|
||||
|
||||
public final static DistanceCommand instance = new DistanceCommand();
|
||||
|
||||
public void distance(
|
||||
@NotNull Player sender,
|
||||
@NotNull CommandArguments args
|
||||
) throws WrapperCommandSyntaxException {
|
||||
/**
|
||||
* 查看距离
|
||||
*/
|
||||
public void distance(@NotNull Player sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = super.getTarget(sender, args);
|
||||
var from = target.getLocation().toBlockLocation();
|
||||
var to = sender.getLocation().toBlockLocation();
|
||||
|
@ -1,27 +0,0 @@
|
||||
package io.github.hello09x.fakeplayer.core.command.impl;
|
||||
|
||||
import dev.jorel.commandapi.executors.CommandExecutor;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionSetting;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class DropCommand extends AbstractCommand {
|
||||
|
||||
public final static DropCommand instance = new DropCommand();
|
||||
|
||||
public @NotNull CommandExecutor drop() {
|
||||
return ActionCommand.instance.action(ActionType.DROP_ITEM, ActionSetting.once());
|
||||
}
|
||||
|
||||
public @NotNull CommandExecutor dropstack() {
|
||||
return ActionCommand.instance.action(ActionType.DROP_STACK, ActionSetting.once());
|
||||
}
|
||||
|
||||
public @NotNull CommandExecutor dropinv() {
|
||||
return ActionCommand.instance.action(ActionType.DROP_INVENTORY, ActionSetting.once());
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,9 @@ public class InvseeCommand extends AbstractCommand {
|
||||
|
||||
public final static InvseeCommand instance = new InvseeCommand();
|
||||
|
||||
/**
|
||||
* 查看背包
|
||||
*/
|
||||
public void invsee(@NotNull Player sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = super.getTarget(sender, args);
|
||||
if (!Objects.equals(sender.getLocation().getWorld(), target.getLocation().getWorld())) {
|
||||
|
@ -4,10 +4,6 @@ import dev.jorel.commandapi.executors.CommandExecutor;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MoveCommand extends AbstractCommand {
|
||||
@ -20,7 +16,7 @@ public class MoveCommand extends AbstractCommand {
|
||||
public CommandExecutor move(float forward, float strafing) {
|
||||
return (sender, args) -> {
|
||||
var target = getTarget(sender, args);
|
||||
var handle = Main.getVersionSupport().player(target);
|
||||
var handle = Main.getBridge().player(target);
|
||||
float vel = target.isSneaking() ? 0.3F : 1.0F;
|
||||
if (forward != 0.0F) {
|
||||
handle.setZza(vel * forward);
|
||||
@ -28,10 +24,6 @@ public class MoveCommand extends AbstractCommand {
|
||||
if (strafing != 0.0F) {
|
||||
handle.setXxa(vel * strafing);
|
||||
}
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.move.success") + "</gray>",
|
||||
Placeholder.component("name", text(target.getName(), WHITE))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.github.hello09x.fakeplayer.core.command.impl;
|
||||
|
||||
import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException;
|
||||
import dev.jorel.commandapi.executors.CommandArguments;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MsgCommand extends AbstractCommand {
|
||||
|
||||
public final static MsgCommand instance = new MsgCommand();
|
||||
|
||||
public void msg(@NotNull CommandSender sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = super.getTarget(sender, args);
|
||||
int skip = (int) args.getOptional("skip").orElse(0);
|
||||
int size = (int) args.getOptional("size").orElse(10);
|
||||
|
||||
var messages = fakeplayerManager.getMessages(target, skip, size);
|
||||
for (var message : messages) {
|
||||
sender.sendMessage(message.content());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,7 +16,7 @@ public class RespawnCommand extends AbstractCommand {
|
||||
|
||||
public void respawn(@NotNull CommandSender sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = super.getTarget(sender, args, Entity::isDead);
|
||||
Main.getVersionSupport().player(target).respawn();
|
||||
Main.getBridge().player(target).respawn();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class RideCommand extends AbstractCommand {
|
||||
if (entities.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Main.getVersionSupport().player(target).startRiding(entities.get(0), true);
|
||||
Main.getBridge().player(target).startRiding(entities.get(0), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ public class RideCommand extends AbstractCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
Main.getVersionSupport().player(target).startRiding(entity, true);
|
||||
Main.getBridge().player(target).startRiding(entity, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +63,7 @@ public class RideCommand extends AbstractCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
Main.getVersionSupport().player(target).startRiding(entity, true);
|
||||
Main.getBridge().player(target).startRiding(entity, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,14 +84,14 @@ public class RideCommand extends AbstractCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
Main.getVersionSupport().player(target).startRiding(sender, true);
|
||||
Main.getBridge().player(target).startRiding(sender, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止骑行
|
||||
*/
|
||||
public void stopRiding(@NotNull CommandSender sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
Main.getVersionSupport().player(getTarget(sender, args)).stopRiding();
|
||||
Main.getBridge().player(getTarget(sender, args)).stopRiding();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ import io.github.hello09x.fakeplayer.core.util.Mth;
|
||||
import io.papermc.paper.entity.LookAnchor;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -19,21 +17,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class RotationCommand extends AbstractCommand {
|
||||
|
||||
public final static RotationCommand instance = new RotationCommand();
|
||||
|
||||
private static String toLocationString(@NotNull Location location) {
|
||||
return StringUtils.joinWith(", ",
|
||||
Mth.floor(location.getX(), 0.5),
|
||||
Mth.floor(location.getY(), 0.5),
|
||||
Mth.floor(location.getZ(), 0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* 看向给定坐标
|
||||
*/
|
||||
@ -42,11 +31,6 @@ public class RotationCommand extends AbstractCommand {
|
||||
var target = getTarget(sender, args);
|
||||
var location = Objects.requireNonNull((Location) args.get("location"));
|
||||
target.lookAt(location, LookAnchor.EYES);
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.look.success") + "</gray>",
|
||||
Placeholder.component("name", text(target.getName(), WHITE)),
|
||||
Placeholder.component("direction", text(toLocationString(location), WHITE))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,12 +40,6 @@ public class RotationCommand extends AbstractCommand {
|
||||
return (sender, args) -> {
|
||||
var target = getTarget(sender, args);
|
||||
look(target, direction);
|
||||
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.look.success") + "</gray>",
|
||||
Placeholder.component("name", text(target.getName(), WHITE)),
|
||||
Placeholder.component("direction", i18n.translate(direction, WHITE))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@ -86,7 +64,7 @@ public class RotationCommand extends AbstractCommand {
|
||||
* 看向指定方向
|
||||
*/
|
||||
private void look(@NotNull Player player, float yaw, float pitch) {
|
||||
var handle = Main.getVersionSupport().player(player);
|
||||
var handle = Main.getBridge().player(player);
|
||||
handle.setYRot(yaw % 360);
|
||||
handle.setXRot(Mth.clamp(pitch, -90, 90));
|
||||
}
|
||||
@ -98,10 +76,6 @@ public class RotationCommand extends AbstractCommand {
|
||||
return (sender, args) -> {
|
||||
var target = getTarget(sender, args);
|
||||
this.turn(target, yaw, pitch);
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.turn.success") + "</gray>",
|
||||
Placeholder.component("name", text(target.getName(), WHITE))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@ -112,10 +86,6 @@ public class RotationCommand extends AbstractCommand {
|
||||
var target = getTarget(sender, args);
|
||||
var rotation = Objects.requireNonNull((Rotation) args.get("rotation"));
|
||||
this.turn(target, rotation.getYaw(), rotation.getPitch());
|
||||
sender.sendMessage(miniMessage.deserialize(
|
||||
"<gray>" + i18n.asString("fakeplayer.command.turn.success") + "</gray>",
|
||||
Placeholder.component("name", text(target.getName(), WHITE))
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.hello09x.fakeplayer.core.command.impl;
|
||||
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import dev.jorel.commandapi.exceptions.WrapperCommandSyntaxException;
|
||||
import dev.jorel.commandapi.executors.CommandArguments;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
@ -7,6 +8,7 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -33,31 +35,41 @@ public class SkinCommand extends AbstractCommand {
|
||||
* 复制皮肤
|
||||
*/
|
||||
public void skin(@NotNull CommandSender sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var player = Objects.requireNonNull((OfflinePlayer) args.get("player"));
|
||||
var target = getTarget(sender, args);
|
||||
var profile = target.getPlayerProfile();
|
||||
|
||||
var from = player.getPlayerProfile();
|
||||
var copy = (Runnable) () -> {
|
||||
profile.setTextures(from.getTextures());
|
||||
from.getProperties().stream().filter(p -> p.getName().equals("textures")).findAny().ifPresent(profile::setProperty);
|
||||
target.setPlayerProfile(profile);
|
||||
};
|
||||
|
||||
if (!from.isComplete()) {
|
||||
if (!sender.isOp() && cd.computeIfAbsent(sender, k -> new MutableInt()).getValue() != 0) {
|
||||
sender.sendMessage(i18n.translate("fakeplayer.command.skin.error.too-many-operations", RED));
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> {
|
||||
if (from.complete()) {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), copy);
|
||||
}
|
||||
cd.computeIfAbsent(sender, k -> new MutableInt()).setValue(COOL_DOWN_TICKS);
|
||||
});
|
||||
} else {
|
||||
copy.run();
|
||||
var player = Objects.requireNonNull((OfflinePlayer) args.get("player"));
|
||||
var profile = player.getPlayerProfile();
|
||||
if (profile.hasTextures()) {
|
||||
this.setTextures(target, profile);
|
||||
return;
|
||||
}
|
||||
|
||||
// 拷贝离线玩家皮肤
|
||||
if (!sender.isOp() && cd.computeIfAbsent(sender, k -> new MutableInt()).getValue() != 0) {
|
||||
// 限制请求数, 防止 mojang api 限流
|
||||
sender.sendMessage(i18n.translate("fakeplayer.command.skin.error.too-many-operations", RED));
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), () -> {
|
||||
// complete 会发起网络请求, 需要异步处理
|
||||
if (profile.complete()) {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> this.setTextures(target, profile));
|
||||
}
|
||||
cd.computeIfAbsent(sender, k -> new MutableInt()).setValue(COOL_DOWN_TICKS);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置皮肤
|
||||
*
|
||||
* @param target 目标玩家
|
||||
* @param source 皮肤来源
|
||||
*/
|
||||
public void setTextures(@NotNull Player target, @NotNull PlayerProfile source) {
|
||||
var profile = target.getPlayerProfile();
|
||||
profile.setTextures(source.getTextures());
|
||||
source.getProperties().stream().filter(p -> p.getName().equals("textures")).findAny().ifPresent(profile::setProperty);
|
||||
target.setPlayerProfile(profile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class TpCommand extends AbstractCommand {
|
||||
public class TeleportCommand extends AbstractCommand {
|
||||
|
||||
public final static TpCommand instance = new TpCommand();
|
||||
public final static TeleportCommand instance = new TeleportCommand();
|
||||
|
||||
public void tp(@NotNull Player sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = getTarget(sender, args);
|
||||
@ -29,8 +29,8 @@ public class TpCommand extends AbstractCommand {
|
||||
public void tps(@NotNull Player sender, @NotNull CommandArguments args) throws WrapperCommandSyntaxException {
|
||||
var target = getTarget(sender, args);
|
||||
|
||||
var l1 = sender.getLocation().clone();
|
||||
var l2 = target.getLocation().clone();
|
||||
var l1 = sender.getLocation();
|
||||
var l2 = target.getLocation();
|
||||
|
||||
Teleportor.teleportAndSound(target, l1);
|
||||
Teleportor.teleportAndSound(sender, l2);
|
@ -5,6 +5,7 @@ import io.github.hello09x.bedrock.i18n.I18n;
|
||||
import io.github.hello09x.bedrock.task.Tasks;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionSetting;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionType;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSServerPlayer;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import io.github.hello09x.fakeplayer.core.command.impl.RefillCommand;
|
||||
@ -26,6 +27,7 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.time.LocalDateTime;
|
||||
@ -34,7 +36,9 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
import static net.kyori.adventure.text.format.TextDecoration.ITALIC;
|
||||
|
||||
public class FakePlayer {
|
||||
|
||||
@ -77,6 +81,10 @@ public class FakePlayer {
|
||||
@NotNull
|
||||
private final UUID uuid;
|
||||
|
||||
@UnknownNullability
|
||||
@Getter
|
||||
private NMSGamePacketListener connection;
|
||||
|
||||
public FakePlayer(
|
||||
@NotNull CommandSender creator,
|
||||
@NotNull String creatorIp,
|
||||
@ -89,7 +97,7 @@ public class FakePlayer {
|
||||
this.creator = creator;
|
||||
this.creatorIp = creatorIp;
|
||||
this.sequenceName = sequenceName;
|
||||
this.handle = Main.getVersionSupport().server(Bukkit.getServer()).newPlayer(uuid, name);
|
||||
this.handle = Main.getBridge().server(Bukkit.getServer()).newPlayer(uuid, name);
|
||||
this.player = handle.getPlayer();
|
||||
this.ticker = new FakeplayerTicker(this, removeAt);
|
||||
|
||||
@ -97,6 +105,11 @@ public class FakePlayer {
|
||||
player.setSleepingIgnored(true);
|
||||
handle.setPlayBefore();
|
||||
handle.unpersistAdvancements(Main.getInstance()); // 可避免一些插件的第一次入服欢迎信息
|
||||
|
||||
var displayName = text(player.getName(), GRAY, ITALIC);
|
||||
player.playerListName(displayName);
|
||||
player.displayName(displayName);
|
||||
player.customName(displayName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,9 +164,9 @@ public class FakePlayer {
|
||||
FakeplayerManager.instance.setRefillable(player, true);
|
||||
}
|
||||
|
||||
var network = Main.getVersionSupport().network();
|
||||
network.bindEmptyServerGamePacketListener(Bukkit.getServer(), this.player, address);
|
||||
var network = Main.getBridge().network();
|
||||
network.bindEmptyLoginPacketListener(Bukkit.getServer(), this.player, address);
|
||||
this.connection = network.bindEmptyServerGamePacketListener(Bukkit.getServer(), this.player, address);
|
||||
handle.configClientOptions(); // 处理皮肤设置问题
|
||||
|
||||
var spawnAt = option.spawnAt().clone();
|
||||
@ -199,10 +212,6 @@ public class FakePlayer {
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull UUID getUUID() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return this.player.isOnline();
|
||||
}
|
||||
@ -248,4 +257,7 @@ public class FakePlayer {
|
||||
return creator.getClass() == sender.getClass() && creator.getName().equals(sender.getName());
|
||||
}
|
||||
|
||||
public @NotNull UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ public class RefillListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
}, 1);
|
||||
}, 1); // delay 1 是因为要等手上的物品在此 tick 消耗完
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +159,7 @@ public class RefillListener implements Listener {
|
||||
var replacement = inv.getItem(i);
|
||||
if (replacement != null && replacement.isSimilar(item)) {
|
||||
inv.setItem(slot, replacement);
|
||||
inv.setItem(i, new ItemStack(Material.AIR));
|
||||
inv.setItem(i, null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -184,7 +184,7 @@ public class RefillListener implements Listener {
|
||||
BlockFace.NORTH
|
||||
);
|
||||
if (!openEvent.callEvent()) {
|
||||
// Could not open this inventory cause by other plugins
|
||||
// 无法打开箱子
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ public class RefillListener implements Listener {
|
||||
var view = target.getOpenInventory();
|
||||
var inv = view.getTopInventory();
|
||||
if (inv.getType() != InventoryType.CHEST) {
|
||||
// closed by other plugins
|
||||
// 被其他插件取消了, 变成打开自己的背包了
|
||||
return;
|
||||
}
|
||||
for (int i = inv.getSize() - 1; i >= 0; i--) {
|
||||
@ -210,16 +210,17 @@ public class RefillListener implements Listener {
|
||||
InventoryAction.MOVE_TO_OTHER_INVENTORY
|
||||
);
|
||||
if (!event.callEvent()) {
|
||||
// canceled by other plugins
|
||||
// 无法操作箱子
|
||||
target.closeInventory(InventoryCloseEvent.Reason.PLAYER);
|
||||
return;
|
||||
}
|
||||
|
||||
target.getInventory().setItem(slot, replacement);
|
||||
inv.setItem(i, new ItemStack(Material.AIR));
|
||||
break;
|
||||
inv.setItem(i, null);
|
||||
target.closeInventory(InventoryCloseEvent.Reason.PLAYER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
target.closeInventory(InventoryCloseEvent.Reason.PLAYER);
|
||||
}, 20);
|
||||
return;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import io.github.hello09x.bedrock.util.Components;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionSetting;
|
||||
import io.github.hello09x.fakeplayer.api.action.ActionType;
|
||||
import io.github.hello09x.fakeplayer.api.constant.ConstantPool;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener.ReceivedMessage;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import io.github.hello09x.fakeplayer.core.config.FakeplayerConfig;
|
||||
import io.github.hello09x.fakeplayer.core.entity.FakePlayer;
|
||||
@ -35,10 +37,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -74,7 +73,7 @@ public class FakeplayerManager {
|
||||
|
||||
private FakeplayerManager() {
|
||||
var timer = Executors.newSingleThreadScheduledExecutor();
|
||||
timer.scheduleAtFixedRate(() -> {
|
||||
timer.scheduleWithFixedDelay(() -> {
|
||||
if (Bukkit.getServer().getTPS()[1] < config.getKaleTps()) {
|
||||
Tasks.run(() -> {
|
||||
if (FakeplayerManager.this.removeAll("low tps") > 0) {
|
||||
@ -116,9 +115,7 @@ public class FakeplayerManager {
|
||||
sn,
|
||||
removeAt
|
||||
);
|
||||
|
||||
var target = fp.getPlayer();
|
||||
target.playerListName(text(target.getName(), GRAY, ITALIC));
|
||||
|
||||
return CompletableFuture
|
||||
.supplyAsync(() -> {
|
||||
@ -419,6 +416,24 @@ public class FakeplayerManager {
|
||||
return target.hasMetadata("fakeplayer:refillable");
|
||||
}
|
||||
|
||||
public @Nullable ReceivedMessage getLastMessage(@NotNull Player target) {
|
||||
return Optional.ofNullable(playerList.getByUUID(target.getUniqueId()))
|
||||
.map(FakePlayer::getConnection)
|
||||
.map(NMSGamePacketListener::getLastMessage)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public @NotNull List<ReceivedMessage> getMessages(@NotNull Player target, int skip, int size) {
|
||||
return Optional.ofNullable(playerList.getByUUID(target.getUniqueId()))
|
||||
.map(FakePlayer::getConnection)
|
||||
.map(NMSGamePacketListener::getRecentMessages)
|
||||
.orElse(Collections.emptyList())
|
||||
.stream()
|
||||
.skip(skip)
|
||||
.limit(size)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 以假人身份执行命令
|
||||
*
|
||||
@ -471,19 +486,19 @@ public class FakeplayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean openInventory(@NotNull Player creator, @NotNull Player player) {
|
||||
var target = this.playerList.getByName(player.getName());
|
||||
if (target == null) {
|
||||
public boolean openInventory(@NotNull Player creator, @NotNull Player target) {
|
||||
var fp = this.playerList.getByName(target.getName());
|
||||
if (fp == null) {
|
||||
return false;
|
||||
}
|
||||
if (!creator.isOp() && !target.isCreator(creator)) {
|
||||
if (!creator.isOp() && !fp.isCreator(creator)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!openInvDepend.openInventory(creator, player)) {
|
||||
this.openInventoryDefault(creator, player);
|
||||
if (!openInvDepend.openInventory(creator, target)) {
|
||||
this.openInventoryDefault(creator, target);
|
||||
}
|
||||
creator.playSound(player.getLocation(), Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.5f, 1.0f);
|
||||
creator.playSound(target.getLocation(), Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.5f, 1.0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class ActionManager {
|
||||
@NotNull ActionSetting setting
|
||||
) {
|
||||
var managers = this.managers.computeIfAbsent(player.getUniqueId(), key -> new HashMap<>());
|
||||
managers.put(action, Main.getVersionSupport().createAction(player, action, setting));
|
||||
managers.put(action, Main.getBridge().createAction(player, action, setting));
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
@ -13,11 +13,11 @@ import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @param name 配置项 key
|
||||
* @param name 配置项 key
|
||||
* @param translationKey 翻译 key
|
||||
* @param defaultValue 默认值
|
||||
* @param options 可选值
|
||||
* @param converter 转换器
|
||||
* @param defaultValue 默认值
|
||||
* @param options 可选值
|
||||
* @param converter 转换器
|
||||
*/
|
||||
public record Config<T>(
|
||||
|
||||
@ -128,14 +128,14 @@ public record Config<T>(
|
||||
|
||||
private static <T> Config<T> build(
|
||||
@NotNull String name,
|
||||
@NotNull String translateKey,
|
||||
@NotNull String translationKey,
|
||||
@NotNull Class<T> type,
|
||||
@NotNull T defaultValue,
|
||||
@NotNull List<String> options,
|
||||
@Nullable String permission,
|
||||
@NotNull Function<String, T> converter
|
||||
) {
|
||||
var config = new Config<>(name, translateKey, type, defaultValue, options, permission, converter);
|
||||
var config = new Config<>(name, translationKey, type, defaultValue, options, permission, converter);
|
||||
values.put(name, config);
|
||||
return config;
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ fakeplayer.command.look.east.description=Look east
|
||||
fakeplayer.command.look.entity.description=Look at nearest entity
|
||||
fakeplayer.command.look.north.description=Look north
|
||||
fakeplayer.command.look.south.description=Look south
|
||||
fakeplayer.command.look.success=<name> is looking <direction> now
|
||||
fakeplayer.command.look.up.description=Look up
|
||||
fakeplayer.command.look.west.description=Look west
|
||||
fakeplayer.command.mine.description=Mine
|
||||
@ -65,7 +64,6 @@ fakeplayer.command.move.description=Move
|
||||
fakeplayer.command.move.forward.description=Move forward
|
||||
fakeplayer.command.move.left.description=Move left
|
||||
fakeplayer.command.move.right.description=Move right
|
||||
fakeplayer.command.move.success=<name> moved
|
||||
fakeplayer.command.refill.description=Config whether auto replacing their broken tools, or items
|
||||
fakeplayer.command.refill.success=<name> refillable was set to <status>
|
||||
fakeplayer.command.reload.description=Reload config file
|
||||
|
@ -56,7 +56,6 @@ fakeplayer.command.look.east.description=\u5411\u4E1C\u770B
|
||||
fakeplayer.command.look.entity.description=\u770B\u5411\u9644\u8FD1\u5B9E\u4F53
|
||||
fakeplayer.command.look.north.description=\u5411\u5317\u770B
|
||||
fakeplayer.command.look.south.description=\u5411\u5357\u770B
|
||||
fakeplayer.command.look.success=<name> \u770B\u5411 <direction>
|
||||
fakeplayer.command.look.up.description=\u5411\u4E0A\u770B
|
||||
fakeplayer.command.look.west.description=\u5411\u897F\u770B
|
||||
fakeplayer.command.mine.description=\u6316\u6398
|
||||
@ -65,7 +64,6 @@ fakeplayer.command.move.description=\u79FB\u52A8
|
||||
fakeplayer.command.move.forward.description=\u5411\u524D\u79FB\u52A8
|
||||
fakeplayer.command.move.left.description=\u5411\u5DE6\u79FB\u52A8
|
||||
fakeplayer.command.move.right.description=\u5411\u53F3\u79FB\u52A8
|
||||
fakeplayer.command.move.success=<name> \u52A8\u4E86\u4E00\u4E0B
|
||||
fakeplayer.command.refill.description=\u8BBE\u7F6E\u81EA\u52A8\u586B\u88C5
|
||||
fakeplayer.command.refill.success=<name> \u81EA\u52A8\u88C5\u586B\u5DF2 <status>
|
||||
fakeplayer.command.reload.description=\u91CD\u65B0\u52A0\u8F7D\u914D\u7F6E\u6587\u4EF6
|
||||
|
@ -19,6 +19,16 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-v1_20_R1</artifactId>
|
||||
|
@ -0,0 +1,2 @@
|
||||
io.github.hello09x.fakeplayer.v1_20_R1.spi.NMSBridgeImpl
|
||||
io.github.hello09x.fakeplayer.v1_20_R2.spi.NMSBridgeImpl
|
@ -1,2 +0,0 @@
|
||||
io.github.hello09x.fakeplayer.v1_20_R1.spi.VersionSupportImpl
|
||||
io.github.hello09x.fakeplayer.v1_20_R2.spi.VersionSupportImpl
|
@ -32,6 +32,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -1,18 +1,27 @@
|
||||
package io.github.hello09x.fakeplayer.v1_20_R1.network;
|
||||
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.api.utils.ClientboundSystemChatPackets;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.network.protocol.game.ClientboundSystemChatPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EmptyServerGamePacketListener extends ServerGamePacketListenerImpl {
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class EmptyServerGamePacketListener extends ServerGamePacketListenerImpl implements NMSGamePacketListener {
|
||||
|
||||
private final LinkedList<ReceivedMessage> messages = new LinkedList<>();
|
||||
private final MutableInt messageId = new MutableInt();
|
||||
|
||||
public EmptyServerGamePacketListener(@NotNull MinecraftServer minecraftServer, @NotNull Connection networkManager, @NotNull ServerPlayer player) {
|
||||
super(minecraftServer, networkManager, player);
|
||||
@ -20,6 +29,34 @@ public class EmptyServerGamePacketListener extends ServerGamePacketListenerImpl
|
||||
|
||||
@Override
|
||||
public void send(Packet<?> packet) {
|
||||
if (packet instanceof ClientboundSystemChatPacket chat) {
|
||||
this.handleSystemChatPacket(chat);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSystemChatPacket(@NotNull ClientboundSystemChatPacket packet) {
|
||||
if (this.messages.size() >= MESSAGE_HISTORY_SIZE) {
|
||||
this.messages.removeFirst();
|
||||
}
|
||||
|
||||
var content = ClientboundSystemChatPackets.getAdventureContent(packet);
|
||||
if (content == null) {
|
||||
content = text(packet.content());
|
||||
}
|
||||
|
||||
this.messages.addLast(new ReceivedMessage(messageId.incrementAndGet(), content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ReceivedMessage getLastMessage() {
|
||||
if (this.messages.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return this.messages.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ReceivedMessage> getRecentMessages() {
|
||||
return new ArrayList<>(this.messages);
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class VersionSupportImpl implements VersionSupport {
|
||||
public class NMSBridgeImpl implements NMSBridge {
|
||||
|
||||
private final static Set<String> SUPPORTS = Set.of("1.20", "1.20.1");
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.hello09x.fakeplayer.v1_20_R1.spi;
|
||||
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSNetwork;
|
||||
import io.github.hello09x.fakeplayer.v1_20_R1.network.EmptyConnection;
|
||||
import io.github.hello09x.fakeplayer.v1_20_R1.network.EmptyLoginPacketListener;
|
||||
@ -16,7 +17,7 @@ import java.net.InetAddress;
|
||||
public class NMSNetworkImpl implements NMSNetwork {
|
||||
|
||||
@Override
|
||||
public void bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address) {
|
||||
public @NotNull NMSGamePacketListener bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address) {
|
||||
var connect = new EmptyConnection(PacketFlow.SERVERBOUND, address);
|
||||
var listener = new EmptyServerGamePacketListener(
|
||||
((CraftServer) server).getServer(),
|
||||
@ -24,6 +25,7 @@ public class NMSNetworkImpl implements NMSNetwork {
|
||||
((CraftPlayer) player).getHandle()
|
||||
);
|
||||
connect.setListener(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,7 +75,6 @@ public class NMSServerPlayerImpl implements NMSServerPlayer {
|
||||
@Override
|
||||
public void doTick() {
|
||||
handle.doTick();
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,11 +27,13 @@
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.hello09x.fakeplayer</groupId>
|
||||
<artifactId>fakeplayer-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -1,19 +1,64 @@
|
||||
package io.github.hello09x.fakeplayer.v1_20_R2.network;
|
||||
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSGamePacketListener;
|
||||
import io.github.hello09x.fakeplayer.api.utils.ClientboundSystemChatPackets;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientboundSystemChatPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.CommonListenerCookie;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
public class EmptyServerGamePacketListener extends ServerGamePacketListenerImpl implements NMSGamePacketListener {
|
||||
|
||||
private final LinkedList<ReceivedMessage> messages = new LinkedList<>();
|
||||
private final MutableInt messageId = new MutableInt();
|
||||
|
||||
public class EmptyServerGamePacketListener extends ServerGamePacketListenerImpl {
|
||||
public EmptyServerGamePacketListener(MinecraftServer minecraftServer, Connection networkManager, ServerPlayer entityPlayer, CommonListenerCookie commonListenerCookie) {
|
||||
super(minecraftServer, networkManager, entityPlayer, commonListenerCookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Packet<?> packet) {
|
||||
if (packet instanceof ClientboundSystemChatPacket chat) {
|
||||
this.handleSystemChatPacket(chat);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSystemChatPacket(@NotNull ClientboundSystemChatPacket packet) {
|
||||
if (this.messages.size() >= MESSAGE_HISTORY_SIZE) {
|
||||
this.messages.removeFirst();
|
||||
}
|
||||
|
||||
var content = ClientboundSystemChatPackets.getAdventureContent(packet);
|
||||
if (content == null) {
|
||||
content = text(packet.content());
|
||||
}
|
||||
|
||||
this.messages.addLast(new ReceivedMessage(messageId.incrementAndGet(), content));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ReceivedMessage getLastMessage() {
|
||||
if (this.messages.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return this.messages.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ReceivedMessage> getRecentMessages() {
|
||||
return new ArrayList<>(this.messages);
|
||||
}
|
||||
|
||||
}
|
@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class VersionSupportImpl implements VersionSupport {
|
||||
public class NMSBridgeImpl implements NMSBridge {
|
||||
|
||||
private final static Set<String> SUPPORTS = Set.of("1.20.2");
|
||||
|
@ -17,7 +17,7 @@ import java.net.InetAddress;
|
||||
public class NMSNetworkImpl implements NMSNetwork {
|
||||
|
||||
@Override
|
||||
public void bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address) {
|
||||
public @NotNull EmptyServerGamePacketListener bindEmptyServerGamePacketListener(@NotNull Server server, @NotNull Player player, @NotNull InetAddress address) {
|
||||
var connect = new EmptyConnection(PacketFlow.CLIENTBOUND, address);
|
||||
var listener = new EmptyServerGamePacketListener(
|
||||
((CraftServer) server).getServer(),
|
||||
@ -26,6 +26,7 @@ public class NMSNetworkImpl implements NMSNetwork {
|
||||
CommonListenerCookie.createInitial(((CraftPlayer) player).getProfile())
|
||||
);
|
||||
connect.setListener(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user