mirror of
https://github.com/tanyaofei/minecraft-fakeplayer.git
synced 2025-07-13 21:02:27 +08:00
Lifecycle commands
This commit is contained in:
parent
a4961e09b3
commit
e050f8772a
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-api</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -1,76 +0,0 @@
|
||||
package io.github.hello09x.fakeplayer.api.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FakePlayerSpawnEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private final static HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
@NotNull
|
||||
@Getter
|
||||
private final CommandSender creator;
|
||||
|
||||
@NotNull
|
||||
@Getter
|
||||
private Result result = Result.ALLOW;
|
||||
|
||||
@NotNull
|
||||
@Getter
|
||||
private Component reason = Component.empty();
|
||||
|
||||
public FakePlayerSpawnEvent(@NotNull CommandSender creator, @NotNull Player who) {
|
||||
super(who);
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.result != Result.ALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cancel true if you wish to cancel this event
|
||||
* @deprecated 请使用 {@link #disallow(Component)} (Result, Component)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.disallow(Component.empty());
|
||||
}
|
||||
|
||||
public void allow() {
|
||||
this.result = Result.ALLOW;
|
||||
this.reason = Component.empty();
|
||||
}
|
||||
|
||||
public void disallow(@NotNull Component reason) {
|
||||
this.result = Result.DISALLOW;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public enum Result {
|
||||
|
||||
ALLOW,
|
||||
|
||||
DISALLOW
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-core</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -9,6 +9,7 @@ import io.github.hello09x.devtools.core.utils.Exceptions;
|
||||
import io.github.hello09x.devtools.database.DatabaseModule;
|
||||
import io.github.hello09x.fakeplayer.core.command.CommandRegistry;
|
||||
import io.github.hello09x.fakeplayer.core.config.FakeplayerConfig;
|
||||
import io.github.hello09x.fakeplayer.core.listener.FakeplayerLifecycleListener;
|
||||
import io.github.hello09x.fakeplayer.core.listener.FakeplayerListener;
|
||||
import io.github.hello09x.fakeplayer.core.listener.PlayerListener;
|
||||
import io.github.hello09x.fakeplayer.core.listener.ReplenishListener;
|
||||
@ -58,6 +59,7 @@ public final class Main extends JavaPlugin {
|
||||
{
|
||||
var manager = getServer().getPluginManager();
|
||||
manager.registerEvents(injector.getInstance(PlayerListener.class), this);
|
||||
manager.registerEvents(injector.getInstance(FakeplayerLifecycleListener.class), this);
|
||||
manager.registerEvents(injector.getInstance(FakeplayerListener.class), this);
|
||||
manager.registerEvents(injector.getInstance(ReplenishListener.class), this);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package io.github.hello09x.fakeplayer.core.command;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import dev.jorel.commandapi.CommandPermission;
|
||||
import io.github.hello09x.devtools.command.exception.HelpCommand;
|
||||
import io.github.hello09x.devtools.command.HelpCommand;
|
||||
import io.github.hello09x.devtools.core.utils.ComponentUtils;
|
||||
import io.github.hello09x.fakeplayer.api.spi.Action;
|
||||
import io.github.hello09x.fakeplayer.core.command.impl.*;
|
||||
@ -15,7 +15,7 @@ import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.github.hello09x.devtools.command.exception.Commands.*;
|
||||
import static io.github.hello09x.devtools.command.Commands.*;
|
||||
import static io.github.hello09x.fakeplayer.core.command.CommandSupports.*;
|
||||
import static net.kyori.adventure.text.Component.translatable;
|
||||
|
||||
|
@ -21,8 +21,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.github.hello09x.devtools.command.exception.Commands.command;
|
||||
import static io.github.hello09x.devtools.command.exception.Commands.int32;
|
||||
import static io.github.hello09x.devtools.command.Commands.command;
|
||||
import static io.github.hello09x.devtools.command.Commands.int32;
|
||||
import static net.kyori.adventure.text.Component.translatable;
|
||||
|
||||
public abstract class CommandSupports {
|
||||
|
@ -111,7 +111,8 @@ public class FakePlayerCommandArgument extends Argument<CommandResult> implement
|
||||
// Get location sender is looking at if they are a Player, matching vanilla behavior
|
||||
// No builtin Commands use the location parameter, but they could
|
||||
Location location = null;
|
||||
if (sender instanceof Player player) {
|
||||
if (sender instanceof Player) {
|
||||
var player = (Player) sender;
|
||||
Block block = player.getTargetBlockExact(5, FluidCollisionMode.NEVER);
|
||||
if (block != null) {
|
||||
location = block.getLocation();
|
||||
|
@ -2,7 +2,7 @@ package io.github.hello09x.fakeplayer.core.command.impl;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import dev.jorel.commandapi.executors.CommandArguments;
|
||||
import io.github.hello09x.devtools.command.exception.Page;
|
||||
import io.github.hello09x.devtools.command.Page;
|
||||
import io.github.hello09x.fakeplayer.core.command.Permission;
|
||||
import io.github.hello09x.fakeplayer.core.util.Mth;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -62,20 +62,35 @@ public class FakeplayerConfig extends PluginConfig {
|
||||
private int kaleTps;
|
||||
|
||||
/**
|
||||
* 准备命令
|
||||
* 创建前执行命令
|
||||
*/
|
||||
private List<String> preparingCommands;
|
||||
private List<String> preSpawnCommands;
|
||||
|
||||
/**
|
||||
* 创建时执行命令
|
||||
*/
|
||||
private List<String> postSpawnCommands;
|
||||
|
||||
/**
|
||||
* 创建后执行命令
|
||||
*/
|
||||
private List<String> afterSpawnCommands;
|
||||
|
||||
/**
|
||||
* 退出前执行命令
|
||||
*/
|
||||
private List<String> postQuitCommands;
|
||||
|
||||
/**
|
||||
* 退出后命令
|
||||
*/
|
||||
private List<String> afterQuitCommands;
|
||||
|
||||
/**
|
||||
* 自执行命令
|
||||
*/
|
||||
private List<String> selfCommands;
|
||||
|
||||
/**
|
||||
* 销毁命令
|
||||
*/
|
||||
private List<String> destroyCommands;
|
||||
|
||||
/**
|
||||
* 退出时是否丢弃背包物品
|
||||
*/
|
||||
@ -140,8 +155,14 @@ public class FakeplayerConfig extends PluginConfig {
|
||||
this.detectIp = file.getBoolean("detect-ip", false);
|
||||
this.kaleTps = file.getInt("kale-tps", 0);
|
||||
this.selfCommands = file.getStringList("self-commands");
|
||||
this.preparingCommands = file.getStringList("preparing-commands");
|
||||
this.destroyCommands = file.getStringList("destroy-commands");
|
||||
this.preSpawnCommands = file.getStringList("pre-spawn-commands");
|
||||
this.postSpawnCommands = file.getStringList("post-spawn-commands");
|
||||
deprecated:
|
||||
this.afterSpawnCommands = file.getStringList("after-spawn-commands");
|
||||
this.postQuitCommands = file.getStringList("post-quit-commands");
|
||||
this.afterQuitCommands = file.getStringList("after-quit-commands");
|
||||
// this.preparingCommands = file.getStringList("preparing-commands");
|
||||
// this.destroyCommands = file.getStringList("destroy-commands");
|
||||
this.nameTemplate = file.getString("name-template", "");
|
||||
this.dropInventoryOnQuiting = file.getBoolean("drop-inventory-on-quiting", true);
|
||||
this.persistData = file.getBoolean("persist-data", true);
|
||||
@ -169,6 +190,19 @@ public class FakeplayerConfig extends PluginConfig {
|
||||
if (!this.allowCommands.isEmpty()) {
|
||||
log.warning("allow-commands is deprecated which will be removed at 0.4.0, you should use Permissions Plugin to assign permission groups to fake players.");
|
||||
}
|
||||
|
||||
var preparingCommands = file.getStringList("preparing-commands");
|
||||
if (!preparingCommands.isEmpty()) {
|
||||
log.warning("preparing-commands is deprecated, use post-spawn-commands instead.");
|
||||
this.postSpawnCommands.addAll(preparingCommands);
|
||||
}
|
||||
|
||||
var destroyCommands = file.getStringList("destroy-commands");
|
||||
if (!destroyCommands.isEmpty()) {
|
||||
log.warning("destroy-commands is deprecated, use post-quit-commands instead.");
|
||||
this.postQuitCommands.addAll(destroyCommands);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private @Nullable Duration getLifespan(@NotNull FileConfiguration file) {
|
||||
|
@ -4,7 +4,6 @@ import io.github.hello09x.devtools.core.message.RuntimeMessageException;
|
||||
import io.github.hello09x.devtools.core.utils.EntityUtils;
|
||||
import io.github.hello09x.devtools.core.utils.SchedulerUtils;
|
||||
import io.github.hello09x.devtools.core.utils.WorldUtils;
|
||||
import io.github.hello09x.fakeplayer.api.event.FakePlayerSpawnEvent;
|
||||
import io.github.hello09x.fakeplayer.api.spi.Action;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSBridge;
|
||||
import io.github.hello09x.fakeplayer.api.spi.NMSNetwork;
|
||||
@ -141,17 +140,6 @@ public class FakePlayer {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var event = this.callSpawnEvent();
|
||||
if (event.isCancelled() && config.getPreventKicking().ordinal() < PreventKicking.ON_SPAWNING.ordinal()) {
|
||||
throw new RuntimeMessageException(translatable(
|
||||
"fakeplayer.command.spawn.error.disallowed", RED,
|
||||
text(player.getName(), WHITE),
|
||||
event.getReason()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (config.isDropInventoryOnQuiting()) {
|
||||
// 跨服背包同步插件可能导致假人既丢弃了一份到地上,在重新生成的时候又回来了
|
||||
// 因此在生成的时候清空一次背包
|
||||
@ -242,12 +230,6 @@ public class FakePlayer {
|
||||
return event;
|
||||
}
|
||||
|
||||
private @NotNull FakePlayerSpawnEvent callSpawnEvent() {
|
||||
var event = new FakePlayerSpawnEvent(this.creator, this.player);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是创建者
|
||||
* <p>如果玩家下线再重新登陆, entityID 将会不一样导致 {@link Object#equals(Object)} 返回 {@code false}</p>
|
||||
|
@ -0,0 +1,85 @@
|
||||
package io.github.hello09x.fakeplayer.core.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import io.github.hello09x.fakeplayer.core.config.FakeplayerConfig;
|
||||
import io.github.hello09x.fakeplayer.core.manager.FakeplayerManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author tanyaofei
|
||||
* @since 2024/8/7
|
||||
**/
|
||||
@Singleton
|
||||
public class FakeplayerLifecycleListener implements Listener {
|
||||
|
||||
private final FakeplayerManager manager;
|
||||
private final FakeplayerConfig config;
|
||||
|
||||
@Inject
|
||||
public FakeplayerLifecycleListener(FakeplayerManager manager, FakeplayerConfig config) {
|
||||
this.manager = manager;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPostSpawn(@NotNull PlayerJoinEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (this.manager.isNotFake(player)) {
|
||||
// Not a fake player
|
||||
return;
|
||||
}
|
||||
|
||||
manager.dispatchCommands(player, config.getPostSpawnCommands());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onAfterSpawn(@NotNull PlayerJoinEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (this.manager.isNotFake(player)) {
|
||||
// Not a fake player
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> {
|
||||
if (player.isOnline()) {
|
||||
manager.dispatchCommands(player, config.getAfterSpawnCommands());
|
||||
manager.issueCommands(player, config.getSelfCommands());
|
||||
}
|
||||
}, 20);
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPostQuit(@NotNull PlayerQuitEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (this.manager.isNotFake(player)) {
|
||||
// Not a fake player
|
||||
return;
|
||||
}
|
||||
|
||||
manager.dispatchCommands(player, config.getPostQuitCommands());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onAfterQuit(@NotNull PlayerQuitEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (this.manager.isNotFake(player)) {
|
||||
// Not a fake player
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> {
|
||||
manager.dispatchCommands(player, config.getAfterQuitCommands());
|
||||
}, 20);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package io.github.hello09x.fakeplayer.core.listener;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import io.github.hello09x.devtools.core.utils.ComponentUtils;
|
||||
@ -60,7 +59,7 @@ public class FakeplayerListener implements Listener {
|
||||
* 拒绝真实玩家使用假人用过的 ID 登陆
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onLogin(@NotNull PlayerLoginEvent event) {
|
||||
public void rejectForUsedUUID(@NotNull PlayerLoginEvent event) {
|
||||
var player = event.getPlayer();
|
||||
|
||||
if (InternalAddressGenerator.canBeGenerated(event.getAddress())) {
|
||||
@ -119,7 +118,7 @@ public class FakeplayerListener implements Listener {
|
||||
* 死亡退出游戏
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onDead(@NotNull PlayerDeathEvent event) {
|
||||
public void kickOnDead(@NotNull PlayerDeathEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (manager.isNotFake(player)) {
|
||||
return;
|
||||
@ -140,29 +139,24 @@ public class FakeplayerListener implements Listener {
|
||||
/**
|
||||
* 退出游戏掉落背包
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onQuit(@NotNull PlayerQuitEvent event) {
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
|
||||
public void cleanup(@NotNull PlayerQuitEvent event) {
|
||||
var target = event.getPlayer();
|
||||
if (manager.isNotFake(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
manager.dispatchCommands(target, config.getDestroyCommands());
|
||||
// 如果移除玩家后没有假人, 则更新命令列表
|
||||
// 这个方法需要在 cleanup 之前执行, 不然无法获取假人的创建者
|
||||
if (manager.getCreator(target) instanceof Player creator && manager.countByCreator(creator) == 1) {
|
||||
Bukkit.getScheduler().runTaskLater(Main.getInstance(), creator::updateCommands, 1); // 需要下 1 tick 移除后才正确刷新
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.warning("执行 destroy-commands 时发生错误: \n" + Throwables.getStackTraceAsString(e));
|
||||
} finally {
|
||||
manager.cleanup(target);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void autoFish(@NotNull PlayerFishEvent event) {
|
||||
public void autoFishing(@NotNull PlayerFishEvent event) {
|
||||
if (event.getState() != PlayerFishEvent.State.BITE) {
|
||||
return;
|
||||
}
|
||||
|
@ -109,8 +109,10 @@ public class FakeplayerManager {
|
||||
sn,
|
||||
lifespan
|
||||
);
|
||||
|
||||
var target = fp.getPlayer(); // 即使出现异常也不需要处理这个玩家, 最终会被 GC 掉
|
||||
|
||||
this.dispatchCommandsEarly(fp, this.config.getPreSpawnCommands());
|
||||
return CompletableFuture
|
||||
.supplyAsync(() -> {
|
||||
var configs = configManager.getConfigs(creator);
|
||||
@ -126,15 +128,8 @@ public class FakeplayerManager {
|
||||
);
|
||||
})
|
||||
.thenComposeAsync(fp::spawnAsync)
|
||||
.thenApply(nul -> {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> {
|
||||
this.playerList.add(fp);
|
||||
});
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> {
|
||||
this.dispatchCommands(target, config.getPreparingCommands());
|
||||
this.issueCommands(target, config.getSelfCommands());
|
||||
}, 20);
|
||||
.thenApply(ignored -> {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> playerList.add(fp));
|
||||
return target;
|
||||
});
|
||||
}
|
||||
@ -451,7 +446,10 @@ public class FakeplayerManager {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var cmd : Commands.formatCommands(commands)) {
|
||||
var p = target.getName();
|
||||
var u = target.getUniqueId().toString();
|
||||
var c = Objects.requireNonNull(this.getCreatorName(target));
|
||||
for (var cmd : Commands.formatCommands(commands, "%p", p, "%u", u, "%c", c)) {
|
||||
if (!target.performCommand(cmd)) {
|
||||
log.warning(target.getName() + " failed to execute command: " + cmd);
|
||||
} else {
|
||||
@ -460,6 +458,25 @@ public class FakeplayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchCommandsEarly(@NotNull FakePlayer fp, @NotNull List<String> commands) {
|
||||
if (commands.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var server = Bukkit.getServer();
|
||||
var sender = Bukkit.getConsoleSender();
|
||||
var p = fp.getName();
|
||||
var u = fp.getUUID().toString();
|
||||
var c = fp.getCreator().getName();
|
||||
for (var cmd : Commands.formatCommands(commands, "%p", p, "%u", u, "%c", c)) {
|
||||
if (!server.dispatchCommand(sender, cmd)) {
|
||||
log.warning("Failed to execute command for %s: ".formatted(p) + cmd);
|
||||
} else {
|
||||
log.info("Dispatched command: " + cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 以控制台身份对玩家执行命令
|
||||
*
|
||||
@ -471,20 +488,15 @@ public class FakeplayerManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isNotFake(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var server = Bukkit.getServer();
|
||||
var sender = Bukkit.getConsoleSender();
|
||||
for (var cmd : Commands.formatCommands(
|
||||
commands,
|
||||
"%p", player.getName(),
|
||||
"%u", player.getUniqueId().toString(),
|
||||
"%c", Objects.requireNonNull(this.getCreatorName(player)))
|
||||
) {
|
||||
|
||||
var p = player.getName();
|
||||
var u = player.getUniqueId().toString();
|
||||
var c = Objects.requireNonNull(this.getCreatorName(player));
|
||||
for (var cmd : Commands.formatCommands(commands, "%p", p, "%u", u, "%c", c)) {
|
||||
if (!server.dispatchCommand(sender, cmd)) {
|
||||
log.warning("Failed to execute command for %s: ".formatted(player.getName()) + cmd);
|
||||
log.warning("Failed to execute command for %s: ".formatted(p) + cmd);
|
||||
} else {
|
||||
log.info("Dispatched command: " + cmd);
|
||||
}
|
||||
@ -494,20 +506,20 @@ public class FakeplayerManager {
|
||||
/**
|
||||
* 让玩家打开假人背包
|
||||
*
|
||||
* @param creator 玩家
|
||||
* @param viewer 玩家
|
||||
* @param target 假人
|
||||
* @return 是否打开成功
|
||||
*/
|
||||
public boolean openInventory(@NotNull Player creator, @NotNull Player target) {
|
||||
public boolean openInventory(@NotNull Player viewer, @NotNull Player target) {
|
||||
var fp = this.playerList.getByName(target.getName());
|
||||
if (fp == null) {
|
||||
return false;
|
||||
}
|
||||
if (!creator.isOp() && !fp.isCreator(creator)) {
|
||||
if (!viewer.isOp() && !fp.isCreator(viewer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.invsee.openInventory(creator, target);
|
||||
this.invsee.openInventory(viewer, target);
|
||||
var pos = target.getLocation();
|
||||
pos.getWorld().playSound(pos, Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.3f, 1.0f);
|
||||
return true;
|
||||
|
@ -111,51 +111,110 @@ kick-on-dead: true
|
||||
# It's not recommended to enable this option, as it may cause the redstone machine to malfunction
|
||||
kale-tps: 0
|
||||
|
||||
# 预准备命令
|
||||
# 假人诞生时会以控制台的身份按顺序执行以下命令, 这些命令会比 `self-commands` 更早执行
|
||||
# 你可以用这个来实现权限组的分配之类的命令
|
||||
# 占位符:
|
||||
# %p: 假人名称
|
||||
# %u: 假人 uuid
|
||||
# %c: 创建者的名称
|
||||
# Server will execute the following commands after the fake player was spawned
|
||||
# You can add some commands to give them permission, such as '/lp user %p permission set xxx true'
|
||||
# placeholder:
|
||||
# %p: the name of the fake player
|
||||
# %u: the uuid of the fake player
|
||||
# %c: the name of creator
|
||||
preparing-commands:
|
||||
|
||||
|
||||
# Pre-Spawn-Commands
|
||||
# Server will execute the following commands BEFORE trying to spawn a fake player.
|
||||
# This is helpful for adding fake player into whitelist
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 服务器会在假人创建前执行这些命令
|
||||
# 这里可以添加类似于白名单的命令来保证后续创建过程的正常执行
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
pre-spawn-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
# 假人销毁时执行的命令
|
||||
# 与 `preparing-commands` 类似, 会在假人销毁时依次执行的命令
|
||||
# 也许可以用来销毁第三方插件的档案?
|
||||
# 占位符:
|
||||
# %p: 假人名称
|
||||
# %u: 假人 uuid
|
||||
# %c: 创建者的名称
|
||||
# Server will execute the following commands before the fake player was quited(PlayerQuitEvent)
|
||||
# you can add some commands to clean up data
|
||||
# placeholder:
|
||||
# %p: the name of the fake player
|
||||
# %u: the uuid of the fake player
|
||||
# %c: the name of creator
|
||||
destroy-commands:
|
||||
# Post-Spawn-Commands
|
||||
# Server will execute the following commands DURING spawning (in PlayerJoinEvent).
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 服务器会在假人正在加入游戏中执行这些命令
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
post-spawn-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
# 自执行命令
|
||||
# 假人在诞生时会以自己的身份按顺序执行命令
|
||||
# 你可以在这里做添加 /register 和 /login 命令来防止 `AuthMe` 等插件踢掉超时未登陆的玩家
|
||||
# The fake player will execute the following commands
|
||||
# You can add some command to make him to login
|
||||
# - '/register ANY_PASSWORD'
|
||||
# - '/login ANY_PASSWORD'
|
||||
# After-Spawn-Commands
|
||||
# Server will execute the following commands AFTER the fake player was spawned (after PlayerJoinEvent).
|
||||
# This is helpful for giving permission.
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 服务器会在假人创建后执行这里的命令
|
||||
# 这里可以添加一些权限组分配之类的命令
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
after-spawn-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
# Self-Commands
|
||||
# The fake player will execute the following commands AFTER they were joined the server.
|
||||
# This is helpful for them to execute some login command.
|
||||
# Ensure the password is complex enough otherwise the login plugin might reject it.
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 假人在加入游戏后会执行以下命令
|
||||
# 你可以添加一些登陆命令来让他们完成登陆过程
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
self-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
# Post-Destroy-Commands
|
||||
# Server will execute the following commands when the fake player is quiting but not quited (in PlayerQuitEvent)
|
||||
# This is helpful for cleaning up their inventory if you want it
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 服务器会在假人正在退出时执行这些命令, 命令执行的那一刻假人还位于服务器
|
||||
# 你可以添加一些用来清空假人背包之类的命令
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
post-quit-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
# Post-Destroy-Commands
|
||||
# Server will execute the following commands AFTER the fake player was quited. (after PlayerQuitEvent)
|
||||
# Variables:
|
||||
# %p: the name of the fake player
|
||||
# %u: the UUID of the fake player
|
||||
# %c: the name of the creator
|
||||
# 销毁后命令
|
||||
# 服务器会在假人退出游戏之后执行这些命令
|
||||
# 你可以添加一些清理白名单、取消权限分配、清理某些插件数据等命令
|
||||
# 变量:
|
||||
# %p: 假人的名称
|
||||
# %u: 假人的 UUID
|
||||
# %c: 创建人的名称
|
||||
after-quit-commands:
|
||||
- ''
|
||||
- ''
|
||||
|
||||
|
||||
# 允许玩家让假人执行的命令
|
||||
# 在这里你可以放一些你服务器的命令,玩家就可以执行
|
||||
# 例如添加 /sit 之后, 玩家可以通过 '/fp cmd myfakeplayer sit' 让假人坐下来
|
||||
|
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-v1_20_R1</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-v1_20_R2</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-v1_20_R3_R4</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
<artifactId>fakeplayer-v1_20_R5_R6</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user