更新内容:

- 优化了挂机玩家的检测方式

 - 增加了挂机配置

 - 新增 status 用于查看当前状态
This commit is contained in:
张宇衡 2022-11-21 21:50:02 +08:00
parent 8b72b2fdcf
commit 050fec6f00
7 changed files with 126 additions and 32 deletions

View File

@ -49,6 +49,10 @@
`/livebot stop` 停止自动跟随。 `/livebot stop` 停止自动跟随。
`/livebot setAFKTime <second>` 设置挂机判断时间。
`/livebot status` 查看当前状态。
### 玩家指令 ### 玩家指令
`/livebot away` 让自己不被跟随。 `/livebot away` 让自己不被跟随。
@ -70,4 +74,8 @@ Setting:
CanBeMoved: true CanBeMoved: true
# 是否在聊天栏公告自己的状态 (未实装) # 是否在聊天栏公告自己的状态 (未实装)
IsNagging: true IsNagging: true
# 是否跳过挂机玩家
SkipAFK: true
# 挂机判断时间(单位:秒)
AFKTime: 60
``` ```

View File

@ -6,7 +6,7 @@
<groupId>deercloud</groupId> <groupId>deercloud</groupId>
<artifactId>LiveBot</artifactId> <artifactId>LiveBot</artifactId>
<version>1.2</version> <version>1.3</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>LiveBot</name> <name>LiveBot</name>

View File

@ -139,10 +139,53 @@ public class Commands implements TabExecutor {
} else { } else {
updateSkipAFK(sender, args); updateSkipAFK(sender, args);
} }
} else if (Objects.equals(args[0], "setAfkTime")) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (player.isOp()) {
if (Integer.parseInt(args[1]) <= 10) {
player.sendMessage(ChatColor.RED + "时间间隔不能小于10秒。");
} else {
m_config_manager.setAfkTime(Integer.parseInt(args[1]));
player.sendMessage("挂机判断时间" + args[1]);
m_work_func.restart();
}
} else {
player.sendMessage(ChatColor.RED + "你没有权限执行此命令。");
}
} else {
m_config_manager.setAfkTime(Integer.parseInt(args[1]));
sender.sendMessage("挂机判断时间" + args[1]);
m_work_func.restart();
}
} else if (Objects.equals(args[0], "status")) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (player.isOp()) {
printStatus(sender);
} else {
player.sendMessage(ChatColor.RED + "你没有权限执行此命令。");
}
} else {
printStatus(sender);
}
} }
return true; return true;
} }
public void printStatus(CommandSender sender) {
sender.sendMessage(ChatColor.GREEN + "====================");
sender.sendMessage(ChatColor.GREEN + "| LiveBot 状态报告");
sender.sendMessage(ChatColor.GREEN + "| 当前被直播玩家:" + ChatColor.YELLOW + m_work_func.getCurrentPlayerName());
sender.sendMessage(ChatColor.GREEN + "| 机器人名:" + ChatColor.YELLOW + m_config_manager.getBotName());
sender.sendMessage(ChatColor.GREEN + "| 聚焦时间:" + ChatColor.YELLOW + m_config_manager.getFocusTime());
sender.sendMessage(ChatColor.GREEN + "| 切换方式:" + ChatColor.YELLOW + m_config_manager.getChangePattern());
sender.sendMessage(ChatColor.GREEN + "| 玩家是否可以拒绝:" + ChatColor.YELLOW + m_config_manager.getCanBeMoved());
sender.sendMessage(ChatColor.GREEN + "| 是否跳过挂机玩家:" + ChatColor.YELLOW + m_config_manager.getSkipAFK());
sender.sendMessage(ChatColor.GREEN + "| 挂机判断时间:" + ChatColor.YELLOW + m_config_manager.getAFKTime());
sender.sendMessage(ChatColor.GREEN + "====================");
}
private void updateSkipAFK(CommandSender sender, String[] args) { private void updateSkipAFK(CommandSender sender, String[] args) {
if (Objects.equals(args[1], "true")) { if (Objects.equals(args[1], "true")) {
m_config_manager.setSkipAFK(true); m_config_manager.setSkipAFK(true);
@ -170,7 +213,7 @@ public class Commands implements TabExecutor {
@Override @Override
public List<String> onTabComplete(org.bukkit.command.CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) { public List<String> onTabComplete(org.bukkit.command.CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) {
if (args.length == 1) { if (args.length == 1) {
return Arrays.asList("reload", "setBot", "away", "setTime", "setPattern", "setCanBeMoved", "stop", "start", "skipAFK"); return Arrays.asList("reload", "setBot", "away", "setTime", "setPattern", "setCanBeMoved", "stop", "start", "skipAFK", "setAfkTime", "status");
} else if (args.length == 2) { } else if (args.length == 2) {
if (Objects.equals(args[0], "setBot")) { if (Objects.equals(args[0], "setBot")) {
ArrayList<Player> playerList = new ArrayList<>(Bukkit.getOnlinePlayers()); ArrayList<Player> playerList = new ArrayList<>(Bukkit.getOnlinePlayers());
@ -180,7 +223,7 @@ public class Commands implements TabExecutor {
playerNames.add(player.getName()); playerNames.add(player.getName());
} }
return playerNames; return playerNames;
} else if (Objects.equals(args[0], "setTime")) { } else if (Objects.equals(args[0], "setTime") || Objects.equals(args[0], "setAfkTime")) {
return Collections.singletonList("请输入时间(单位秒)"); return Collections.singletonList("请输入时间(单位秒)");
} else if (Objects.equals(args[0], "setPattern")) { } else if (Objects.equals(args[0], "setPattern")) {
return Arrays.asList("ORDER", "RANDOM"); return Arrays.asList("ORDER", "RANDOM");

View File

@ -33,6 +33,7 @@ public class ConfigManager {
m_can_be_moved = m_config_file.getBoolean("Setting.CanBeMoved", true); m_can_be_moved = m_config_file.getBoolean("Setting.CanBeMoved", true);
m_is_nagging = m_config_file.getBoolean("Setting.IsNagging", true); m_is_nagging = m_config_file.getBoolean("Setting.IsNagging", true);
m_skip_afk = m_config_file.getBoolean("Setting.SkipAFK", true); m_skip_afk = m_config_file.getBoolean("Setting.SkipAFK", true);
m_afk_time = m_config_file.getInt("Setting.AFKTime", 60);
m_logger.info("配置文件当前内容"); m_logger.info("配置文件当前内容");
m_logger.info(" - 直播机器人名称 " + m_bot_name); m_logger.info(" - 直播机器人名称 " + m_bot_name);
m_logger.info(" - 切换频率 " + m_focus_time + ""); m_logger.info(" - 切换频率 " + m_focus_time + "");
@ -50,6 +51,7 @@ public class ConfigManager {
private boolean m_can_be_moved; private boolean m_can_be_moved;
private boolean m_is_nagging; private boolean m_is_nagging;
private boolean m_skip_afk; private boolean m_skip_afk;
private int m_afk_time;
@ -113,6 +115,16 @@ public class ConfigManager {
m_plugin.saveConfig(); m_plugin.saveConfig();
} }
public int getAFKTime() {
return m_afk_time;
}
public void setAfkTime (int time) {
m_afk_time = time;
m_config_file.set("Setting.AFKTime", time);
m_plugin.saveConfig();
}
} }

View File

@ -22,6 +22,7 @@ public final class LiveBot extends JavaPlugin {
Objects.requireNonNull(Bukkit.getPluginCommand("livebot")).setExecutor(new Commands()); Objects.requireNonNull(Bukkit.getPluginCommand("livebot")).setExecutor(new Commands());
Objects.requireNonNull(Bukkit.getPluginCommand("livebot")).setTabCompleter(new Commands()); Objects.requireNonNull(Bukkit.getPluginCommand("livebot")).setTabCompleter(new Commands());
m_work_func.reFindBot();
getLogger().info("LiveBot启动完成。"); getLogger().info("LiveBot启动完成。");
} }

View File

@ -20,7 +20,7 @@ public class WorkFunc {
m_logger = m_plugin.getLogger(); m_logger = m_plugin.getLogger();
} }
private class task extends BukkitRunnable { private class mainTask extends BukkitRunnable {
@Override @Override
public void run() { public void run() {
if (!is_running) { if (!is_running) {
@ -34,25 +34,43 @@ public class WorkFunc {
m_logger.info("准备切换玩家视角。"); m_logger.info("准备切换玩家视角。");
Player player = getNext(); Player player = getNext();
if (player == null) { int total_players = m_players.size();
if (player == null || total_players == 0) {
m_logger.info("没有玩家,本次切换跳过。"); m_logger.info("没有玩家,本次切换跳过。");
player = getNext(); return;
} }
if (player.isDead()) { int counter = 0;
m_logger.info("玩家" + player.getName() + "已经死亡,跳过此玩家。"); while (counter < total_players) {
player = getNext(); counter++;
} if (player.isDead()) {
if (isAFK(player) && m_config_manager.getSkipAFK()) { m_logger.info("玩家" + player.getName() + "已经死亡,跳过此玩家。");
m_logger.info("玩家" + player.getName() + "可能在挂机,跳过此玩家。"); player = getNext();
player = getNext(); continue;
}
if (isAFK(player) && m_config_manager.getSkipAFK()) {
m_logger.info("玩家" + player.getName() + "可能在挂机,跳过此玩家。");
player = getNext();
continue;
}
break;
} }
m_logger.info("切换到玩家:" + player.getName()); m_logger.info("切换到玩家:" + player.getName());
m_bot.setSpectatorTarget(Bukkit.getPlayer(player.getName())); m_bot.setGameMode(GameMode.SPECTATOR);
m_bot.setSpectatorTarget(player);
m_current_player_name = player.getName(); m_current_player_name = player.getName();
player.sendMessage(ChatColor.GOLD + "你被直播机器人选中了,如果不想被直播可以使用/livebot away 在本次登录不再被选中。被直播有助于给服务器增加人气哦~"); player.sendMessage(ChatColor.GOLD + "你被直播机器人选中了,如果不想被直播可以使用/livebot away 在本次登录不再被选中。被直播有助于给服务器增加人气哦~");
} }
}; }
private class updateLocationTask extends BukkitRunnable {
@Override
public void run() {
for (Map.Entry<Player, Location> entry : m_players.entrySet()) {
Player player = entry.getKey();
m_players.put(player, player.getLocation());
}
}
}
private boolean isAFK(Player player) { private boolean isAFK(Player player) {
@ -61,7 +79,7 @@ public class WorkFunc {
m_logger.warning("玩家" + player.getName() + "不在玩家列表中,无法判断是否在挂机。"); m_logger.warning("玩家" + player.getName() + "不在玩家列表中,无法判断是否在挂机。");
return true; return true;
} }
Location location_2 = m_players.put(player, player.getLocation()); Location location_2 = m_players.get(player);
if (location_2 == null) { if (location_2 == null) {
m_logger.warning("玩家" + player.getName() + "上一次位置为空,无法判断是否在挂机。"); m_logger.warning("玩家" + player.getName() + "上一次位置为空,无法判断是否在挂机。");
return true; return true;
@ -75,15 +93,15 @@ public class WorkFunc {
if (m_index >= m_players.size()) { if (m_index >= m_players.size()) {
m_index = 0; m_index = 0;
} }
return get_m_players(m_index); return get_m_player(m_index);
} else if (m_config_manager.getChangePattern().equals("RANDOM")) { } else if (m_config_manager.getChangePattern().equals("RANDOM")) {
int random_index = (int) (Math.random() * m_players.size()); int random_index = (int) (Math.random() * m_players.size());
return get_m_players(random_index); return get_m_player(random_index);
} }
return null; return null;
} }
private Player get_m_players(int index) { private Player get_m_player(int index) {
int i = 0; int i = 0;
for (Map.Entry<Player, Location> entry : m_players.entrySet()) { for (Map.Entry<Player, Location> entry : m_players.entrySet()) {
if (i == index) { if (i == index) {
@ -97,21 +115,19 @@ public class WorkFunc {
public void start(long delay,long time) { public void start(long delay,long time) {
if (!is_running) { if (!is_running) {
is_running = true; is_running = true;
m_task = new task(); m_mainTask = new mainTask();
m_task.runTaskTimer(m_plugin,20L*delay,20L*time); m_updateLocationTask = new updateLocationTask();
m_mainTask.runTaskTimer(m_plugin,20L*delay,20L*time);
m_updateLocationTask.runTaskTimer(m_plugin,20L*delay,m_config_manager.getAFKTime()*20L);
return; return;
} }
m_logger.info("直播机器人已经在运行了。"); m_logger.info("直播机器人已经在运行了。");
} }
public void reFindBot(){ public void reFindBot(){
m_logger.info("重新寻找直播机器人。"); m_logger.info("正在寻找直播机器人。");
botOffline(); botOffline();
m_players.clear(); updatePlayerList();
ArrayList<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
for (Player player : players) {
m_players.put(player, player.getLocation());
}
// 获取对应名字的玩家 // 获取对应名字的玩家
Player bot = Bukkit.getPlayer(m_config_manager.getBotName()); Player bot = Bukkit.getPlayer(m_config_manager.getBotName());
if (bot == null) { if (bot == null) {
@ -125,6 +141,15 @@ public class WorkFunc {
} }
} }
public void updatePlayerList(){
m_logger.info("更新玩家列表。");
m_players.clear();
ArrayList<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
for (Player player : players) {
m_players.put(player, player.getLocation());
}
}
public void restart() { public void restart() {
m_logger.info("重启序列。"); m_logger.info("重启序列。");
stop(); stop();
@ -135,8 +160,10 @@ public class WorkFunc {
if (is_running) { if (is_running) {
m_index = 0; m_index = 0;
is_running = false; is_running = false;
m_task.cancel(); m_mainTask.cancel();
m_task = null; m_updateLocationTask.cancel();
m_mainTask = null;
m_updateLocationTask = null;
m_logger.warning("序列停止。"); m_logger.warning("序列停止。");
return; return;
} }
@ -152,7 +179,8 @@ public class WorkFunc {
private final Map<Player, Location> m_players = new HashMap<>(); private final Map<Player, Location> m_players = new HashMap<>();
private boolean m_is_bot_online = false; private boolean m_is_bot_online = false;
private int m_index = 0; private int m_index = 0;
private task m_task = null; private mainTask m_mainTask = null;
private updateLocationTask m_updateLocationTask = null;
private final LiveBot m_plugin; private final LiveBot m_plugin;
private final ConfigManager m_config_manager; private final ConfigManager m_config_manager;
private final Logger m_logger; private final Logger m_logger;

View File

@ -11,4 +11,6 @@ Setting:
# 是否在聊天栏公告自己的状态 # 是否在聊天栏公告自己的状态
IsNagging: true IsNagging: true
# 是否跳过挂机玩家 # 是否跳过挂机玩家
SkipAFK: true SkipAFK: true
# 挂机判断时间(单位:秒)
AFKTime: 60