实现了缓存机制

This commit is contained in:
zhangyuheng 2024-02-12 16:06:47 +08:00
parent 1d369afc80
commit d52cd2d9d6
5 changed files with 142 additions and 5 deletions

View File

@ -0,0 +1,120 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.XLogger;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.util.*;
public class Cache {
public Cache() {
player_current_dominion = new HashMap<>();
loadDominions();
loadPlayerPrivileges();
}
/**
* 从数据库加载所有领地
*/
public void loadDominions() {
world_dominions = new HashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) {
world_dominions.put(d.getWorld(), new ArrayList<>());
}
world_dominions.get(d.getWorld()).add(d);
}
}
/**
* 从数据库加载所有玩家特权
*/
public void loadPlayerPrivileges() {
player_current_dominion = new HashMap<>();
List<PlayerPrivilegeDTO> all_privileges = PlayerPrivilegeDTO.selectAll();
if (all_privileges == null) {
XLogger.err("加载玩家特权失败");
return;
}
player_uuid_to_privilege = new HashMap<>();
for (PlayerPrivilegeDTO privilege : all_privileges) {
UUID player_uuid = privilege.getPlayerUUID();
if (!player_uuid_to_privilege.containsKey(player_uuid)) {
player_uuid_to_privilege.put(player_uuid, new HashMap<>());
}
player_uuid_to_privilege.get(player_uuid).put(privilege.getDomID(), privilege);
}
}
/**
* 获取玩家当前所在领地
* 此方法会先判断缓存中是否有玩家当前所在领地如果没有则遍历所有领地判断玩家所在位置
* 如果玩家不在任何领地内则返回null
* 如果玩家在领地内则返回领地信息
*
* @param player 玩家
* @return 玩家当前所在领地
*/
public DominionDTO getPlayerCurrentDominion(Player player) {
DominionDTO dominion = player_current_dominion.get(player.getUniqueId());
if (dominion != null) {
if (!isInDominion(dominion, player)) {
Notification.info(player, "您已离开领地:" + dominion.getName());
Notification.info(player, dominion.getLeaveMessage());
player_current_dominion.put(player.getUniqueId(), null);
dominion = null;
}
}
if (dominion == null) {
String world = player.getWorld().getName();
List<DominionDTO> dominions = world_dominions.get(world);
if (dominions == null) return null;
List<DominionDTO> in_dominions = new ArrayList<>();
for (DominionDTO d : dominions) {
if (isInDominion(d, player)) {
in_dominions.add(d);
}
}
if (in_dominions.size() == 0) return null;
in_dominions.sort(Comparator.comparingInt(DominionDTO::getId));
dominion = in_dominions.get(in_dominions.size() - 1);
player_current_dominion.put(player.getUniqueId(), dominion);
Notification.info(player, "您正在进入领地:" + dominion.getName());
Notification.info(player, dominion.getJoinMessage());
}
return dominion;
}
/**
* 获取玩家在指定领地的特权
* 如果玩家不存在特权则返回null
*
* @param player 玩家
* @param dominion 领地
* @return 特权表
*/
public PlayerPrivilegeDTO getPlayerPrivilege(Player player, DominionDTO dominion) {
if (!player_uuid_to_privilege.containsKey(player.getUniqueId())) return null;
return player_uuid_to_privilege.get(player.getUniqueId()).get(dominion.getId());
}
private static boolean isInDominion(@Nullable DominionDTO dominion, Player player) {
if (dominion == null) return false;
double x = player.getLocation().getX();
double y = player.getLocation().getY();
double z = player.getLocation().getZ();
return x >= dominion.getX1() && x <= dominion.getX2() &&
y >= dominion.getY1() && y <= dominion.getY2() &&
z >= dominion.getZ1() && z <= dominion.getZ2();
}
public static Cache instance;
private Map<String, List<DominionDTO>> world_dominions; // 所有领地
private Map<UUID, Map<Integer, PlayerPrivilegeDTO>> player_uuid_to_privilege; // 玩家所有的特权
private Map<UUID, DominionDTO> player_current_dominion; // 玩家当前所在领地
}

View File

@ -20,6 +20,7 @@ public final class Dominion extends JavaPlugin {
config = new ConfigManager(this);
dbConnection = Database.createConnection();
Database.migrate();
Cache.instance = new Cache();
Bukkit.getPluginManager().registerEvents(new PlayerEvents(), this);
Objects.requireNonNull(Bukkit.getPluginCommand("dominion")).setExecutor(new Commands());

View File

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.utils.Database;
import cn.lunadeer.dominion.utils.XLogger;
@ -69,6 +70,10 @@ public class DominionDTO {
rs.getBoolean("harvest"));
dominions.add(dominion);
}
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
}
} catch (SQLException e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);
@ -177,7 +182,7 @@ public class DominionDTO {
"cake = " + dominion.getCake() + ", " +
"container = " + dominion.getContainer() + ", " +
"craft = " + dominion.getCraft() + ", " +
"creeper_explode = " + dominion.getCreeperExplode() + ", " +
"creeper_explode = " + dominion.getCreeperExplode() + ", " + // dom only
"diode = " + dominion.getDiode() + ", " +
"door = " + dominion.getDoor() + ", " +
"dye = " + dominion.getDye() + ", " +
@ -185,8 +190,8 @@ public class DominionDTO {
"enchant = " + dominion.getEnchant() + ", " +
"ender_pearl = " + dominion.getEnderPearl() + ", " +
"feed = " + dominion.getFeed() + ", " +
"fire_spread = " + dominion.getFireSpread() + ", " +
"flow_in_protection = " + dominion.getFlowInProtection() + ", " +
"fire_spread = " + dominion.getFireSpread() + ", " + // dom only
"flow_in_protection = " + dominion.getFlowInProtection() + ", " + // dom only
"glow = " + dominion.getGlow() + ", " +
"grow = " + dominion.getGrow() + ", " +
"honey = " + dominion.getHoney() + ", " +
@ -199,10 +204,10 @@ public class DominionDTO {
"riding = " + dominion.getRiding() + ", " +
"shear = " + dominion.getShear() + ", " +
"shoot = " + dominion.getShoot() + ", " +
"tnt_explode = " + dominion.getTntExplode() + ", " +
"tnt_explode = " + dominion.getTntExplode() + ", " + // dom only
"trade = " + dominion.getTrade() + ", " +
"vehicle_destroy = " + dominion.getVehicleDestroy() + ", " +
"wither_spawn = " + dominion.getWitherSpawn() + ", " +
"wither_spawn = " + dominion.getWitherSpawn() + ", " + // dom only
"harvest = " + dominion.getHarvest() +
" WHERE id = " + dominion.getId() +
" RETURNING *;";

View File

@ -1,5 +1,6 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.utils.Database;
import cn.lunadeer.dominion.utils.XLogger;
@ -40,6 +41,11 @@ public class PlayerPrivilegeDTO {
query(sql);
}
public static List<PlayerPrivilegeDTO> selectAll(){
String sql = "SELECT * FROM player_privilege;";
return query(sql);
}
private final Integer id;
private final UUID playerUUID;
private Boolean admin;
@ -476,6 +482,10 @@ public class PlayerPrivilegeDTO {
);
players.add(player);
}
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")){
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
}
} catch (Exception e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);

View File

@ -144,6 +144,7 @@ public class Database {
" vehicle_destroy BOOLEAN NOT NULL DEFAULT FALSE," +
" harvest BOOLEAN NOT NULL DEFAULT FALSE," +
" UNIQUE (player_uuid, dom_id)," +
" FOREIGN KEY (player_uuid) REFERENCES player_name(uuid)," +
" FOREIGN KEY (dom_id) REFERENCES dominion(id)" +
");";