mirror of
https://github.com/tanyaofei/minecraft-fakeplayer.git
synced 2025-07-13 21:02:27 +08:00
Notify creator when his fake player is dead
This commit is contained in:
parent
492348420d
commit
a778ae4b78
@ -2,6 +2,7 @@ package io.github.hello09x.fakeplayer.core;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import io.github.hello09x.devtools.command.CommandModule;
|
||||
import io.github.hello09x.devtools.core.TranslationModule;
|
||||
import io.github.hello09x.devtools.core.translation.TranslationConfig;
|
||||
import io.github.hello09x.devtools.core.translation.TranslatorUtils;
|
||||
@ -39,6 +40,7 @@ public final class Main extends JavaPlugin {
|
||||
|
||||
injector = Guice.createInjector(
|
||||
new FakeplayerModule(),
|
||||
new CommandModule(),
|
||||
new DatabaseModule(),
|
||||
new TranslationModule(new TranslationConfig(
|
||||
"message/message",
|
||||
|
@ -7,6 +7,8 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static net.kyori.adventure.text.Component.translatable;
|
||||
|
||||
@Singleton
|
||||
public class RespawnCommand extends AbstractCommand {
|
||||
|
||||
@ -16,6 +18,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);
|
||||
bridge.fromPlayer(target).respawn();
|
||||
sender.sendMessage(translatable("fakeplayer.command.generic.success"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package io.github.hello09x.fakeplayer.core.command.impl;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Singleton;
|
||||
import dev.jorel.commandapi.executors.CommandArguments;
|
||||
import io.github.hello09x.devtools.core.message.IMessageException;
|
||||
import io.github.hello09x.devtools.core.message.MessageException;
|
||||
import io.github.hello09x.devtools.command.exception.CommandException;
|
||||
import io.github.hello09x.devtools.command.exception.HandleCommandException;
|
||||
import io.github.hello09x.fakeplayer.core.Main;
|
||||
import io.github.hello09x.fakeplayer.core.util.Mth;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -14,6 +14,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
@ -29,6 +30,7 @@ import static net.kyori.adventure.text.format.NamedTextColor.*;
|
||||
public class SpawnCommand extends AbstractCommand {
|
||||
|
||||
private final static DateTimeFormatter REMOVE_AT_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
|
||||
private final static BukkitScheduler scheduler = Bukkit.getScheduler();
|
||||
|
||||
private static String toLocationString(@NotNull Location location) {
|
||||
return location.getWorld().getName()
|
||||
@ -42,6 +44,7 @@ public class SpawnCommand extends AbstractCommand {
|
||||
/**
|
||||
* 创建假人
|
||||
*/
|
||||
@HandleCommandException
|
||||
public void spawn(@NotNull CommandSender sender, @NotNull CommandArguments args) {
|
||||
var name = (String) args.get("name");
|
||||
if (name != null && name.isEmpty()) {
|
||||
@ -65,47 +68,42 @@ public class SpawnCommand extends AbstractCommand {
|
||||
}
|
||||
|
||||
var removedAt = Optional.ofNullable(config.getLifespan()).map(lifespan -> LocalDateTime.now().plus(lifespan)).orElse(null);
|
||||
try {
|
||||
manager.spawnAsync(sender, name, spawnpoint, Optional.ofNullable(config.getLifespan()).map(Duration::toMillis).orElse(-1L))
|
||||
.thenAcceptAsync(player -> {
|
||||
if (player == null) {
|
||||
return;
|
||||
manager.spawnAsync(sender, name, spawnpoint, Optional.ofNullable(config.getLifespan()).map(Duration::toMillis).orElse(-1L))
|
||||
.thenAcceptAsync(player -> {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
Component message;
|
||||
if (removedAt == null) {
|
||||
message = translatable(
|
||||
"fakeplayer.command.spawn.success.without-lifespan",
|
||||
text(player.getName(), WHITE),
|
||||
text(toLocationString(spawnpoint), WHITE)
|
||||
).color(GRAY);
|
||||
} else {
|
||||
message = translatable(
|
||||
"fakeplayer.command.spawn.success.with-lifespan",
|
||||
text(player.getName(), WHITE),
|
||||
text(toLocationString(spawnpoint), WHITE),
|
||||
text(REMOVE_AT_FORMATTER.format(removedAt))
|
||||
).color(GRAY);
|
||||
}
|
||||
scheduler.runTask(Main.getInstance(), () -> {
|
||||
sender.sendMessage(message);
|
||||
if (sender instanceof Player p && manager.countByCreator(sender) == 1) {
|
||||
// 有些命令在有假人的时候才会显示, 因此需要强制刷新一下
|
||||
p.updateCommands();
|
||||
}
|
||||
Component message;
|
||||
if (removedAt == null) {
|
||||
message = translatable(
|
||||
"fakeplayer.command.spawn.success.without-lifespan",
|
||||
text(player.getName(), WHITE),
|
||||
text(toLocationString(spawnpoint), WHITE)
|
||||
).color(GRAY);
|
||||
} else {
|
||||
message = translatable(
|
||||
"fakeplayer.command.spawn.success.with-lifespan",
|
||||
text(player.getName(), WHITE),
|
||||
text(toLocationString(spawnpoint), WHITE),
|
||||
text(REMOVE_AT_FORMATTER.format(removedAt))
|
||||
).color(GRAY);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> {
|
||||
sender.sendMessage(message);
|
||||
if (sender instanceof Player p && manager.countByCreator(sender) == 1) {
|
||||
// 有些命令在有假人的时候才会显示, 因此需要强制刷新一下
|
||||
p.updateCommands();
|
||||
}
|
||||
});
|
||||
}).exceptionally(e -> {
|
||||
if (Throwables.getRootCause(e) instanceof IMessageException me) {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> sender.sendMessage(me.getComponent()));
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(Main.getInstance(), () -> sender.sendMessage(translatable("fakeplayer.command.spawn.error.unknown", RED)));
|
||||
log.severe(Throwables.getStackTraceAsString(e));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} catch (MessageException e) {
|
||||
sender.sendMessage(e.getComponent());
|
||||
}
|
||||
|
||||
}).exceptionally(e -> {
|
||||
if (Throwables.getRootCause(e) instanceof CommandException ce) {
|
||||
scheduler.runTask(Main.getInstance(), () -> sender.sendMessage(ce.component()));
|
||||
} else {
|
||||
scheduler.runTask(Main.getInstance(), () -> sender.sendMessage(translatable("fakeplayer.command.spawn.error.unknown", RED)));
|
||||
log.severe(Throwables.getStackTraceAsString(e));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.hello09x.fakeplayer.core.entity;
|
||||
|
||||
import io.github.hello09x.devtools.core.message.RuntimeMessageException;
|
||||
import io.github.hello09x.devtools.command.exception.CommandException;
|
||||
import io.github.hello09x.devtools.core.utils.EntityUtils;
|
||||
import io.github.hello09x.devtools.core.utils.SchedulerUtils;
|
||||
import io.github.hello09x.devtools.core.utils.WorldUtils;
|
||||
@ -121,7 +121,7 @@ public class FakePlayer {
|
||||
.runTaskAsynchronously(Main.getInstance(), () -> {
|
||||
var event = this.callPreLoginEvent(address);
|
||||
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||
throw new RuntimeMessageException(translatable(
|
||||
throw new CommandException(translatable(
|
||||
"fakeplayer.command.spawn.error.disallowed",
|
||||
text(player.getName(), WHITE),
|
||||
event.kickMessage()
|
||||
@ -132,7 +132,7 @@ public class FakePlayer {
|
||||
{
|
||||
var event = this.callLoginEvent(address);
|
||||
if (event.getResult() != PlayerLoginEvent.Result.ALLOWED && config.getPreventKicking().ordinal() < PreventKicking.ON_SPAWNING.ordinal()) {
|
||||
throw new RuntimeMessageException(translatable(
|
||||
throw new CommandException(translatable(
|
||||
"fakeplayer.command.spawn.error.disallowed", RED,
|
||||
text(player.getName(), WHITE),
|
||||
event.kickMessage()
|
||||
|
@ -32,8 +32,9 @@ import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static net.kyori.adventure.text.Component.*;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
import static net.kyori.adventure.text.event.ClickEvent.runCommand;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.*;
|
||||
import static net.kyori.adventure.text.format.TextDecoration.UNDERLINED;
|
||||
|
||||
@Singleton
|
||||
public class FakeplayerListener implements Listener {
|
||||
@ -118,12 +119,20 @@ public class FakeplayerListener implements Listener {
|
||||
* 死亡退出游戏
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void kickOnDead(@NotNull PlayerDeathEvent event) {
|
||||
public void kickOrNotifyOnDead(@NotNull PlayerDeathEvent event) {
|
||||
var player = event.getPlayer();
|
||||
if (manager.isNotFake(player)) {
|
||||
return;
|
||||
}
|
||||
if (!config.isKickOnDead()) {
|
||||
var creator = manager.getCreator(player);
|
||||
if (creator != null) {
|
||||
creator.sendMessage(translatable(
|
||||
"fakeplayer.listener.death.notify",
|
||||
text(player.getName(), GOLD),
|
||||
text("/fp respawn", DARK_GREEN, UNDERLINED).clickEvent(runCommand("/fp respawn " + player.getName()))
|
||||
).color(RED));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,7 @@ package io.github.hello09x.fakeplayer.core.manager;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import io.github.hello09x.devtools.core.message.MessageException;
|
||||
import io.github.hello09x.devtools.core.message.RuntimeMessageException;
|
||||
import io.github.hello09x.devtools.command.exception.CommandException;
|
||||
import io.github.hello09x.devtools.core.utils.Exceptions;
|
||||
import io.github.hello09x.devtools.core.utils.MetadataUtils;
|
||||
import io.github.hello09x.fakeplayer.api.spi.Action;
|
||||
@ -15,8 +14,6 @@ import io.github.hello09x.fakeplayer.core.entity.FakePlayer;
|
||||
import io.github.hello09x.fakeplayer.core.entity.SpawnOption;
|
||||
import io.github.hello09x.fakeplayer.core.manager.invsee.Invsee;
|
||||
import io.github.hello09x.fakeplayer.core.manager.naming.NameManager;
|
||||
import io.github.hello09x.fakeplayer.core.manager.naming.SequenceName;
|
||||
import io.github.hello09x.fakeplayer.core.manager.naming.exception.IllegalCustomNameException;
|
||||
import io.github.hello09x.fakeplayer.core.repository.model.Config;
|
||||
import io.github.hello09x.fakeplayer.core.util.AddressUtils;
|
||||
import io.github.hello09x.fakeplayer.core.util.Commands;
|
||||
@ -93,15 +90,10 @@ public class FakeplayerManager {
|
||||
@Nullable String name,
|
||||
@NotNull Location spawnAt,
|
||||
long lifespan
|
||||
) throws MessageException {
|
||||
) {
|
||||
this.checkLimit(creator);
|
||||
|
||||
SequenceName sn;
|
||||
try {
|
||||
sn = name == null ? nameManager.register(creator) : nameManager.specify(name);
|
||||
} catch (IllegalCustomNameException e) {
|
||||
throw new RuntimeMessageException(e.getMessage());
|
||||
}
|
||||
var sn = name == null ? nameManager.register(creator) : nameManager.specify(name);
|
||||
|
||||
var fp = new FakePlayer(
|
||||
creator,
|
||||
@ -527,23 +519,22 @@ public class FakeplayerManager {
|
||||
* 检测限制, 不满足条件则抛出异常
|
||||
*
|
||||
* @param creator 创建者
|
||||
* @throws MessageException 消息
|
||||
*/
|
||||
private void checkLimit(@NotNull CommandSender creator) throws MessageException {
|
||||
private void checkLimit(@NotNull CommandSender creator) throws CommandException {
|
||||
if (creator.isOp()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.playerList.count() >= this.config.getServerLimit()) {
|
||||
throw new MessageException(translatable("fakeplayer.command.spawn.error.server-limit"));
|
||||
throw new CommandException(translatable("fakeplayer.command.spawn.error.server-limit"));
|
||||
}
|
||||
|
||||
if (this.playerList.getByCreator(creator.getName()).size() >= this.config.getPlayerLimit()) {
|
||||
throw new MessageException(translatable("fakeplayer.command.spawn.error.player-limit"));
|
||||
throw new CommandException(translatable("fakeplayer.command.spawn.error.player-limit"));
|
||||
}
|
||||
|
||||
if (this.config.isDetectIp() && this.countByAddress(AddressUtils.getAddress(creator)) >= this.config.getPlayerLimit()) {
|
||||
throw new MessageException(translatable("fakeplayer.command.spawn.error.ip-limit"));
|
||||
throw new CommandException(translatable("fakeplayer.command.spawn.error.ip-limit"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,13 @@
|
||||
package io.github.hello09x.fakeplayer.core.manager.naming.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import io.github.hello09x.devtools.command.exception.CommandException;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IllegalCustomNameException extends IllegalArgumentException {
|
||||
|
||||
@Getter
|
||||
private final Component text;
|
||||
public class IllegalCustomNameException extends CommandException {
|
||||
|
||||
public IllegalCustomNameException(@NotNull Component message) {
|
||||
super(PlainTextComponentSerializer.plainText().serialize(message));
|
||||
this.text = message;
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ fakeplayer.direction.south=south
|
||||
fakeplayer.direction.up=up
|
||||
fakeplayer.direction.west=west
|
||||
fakeplayer.listener.login.deny-used-uuid=Your UUID was used by fake player, disallow to login
|
||||
fakeplayer.listener.death.notify=Fake player {0} is dead, you could use {1} to respawn him
|
||||
fakeplayer.manager.inventory.title=Inventory of {0}
|
||||
fakeplayer.manager.remove-all-on-low-tps=[Low tps, all fake players have been removed]
|
||||
fakeplayer.spawn.error.name.existed=This name already existed
|
||||
|
@ -127,6 +127,7 @@ fakeplayer.direction.north=north
|
||||
fakeplayer.direction.south=south
|
||||
fakeplayer.direction.up=up
|
||||
fakeplayer.direction.west=west
|
||||
fakeplayer.listener.death.notify=Fake player {0} is dead, you could use {1} to respawn him
|
||||
fakeplayer.listener.login.deny-used-uuid=Your UUID was used by fake player, disallow to login
|
||||
fakeplayer.manager.inventory.title=Inventory of {0}
|
||||
fakeplayer.manager.remove-all-on-low-tps=[Low tps, all fake players have been removed]
|
||||
|
@ -127,6 +127,7 @@ fakeplayer.direction.north=\u5317\u65B9
|
||||
fakeplayer.direction.south=\u5357\u65B9
|
||||
fakeplayer.direction.up=\u4E0A\u65B9
|
||||
fakeplayer.direction.west=\u897F\u65B9
|
||||
fakeplayer.listener.death.notify=\u5047\u4EBA {0} \u6B7B\u4EA1, \u53EF\u4EE5\u4F7F\u7528 {1} \u53BB\u590D\u6D3B\u4ED6
|
||||
fakeplayer.listener.login.deny-used-uuid=\u4F60\u7684 UUID \u88AB\u4F7F\u7528\u8FC7, \u4E0D\u80FD\u767B\u5F55\u670D\u52A1\u5668
|
||||
fakeplayer.manager.inventory.title={0} \u7684\u7269\u54C1\u680F
|
||||
fakeplayer.manager.remove-all-on-low-tps=[\u670D\u52A1\u5668\u8FC7\u4E8E\u5361\u987F, \u5DF2\u79FB\u9664\u6240\u6709\u5047\u4EBA]
|
||||
|
@ -127,6 +127,7 @@ fakeplayer.direction.north=\u5317\u65B9
|
||||
fakeplayer.direction.south=\u5357\u65B9
|
||||
fakeplayer.direction.up=\u4E0A\u65B9
|
||||
fakeplayer.direction.west=\u897F\u65B9
|
||||
fakeplayer.listener.death.notify=\u5047\u4EBA {0} \u6B7B\u4EA1, \u53EF\u4EE5\u4F7F\u7528 {1} \u6765\u590D\u6D3B\u4ED6
|
||||
fakeplayer.listener.login.deny-used-uuid=\u4F60\u7684 UUID \u88AB\u4F7F\u7528\u8FC7, \u4E0D\u80FD\u767B\u5F55\u670D\u52A1\u5668
|
||||
fakeplayer.manager.inventory.title={0} \u7684\u7269\u54C1\u680F
|
||||
fakeplayer.manager.remove-all-on-low-tps=[\u670D\u52A1\u5668\u8FC7\u4E8E\u5361\u987F, \u5DF2\u79FB\u9664\u6240\u6709\u5047\u4EBA]
|
||||
|
@ -127,6 +127,7 @@ fakeplayer.direction.north=\u5317\u65B9
|
||||
fakeplayer.direction.south=\u5357\u65B9
|
||||
fakeplayer.direction.up=\u4E0A\u65B9
|
||||
fakeplayer.direction.west=\u897F\u65B9
|
||||
fakeplayer.listener.death.notify=\u5047\u4EBA {0} \u6B7B\u4EA1, \u53EF\u4EE5\u4F7F\u7528 {1} \u569F\u5FA9\u6D3B\u4F62
|
||||
fakeplayer.listener.login.deny-used-uuid=\u4F60\u5605 UUID \u88AB\u4F7F\u7528\u904E, \u5514\u53EF\u4EE5\u767B\u9304\u4F3A\u670D\u5668
|
||||
fakeplayer.manager.inventory.title={0} \u7684\u7269\u54C1\u6B04
|
||||
fakeplayer.manager.remove-all-on-low-tps=[\u7531\u4E8E\u4F3A\u670D\u5668 lag \u6A5F, \u5DF2\u79FB\u9664\u6240\u6709\u5047\u4EBA]
|
||||
|
@ -127,6 +127,7 @@ fakeplayer.direction.north=\u5317\u65B9
|
||||
fakeplayer.direction.south=\u5357\u65B9
|
||||
fakeplayer.direction.up=\u4E0A\u65B9
|
||||
fakeplayer.direction.west=\u897F\u65B9
|
||||
fakeplayer.listener.death.notify=\u5047\u4EBA {0} \u6B7B\u4EA1, \u53EF\u4EE5\u4F7F\u7528 \u00A7f/fp respawn\u00A7r \u4F86\u5FA9\u6D3B\u4ED6
|
||||
fakeplayer.listener.login.deny-used-uuid=\u4F60\u7684 UUID \u88AB\u4F7F\u7528\u904E, \u4E0D\u80FD\u767B\u9304\u4F3A\u670D\u5668
|
||||
fakeplayer.manager.inventory.title={0} \u7684\u7269\u54C1\u6B04
|
||||
fakeplayer.manager.remove-all-on-low-tps=[\u4F3A\u670D\u5668\u904E\u65BC\u5361\u9813, \u5DF2\u79FB\u9664\u6240\u6709\u5047\u4EBA]
|
||||
|
Loading…
Reference in New Issue
Block a user