初步实现跨服传送功能(未测试)

This commit is contained in:
zhangyuheng 2024-06-26 16:16:02 +08:00
parent b1d76a8cff
commit d514984e56
7 changed files with 146 additions and 49 deletions

View File

@ -6,7 +6,7 @@
<groupId>cn.lunadeer</groupId> <groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId> <artifactId>Dominion</artifactId>
<version>1.33.7-beta</version> <version>1.33.7-global-tp-beta</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Dominion</name> <name>Dominion</name>

View File

@ -4,6 +4,7 @@ import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerDTO; import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.managers.GlobalTeleport;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.ParticleRender; import cn.lunadeer.minecraftpluginutils.ParticleRender;
import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.Scheduler;
@ -65,7 +66,7 @@ public class Cache {
id_dominions = new ConcurrentHashMap<>(); id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>(); world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>(); dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll(); List<DominionDTO> dominions = DominionDTO.selectAllOfServer(GlobalTeleport.instance.getThisServerId());
count = dominions.size(); count = dominions.size();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>(); Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) { for (DominionDTO d : dominions) {

View File

@ -7,6 +7,7 @@ import cn.lunadeer.dominion.controllers.DominionController;
import cn.lunadeer.dominion.dtos.DominionDTO; import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO; import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.managers.GlobalTeleport;
import cn.lunadeer.minecraftpluginutils.Notification; import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Scheduler; import cn.lunadeer.minecraftpluginutils.Scheduler;
import cn.lunadeer.minecraftpluginutils.Teleport; import cn.lunadeer.minecraftpluginutils.Teleport;
@ -15,6 +16,7 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
@ -22,6 +24,7 @@ import java.util.Map;
import static cn.lunadeer.dominion.DominionNode.isInDominion; import static cn.lunadeer.dominion.DominionNode.isInDominion;
import static cn.lunadeer.dominion.commands.Apis.autoPoints; import static cn.lunadeer.dominion.commands.Apis.autoPoints;
import static cn.lunadeer.dominion.commands.Apis.playerOnly; import static cn.lunadeer.dominion.commands.Apis.playerOnly;
import static cn.lunadeer.dominion.managers.GlobalTeleport.doTp;
public class DominionOperate { public class DominionOperate {
/** /**
@ -357,16 +360,7 @@ public class DominionOperate {
} }
if (player.isOp() && Dominion.config.getLimitOpBypass()) { if (player.isOp() && Dominion.config.getLimitOpBypass()) {
Notification.warn(sender, "你是OP将忽略领地传送限制"); Notification.warn(sender, "你是OP将忽略领地传送限制");
Location location = dominionDTO.getTpLocation(); doTp(player, dominionDTO);
if (location == null) {
int x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
location = new Location(world, x, player.getLocation().getY(), z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
}
Teleport.doTeleportSafely(player, location);
Notification.info(player, "已将你传送到 " + dominionDTO.getName());
return; return;
} }
if (!Dominion.config.getTpEnable()) { if (!Dominion.config.getTpEnable()) {
@ -418,26 +412,7 @@ public class DominionOperate {
} }
Cache.instance.NextTimeAllowTeleport.put(player.getUniqueId(), now.plusSeconds(Dominion.config.getTpCoolDown())); Cache.instance.NextTimeAllowTeleport.put(player.getUniqueId(), now.plusSeconds(Dominion.config.getTpCoolDown()));
Scheduler.runTaskLater(() -> { Scheduler.runTaskLater(() -> {
Location location = dominionDTO.getTpLocation(); doTp(player, dominionDTO);
int center_x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int center_z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
if (location == null) {
location = new Location(world, center_x, player.getLocation().getY(), center_z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
} else if (!isInDominion(dominionDTO, location)) {
location = new Location(world, center_x, player.getLocation().getY(), center_z);
XLogger.warn("领地 %s 传送点不在领地内,将尝试传送到中心点", dominionDTO.getName());
}
if (player.isOnline()) {
Teleport.doTeleportSafely(player, location).thenAccept(b -> {
if (b) {
Notification.info(player, "已将你传送到 " + dominionDTO.getName());
} else {
Notification.error(player, "传送失败,请重试");
}
});
}
}, 20L * Dominion.config.getTpDelay()); }, 20L * Dominion.config.getTpDelay());
} }

View File

@ -2,6 +2,7 @@ package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache; import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion; import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.managers.GlobalTeleport;
import cn.lunadeer.minecraftpluginutils.XLogger; import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager; import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field; import cn.lunadeer.minecraftpluginutils.databse.Field;
@ -47,13 +48,15 @@ public class DominionDTO {
flags.put(f, rs.getBoolean(f.getFlagName())); flags.put(f, rs.getBoolean(f.getFlagName()));
} }
String color = rs.getString("color"); String color = rs.getString("color");
Integer serverId = rs.getInt("server_id");
DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId, DominionDTO dominion = new DominionDTO(id, owner, name, world, x1, y1, z1, x2, y2, z2, parentDomId,
rs.getString("join_message"), rs.getString("join_message"),
rs.getString("leave_message"), rs.getString("leave_message"),
flags, flags,
tp_location, tp_location,
color color,
serverId
); );
dominions.add(dominion); dominions.add(dominion);
} }
@ -65,6 +68,11 @@ public class DominionDTO {
return query(sql); return query(sql);
} }
public static List<DominionDTO> selectAllOfServer(Integer id) {
String sql = "SELECT * FROM dominion WHERE id > 0 AND server_id = ?;";
return query(sql, id);
}
public static List<DominionDTO> selectAll(String world) { public static List<DominionDTO> selectAll(String world) {
String sql = "SELECT * FROM dominion WHERE world = ? AND id > 0;"; String sql = "SELECT * FROM dominion WHERE world = ? AND id > 0;";
return query(sql, world); return query(sql, world);
@ -123,7 +131,7 @@ public class DominionDTO {
.field(dominion.x2).field(dominion.y2).field(dominion.z2) .field(dominion.x2).field(dominion.y2).field(dominion.z2)
.field(dominion.parentDomId) .field(dominion.parentDomId)
.field(dominion.joinMessage).field(dominion.leaveMessage) .field(dominion.joinMessage).field(dominion.leaveMessage)
.field(dominion.tp_location); .field(dominion.tp_location).field(dominion.serverId);
for (Flag f : Flag.getDominionFlagsEnabled()) { for (Flag f : Flag.getDominionFlagsEnabled()) {
insert.field(new Field(f.getFlagName(), f.getDefaultValue())); insert.field(new Field(f.getFlagName(), f.getDefaultValue()));
} }
@ -150,7 +158,7 @@ public class DominionDTO {
String joinMessage, String leaveMessage, String joinMessage, String leaveMessage,
Map<Flag, Boolean> flags, Map<Flag, Boolean> flags,
String tp_location, String tp_location,
String color) { String color, Integer serverId) {
this.id.value = id; this.id.value = id;
this.owner.value = owner.toString(); this.owner.value = owner.toString();
this.name.value = name; this.name.value = name;
@ -167,6 +175,7 @@ public class DominionDTO {
this.flags.putAll(flags); this.flags.putAll(flags);
this.tp_location.value = tp_location; this.tp_location.value = tp_location;
this.color.value = color; this.color.value = color;
this.serverId.value = serverId;
} }
@ -207,7 +216,7 @@ public class DominionDTO {
private final Map<Flag, Boolean> flags = new HashMap<>(); private final Map<Flag, Boolean> flags = new HashMap<>();
private final Field tp_location = new Field("tp_location", "default"); private final Field tp_location = new Field("tp_location", "default");
private final Field color = new Field("color", "#00BFFF"); private final Field color = new Field("color", "#00BFFF");
private final Field serverId = new Field("server_id", GlobalTeleport.instance.getThisServerId());
// getters and setters // getters and setters
public Integer getId() { public Integer getId() {
@ -423,4 +432,12 @@ public class DominionDTO {
public String getColor() { public String getColor() {
return (String) color.value; return (String) color.value;
} }
public Integer getServerId() {
return (Integer) serverId.value;
}
public String getServerName() {
return GlobalTeleport.instance.getServerName(getServerId());
}
} }

View File

@ -28,20 +28,8 @@ public class ServerInfoDTO {
return (String) name.value; return (String) name.value;
} }
private static void initTable() {
TableColumn server_info_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn server_info_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "server");
CreateTable privilege_template = new CreateTable().ifNotExists();
privilege_template.table("server_info")
.field(server_info_id)
.field(server_info_name);
privilege_template.execute();
}
public static ServerInfoDTO initServerInfo(JavaPlugin plugin, File se) { public static ServerInfoDTO initServerInfo(JavaPlugin plugin, File se) {
initTable();
ServerInfoDTO serverInfoDTO = new ServerInfoDTO(); ServerInfoDTO serverInfoDTO = new ServerInfoDTO();
serverInfoDTO.name.value = plugin.getServer().getName(); serverInfoDTO.name.value = plugin.getServer().getName();
InsertRow insertRow = new InsertRow(); InsertRow insertRow = new InsertRow();

View File

@ -1,6 +1,8 @@
package cn.lunadeer.dominion.managers; package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.Flag; import cn.lunadeer.dominion.dtos.Flag;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field; import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.FieldType; import cn.lunadeer.minecraftpluginutils.databse.FieldType;
import cn.lunadeer.minecraftpluginutils.databse.TableColumn; import cn.lunadeer.minecraftpluginutils.databse.TableColumn;
@ -155,5 +157,25 @@ public class DatabaseTables {
// 1.31.6 // 1.31.6
TableColumn dominion_color = new TableColumn("color", FieldType.STRING, false, false, true, false, "'#00BFFF'"); TableColumn dominion_color = new TableColumn("color", FieldType.STRING, false, false, true, false, "'#00BFFF'");
new AddColumn(dominion_color).table("dominion").ifNotExists().execute(); new AddColumn(dominion_color).table("dominion").ifNotExists().execute();
// global teleport
TableColumn server_info_id = new TableColumn("id", FieldType.INT, true, true, true, true, 0);
TableColumn server_info_name = new TableColumn("name", FieldType.STRING, false, false, true, false, "server");
CreateTable server_info = new CreateTable().ifNotExists();
server_info.table("server_info")
.field(server_info_id)
.field(server_info_name);
server_info.execute();
new GlobalTeleport(Dominion.instance); // init server info
TableColumn server_id = new TableColumn("server_id", FieldType.INT, false, false, true, false, GlobalTeleport.instance.getThisServerId());
new AddColumn(server_id).table("dominion").ifNotExists().execute();
TableColumn bc_tp_cache_player_uuid = new TableColumn("player_uuid", FieldType.STRING, false, false, true, true, "''");
TableColumn bc_tp_cache_dom_id = new TableColumn("dom_id", FieldType.INT, false, false, true, false, -1);
CreateTable bc_tp_cache = new CreateTable().ifNotExists();
bc_tp_cache.table("bc_tp_cache")
.field(bc_tp_cache_player_uuid)
.field(bc_tp_cache_dom_id);
bc_tp_cache.execute();
} }
} }

View File

@ -1,15 +1,35 @@
package cn.lunadeer.dominion.managers; package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.commands.DominionOperate;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.ServerInfoDTO; import cn.lunadeer.dominion.dtos.ServerInfoDTO;
import cn.lunadeer.minecraftpluginutils.Notification;
import cn.lunadeer.minecraftpluginutils.Teleport;
import cn.lunadeer.minecraftpluginutils.XLogger;
import cn.lunadeer.minecraftpluginutils.databse.DatabaseManager;
import cn.lunadeer.minecraftpluginutils.databse.Field;
import cn.lunadeer.minecraftpluginutils.databse.syntax.InsertRow;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.PluginMessageListener; import org.bukkit.plugin.messaging.PluginMessageListener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.xml.crypto.Data;
import java.io.File; import java.io.File;
import java.sql.ResultSet;
import java.util.Map; import java.util.Map;
public class GlobalTeleport implements PluginMessageListener { import static cn.lunadeer.dominion.DominionNode.isInDominion;
public class GlobalTeleport implements PluginMessageListener, Listener {
public static GlobalTeleport instance; public static GlobalTeleport instance;
@ -22,6 +42,7 @@ public class GlobalTeleport implements PluginMessageListener {
File infoFile = new File(plugin.getDataFolder(), "server_info.json"); File infoFile = new File(plugin.getDataFolder(), "server_info.json");
this.plugin.getServer().getMessenger().registerOutgoingPluginChannel(this.plugin, "BungeeCord"); this.plugin.getServer().getMessenger().registerOutgoingPluginChannel(this.plugin, "BungeeCord");
this.plugin.getServer().getMessenger().registerIncomingPluginChannel(this.plugin, "BungeeCord", this); this.plugin.getServer().getMessenger().registerIncomingPluginChannel(this.plugin, "BungeeCord", this);
this.plugin.getServer().getPluginManager().registerEvents(this, this.plugin);
instance = this; instance = this;
if (!infoFile.exists()) { if (!infoFile.exists()) {
@ -36,6 +57,10 @@ public class GlobalTeleport implements PluginMessageListener {
return thisServerInfo.getName(); return thisServerInfo.getName();
} }
public int getThisServerId() {
return thisServerInfo.getId();
}
public String getServerName(int id) { public String getServerName(int id) {
return allServerInfo.get(id); return allServerInfo.get(id);
} }
@ -52,4 +77,73 @@ public class GlobalTeleport implements PluginMessageListener {
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
} }
private void teleportToServer(Player player, DominionDTO dominionDTO) {
Field player_uuid = new Field("player_uuid", player.getUniqueId().toString());
Field dom_id = new Field("dom_id", dominionDTO.getId());
InsertRow addCache = new InsertRow();
addCache.field(player_uuid)
.field(dom_id)
.onConflictOverwrite(player_uuid)
.table("bc_tp_cache");
addCache.execute();
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(dominionDTO.getServerName());
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
String sql = "SELECT dom_id FROM bc_tp_cache WHERE player_uuid = ?";
int dominionId;
try (ResultSet res = DatabaseManager.instance.query(sql, player.getUniqueId().toString())) {
if (res.next()) {
dominionId = res.getInt("dom_id");
} else {
XLogger.debug("玩家 %s 没有传送缓存", player.getName());
return;
}
} catch (Exception e) {
DatabaseManager.handleDatabaseError("获取玩家的传送缓存失败", e, sql);
return;
}
DominionDTO dominionDTO = DominionDTO.select(dominionId);
if (dominionDTO == null) {
Notification.error(player, "无法获取目标领地信息");
} else {
doTp(player, dominionDTO);
}
sql = "DELETE FROM bc_tp_cache WHERE player_uuid = ?";
DatabaseManager.instance.query(sql, player.getUniqueId().toString());
}
public static void doTp(@NotNull Player player, @NotNull DominionDTO dominionDTO) {
if (dominionDTO.getServerId() != GlobalTeleport.instance.getThisServerId()) {
GlobalTeleport.instance.teleportToServer(player, dominionDTO);
return;
}
Location location = dominionDTO.getTpLocation();
int center_x = (dominionDTO.getX1() + dominionDTO.getX2()) / 2;
int center_z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
if (location == null) {
location = new Location(world, center_x, player.getLocation().getY(), center_z);
XLogger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
} else if (!isInDominion(dominionDTO, location)) {
location = new Location(world, center_x, player.getLocation().getY(), center_z);
XLogger.warn("领地 %s 传送点不在领地内,将尝试传送到中心点", dominionDTO.getName());
}
if (player.isOnline()) {
Teleport.doTeleportSafely(player, location).thenAccept(b -> {
if (b) {
Notification.info(player, "已将你传送到 " + dominionDTO.getName());
} else {
Notification.error(player, "传送失败,请重试");
}
});
}
}
} }