允许玩家间互相传送,允许修改玩家设置

This commit is contained in:
2024-12-25 04:16:21 +08:00
parent 42bf3d1a80
commit 60b567ffa9
9 changed files with 631 additions and 48 deletions

View File

@@ -3,10 +3,10 @@ package ling.coordinateRecorder.Commands;
import ling.coordinateRecorder.CoordinateRecorder; import ling.coordinateRecorder.CoordinateRecorder;
import ling.coordinateRecorder.Listener.PlayerMap; import ling.coordinateRecorder.Listener.PlayerMap;
import ling.coordinateRecorder.data.PlayerData; import ling.coordinateRecorder.data.PlayerData;
import ling.coordinateRecorder.data.TransmitData;
import ling.database.tables.records.LocationnotepadPO; import ling.database.tables.records.LocationnotepadPO;
import org.bukkit.Bukkit; import ling.database.tables.records.PlayersettingsPO;
import org.bukkit.ChatColor; import org.bukkit.*;
import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -17,6 +17,8 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.BookMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jooq.Record;
import org.jooq.UpdateSetMoreStep;
import org.jooq.impl.DSL; import org.jooq.impl.DSL;
import java.sql.SQLException; import java.sql.SQLException;
@@ -25,12 +27,13 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import static ling.database.tables.LocationnotepadTB.LOCATIONNOTEPAD; import static ling.database.tables.LocationnotepadTB.LOCATIONNOTEPAD;
import static ling.database.tables.PlayersettingsTB.PLAYERSETTINGS;
/// zb命令处理器 /// zb命令处理器
public class ZbCommand implements CommandExecutor, TabCompleter { public class ZbCommand implements CommandExecutor, TabCompleter {
protected final static List<String> TAB_1 = Arrays.asList("add", "remove", "help", "reload", "list", "fixed", protected final static List<String> TAB_1 = Arrays.asList("add", "remove", "help", "reload", "list", "fixed",
"unfixed", "unlock", "sb"); "unfixed", "unlock", "sb", "tp", "yes", "no", "setting");
public ZbCommand() { public ZbCommand() {
@@ -292,6 +295,152 @@ public class ZbCommand implements CommandExecutor, TabCompleter {
player.sendMessage("从侧边栏取消固定 " + name); player.sendMessage("从侧边栏取消固定 " + name);
} }
protected void playerTp(PlayerData data, Player toPlayer) {
PlayerData to = PlayerMap.getCurrent().getPlayerData(toPlayer);
if (to == null) {
data.getPlayer().sendMessage("目标玩家没有注册");
return;
}
if (to.getTransmitData() != null) {
data.getPlayer().sendMessage("目标玩家正在传送引导中,请稍后再试");
return;
}
if (to.getToMeTransmitData() != null) {
data.getPlayer().sendMessage("有人正在向目标玩家传送,请稍后再试");
return;
}
TransmitData transmitData = new TransmitData(data, to);
CoordinateRecorder.getTransmitService().addTransmit(transmitData);
}
protected void locationTp(PlayerData data, String name) throws SQLException {
var ctx = CoordinateRecorder.getDatabase().getDSL();
Record result = ctx.select().from(LOCATIONNOTEPAD).where(
LOCATIONNOTEPAD.UID.eq(data.getPlayer().getUniqueId().toString())
.and(LOCATIONNOTEPAD.ISDELETE.eq(false).and(LOCATIONNOTEPAD.NAME.eq(name)))).fetchOne();
if (result == null) {
data.getPlayer().sendMessage(ChatColor.RED + "目标不存在");
return;
}
LocationnotepadPO res = result.into(LocationnotepadPO.class);
World world = Bukkit.getWorld(res.getWorld());
if (world == null) {
data.getPlayer().sendMessage(ChatColor.RED + "世界不存在");
return;
}
Location target = new Location(world, res.getX(), res.getY(), res.getZ());
CoordinateRecorder.getTransmitService().addTransmit(new TransmitData(data, target));
//data.getPlayer().teleport(target);
//data.getPlayer().sendMessage("已将您送达 " + name);
}
protected void tp(Player player, String[] strings) throws SQLException {
if (strings.length > 2) {
player.sendMessage(ChatColor.RED + "命令过长");
return;
}
if (strings.length != 2) {
player.sendMessage(ChatColor.RED + "请指定目标");
return;
}
PlayerData data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) {
player.sendMessage(ChatColor.RED + "玩家未注册");
return;
}
if (data.getTransmitData() != null) {
player.sendMessage(ChatColor.RED + "你已经在引导传送了");
return;
}
if (data.getToMeTransmitData() != null) {
player.sendMessage(ChatColor.RED + "有人正在向你传送");
return;
}
String targetName = strings[1];
Player targetPlayer = Bukkit.getPlayer(targetName);
if (targetPlayer == null) {
locationTp(data, targetName);
return;
} else {
playerTp(data, targetPlayer);
}
}
protected void yesOnNo(Player player, String[] strings) {
if (strings.length != 1) {
player.sendMessage(ChatColor.RED + "命令过长!");
return;
}
PlayerData data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) {
player.sendMessage(ChatColor.RED + "玩家没有登录");
return;
}
if (data.getToMeTransmitData() == null) {
player.sendMessage(ChatColor.RED + "没有找到指向你的传送请求");
return;
}
if (strings[0].equals("yes")) {
CoordinateRecorder.getTransmitService().confirmTransmit(data.getToMeTransmitData());
} else {
CoordinateRecorder.getTransmitService().rejectTransmit(data.getToMeTransmitData());
}
}
protected void settingTp(Player player, String[] strings) {
PlayerData data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) {
player.sendMessage(ChatColor.RED + "玩家没有注册");
return;
}
if (strings.length > 4) {
player.sendMessage(ChatColor.RED + "命令过长!");
return;
}
if (strings.length < 3) {
player.sendMessage(ChatColor.RED + "命令过短使用true/false表示是否允许他人向你传送");
return;
}
boolean isTp;
if (strings[2].equals("true"))
isTp = true;
else if (strings[2].equals("false"))
isTp = false;
else {
player.sendMessage(ChatColor.RED + "语法错误,在" + strings[2] + "");
return;
}
String message = null;
if (strings.length == 4) {
message = strings[3];
}
try {
var ctx = CoordinateRecorder.getDatabase().getDSL();
UpdateSetMoreStep<PlayersettingsPO> update = ctx.update(PLAYERSETTINGS).set(PLAYERSETTINGS.TPME, isTp);
if (message != null)
update = update.set(PLAYERSETTINGS.SETTINGSREJECTTPMESSAGE, message);
update.where(PLAYERSETTINGS.UID.eq(player.getUniqueId().toString())).execute();
data.loadPlayerSettings();
player.sendMessage("设置已经成功更新!");
} catch (SQLException e) {
System.out.println("修改设置失败:" + e.getMessage());
player.sendMessage(ChatColor.RED + "修改设置失败:服务器内部错误!");
}
}
protected void setting(Player player, String[] strings) {
if (strings.length < 2) {
player.sendMessage(ChatColor.RED + "命令过短。");
return;
}
if (strings[1].equals("tp")) {
settingTp(player, strings);
} else {
player.sendMessage(ChatColor.RED + "未知的选项:" + strings[1]);
}
}
protected boolean execute(Player player, String[] strings) { protected boolean execute(Player player, String[] strings) {
if (strings.length < 1) { if (strings.length < 1) {
player.sendMessage(ChatColor.RED + "语法错误:需要 [选项]"); player.sendMessage(ChatColor.RED + "语法错误:需要 [选项]");
@@ -326,6 +475,16 @@ public class ZbCommand implements CommandExecutor, TabCompleter {
case "sb": case "sb":
sb(player, strings); sb(player, strings);
break; break;
case "tp":
tp(player, strings);
break;
case "yes":
case "no":
yesOnNo(player, strings);
break;
case "setting":
setting(player, strings);
break;
default: default:
player.sendMessage(ChatColor.RED + "未知的选项:" + strings[0]); player.sendMessage(ChatColor.RED + "未知的选项:" + strings[0]);
break; break;
@@ -382,6 +541,35 @@ public class ZbCommand implements CommandExecutor, TabCompleter {
return list; return list;
} }
protected List<String> onTpTab(Player player, String latest, String[] strings) {
var data = PlayerMap.getCurrent().getPlayerData(player);
if (data == null) return List.of();
List<String> list = new ArrayList<>();
var locations = data.getLocationList();
for (LocationnotepadPO location : locations) {
list.add(location.getName());
}
var playerList = Bukkit.getOnlinePlayers();
for (Player obj : playerList) {
if (obj.getUniqueId().equals(player.getUniqueId())) continue;
list.add(obj.getName());
}
return filter(latest, list);
}
protected List<String> onSettingTab(Player player, String latest, String[] strings) {
if (strings.length == 2) {
return filter(latest, new ArrayList<>(List.of("tp")));
}
if (strings.length == 3) {
return List.of("<是否允许向你传送true 或 false>");
}
if (strings.length == 4) {
return List.of("<拒绝玩家的理由>");
}
return List.of();
}
@Override @Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
if (!(commandSender instanceof Player player)) { if (!(commandSender instanceof Player player)) {
@@ -409,11 +597,17 @@ public class ZbCommand implements CommandExecutor, TabCompleter {
case "sb" -> { case "sb" -> {
return onSbTab(player, latest, strings); return onSbTab(player, latest, strings);
} }
case "tp" -> {
return onTpTab(player, latest, strings);
}
} }
} }
if (strings[0].equals("add")) { if (strings[0].equals("add")) {
return onAddTab(player, latest, strings); return onAddTab(player, latest, strings);
} }
if (strings[0].equals("setting")) {
return onSettingTab(player, latest, strings);
}
return List.of(); return List.of();
} }

View File

@@ -1,5 +1,6 @@
package ling.coordinateRecorder; package ling.coordinateRecorder;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -13,8 +14,20 @@ public class Config {
public static final int TOMBSTONE_PUNISHMENT = 3; public static final int TOMBSTONE_PUNISHMENT = 3;
/// 禁止解锁墓碑阈值 /// 禁止解锁墓碑阈值
public static final int UNLOCK_PROHIBITED = 24; public static final int UNLOCK_PROHIBITED = 24;
/// 禁止传送阈值
public static final int TRANSMIT_PROHIBITED = 48;
/// 传送引导时间
public static final int TRANSMIT_GUIDE_TIME = 8000;
/// 传送请求失效时间
public static final int TRANSMIT_EXPIRATION_TIME = 45000;
/// 跨世界传送惩罚
public static final int CROSS_WORLD_TELEPORTATION_PENALTY = 10;
public static final HashMap<Material, Double> ITEM_VALUE_MAP = new HashMap<>(); public static final HashMap<Material, Double> ITEM_VALUE_MAP = new HashMap<>();
public static String getFractionTimeMessage(long value) {
return "" + ChatColor.YELLOW + value + ChatColor.WHITE;
}
/// 计算物品堆的价值 /// 计算物品堆的价值
public static int getItemStackValue(List<ItemStack> stack) { public static int getItemStackValue(List<ItemStack> stack) {
double[] value = {0d}; double[] value = {0d};

View File

@@ -1,12 +1,14 @@
package ling.coordinateRecorder; package ling.coordinateRecorder;
import ling.coordinateRecorder.Commands.ZbCommand; import ling.coordinateRecorder.Commands.ZbCommand;
import ling.coordinateRecorder.Listener.InterruptTransmit;
import ling.coordinateRecorder.Listener.PlayerAuthMeLoginEventListener; import ling.coordinateRecorder.Listener.PlayerAuthMeLoginEventListener;
import ling.coordinateRecorder.Listener.PlayerEventListener; import ling.coordinateRecorder.Listener.PlayerEventListener;
import ling.coordinateRecorder.Listener.PlayerLoginEventListener; import ling.coordinateRecorder.Listener.PlayerLoginEventListener;
import ling.coordinateRecorder.Service.ServiceManager;
import ling.coordinateRecorder.Service.TransmitService;
import ling.coordinateRecorder.data.Database; import ling.coordinateRecorder.data.Database;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@@ -17,6 +19,7 @@ public final class CoordinateRecorder extends JavaPlugin {
private static CoordinateRecorder current; private static CoordinateRecorder current;
private static Database database; private static Database database;
private static Plugin authMePlugin; private static Plugin authMePlugin;
private static TransmitService transmitService;
private static void start() throws SQLException { private static void start() throws SQLException {
database.installPlugin(); database.installPlugin();
@@ -24,6 +27,7 @@ public final class CoordinateRecorder extends JavaPlugin {
private void loadListener() { private void loadListener() {
Bukkit.getPluginManager().registerEvents(new PlayerEventListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerEventListener(), this);
Bukkit.getPluginManager().registerEvents(new InterruptTransmit(), this);
if (authMePlugin != null && authMePlugin.isEnabled()) { if (authMePlugin != null && authMePlugin.isEnabled()) {
getLogger().info("找到AuthMe插件将使用AuthMe兼容接口"); getLogger().info("找到AuthMe插件将使用AuthMe兼容接口");
Bukkit.getPluginManager().registerEvents(new PlayerAuthMeLoginEventListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerAuthMeLoginEventListener(), this);
@@ -47,12 +51,19 @@ public final class CoordinateRecorder extends JavaPlugin {
assert command != null; assert command != null;
command.setExecutor(zb); command.setExecutor(zb);
command.setTabCompleter(zb); command.setTabCompleter(zb);
transmitService = (TransmitService) ServiceManager.getCurrent().startService(TransmitService.class, 4L);
getLogger().info("加载完毕"); getLogger().info("加载完毕");
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException("插件初始化失败", e); throw new RuntimeException("插件初始化失败", e);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("启动服务失败");
} }
} }
public static TransmitService getTransmitService() {
return transmitService;
}
@Override @Override
public void onDisable() { public void onDisable() {
// Plugin shutdown logic // Plugin shutdown logic

View File

@@ -0,0 +1,30 @@
package ling.coordinateRecorder.Listener;
import ling.coordinateRecorder.data.PlayerData;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
public class InterruptTransmit implements Listener {
/// 当玩家移动了自己的位置时,打断传送引导
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Location from = event.getFrom();
Location to = event.getTo();
if (to == null)
return;
if (from.getBlockX() == to.getBlockX() && from.getBlockY() == to.getBlockY() && from.getBlockZ() == to.getBlockZ())
return;
PlayerData data = PlayerMap.getCurrent().getPlayerData(event.getPlayer());
if (data == null)
return;
if (data.getTransmitData() != null)
data.getTransmitData().interrupt("传送来源的位置发生了变化");
if (data.getToMeTransmitData() != null && data.getToMeTransmitData().isConfirm())
data.getToMeTransmitData().interrupt("传送目标的位置发生了变化");
}
}

View File

@@ -0,0 +1,5 @@
package ling.coordinateRecorder.Service;
public interface Service {
void start();
}

View File

@@ -0,0 +1,23 @@
package ling.coordinateRecorder.Service;
import ling.coordinateRecorder.CoordinateRecorder;
import org.bukkit.Bukkit;
public final class ServiceManager {
private static final ServiceManager current = new ServiceManager();
private ServiceManager() {
}
public static ServiceManager getCurrent() {
return current;
}
/// 启动一个服务
public Service startService(Class<? extends Service> server,long tick) throws ReflectiveOperationException {
Service service = server.getDeclaredConstructor().newInstance();
Bukkit.getScheduler().runTaskTimer(CoordinateRecorder.getCurrent(), service::start, 0L, tick);
return service;
}
}

View File

@@ -0,0 +1,198 @@
package ling.coordinateRecorder.Service;
import ling.coordinateRecorder.Config;
import ling.coordinateRecorder.data.TransmitData;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/// 传送服务
public final class TransmitService implements Service {
private final AtomicBoolean lockFlag = new AtomicBoolean(false);
private final HashMap<Player, TransmitData> list = new HashMap<>();
public TransmitService() {
}
private void lock() {
while (!lockFlag.compareAndSet(false, true)) {
}
}
private void unlock() {
lockFlag.set(false);
}
/// 输出传送提示信息
private void sendTransmitMessage(TransmitData data) {
Player player = data.getPlayer().getPlayer();
Location from = player.getLocation();
Location to = data.getTarget();
if (to == null)
to = data.getTargetPlayer().getPlayer().getLocation();
if (data.isConfirm()) {
player.sendMessage(
"传送引导中...(将带来" + Config.getFractionTimeMessage(
getTransmitCost(from, to)) +
"点沙雕值惩罚,当前" + Config.getFractionTimeMessage(data.getPlayer().getFraction()) +
")");
} else {
player.sendMessage("正在等待目标玩家响应...");
data.getTargetPlayer().getPlayer().sendMessage("玩家 " + player.getName() + " 正在请求向你传送\n使用"
+ ChatColor.YELLOW + "/zb yes" + ChatColor.WHITE + "同意该请求,使用" + ChatColor.YELLOW + "/zb no" + ChatColor.WHITE + "拒绝");
}
}
/// 检查沙雕值是否超出阈值
private boolean isFractionTransmit(TransmitData data) {
return data.getPlayer().getFraction() <= Config.TRANSMIT_PROHIBITED;
}
/// 同意一个传送请求
public void confirmTransmit(TransmitData data) {
data.confirm();
sendTransmitMessage(data);
}
/// 拒绝一个传送请求
public void rejectTransmit(TransmitData data) {
lock();
data.getPlayer().getPlayer().sendMessage("目标玩家拒绝了你的传送请求");
data.getTargetPlayer().getPlayer().sendMessage("已拒绝");
list.remove(data.getPlayer().getPlayer());
clearTransmitData(data);
unlock();
}
public void addTransmit(TransmitData data) {
if (!isFractionTransmit(data)) {
data.getPlayer().getPlayer().sendMessage(
"你的沙雕值过高,被禁止传送!( >" + Config.getFractionTimeMessage(data.getPlayer().getFraction()) +
" )");
return;
}
// 如果目标玩家不允许任何人向它传送
if (data.getTargetPlayer() != null && !data.getTargetPlayer().isTpMe()) {
data.getPlayer().getPlayer().sendMessage(
"目标玩家拒绝了你的传送请求,因为:" + data.getTargetPlayer().rejectMessage());
data.getTargetPlayer().getPlayer().sendMessage("玩家 " + data.getPlayer().getPlayer().getName() + " " +
"试图向你传送,已根据设置自动拒绝。");
clearTransmitData(data);
return;
}
lock();
sendTransmitMessage(data);
data.getPlayer().setTransmitData(data);
if (data.getTargetPlayer() != null)
data.getTargetPlayer().setToMeTransmitData(data);
list.put(data.getPlayer().getPlayer(), data);
unlock();
}
/// 计算传送将要带来的沙雕值惩罚
///
/// 两千米内每五百米带来一点沙雕值惩罚
/// 两万米内每两千米带来一点沙雕值惩罚
/// 两万米后每两万米带来一点沙雕值惩罚
/// 单次传送封顶带来 Config.UNLOCK_PROHIBITED 点沙雕值惩罚
public static int getTransmitCost(Location from, Location to) {
assert from.getWorld() != null;
assert to.getWorld() != null;
//不在同一世界的传送,使用统一沙雕值惩罚
if (!from.getWorld().toString().equals(to.getWorld().toString())) {
return Config.CROSS_WORLD_TELEPORTATION_PENALTY;
}
double distance = from.distance(to);
int value = 0;
{
//两千米
double dis = Math.min(distance, 2000);
value += (int) ((dis + 500 + 1) / 500);
}
if (distance > 2000) {
//两万米
double dis = Math.min(distance, 20000) - 2000;
value += (int) ((dis + 2000 + 1) / 2000);
}
if (distance > 20000) {
double dis = distance - 20000;
value += (int) ((dis + 20000 + 1) / 20000);
}
return Math.min(value, Config.UNLOCK_PROHIBITED);
}
/// 处理一个传送请求
private void success(TransmitData data) {
Location from = data.getPlayer().getPlayer().getLocation();
Location to = data.getTarget();
if (to == null)
to = data.getTargetPlayer().getPlayer().getLocation();
int value = getTransmitCost(from, to);
try {
data.getPlayer().addFraction(value);
data.getPlayer().getPlayer().teleport(to);
data.getPlayer().getPlayer().sendMessage(
"传送完毕!您受到了" + Config.getFractionTimeMessage(value) + "点沙雕值惩罚!(当前:"
+ Config.getFractionTimeMessage(data.getPlayer().getFraction()) + "");
} catch (SQLException e) {
data.getPlayer().getPlayer().sendMessage(ChatColor.RED + "传送失败:施加沙雕值惩罚出错!");
}
}
/// 使一个传送请求失效
private void clearTransmitData(TransmitData data) {
data.getPlayer().setTransmitData(null);
if (data.getTargetPlayer() != null)
data.getTargetPlayer().setToMeTransmitData(null);
data.clear();
}
@Override
public void start() {
lock();
Iterator<Map.Entry<Player, TransmitData>> iterator = list.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Player, TransmitData> entry = iterator.next();
var data = entry.getValue();
//移除失效请求
if (!data.isConfirm() && data.getTime() + Config.TRANSMIT_EXPIRATION_TIME < System.currentTimeMillis()) {
data.getPlayer().getPlayer().sendMessage("对方超时未响应,传送取消。");
data.getTargetPlayer().getPlayer().sendMessage("超时未响应,已自动拒绝对方!");
clearTransmitData(data);
iterator.remove();
continue;
}
//删除已经被取消的传送请求
if (data.isInterrupt()) {
data.getPlayer().getPlayer().sendMessage("传送取消!因为" + data.getInterruptMessage());
if (data.getTargetPlayer() != null)
data.getTargetPlayer().getPlayer().sendMessage(
"玩家 " + data.getPlayer().getPlayer()
.getName() + " " + "的传送已取消,因为" + data.getInterruptMessage());
clearTransmitData(data);
iterator.remove();
continue;
}
if (!data.isConfirm())
continue;
//处理已经引导完毕的传送请求
if (data.getTime() + Config.TRANSMIT_GUIDE_TIME < System.currentTimeMillis()) {
success(data);
iterator.remove();
clearTransmitData(data);
continue;
}
//计算其余传送请求的引导时间
long time = System.currentTimeMillis() - data.getTime();
data.getBossBar().setProgress((double) time / Config.TRANSMIT_GUIDE_TIME);
}
unlock();
}
}

View File

@@ -37,6 +37,8 @@ public class PlayerData {
protected PlayerDeathData death; protected PlayerDeathData death;
//上次计分时间 //上次计分时间
protected long fractionTime; protected long fractionTime;
protected TransmitData transmitData = null;
protected TransmitData toMeTransmitData = null;
public PlayerData(Player player) throws SQLException { public PlayerData(Player player) throws SQLException {
@@ -60,19 +62,49 @@ public class PlayerData {
return settings.getFraction(); return settings.getFraction();
} }
/// 是否允许其他玩家向自己传送
public boolean isTpMe() {
return settings.getTpme();
}
/// 拒绝传送消息
public String rejectMessage() {
return settings.getSettingsrejecttpmessage();
}
public void setTombstoneBlock(Block tombstone) { public void setTombstoneBlock(Block tombstone) {
this.tombstoneBlock = tombstone; this.tombstoneBlock = tombstone;
} }
public TransmitData getTransmitData() {
return transmitData;
}
public void setTransmitData(TransmitData transmitData) {
this.transmitData = transmitData;
}
public TransmitData getToMeTransmitData() {
return toMeTransmitData;
}
public void setToMeTransmitData(TransmitData toMeTransmitData) {
this.toMeTransmitData = toMeTransmitData;
}
/// 检查两个地点是否位于同一个世界 /// 检查两个地点是否位于同一个世界
public static boolean isSameWorld(Location l1, Location l2) { public static boolean isSameWorld(Location l1, Location l2) {
World w1 = l1.getWorld(); World w1 = l1.getWorld();
World w2 = l2.getWorld(); World w2 = l2.getWorld();
if (w1 == null || w2 == null) if (w1 == null || w2 == null) return false;
return false;
return w1.getName().equals(w2.getName()); return w1.getName().equals(w2.getName());
} }
public Player getPlayer() {
return player;
}
/// 解锁墓碑 /// 解锁墓碑
public void unlockTombstoneBlock() { public void unlockTombstoneBlock() {
if (tombstoneBlock == null) { if (tombstoneBlock == null) {
@@ -201,12 +233,17 @@ public class PlayerData {
protected Record loadPlayerSettingsRecord() throws SQLException { protected Record loadPlayerSettingsRecord() throws SQLException {
return CoordinateRecorder.getDatabase().getDSL().select().from(PLAYERSETTINGS).where( return CoordinateRecorder.getDatabase().getDSL().select().from(PLAYERSETTINGS).where(
PLAYERSETTINGS.UID.eq(player.getUniqueId().toString()) PLAYERSETTINGS.UID.eq(player.getUniqueId().toString())).fetchOne();
).fetchOne();
} }
/// 关闭ui /// 关闭ui
public void closeUI() { public void closeUI() {
if (this.transmitData != null) {
this.transmitData.interrupt("玩家离线");
}
if (this.toMeTransmitData != null) {
this.toMeTransmitData.interrupt("玩家离线");
}
ui.closeUI(); ui.closeUI();
} }
@@ -220,9 +257,8 @@ public class PlayerData {
return false; return false;
} }
var ctx = CoordinateRecorder.getDatabase().getDSL(); var ctx = CoordinateRecorder.getDatabase().getDSL();
int rows = ctx.update(PLAYERSETTINGS).set( int rows = ctx.update(PLAYERSETTINGS).set(PLAYERSETTINGS.FRACTION,
PLAYERSETTINGS.FRACTION, DSL.greatest(PLAYERSETTINGS.FRACTION.plus(fraction), DSL.val(0)))
DSL.greatest(PLAYERSETTINGS.FRACTION.plus(fraction), DSL.val(0)))
.where(PLAYERSETTINGS.UID.eq(player.getUniqueId().toString())).execute(); .where(PLAYERSETTINGS.UID.eq(player.getUniqueId().toString())).execute();
loadPlayerSettings(); loadPlayerSettings();
return rows == 1; return rows == 1;
@@ -231,11 +267,9 @@ public class PlayerData {
/// 删除一个地标 /// 删除一个地标
public boolean removeLocation(String name) throws SQLException { public boolean removeLocation(String name) throws SQLException {
var ctx = CoordinateRecorder.getDatabase().getDSL(); var ctx = CoordinateRecorder.getDatabase().getDSL();
int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISDELETE, true) int rows = ctx.update(LOCATIONNOTEPAD).set(LOCATIONNOTEPAD.ISDELETE, true).where(
.where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()) LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString())
.and(LOCATIONNOTEPAD.NAME.eq(name) .and(LOCATIONNOTEPAD.NAME.eq(name).and(LOCATIONNOTEPAD.ISDELETE.eq(false)))).execute();
.and(LOCATIONNOTEPAD.ISDELETE.eq(false)))
).execute();
if (rows == 0) { if (rows == 0) {
player.sendMessage(ChatColor.RED + "操作失败:记录不存在"); player.sendMessage(ChatColor.RED + "操作失败:记录不存在");
return false; return false;
@@ -251,35 +285,21 @@ public class PlayerData {
return false; return false;
} }
var ctx = CoordinateRecorder.getDatabase().getDSL(); var ctx = CoordinateRecorder.getDatabase().getDSL();
Record record = ctx.select().from(LOCATIONNOTEPAD).where( Record record = ctx.select().from(LOCATIONNOTEPAD).where(LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString())
LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()) .and(LOCATIONNOTEPAD.NAME.eq(name))
.and(LOCATIONNOTEPAD.NAME.eq(name)) .and(LOCATIONNOTEPAD.ISDELETE.eq(false)))
.and(LOCATIONNOTEPAD.ISDELETE.eq(false)) .fetchOne();
).fetchOne();
if (record != null) { if (record != null) {
player.sendMessage(ChatColor.RED + "该名称的地点已经存在"); player.sendMessage(ChatColor.RED + "该名称的地点已经存在");
return false; return false;
} }
Location location = player.getLocation(); Location location = player.getLocation();
ctx.insertInto(LOCATIONNOTEPAD).columns( ctx.insertInto(LOCATIONNOTEPAD).columns(LOCATIONNOTEPAD.UID, LOCATIONNOTEPAD.WORLD, LOCATIONNOTEPAD.NAME,
LOCATIONNOTEPAD.UID, LOCATIONNOTEPAD.X, LOCATIONNOTEPAD.Y, LOCATIONNOTEPAD.Z,
LOCATIONNOTEPAD.WORLD, LOCATIONNOTEPAD.TIME, LOCATIONNOTEPAD.ISFIXED).values(
LOCATIONNOTEPAD.NAME, player.getUniqueId().toString(), Objects.requireNonNull(location.getWorld()).getName(), name,
LOCATIONNOTEPAD.X, (int) location.getX(), (int) location.getY(), (int) location.getZ(),
LOCATIONNOTEPAD.Y, BigDecimal.valueOf(System.currentTimeMillis()), isFixed).execute();
LOCATIONNOTEPAD.Z,
LOCATIONNOTEPAD.TIME,
LOCATIONNOTEPAD.ISFIXED
).values(
player.getUniqueId().toString(),
Objects.requireNonNull(location.getWorld()).getName(),
name,
(int) location.getX(),
(int) location.getY(),
(int) location.getZ(),
BigDecimal.valueOf(System.currentTimeMillis()),
isFixed
).execute();
locationListUpdate(); locationListUpdate();
return true; return true;
} }
@@ -289,10 +309,8 @@ public class PlayerData {
var record = loadPlayerSettingsRecord(); var record = loadPlayerSettingsRecord();
if (record == null) { if (record == null) {
//设置不存在,新建一行 //设置不存在,新建一行
CoordinateRecorder.getDatabase().getDSL().insertInto(PLAYERSETTINGS) CoordinateRecorder.getDatabase().getDSL().insertInto(PLAYERSETTINGS).columns(PLAYERSETTINGS.UID).values(
.columns(PLAYERSETTINGS.UID) player.getUniqueId().toString()).execute();
.values(player.getUniqueId().toString())
.execute();
record = loadPlayerSettingsRecord(); record = loadPlayerSettingsRecord();
assert record != null; assert record != null;
} }
@@ -302,9 +320,8 @@ public class PlayerData {
/// 重新载入玩家的固定地点数据 /// 重新载入玩家的固定地点数据
public void locationListUpdate() throws SQLException { public void locationListUpdate() throws SQLException {
Result<Record> result = CoordinateRecorder.getDatabase().getDSL().select().from(LOCATIONNOTEPAD).where( Result<Record> result = CoordinateRecorder.getDatabase().getDSL().select().from(LOCATIONNOTEPAD).where(
LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()).and(LOCATIONNOTEPAD.ISFIXED.eq(true)) LOCATIONNOTEPAD.UID.eq(player.getUniqueId().toString()).and(LOCATIONNOTEPAD.ISFIXED.eq(true))
.and(LOCATIONNOTEPAD.ISDELETE.eq(false))).orderBy(LOCATIONNOTEPAD.ID.desc()) .and(LOCATIONNOTEPAD.ISDELETE.eq(false))).orderBy(LOCATIONNOTEPAD.ID.desc()).limit(10).fetch();
.limit(10).fetch();
locationList = result.into(LocationnotepadPO.class); locationList = result.into(LocationnotepadPO.class);
ui.flashLocations(); ui.flashLocations();
} }

View File

@@ -0,0 +1,92 @@
package ling.coordinateRecorder.data;
import ling.coordinateRecorder.CoordinateRecorder;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.jetbrains.annotations.Nullable;
/// 传送数据
public class TransmitData {
protected final PlayerData player;
protected final Location target;
protected final PlayerData targetPlayer;
protected long time;
protected boolean isInterrupt = false;
protected boolean isConfirm = true;
protected BossBar bossBar = Bukkit.createBossBar(new NamespacedKey(CoordinateRecorder.getCurrent(), "transmitBar"),
"正在准备传送", BarColor.BLUE, BarStyle.SOLID, BarFlag.DARKEN_SKY);
protected String interruptMessage = "未知原因";
public TransmitData(PlayerData player, Location target) {
this.target = target;
this.player = player;
this.targetPlayer = null;
time = System.currentTimeMillis();
bossBar.addPlayer(player.getPlayer());
}
public TransmitData(PlayerData player, PlayerData target) {
this.targetPlayer = target;
this.target = null;
this.player = player;
this.time = System.currentTimeMillis();
isConfirm = false;
bossBar.setTitle("等待目标玩家响应");
bossBar.addPlayer(player.getPlayer());
}
public boolean isConfirm() {
return isConfirm;
}
public void confirm() {
isConfirm = true;
bossBar.setTitle("正在准备传送");
time = System.currentTimeMillis();
bossBar.addPlayer(targetPlayer.getPlayer());
}
public void clear() {
bossBar.removeAll();
}
/// 打断传送
public void interrupt(@Nullable String message) {
this.isInterrupt = true;
if (message != null)
this.interruptMessage = message;
}
public String getInterruptMessage() {
return interruptMessage;
}
public BossBar getBossBar() {
return bossBar;
}
public boolean isInterrupt() {
return isInterrupt;
}
public long getTime() {
return time;
}
public PlayerData getTargetPlayer() {
return targetPlayer;
}
public PlayerData getPlayer() {
return player;
}
public Location getTarget() {
return target;
}
}