mirror of
https://github.com/Xiao-MoMi/Custom-Nameplates.git
synced 2025-12-25 09:59:16 +00:00
1.0 - SNAPSHOT
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package net.momirealms.customnameplates;
|
||||
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AdventureManager {
|
||||
//发送控制台消息
|
||||
public static void consoleMessage(String s) {
|
||||
Audience au = CustomNameplates.adventure.sender(Bukkit.getConsoleSender());
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
Component parsed = mm.deserialize(s);
|
||||
au.sendMessage(parsed);
|
||||
}
|
||||
//发送玩家消息
|
||||
public static void playerMessage(Player player, String s){
|
||||
Audience au = CustomNameplates.adventure.player(player);
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
Component parsed = mm.deserialize(s);
|
||||
au.sendMessage(parsed);
|
||||
}
|
||||
}
|
||||
157
src/main/java/net/momirealms/customnameplates/ConfigManager.java
Normal file
157
src/main/java/net/momirealms/customnameplates/ConfigManager.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package net.momirealms.customnameplates;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
//根据文件名获取配置文件
|
||||
public static YamlConfiguration getConfig(String configName) {
|
||||
File file = new File(CustomNameplates.instance.getDataFolder(), configName);
|
||||
//文件不存在则生成默认配置
|
||||
if (!file.exists()) {
|
||||
CustomNameplates.instance.saveResource(configName, false);
|
||||
}
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
//主配置文件
|
||||
public static class MainConfig{
|
||||
|
||||
public static String namespace;
|
||||
public static String fontName;
|
||||
public static String start_char;
|
||||
public static String folder_path;
|
||||
public static String font;
|
||||
public static String default_nameplate;
|
||||
public static String player_prefix;
|
||||
public static String player_suffix;
|
||||
public static Key key;
|
||||
public static boolean itemsAdder;
|
||||
public static boolean placeholderAPI;
|
||||
public static boolean show_after;
|
||||
public static String lang;
|
||||
public static Long preview;
|
||||
|
||||
public static void ReloadConfig(){
|
||||
CustomNameplates.instance.saveDefaultConfig();
|
||||
CustomNameplates.instance.reloadConfig();
|
||||
FileConfiguration config = CustomNameplates.instance.getConfig();
|
||||
|
||||
lang = config.getString("config.lang");
|
||||
namespace = config.getString("config.namespace");
|
||||
font = config.getString("config.font");
|
||||
fontName = namespace + ":" + font;
|
||||
start_char = config.getString("config.start-char");
|
||||
folder_path = config.getString("config.folder-path");
|
||||
default_nameplate = config.getString("config.default-nameplate");
|
||||
player_prefix = config.getString("config.prefix");
|
||||
player_suffix = config.getString("config.suffix");
|
||||
itemsAdder =config.getBoolean("config.integrations.ItemsAdder");
|
||||
placeholderAPI = config.getBoolean("config.integrations.PlaceholderAPI");
|
||||
show_after = config.getBoolean("config.show-after-load-resourcepack");
|
||||
key = Key.key(fontName);
|
||||
preview = config.getLong("config.preview-duration");
|
||||
}
|
||||
}
|
||||
//消息文件
|
||||
public static class Message{
|
||||
|
||||
public static String noPerm;
|
||||
public static String prefix;
|
||||
public static String lackArgs;
|
||||
public static String reload;
|
||||
public static String equip;
|
||||
public static String unequip;
|
||||
public static String force_equip;
|
||||
public static String force_unequip;
|
||||
public static String not_exist;
|
||||
public static String not_online;
|
||||
public static String no_console;
|
||||
public static String notAvailable;
|
||||
public static String available;
|
||||
public static String cooldown;
|
||||
public static String preview;
|
||||
|
||||
public static void ReloadConfig(){
|
||||
YamlConfiguration messagesConfig = getConfig("messages/messages_" + MainConfig.lang +".yml");
|
||||
noPerm = messagesConfig.getString("messages.no-perm");
|
||||
prefix = messagesConfig.getString("messages.prefix");
|
||||
lackArgs = messagesConfig.getString("messages.lack-args");
|
||||
reload = messagesConfig.getString("messages.reload");
|
||||
equip = messagesConfig.getString("messages.equip");
|
||||
unequip = messagesConfig.getString("messages.unequip");
|
||||
force_equip = messagesConfig.getString("messages.force-equip");
|
||||
force_unequip = messagesConfig.getString("messages.force-unequip");
|
||||
not_exist = messagesConfig.getString("messages.not-exist");
|
||||
not_online = messagesConfig.getString("messages.not-online");
|
||||
no_console = messagesConfig.getString("messages.no-console");
|
||||
notAvailable = messagesConfig.getString("messages.not-available");
|
||||
available = messagesConfig.getString("messages.available");
|
||||
cooldown = messagesConfig.getString("messages.cooldown");
|
||||
preview = messagesConfig.getString("messages.preview");
|
||||
}
|
||||
}
|
||||
//数据库配置
|
||||
public static class DatabaseConfig{
|
||||
|
||||
public static String user;
|
||||
public static String password;
|
||||
public static String url;
|
||||
public static String ENCODING;
|
||||
public static String tableName;
|
||||
public static boolean enable_pool;
|
||||
public static boolean use_mysql;
|
||||
public static int maximum_pool_size;
|
||||
public static int minimum_idle;
|
||||
public static int maximum_lifetime;
|
||||
public static int idle_timeout;
|
||||
|
||||
public static void LoadConfig(){
|
||||
YamlConfiguration databaseConfig = getConfig("database.yml");
|
||||
String storage_mode = databaseConfig.getString("settings.storage-mode");
|
||||
|
||||
//使用SQLite
|
||||
if(storage_mode.equals("SQLite")){
|
||||
enable_pool = false;
|
||||
use_mysql = false;
|
||||
tableName = "nameplates";
|
||||
}
|
||||
//使用MYSQL
|
||||
else if(storage_mode.equals("MYSQL")){
|
||||
|
||||
use_mysql = true;
|
||||
ENCODING = databaseConfig.getString("MySQL.property.encoding");
|
||||
tableName = databaseConfig.getString("MySQL.table-name");
|
||||
user = databaseConfig.getString("MySQL.user");
|
||||
password = databaseConfig.getString("MySQL.password");
|
||||
|
||||
url = "jdbc:mysql://" + databaseConfig.getString("MySQL.host")
|
||||
+ ":" + databaseConfig.getString("MySQL.port") + "/"
|
||||
+ databaseConfig.getString("MySQL.database") + "?characterEncoding="
|
||||
+ ENCODING + "&useSSL="
|
||||
+ databaseConfig.getString("MySQL.property.use-ssl");
|
||||
if (databaseConfig.getString("MySQL.property.timezone") != null &&
|
||||
!databaseConfig.getString("MySQL.property.timezone").equals("")) {
|
||||
url = url + "&serverTimezone=" + databaseConfig.getString("MySQL.property.timezone");
|
||||
}
|
||||
if (databaseConfig.getBoolean("MySQL.property.allowPublicKeyRetrieval")) {
|
||||
url = url + "&allowPublicKeyRetrieval=true";
|
||||
}
|
||||
enable_pool = databaseConfig.getBoolean("settings.use-pool");
|
||||
if(enable_pool){
|
||||
maximum_pool_size = databaseConfig.getInt("Pool-Settings.maximum-pool-size");
|
||||
minimum_idle = databaseConfig.getInt("Pool-Settings.minimum-idle");
|
||||
maximum_lifetime = databaseConfig.getInt("Pool-Settings.maximum-lifetime");
|
||||
idle_timeout = databaseConfig.getInt("Pool-Settings.idle-timeout");
|
||||
}
|
||||
}else {
|
||||
AdventureManager.consoleMessage("这种存储方式不存在");
|
||||
Bukkit.getPluginManager().disablePlugin(CustomNameplates.instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package net.momirealms.customnameplates;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.momirealms.customnameplates.commands.Execute;
|
||||
import net.momirealms.customnameplates.commands.TabComplete;
|
||||
import net.momirealms.customnameplates.data.DataManager;
|
||||
import net.momirealms.customnameplates.data.SqlHandler;
|
||||
import net.momirealms.customnameplates.listener.PlayerListener;
|
||||
import net.momirealms.customnameplates.listener.PacketsListener;
|
||||
import net.momirealms.customnameplates.resource.ResourceManager;
|
||||
import net.momirealms.customnameplates.scoreboard.ScoreBoardManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class CustomNameplates extends JavaPlugin {
|
||||
|
||||
public static JavaPlugin instance;
|
||||
public static BukkitAudiences adventure;
|
||||
|
||||
private ResourceManager resourceManager;
|
||||
private DataManager dataManager;
|
||||
private HookManager hookManager;
|
||||
private ScoreBoardManager scoreBoardManager;
|
||||
|
||||
public ResourceManager getResourceManager() {
|
||||
return this.resourceManager;
|
||||
}
|
||||
public DataManager getDataManager() { return this.dataManager; }
|
||||
public HookManager getHookManager() { return this.hookManager; }
|
||||
public ScoreBoardManager getScoreBoardManager() { return this.scoreBoardManager; }
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
adventure = BukkitAudiences.create(this);
|
||||
//重载插件
|
||||
ConfigManager.MainConfig.ReloadConfig();
|
||||
ConfigManager.Message.ReloadConfig();
|
||||
ConfigManager.DatabaseConfig.LoadConfig();
|
||||
//指令注册
|
||||
Objects.requireNonNull(Bukkit.getPluginCommand("customnameplates")).setExecutor(new Execute(this));
|
||||
Objects.requireNonNull(Bukkit.getPluginCommand("customnameplates")).setTabCompleter(new TabComplete(this));
|
||||
//事件注册
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(this),this);
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketsListener(this));
|
||||
//新建单例
|
||||
this.resourceManager = new ResourceManager(this);
|
||||
this.dataManager = new DataManager();
|
||||
this.hookManager = new HookManager(this);
|
||||
this.scoreBoardManager = new ScoreBoardManager(this);
|
||||
//生成资源包
|
||||
resourceManager.generateResourcePack();
|
||||
if (!DataManager.create()) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to enable Data Manager! Disabling plugin...</red>");
|
||||
instance.getPluginLoader().disablePlugin(instance);
|
||||
return;
|
||||
}
|
||||
//启动完成
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Plugin has been enabled! Author: XiaoMoMi");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
SqlHandler.saveAll();
|
||||
SqlHandler.close();
|
||||
//清除缓存实体
|
||||
Execute.pCache.forEach(Entity::remove);
|
||||
//卸载完成
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Plugin has been disabled! Author: XiaoMoMi");
|
||||
//关闭adventure
|
||||
if(adventure != null) {
|
||||
adventure.close();
|
||||
adventure = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package net.momirealms.customnameplates;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class HookManager {
|
||||
|
||||
private boolean placeholderAPI;
|
||||
private boolean itemsAdder;
|
||||
|
||||
public boolean hasPlaceholderAPI() {
|
||||
return this.placeholderAPI;
|
||||
}
|
||||
public boolean hasItemsAdder() {
|
||||
return this.itemsAdder;
|
||||
}
|
||||
|
||||
public HookManager(CustomNameplates plugin) {
|
||||
this.initializePlaceholderAPI();
|
||||
this.initializeItemsAdder();
|
||||
}
|
||||
|
||||
//Papi Hook检测
|
||||
private void initializePlaceholderAPI() {
|
||||
if(!ConfigManager.MainConfig.placeholderAPI){
|
||||
this.placeholderAPI = false;
|
||||
return;
|
||||
}
|
||||
if(CustomNameplates.instance.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null){
|
||||
this.placeholderAPI = true;
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> " + "<color:#F5F5F5>PlaceholderAPI Hooked!");
|
||||
}
|
||||
}
|
||||
//ItemsAdder Hook检测
|
||||
private void initializeItemsAdder() {
|
||||
if (!ConfigManager.MainConfig.itemsAdder) {
|
||||
this.itemsAdder = false;
|
||||
}
|
||||
if(CustomNameplates.instance.getServer().getPluginManager().getPlugin("ItemsAdder") != null){
|
||||
this.itemsAdder = true;
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> " + "<color:#F5F5F5>ItemsAdder Hooked!");
|
||||
}
|
||||
}
|
||||
/*
|
||||
解析prefix与suffix
|
||||
*/
|
||||
public String parsePlaceholders(Player player, String papi) {
|
||||
String s = StringUtils.replace(StringUtils.replace(papi, "%player_name%", player.getName()), "%player_displayname%", player.getDisplayName());
|
||||
s = PlaceholderAPI.setPlaceholders(player, s);
|
||||
return ChatColor.translateAlternateColorCodes('&', s);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
package net.momirealms.customnameplates.commands;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.AdventureManager;
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import net.momirealms.customnameplates.data.DataManager;
|
||||
import net.momirealms.customnameplates.scoreboard.NameplatesTeam;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Execute implements CommandExecutor {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final HashMap<Player, Long> coolDown;
|
||||
{
|
||||
coolDown = new HashMap<>();
|
||||
}
|
||||
public static List<Entity> pCache;
|
||||
{
|
||||
pCache = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Execute(CustomNameplates plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ParametersAreNonnullByDefault
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
//参数不足
|
||||
if (args.length < 1){
|
||||
if (sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
switch (args[0]) {
|
||||
case "reload" -> {
|
||||
if (sender.hasPermission("customnameplates.reload") || sender.isOp()) {
|
||||
ConfigManager.MainConfig.ReloadConfig();
|
||||
ConfigManager.Message.ReloadConfig();
|
||||
if (sender instanceof Player) {
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.reload);
|
||||
} else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.reload);
|
||||
}
|
||||
} else {
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.noPerm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "equip" -> {
|
||||
if (sender instanceof Player player) {
|
||||
if (args.length < 2) {
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
return true;
|
||||
}
|
||||
if (sender.hasPermission("customnameplates.equip." + args[1]) || sender.isOp()) {
|
||||
if (plugin.getResourceManager().getNameplateInfo(args[1]) == null) {
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.not_exist);
|
||||
return true;
|
||||
}
|
||||
DataManager.cache.get(player.getUniqueId()).equipNameplate(args[1]);
|
||||
this.plugin.getScoreBoardManager().getTeam(player.getName()).updateNameplates();
|
||||
this.plugin.getDataManager().savePlayer(player.getUniqueId());
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.equip.replace("{Nameplate}", plugin.getResourceManager().getNameplateInfo(args[1]).getConfig().getName()));
|
||||
} else {
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.notAvailable);
|
||||
}
|
||||
} else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.no_console);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "forceequip" -> {
|
||||
if (args.length < 3){
|
||||
if(sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (sender.hasPermission("customnameplates.forceequip") || sender.isOp()){
|
||||
if (Bukkit.getPlayer(args[1]) != null){
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
//铭牌是否存在
|
||||
if (plugin.getResourceManager().getNameplateInfo(args[2]) == null){
|
||||
if(sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.not_exist);
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.not_exist);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
DataManager.cache.get(player.getUniqueId()).equipNameplate(args[2]);
|
||||
this.plugin.getScoreBoardManager().getTeam(args[1]).updateNameplates();
|
||||
this.plugin.getDataManager().savePlayer(player.getUniqueId());
|
||||
if (sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.force_equip.replace("{Nameplate}", plugin.getResourceManager().getNameplateInfo(args[2]).getConfig().getName()).replace("{Player}", args[1]));
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.force_equip.replace("{Nameplate}", plugin.getResourceManager().getNameplateInfo(args[2]).getConfig().getName()).replace("{Player}", args[1]));
|
||||
}
|
||||
}else {
|
||||
//玩家不存在,不在线
|
||||
if(sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.not_online.replace("{Player}",args[1]));
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.not_online.replace("{Player}",args[1]));
|
||||
}
|
||||
}
|
||||
}else {
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.noPerm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "unequip" -> {
|
||||
if (sender instanceof Player player){
|
||||
DataManager.cache.get(player.getUniqueId()).equipNameplate("none");
|
||||
this.plugin.getScoreBoardManager().getTeam(player.getName()).updateNameplates();
|
||||
this.plugin.getDataManager().savePlayer(player.getUniqueId());
|
||||
AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.unequip);
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.no_console);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "forceunequip" -> {
|
||||
if (args.length < 2){
|
||||
if(sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.lackArgs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (sender.hasPermission("customnameplates.forceunequip")){
|
||||
if (Bukkit.getPlayer(args[1]) != null){
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
DataManager.cache.get(player.getUniqueId()).equipNameplate("none");
|
||||
this.plugin.getScoreBoardManager().getTeam(args[1]).updateNameplates();
|
||||
this.plugin.getDataManager().savePlayer(player.getUniqueId());
|
||||
if (sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.force_unequip.replace("{Player}", args[1]));
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.force_unequip.replace("{Player}", args[1]));
|
||||
}
|
||||
}else {
|
||||
//玩家不存在,不在线
|
||||
if(sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.not_online.replace("{Player}",args[1]));
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.not_online.replace("{Player}",args[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "preview" -> {
|
||||
if (sender instanceof Player player){
|
||||
//指令冷却
|
||||
long time = System.currentTimeMillis();
|
||||
//冷却时间判断
|
||||
if (time - (coolDown.getOrDefault(player, time - ConfigManager.MainConfig.preview * 1050)) < ConfigManager.MainConfig.preview * 1050) {
|
||||
AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.cooldown);
|
||||
return true;
|
||||
}
|
||||
//重置冷却时间
|
||||
coolDown.put(player, time);
|
||||
if (player.hasPermission("customnameplates.preview") || player.isOp()){
|
||||
AdventureManager.playerMessage(player,ConfigManager.Message.prefix + ConfigManager.Message.preview);
|
||||
ArmorStand entity = player.getWorld().spawn(player.getLocation().add(0,0.8,0), ArmorStand.class, a -> {
|
||||
a.setInvisible(true);
|
||||
a.setCollidable(false);
|
||||
a.setInvulnerable(true);
|
||||
a.setVisible(false);
|
||||
a.setCustomNameVisible(false);
|
||||
a.setSmall(true);
|
||||
a.setGravity(false);
|
||||
});
|
||||
pCache.add(entity);
|
||||
NameplatesTeam team = this.plugin.getScoreBoardManager().getOrCreateTeam(player);
|
||||
Component full = team.getPrefix().append(Component.text(player.getName()).font(Key.key("default")).append(team.getSuffix()));
|
||||
|
||||
WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher();
|
||||
wrappedDataWatcher.setEntity(entity);
|
||||
WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Boolean.class);
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(full)).getHandle()));
|
||||
wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer), true);
|
||||
PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packetContainer.getIntegers().write(0, entity.getEntityId());
|
||||
packetContainer.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects());
|
||||
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer);
|
||||
}
|
||||
catch (Exception e) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to preview for "+ player.getName()+"</red>");
|
||||
e.printStackTrace();
|
||||
}
|
||||
BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
||||
for (int i = 1; i < ConfigManager.MainConfig.preview * 20; i++){
|
||||
bukkitScheduler.runTaskLater(CustomNameplates.instance,()-> entity.teleport(player.getLocation().add(0,0.8,0)), i);
|
||||
}
|
||||
bukkitScheduler.runTaskLater(CustomNameplates.instance, ()->{
|
||||
entity.remove();
|
||||
pCache.remove(entity);
|
||||
}, ConfigManager.MainConfig.preview * 20L);
|
||||
}else {
|
||||
AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.noPerm);
|
||||
}
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.no_console);
|
||||
}
|
||||
}
|
||||
case "list" -> {
|
||||
if (sender instanceof Player player){
|
||||
if (player.isOp()){
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
this.plugin.getResourceManager().caches.keySet().forEach(key ->{
|
||||
if(key.equalsIgnoreCase("none")) return;
|
||||
stringBuilder.append(key).append(" ");
|
||||
});
|
||||
AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.available.replace("{Nameplates}", stringBuilder.toString()));
|
||||
}else if(player.hasPermission("customnameplates.list")){
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (PermissionAttachmentInfo info : player.getEffectivePermissions()) {
|
||||
String permission = info.getPermission().toLowerCase();
|
||||
if (permission.startsWith("customnameplates.equip.")) {
|
||||
permission = StringUtils.replace(permission, "customnameplates.equip.", "");
|
||||
if (this.plugin.getResourceManager().caches.get(permission) != null){
|
||||
stringBuilder.append(permission).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.available.replace("{Nameplates}", stringBuilder.toString()));
|
||||
}else {
|
||||
AdventureManager.playerMessage(player,ConfigManager.Message.prefix + ConfigManager.Message.noPerm);
|
||||
}
|
||||
}else {
|
||||
AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.no_console);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
if(sender instanceof Player player){
|
||||
if (player.hasPermission("customnameplates.help")){
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates help - <color:#7FFFAA>show the command list");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates reload - <color:#7FFFAA>reload the configuration");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates equip <nameplate> - <color:#7FFFAA>equip a specified nameplate");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates forceequip <player> <nameplate> - <color:#7FFFAA>force a player to equip a specified nameplate");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates unequip - <color:#7FFFAA>unequip your nameplate");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates forceunequip - <color:#7FFFAA>force unequip a player's nameplate");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates preview - <color:#7FFFAA>preview your nameplate");
|
||||
AdventureManager.playerMessage(player,"<color:#87CEFA>/nameplates list - <color:#7FFFAA>list your available nameplates");
|
||||
}
|
||||
}else {
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates help - <color:#7FFFAA>show the command list");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates reload - <color:#7FFFAA>reload the configuration");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates equip <nameplate> - <color:#7FFFAA>equip a specified nameplate");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates forceequip <player> <nameplate> - <color:#7FFFAA>force a player to equip a specified nameplate");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates unequip - <color:#7FFFAA>unequip your nameplate");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates forceunequip - <color:#7FFFAA>force unequip a player's nameplate");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates preview - <color:#7FFFAA>preview your nameplate");
|
||||
AdventureManager.consoleMessage("<color:#87CEFA>/nameplates list - <color:#7FFFAA>list your available nameplates");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package net.momirealms.customnameplates.commands;
|
||||
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TabComplete implements TabCompleter {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
|
||||
public TabComplete(CustomNameplates plugin){
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ParametersAreNonnullByDefault
|
||||
public @Nullable List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
|
||||
if(1 == args.length){
|
||||
List<String> tab = new ArrayList<>();
|
||||
if (sender.hasPermission("customnameplates.reload")) tab.add("reload");
|
||||
if (sender.hasPermission("customnameplates.help")) tab.add("help");
|
||||
if (sender.hasPermission("customnameplates.equip")) tab.add("equip");
|
||||
if (sender.hasPermission("customnameplates.forceequip")) tab.add("forceequip");
|
||||
if (sender.hasPermission("customnameplates.unequip")) tab.add("unequip");
|
||||
if (sender.hasPermission("customnameplates.forceunequip")) tab.add("forceunequip");
|
||||
if (sender.hasPermission("customnameplates.preview")) tab.add("preview");
|
||||
if (sender.hasPermission("customnameplates.list")) tab.add("list");
|
||||
return tab;
|
||||
}
|
||||
if(2 == args.length){
|
||||
List<String> tab = new ArrayList<>();
|
||||
if (args[0].equalsIgnoreCase("equip")){
|
||||
return availableNameplates(sender);
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("forceunequip") && sender.hasPermission("customnameplates.forceunequip")){
|
||||
return online_players();
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("forceequip") && sender.hasPermission("customnameplates.forceequip")){
|
||||
return online_players();
|
||||
}
|
||||
}
|
||||
if(3 == args.length){
|
||||
if (args[0].equalsIgnoreCase("forceequip") && sender.hasPermission("customnameplates.forceequip")){
|
||||
return nameplates();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<String> online_players(){
|
||||
List<String> online = new ArrayList<>();
|
||||
Bukkit.getOnlinePlayers().forEach((player -> online.add(player.getName())));
|
||||
return online;
|
||||
}
|
||||
|
||||
private List<String> availableNameplates(CommandSender sender){
|
||||
List<String> availableNameplates = new ArrayList<>();
|
||||
if (sender instanceof Player player){
|
||||
for (PermissionAttachmentInfo info : player.getEffectivePermissions()) {
|
||||
String permission = info.getPermission().toLowerCase();
|
||||
if (permission.startsWith("customnameplates.equip.")) {
|
||||
permission = StringUtils.replace(permission, "customnameplates.equip.", "");
|
||||
if (this.plugin.getResourceManager().caches.get(permission) != null){
|
||||
availableNameplates.add(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return availableNameplates;
|
||||
}
|
||||
|
||||
private List<String> nameplates(){
|
||||
return new ArrayList<>(this.plugin.getResourceManager().caches.keySet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package net.momirealms.customnameplates.data;
|
||||
|
||||
import net.momirealms.customnameplates.AdventureManager;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DataManager {
|
||||
|
||||
public static Map<UUID, PlayerData> cache;
|
||||
public DataManager() {
|
||||
cache = new HashMap<>();
|
||||
}
|
||||
|
||||
public PlayerData getOrCreate(UUID uuid) {
|
||||
if (cache.containsKey(uuid)) {
|
||||
return cache.get(uuid);
|
||||
}
|
||||
PlayerData playerData = SqlHandler.getPlayerData(uuid);
|
||||
if (playerData == null) {
|
||||
playerData = PlayerData.EMPTY;
|
||||
}
|
||||
cache.put(uuid, playerData);
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public void unloadPlayer(UUID uuid) {
|
||||
if (!cache.containsKey(uuid)) {
|
||||
return;
|
||||
}
|
||||
SqlHandler.save(cache.get(uuid), uuid);
|
||||
cache.remove(uuid);
|
||||
}
|
||||
|
||||
public void savePlayer(UUID uuid) {
|
||||
SqlHandler.save(cache.get(uuid), uuid);
|
||||
}
|
||||
|
||||
public static boolean create() {
|
||||
if(ConfigManager.DatabaseConfig.use_mysql){
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#00CED1>Storage Mode - MYSQL");
|
||||
}else {
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#00CED1>Storage Mode - SQLite");
|
||||
}
|
||||
if (SqlHandler.connect()) {
|
||||
if (ConfigManager.DatabaseConfig.use_mysql) {
|
||||
SqlHandler.getWaitTimeOut();
|
||||
}
|
||||
SqlHandler.createTable();
|
||||
} else {
|
||||
AdventureManager.consoleMessage("<red>//DATA storage ERROR//</red>");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.momirealms.customnameplates.data;
|
||||
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
public static PlayerData EMPTY;
|
||||
static {
|
||||
EMPTY = new PlayerData(ConfigManager.MainConfig.default_nameplate, 0);
|
||||
}
|
||||
|
||||
private String equipped;
|
||||
private int accepted;
|
||||
|
||||
public PlayerData(String equipped, int accepted) {
|
||||
this.equipped = equipped;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
public int getAccepted(){
|
||||
return this.accepted;
|
||||
}
|
||||
|
||||
public void setAccepted(int accepted){
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
public String getEquippedNameplate() {
|
||||
return this.equipped;
|
||||
}
|
||||
|
||||
public void equipNameplate(String nameplate) {
|
||||
this.equipped = nameplate.toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package net.momirealms.customnameplates.data;
|
||||
|
||||
import net.momirealms.customnameplates.AdventureManager;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.utils.SqlConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SqlHandler {
|
||||
|
||||
public static String tableName = ConfigManager.DatabaseConfig.tableName;
|
||||
public final static SqlConnection database = new SqlConnection();
|
||||
|
||||
public static boolean connect() {
|
||||
return database.setGlobalConnection();
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
database.close();
|
||||
}
|
||||
|
||||
public static void getWaitTimeOut() {
|
||||
if (ConfigManager.DatabaseConfig.use_mysql && !ConfigManager.DatabaseConfig.enable_pool) {
|
||||
try {
|
||||
Connection connection = database.getConnectionAndCheck();
|
||||
String query = "show variables LIKE 'wait_timeout'";
|
||||
PreparedStatement statement = connection.prepareStatement(query);
|
||||
ResultSet rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
int waitTime = rs.getInt(2);
|
||||
if (waitTime > 50) {
|
||||
database.waitTimeOut = waitTime - 30;
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
statement.close();
|
||||
database.closeHikariConnection(connection);
|
||||
} catch (SQLException ignored) {
|
||||
AdventureManager.consoleMessage("[CustomNameplates] Failed to get wait time out");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void createTable() {
|
||||
try {
|
||||
Connection connection = database.getConnectionAndCheck();
|
||||
Statement statement = connection.createStatement();
|
||||
if (statement == null) {
|
||||
return;
|
||||
}
|
||||
String query;
|
||||
if (ConfigManager.DatabaseConfig.use_mysql) {
|
||||
query = "CREATE TABLE IF NOT EXISTS " + tableName
|
||||
+ "(player VARCHAR(50) NOT NULL, equipped VARCHAR(50) NOT NULL, accepted INT(1) NOT NULL,"
|
||||
+ " PRIMARY KEY (player)) DEFAULT charset = " + ConfigManager.DatabaseConfig.ENCODING + ";";
|
||||
} else {
|
||||
query = "CREATE TABLE IF NOT EXISTS " + tableName
|
||||
+ "(player VARCHAR(50) NOT NULL, equipped VARCHAR(50) NOT NULL, accepted INT(1) NOT NULL,"
|
||||
+ " PRIMARY KEY (player));";
|
||||
}
|
||||
statement.executeUpdate(query);
|
||||
statement.close();
|
||||
database.closeHikariConnection(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerData getPlayerData(UUID uuid) {
|
||||
PlayerData playerData = null;
|
||||
try {
|
||||
Connection connection = database.getConnectionAndCheck();
|
||||
String sql = "SELECT * FROM " + tableName + " WHERE player = ?";
|
||||
PreparedStatement statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, uuid.toString());
|
||||
ResultSet rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
playerData = new PlayerData(rs.getString(2), rs.getInt(3));
|
||||
}else {
|
||||
sql = "INSERT INTO nameplates(player,equipped,accepted) values(?,?,?)";
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, "none");
|
||||
statement.setInt(3, 0);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
rs.close();
|
||||
statement.close();
|
||||
database.closeHikariConnection(connection);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public static void save(PlayerData playerData, UUID uuid) {
|
||||
Connection connection = database.getConnectionAndCheck();
|
||||
try {
|
||||
String query = " SET equipped = ?, accepted = ? WHERE player = ?";
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE " + tableName + query);
|
||||
statement.setString(1, playerData.getEquippedNameplate());
|
||||
statement.setInt(2, playerData.getAccepted());
|
||||
statement.setString(3, uuid.toString());
|
||||
statement.executeUpdate();
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
database.closeHikariConnection(connection);
|
||||
}
|
||||
|
||||
public static void saveAll() {
|
||||
Connection connection = database.getConnectionAndCheck();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
try {
|
||||
PlayerData playerData = DataManager.cache.get(player.getUniqueId());
|
||||
String query = " SET equipped = ?, accepted = ? WHERE player = ?";
|
||||
PreparedStatement statement = connection.prepareStatement("UPDATE " + tableName + query);
|
||||
statement.setString(1, playerData.getEquippedNameplate());
|
||||
statement.setInt(2, playerData.getAccepted());
|
||||
statement.setString(3, String.valueOf(player.getUniqueId()));
|
||||
statement.executeUpdate();
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
database.closeHikariConnection(connection);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package net.momirealms.customnameplates.font;
|
||||
|
||||
import net.momirealms.customnameplates.nameplates.NameplateConfig;
|
||||
|
||||
public record FontCache(String name, FontChar fontChar, NameplateConfig config) {
|
||||
|
||||
public static FontCache EMPTY;
|
||||
static {
|
||||
FontCache.EMPTY = new FontCache("none", new FontChar(' ', ' ', ' '), NameplateConfig.EMPTY);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public FontChar getChar() {
|
||||
return this.fontChar;
|
||||
}
|
||||
public NameplateConfig getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof FontCache fontCache)) {
|
||||
return false;
|
||||
}
|
||||
if (!fontCache.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
final String name = this.getName();
|
||||
final String name2 = fontCache.getName();
|
||||
Label_a:
|
||||
{
|
||||
if (name == null) {
|
||||
if (name2 == null) {
|
||||
break Label_a;
|
||||
}
|
||||
} else if (name.equals(name2)) {
|
||||
break Label_a;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
FontChar info = this.getChar();
|
||||
FontChar info2 = fontCache.getChar();
|
||||
Label_b:
|
||||
{
|
||||
if (info == null) {
|
||||
if (info2 == null) {
|
||||
break Label_b;
|
||||
}
|
||||
} else if (info.equals(info2)) {
|
||||
break Label_b;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final NameplateConfig config = this.getConfig();
|
||||
final NameplateConfig config2 = fontCache.getConfig();
|
||||
if (config == null) {
|
||||
return config2 == null;
|
||||
} else return config.equals(config2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int n = 1;
|
||||
final String name = this.getName();
|
||||
final int n2 = n * 59 + ((name == null) ? 43 : name.hashCode());
|
||||
final FontChar fontChar = this.getChar();
|
||||
final int n3 = n2 * 59 + ((fontChar == null) ? 43 : fontChar.hashCode());
|
||||
final NameplateConfig config = this.getConfig();
|
||||
return n3 * 59 + ((config == null) ? 43 : config.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FontCache(name=" + this.getName() + ", info=" + this.getChar() + ", config=" + this.getConfig() + ")";
|
||||
}
|
||||
|
||||
private boolean canEqual(final Object other) {
|
||||
return other instanceof FontCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.momirealms.customnameplates.font;
|
||||
|
||||
|
||||
public record FontChar(char left, char middle, char right) {
|
||||
|
||||
public char getLeft() {
|
||||
return this.left;
|
||||
}
|
||||
|
||||
public char getMiddle() {
|
||||
return this.middle;
|
||||
}
|
||||
|
||||
public char getRight() {
|
||||
return this.right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof FontChar fontInfo)) {
|
||||
return false;
|
||||
}
|
||||
return this.getLeft() == fontInfo.getLeft() && this.getMiddle() == fontInfo.getMiddle() && this.getRight() == fontInfo.getRight();
|
||||
}
|
||||
|
||||
/*
|
||||
如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写
|
||||
比如:有个A类重写了equals方法,但是没有重写hashCode方法,看输出结果,对象a1和对象a2使用equals方法相等,
|
||||
所以,我们在重写了equals方法后,尽量也重写了hashcode方法,通过一定的算法,使他们在equals相等时,也会有相同的hashcode值。
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((59 + this.getLeft()) * 59 + this.getMiddle()) * 59 + this.getRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FontChar=" + this.getLeft() + this.getMiddle() + this.getRight();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package net.momirealms.customnameplates.font;
|
||||
|
||||
public enum FontNegative {
|
||||
|
||||
/*
|
||||
实际向左移的距离是height(尺寸)-2
|
||||
*/
|
||||
NEG_1('\uf801', -1, -3),
|
||||
NEG_2('\uf802', -2, -4),
|
||||
NEG_3('\uf803', -3, -5),
|
||||
NEG_4('\uf804', -4, -6),
|
||||
NEG_5('\uf805', -5, -7),
|
||||
NEG_6('\uf806', -6, -8),
|
||||
NEG_7('\uf807', -7, -9),
|
||||
NEG_8('\uf808', -8, -10),
|
||||
NEG_16('\uf809', -16, -18),
|
||||
NEG_32('\uf80a', -32, -34),
|
||||
NEG_64('\uf80b', -64, -66),
|
||||
NEG_128('\uf80c', -128, -130);
|
||||
|
||||
private final char character;
|
||||
private final int space;
|
||||
private final int height;
|
||||
|
||||
FontNegative(char character, int space, int height) {
|
||||
this.character = character;
|
||||
this.space = space;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/*
|
||||
获取最短的负空格字符
|
||||
*/
|
||||
public static String getShortestNegChars(int n) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (n > 128) {
|
||||
stringBuilder.append(FontNegative.NEG_128.getCharacter());
|
||||
n -= 129;
|
||||
}
|
||||
if (n - 64 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_64.getCharacter());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_32.getCharacter());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_16.getCharacter());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_8.getCharacter());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 7 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_7.getCharacter());
|
||||
n -= 7;
|
||||
}
|
||||
if (n - 6 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_6.getCharacter());
|
||||
n -= 6;
|
||||
}
|
||||
if (n - 5 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_5.getCharacter());
|
||||
n -= 5;
|
||||
}
|
||||
if (n - 4 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_4.getCharacter());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 3 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_3.getCharacter());
|
||||
n -= 3;
|
||||
}
|
||||
if (n - 2 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_2.getCharacter());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 > 0) {
|
||||
stringBuilder.append(FontNegative.NEG_1.getCharacter());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return this.character;
|
||||
}
|
||||
|
||||
public int getSpace() {
|
||||
return this.space;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.momirealms.customnameplates.font;
|
||||
|
||||
public enum FontWidth {
|
||||
|
||||
A('A', 5), a('a', 5), B('B', 5), b('b', 5),
|
||||
C('C', 5), c('c', 5), D('D', 5), d('d', 5),
|
||||
E('E', 5), e('e', 5), F('F', 5), f('f', 4),
|
||||
G('G', 5), g('g', 5), H('H', 5), h('h', 5),
|
||||
I('I', 3), i('i', 1), J('J', 5), j('j', 5),
|
||||
K('K', 5), k('k', 4), L('L', 5), l('l', 2),
|
||||
M('M', 5), m('m', 5), N('N', 5), n('n', 5),
|
||||
O('O', 5), o('o', 5), P('P', 5), p('p', 5),
|
||||
Q('Q', 5), q('q', 5), R('R', 5), r('r', 5),
|
||||
S('S', 5), s('s', 5), T('T', 5), t('t', 4),
|
||||
U('U', 5), u('u', 5), V('V', 5), v('v', 5),
|
||||
W('W', 5), w('w', 5), X('X', 5), x('x', 5),
|
||||
Y('Y', 5), y('y', 5), Z('Z', 5), z('z', 5),
|
||||
NUM_1('1', 5), NUM_2('2', 5), NUM_3('3', 5), NUM_4('4', 5),
|
||||
NUM_5('5', 5), NUM_6('6', 5), NUM_7('7', 5), NUM_8('8', 5),
|
||||
NUM_9('9', 5), NUM_0('0', 5), EXCLAMATION_POINT('!', 1), AT_SYMBOL('@', 6),
|
||||
NUM_SIGN('#', 5), DOLLAR_SIGN('$', 5), PERCENT('%', 5), UP_ARROW('^', 5),
|
||||
AMPERSAND('&', 5), ASTERISK('*', 5), LEFT_PARENTHESIS('(', 4),
|
||||
RIGHT_PARENTHESIS(')', 4), MINUS('-', 5), UNDERSCORE('_', 5), PLUS_SIGN('+', 5),
|
||||
EQUALS_SIGN('=', 5), LEFT_CURL_BRACE('{', 4), RIGHT_CURL_BRACE('}', 4),
|
||||
LEFT_BRACKET('[', 3), RIGHT_BRACKET(']', 3), COLON(':', 1), SEMI_COLON(';', 1),
|
||||
DOUBLE_QUOTE('\"', 3), SINGLE_QUOTE('\'', 1), LEFT_ARROW('<', 4),
|
||||
RIGHT_ARROW('>', 4), QUESTION_MARK('?', 5), SLASH('/', 5),
|
||||
BACK_SLASH('\\', 5), LINE('|', 1), TILDE('~', 5), TICK('`', 2),
|
||||
PERIOD('.', 1), COMMA(',', 1), SPACE(' ', 3),
|
||||
IN_BETWEEN(' ', 1), DEFAULT('默', 8), DEFAULT2('米', 7);
|
||||
|
||||
private final char character;
|
||||
private final int length;
|
||||
|
||||
FontWidth(char character, int length) {
|
||||
this.character = character;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return this.character;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
public int getBoldLength() {
|
||||
if (this == FontWidth.SPACE) {
|
||||
return this.getLength();
|
||||
}
|
||||
return this.getLength() + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
获取每个字符的像素宽度
|
||||
*/
|
||||
public static FontWidth getInfo(char c) {
|
||||
for (FontWidth minecraftFontWidth : values()) {
|
||||
if (minecraftFontWidth.getCharacter() == c) {
|
||||
return minecraftFontWidth;
|
||||
}
|
||||
}
|
||||
return FontWidth.DEFAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
计算一个字符串的总宽度
|
||||
*/
|
||||
public static int getTotalWidth(String s) {
|
||||
int length = s.length();
|
||||
int n = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
n += getInfo(s.charAt(i)).getLength();
|
||||
}
|
||||
return n + FontWidth.IN_BETWEEN.getLength() * (length - 1); //总长还需加上字符间距
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.momirealms.customnameplates.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.InternalStructure;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import net.momirealms.customnameplates.data.DataManager;
|
||||
import net.momirealms.customnameplates.scoreboard.NameplatesTeam;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class PacketsListener extends PacketAdapter {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
|
||||
public PacketsListener(CustomNameplates plugin) {
|
||||
super(plugin, ListenerPriority.HIGHEST, PacketType.Play.Server.SCOREBOARD_TEAM);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
Integer n = event.getPacket().getIntegers().read(0);
|
||||
//create team && update team info
|
||||
if (n != 0 && n != 2) {
|
||||
return;
|
||||
}
|
||||
Optional<InternalStructure> optional = event.getPacket().getOptionalStructures().read(0);
|
||||
if (optional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
InternalStructure internalStructure = optional.get();
|
||||
String teamName = event.getPacket().getStrings().read(0);
|
||||
NameplatesTeam team = this.plugin.getScoreBoardManager().getTeam(teamName);
|
||||
if (!this.plugin.getScoreBoardManager().doesTeamExist(teamName)){
|
||||
return;
|
||||
}
|
||||
if (ConfigManager.MainConfig.show_after && DataManager.cache.get(event.getPlayer().getUniqueId()).getAccepted() == 0) {
|
||||
internalStructure.getChatComponents().write(1, WrappedChatComponent.fromJson("{\"text\":\"\"}"));
|
||||
internalStructure.getChatComponents().write(2, WrappedChatComponent.fromJson("{\"text\":\"\"}"));
|
||||
internalStructure.getEnumModifier(ChatColor.class, MinecraftReflection.getMinecraftClass("EnumChatFormat")).write(0,ChatColor.WHITE);
|
||||
return;
|
||||
}
|
||||
//在新建队伍名字的时候其实就是以玩家名命名,所以获得的teamName=playerName
|
||||
internalStructure.getChatComponents().write(1, WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(team.getPrefix())));
|
||||
internalStructure.getChatComponents().write(2, WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(team.getSuffix())));
|
||||
internalStructure.getEnumModifier(ChatColor.class, MinecraftReflection.getMinecraftClass("EnumChatFormat")).write(0,team.getColor());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.momirealms.customnameplates.listener;
|
||||
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import net.momirealms.customnameplates.data.DataManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerResourcePackStatusEvent;
|
||||
|
||||
public record PlayerListener(CustomNameplates plugin) implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||
this.plugin.getDataManager().getOrCreate(event.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
this.plugin.getScoreBoardManager().getOrCreateTeam(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
this.plugin.getDataManager().unloadPlayer(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onAccept(PlayerResourcePackStatusEvent event) {
|
||||
if (event.getStatus() == PlayerResourcePackStatusEvent.Status.SUCCESSFULLY_LOADED) {
|
||||
DataManager.cache.get(event.getPlayer().getUniqueId()).setAccepted(1);
|
||||
Bukkit.getOnlinePlayers().forEach(player -> this.plugin.getScoreBoardManager().getTeam(player.getName()).updateNameplates());
|
||||
} else {
|
||||
DataManager.cache.get(event.getPlayer().getUniqueId()).setAccepted(0);
|
||||
Bukkit.getOnlinePlayers().forEach(player -> this.plugin.getScoreBoardManager().getTeam(player.getName()).updateNameplates());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.momirealms.customnameplates.nameplates;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public record NameplateConfig(ChatColor color, int height, String name) {
|
||||
|
||||
public static NameplateConfig EMPTY;
|
||||
|
||||
static {
|
||||
EMPTY = new NameplateConfig(ChatColor.WHITE, 16, "none");
|
||||
}
|
||||
|
||||
//获取Team颜色
|
||||
public ChatColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
//获取自定义font大小
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
//获取铭牌名
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package net.momirealms.customnameplates.nameplates;
|
||||
|
||||
import net.momirealms.customnameplates.font.FontCache;
|
||||
import net.momirealms.customnameplates.font.FontNegative;
|
||||
import net.momirealms.customnameplates.font.FontWidth;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class NameplateUtil {
|
||||
|
||||
private final FontCache fontcache;
|
||||
|
||||
public NameplateUtil(FontCache font) {
|
||||
this.fontcache = font;
|
||||
}
|
||||
|
||||
/*
|
||||
根据玩家名构造长度适合的铭牌字符
|
||||
当然这个玩家名是带上前缀与后缀的
|
||||
*/
|
||||
public String makeCustomNameplate(String prefix, String name, String suffix) {
|
||||
int totalWidth = FontWidth.getTotalWidth(ChatColor.stripColor(prefix + name + suffix));
|
||||
boolean isEven = totalWidth % 2 == 0; //奇偶判断
|
||||
char left = this.fontcache.getChar().getLeft();
|
||||
char middle = this.fontcache.getChar().getMiddle();
|
||||
char right = this.fontcache.getChar().getRight();
|
||||
char neg_1 = FontNegative.NEG_1.getCharacter();
|
||||
int left_offset = totalWidth + 16 + 1;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(FontNegative.getShortestNegChars(isEven ? left_offset : left_offset + 1)); //先向左平移一个正方形的距离
|
||||
stringBuilder.append(left).append(neg_1); //将铭牌的左部分拼接
|
||||
int mid_amount = (totalWidth + 1) / 16; //显示名称的总长,如果超过一个正方形则多复制几个正方形
|
||||
for (int i = 0; i < (mid_amount == 0 ? 1 : mid_amount); i++) {
|
||||
stringBuilder.append(middle).append(neg_1); //减一是字符之间的间距(3)
|
||||
}
|
||||
stringBuilder.append(FontNegative.getShortestNegChars(16 - ((totalWidth + 1) % 16 + (isEven ? 0 : 1))));
|
||||
stringBuilder.append(middle).append(neg_1);
|
||||
stringBuilder.append(right).append(neg_1); //将铭牌的右部分拼接
|
||||
stringBuilder.append(FontNegative.getShortestNegChars(isEven ? left_offset : left_offset + 1)); //首尾对称处理,保证铭牌位于正中央
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
用于为增加了后缀的玩家名计算负空格
|
||||
保证铭牌总是位于玩家头顶中央的位置
|
||||
*/
|
||||
public String getSuffixLength(String name) {
|
||||
final int totalWidth = FontWidth.getTotalWidth(ChatColor.stripColor(name));
|
||||
return FontNegative.getShortestNegChars(totalWidth + totalWidth % 2 + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
获取铭牌上玩家名的颜色
|
||||
*/
|
||||
public ChatColor getColor() {
|
||||
return this.fontcache.getConfig().getColor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package net.momirealms.customnameplates.resource;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import net.momirealms.customnameplates.AdventureManager;
|
||||
import net.momirealms.customnameplates.font.FontCache;
|
||||
import net.momirealms.customnameplates.font.FontChar;
|
||||
import net.momirealms.customnameplates.font.FontNegative;
|
||||
import net.momirealms.customnameplates.nameplates.NameplateConfig;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class ResourceManager {
|
||||
|
||||
public final HashMap<String, FontCache> caches;
|
||||
private CustomNameplates plugin;
|
||||
|
||||
public ResourceManager(CustomNameplates plugin) {
|
||||
this.caches = new HashMap<>();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/*
|
||||
此方法用于生成资源包
|
||||
*/
|
||||
public void generateResourcePack() {
|
||||
|
||||
File r_file = new File(CustomNameplates.instance.getDataFolder() + File.separator + "resources");
|
||||
File g_file = new File(CustomNameplates.instance.getDataFolder() + File.separator + "generated");
|
||||
//如果资源文件夹不存在则创建
|
||||
if (!r_file.exists()) {
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Failed to detect resources folder! Generating default resources...");
|
||||
if (!r_file.mkdir()) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to create resources folder...</red>");
|
||||
return;
|
||||
}
|
||||
saveDefaultResources();
|
||||
}
|
||||
//获取资源文件夹下的所有png文件
|
||||
File[] pngFiles = r_file.listFiles(file -> file.getName().endsWith(".png"));
|
||||
if (pngFiles == null) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! No png files detected in resource folder...</red>");
|
||||
return;
|
||||
}
|
||||
Arrays.sort(pngFiles); //将png文件按照首字母进行排序
|
||||
deleteDirectory(g_file); //删除文件夹以重置自动生成的资源
|
||||
|
||||
File f_file = new File(CustomNameplates.instance.getDataFolder() + File.separator + "generated" + File.separatorChar + ConfigManager.MainConfig.namespace + File.separatorChar + "font");
|
||||
File t_file = new File(CustomNameplates.instance.getDataFolder() + File.separator + "generated" + File.separatorChar + ConfigManager.MainConfig.namespace + File.separatorChar + "textures");
|
||||
|
||||
if (!f_file.mkdirs() || !t_file.mkdirs()) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to generate resource pack folders...</red>");
|
||||
return;
|
||||
}
|
||||
char start = ConfigManager.MainConfig.start_char.charAt(0); //获取起始字符
|
||||
JsonObject jsonObject_1 = new JsonObject(); //新建json对象
|
||||
JsonArray jsonArray_1 = new JsonArray();
|
||||
jsonObject_1.add("providers", jsonArray_1);
|
||||
for (File png : pngFiles) {
|
||||
JsonObject jsonObject_2 = new JsonObject();
|
||||
char left = start;
|
||||
char middle;
|
||||
char right;
|
||||
start = (char)((right = (char)((middle = (char)(start + '\u0001')) + '\u0001')) + '\u0001'); //依次+1
|
||||
FontChar fontChar = new FontChar(left, middle, right);
|
||||
String pngName = png.getName().substring(0, png.getName().length() - 4); //删除.png后缀
|
||||
NameplateConfig config = this.getConfiguration(pngName);
|
||||
caches.put(pngName, new FontCache(pngName, fontChar, config));
|
||||
jsonObject_2.add("type", new JsonPrimitive("bitmap"));
|
||||
jsonObject_2.add("file", new JsonPrimitive(ConfigManager.MainConfig.namespace + ":" + ConfigManager.MainConfig.folder_path.replaceAll("\\\\","/") + png.getName().toLowerCase()));
|
||||
jsonObject_2.add("ascent", new JsonPrimitive(12));
|
||||
jsonObject_2.add("height", new JsonPrimitive(config.getHeight()));
|
||||
JsonArray jsonArray_2 = new JsonArray();
|
||||
jsonArray_2.add(native2ascii(fontChar.getLeft()) + native2ascii(fontChar.getMiddle()) + native2ascii(fontChar.getRight()));
|
||||
jsonObject_2.add("chars", jsonArray_2);
|
||||
jsonArray_1.add(jsonObject_2);
|
||||
try{
|
||||
FileUtils.copyFile(png, new File(t_file.getPath() + File.separatorChar + ConfigManager.MainConfig.folder_path + png.getName()));
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to copy png files to resource pack...</red>");
|
||||
}
|
||||
}
|
||||
caches.put("none", FontCache.EMPTY);
|
||||
CustomNameplates.instance.saveResource("space_split.png", false); //复制space_split.png
|
||||
try{
|
||||
FileUtils.copyFile(new File(CustomNameplates.instance.getDataFolder(),"space_split.png"), new File(t_file.getPath() + File.separatorChar + ConfigManager.MainConfig.folder_path + "space_split.png"));
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to copy space_split.png to resource pack...</red>");
|
||||
return;
|
||||
}
|
||||
new File(CustomNameplates.instance.getDataFolder(),"space_split.png").delete(); //删除拷贝出的默认文件
|
||||
this.getNegativeFontEnums().forEach(jsonArray_1::add); //添加负空格
|
||||
//存储default.json
|
||||
try (FileWriter fileWriter = new FileWriter(f_file.getPath() + File.separatorChar + ConfigManager.MainConfig.font + ".json")) {
|
||||
fileWriter.write(jsonObject_1.toString().replace("\\\\", "\\"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to generate font json...</red>");
|
||||
return;
|
||||
}
|
||||
//资源包生成成功提示
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Resource pack has been successfully generated! <color:#3CB371>" + this.caches.size() + " <color:#F5F5F5>nameplates Loaded.");
|
||||
if (this.plugin.getHookManager().hasItemsAdder()){
|
||||
try{
|
||||
FileUtils.copyDirectory(g_file, new File(Bukkit.getPluginManager().getPlugin("ItemsAdder").getDataFolder() + File.separator + "data"+ File.separator + "resource_pack" + File.separator + "assets") );
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to copy files to ItemsAdder...</red>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
保存插件预设资源
|
||||
*/
|
||||
private void saveDefaultResources() {
|
||||
List<String> list = Arrays.asList("cat", "egg", "cheems", "wither");
|
||||
list.forEach(name -> CustomNameplates.instance.saveResource("resources" + File.separatorChar + name + ".png", false));
|
||||
}
|
||||
|
||||
/*
|
||||
删除文件夹
|
||||
*/
|
||||
private void deleteDirectory(File file){
|
||||
if(file.exists()){
|
||||
try{
|
||||
FileUtils.deleteDirectory(file);
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Successfully copy files to ItemsAdder...");
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to delete generated folder...</red>" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
获取铭牌的config
|
||||
*/
|
||||
private NameplateConfig getConfiguration(String nameplate) {
|
||||
try {
|
||||
File file = new File(CustomNameplates.instance.getDataFolder().getPath() + File.separator + "resources" + File.separator + nameplate + ".yml");
|
||||
if (!file.exists()){
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("铭牌配置生成出错!");
|
||||
}
|
||||
}
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
config.load(CustomNameplates.instance.getDataFolder().getPath() + File.separator + "resources" + File.separator + nameplate + ".yml");
|
||||
if (!config.contains("name")){
|
||||
config.set("name", nameplate);
|
||||
}
|
||||
if (!config.contains("color")){
|
||||
config.set("color","WHITE");
|
||||
}
|
||||
if (!config.contains("size")){
|
||||
config.set("size", 12);
|
||||
}
|
||||
ChatColor color = ChatColor.WHITE;
|
||||
try {
|
||||
color = ChatColor.valueOf(Objects.requireNonNull(config.getString("color")).toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Invalid Color of " + nameplate + "</red>");
|
||||
}
|
||||
int size = config.getInt("size");
|
||||
String name = config.getString("name");
|
||||
config.save(file);
|
||||
return new NameplateConfig(color, size, name);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return NameplateConfig.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
获取负空格并返回list
|
||||
*/
|
||||
private List<JsonObject> getNegativeFontEnums() {
|
||||
ArrayList<JsonObject> list = new ArrayList<>();
|
||||
for (FontNegative negativeFont : FontNegative.values()) {
|
||||
list.add(this.getNegativeFontChar(negativeFont.getHeight(), negativeFont.getCharacter()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
private JsonObject getNegativeFontChar(int height, char character) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.add("type", new JsonPrimitive("bitmap"));
|
||||
jsonObject.add("file", new JsonPrimitive(ConfigManager.MainConfig.namespace + ":" + ConfigManager.MainConfig.folder_path.replaceAll("\\\\","/") +"space_split.png"));
|
||||
jsonObject.add("ascent", new JsonPrimitive(-5000));
|
||||
jsonObject.add("height", new JsonPrimitive(height));
|
||||
final JsonArray jsonArray = new JsonArray();
|
||||
jsonArray.add(native2ascii(character));
|
||||
jsonObject.add("chars", jsonArray);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/*
|
||||
根据铭牌名获取铭牌的FontCache
|
||||
*/
|
||||
public FontCache getNameplateInfo(String nameplate) {
|
||||
return caches.get(nameplate);
|
||||
}
|
||||
|
||||
/*
|
||||
字符转换
|
||||
*/
|
||||
private String native2ascii(char ch) {
|
||||
if (ch > '\u007f') {
|
||||
StringBuilder stringBuilder_1 = new StringBuilder("\\u");
|
||||
StringBuilder stringBuilder_2 = new StringBuilder(Integer.toHexString(ch));
|
||||
stringBuilder_2.reverse();
|
||||
for (int n = 4 - stringBuilder_2.length(), i = 0; i < n; i++) {
|
||||
stringBuilder_2.append('0');
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
stringBuilder_1.append(stringBuilder_2.charAt(3 - j));
|
||||
}
|
||||
return stringBuilder_1.toString();
|
||||
}
|
||||
return Character.toString(ch);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package net.momirealms.customnameplates.scoreboard;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import net.momirealms.customnameplates.data.DataManager;
|
||||
import net.momirealms.customnameplates.font.FontCache;
|
||||
import net.momirealms.customnameplates.nameplates.NameplateUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class NameplatesTeam {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
private final Player player;
|
||||
private final Team team;
|
||||
private Component prefix;
|
||||
private Component suffix;
|
||||
private ChatColor color;
|
||||
|
||||
public void hideNameplate() {
|
||||
this.team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.NEVER);
|
||||
}
|
||||
public void showNameplate() {
|
||||
this.team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
|
||||
}
|
||||
public Component getPrefix() {
|
||||
return this.prefix;
|
||||
}
|
||||
public Component getSuffix() {
|
||||
return this.suffix;
|
||||
}
|
||||
public ChatColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public NameplatesTeam(CustomNameplates plugin, Player player) {
|
||||
this.color = ChatColor.WHITE;
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
|
||||
String name = player.getName();
|
||||
this.team = Optional.ofNullable(Bukkit.getScoreboardManager().getMainScoreboard().getTeam(name)).orElseGet(() -> scoreboard.registerNewTeam(name));
|
||||
team.addEntry(player.getName());
|
||||
}
|
||||
|
||||
public void updateNameplates() {
|
||||
//获取玩家的铭牌,没有数据则创建数据,没有铭牌则设置为空铭牌
|
||||
String nameplate = (this.plugin.getDataManager().getOrCreate(this.player.getUniqueId())).getEquippedNameplate();
|
||||
//如果是空铭牌直接飞机票送走
|
||||
if (nameplate.equals("none")) {
|
||||
this.prefix = Component.text("");
|
||||
this.suffix = Component.text("");
|
||||
this.color = ChatColor.WHITE;
|
||||
this.team.setPrefix("");
|
||||
return;
|
||||
}
|
||||
//根据铭牌名获取FontCache
|
||||
FontCache fontCache = this.plugin.getResourceManager().getNameplateInfo(nameplate);
|
||||
if (fontCache == null){
|
||||
DataManager.cache.get(player.getUniqueId()).equipNameplate("none");
|
||||
return;
|
||||
}
|
||||
NameplateUtil nameplateUtil = new NameplateUtil(fontCache);
|
||||
String name = this.player.getName();
|
||||
String playerPrefix;
|
||||
String playerSuffix;
|
||||
//有Papi才解析
|
||||
if (plugin.getHookManager().hasPlaceholderAPI()) {
|
||||
playerPrefix = this.plugin.getHookManager().parsePlaceholders(this.player, ConfigManager.MainConfig.player_prefix);
|
||||
playerSuffix = this.plugin.getHookManager().parsePlaceholders(this.player, ConfigManager.MainConfig.player_suffix);
|
||||
}else {
|
||||
playerPrefix = ConfigManager.MainConfig.player_prefix;
|
||||
playerSuffix = ConfigManager.MainConfig.player_suffix;
|
||||
}
|
||||
//最终prefix: 偏移 + 铭牌左 + 偏移 + 铭牌中 + 偏移 + 铭牌右 + 偏移 + 前缀
|
||||
//最终suffix: 偏移 + 后缀
|
||||
this.prefix = Component.text(nameplateUtil.makeCustomNameplate(playerPrefix, name, playerSuffix)).font(ConfigManager.MainConfig.key).append(Component.text(playerPrefix).font(Key.key("default")));
|
||||
this.suffix = Component.text(playerSuffix).append(Component.text(nameplateUtil.getSuffixLength(playerPrefix + name + playerSuffix)).font(ConfigManager.MainConfig.key));
|
||||
this.color = nameplateUtil.getColor();
|
||||
this.team.setPrefix("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.momirealms.customnameplates.scoreboard;
|
||||
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ScoreBoardManager {
|
||||
|
||||
private final CustomNameplates plugin;
|
||||
/*
|
||||
虽然会内存占用会随着玩家数量持续增加,但是这点内存根本不值一提
|
||||
*/
|
||||
private final Map<String, NameplatesTeam> teams;
|
||||
|
||||
/*
|
||||
该类存在的意义是判断玩家是否已经
|
||||
*/
|
||||
public ScoreBoardManager(CustomNameplates plugin) {
|
||||
this.teams = new HashMap<>();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public NameplatesTeam getOrCreateTeam(Player player) {
|
||||
if (!this.teams.containsKey(player.getName())) {
|
||||
this.teams.put(player.getName(), new NameplatesTeam(this.plugin, player));
|
||||
}
|
||||
//延后一秒确保数据库完成请求
|
||||
Bukkit.getScheduler().runTaskLater(this.plugin, () -> this.getTeam(player.getName()).updateNameplates(), 20);
|
||||
return this.teams.get(player.getName());
|
||||
}
|
||||
|
||||
public void removeTeam(String playerName) {
|
||||
this.teams.remove(playerName);
|
||||
}
|
||||
|
||||
public NameplatesTeam getTeam(String team) {
|
||||
return this.teams.get(team);
|
||||
}
|
||||
|
||||
public boolean doesTeamExist(String playerName) {
|
||||
return this.teams.containsKey(playerName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package net.momirealms.customnameplates.utils;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import net.momirealms.customnameplates.AdventureManager;
|
||||
import net.momirealms.customnameplates.ConfigManager;
|
||||
import net.momirealms.customnameplates.CustomNameplates;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SqlConnection {
|
||||
|
||||
private String driver = "com.mysql.jdbc.Driver";
|
||||
|
||||
private final File dataFolder = CustomNameplates.instance.getDataFolder();
|
||||
|
||||
private boolean secon = false;
|
||||
private boolean isfirstry = true;
|
||||
|
||||
public int waitTimeOut = 10;
|
||||
|
||||
public File userdata = new File(dataFolder, "data.db");
|
||||
private Connection connection = null;
|
||||
private HikariDataSource hikari = null;
|
||||
|
||||
/*
|
||||
新建Hikari配置
|
||||
*/
|
||||
private void createNewHikariConfiguration() {
|
||||
hikari = new HikariDataSource();
|
||||
hikari.setPoolName("[Nameplates]");
|
||||
hikari.setJdbcUrl(ConfigManager.DatabaseConfig.url);
|
||||
hikari.setUsername(ConfigManager.DatabaseConfig.user);
|
||||
hikari.setPassword(ConfigManager.DatabaseConfig.password);
|
||||
hikari.setMaximumPoolSize(ConfigManager.DatabaseConfig.maximum_pool_size);
|
||||
hikari.setMinimumIdle(ConfigManager.DatabaseConfig.minimum_idle);
|
||||
hikari.setMaxLifetime(ConfigManager.DatabaseConfig.maximum_lifetime);
|
||||
hikari.addDataSourceProperty("cachePrepStmts", "true");
|
||||
hikari.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
hikari.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
hikari.addDataSourceProperty("userServerPrepStmts", "true");
|
||||
if (hikari.getMinimumIdle() < hikari.getMaximumPoolSize()) {
|
||||
hikari.setIdleTimeout(ConfigManager.DatabaseConfig.idle_timeout);
|
||||
} else {
|
||||
hikari.setIdleTimeout(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
设置驱动,区分Mysql5与8
|
||||
*/
|
||||
private void setDriver() {
|
||||
if(ConfigManager.DatabaseConfig.use_mysql){
|
||||
try {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
} catch (ClassNotFoundException e) {
|
||||
driver = ("com.mysql.jdbc.Driver");
|
||||
return;
|
||||
}
|
||||
driver = ("com.mysql.cj.jdbc.Driver");
|
||||
}else {
|
||||
driver = ("org.sqlite.JDBC");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setGlobalConnection() {
|
||||
setDriver();
|
||||
try {
|
||||
if (ConfigManager.DatabaseConfig.enable_pool) {
|
||||
createNewHikariConfiguration();
|
||||
Connection connection = getConnection();
|
||||
closeHikariConnection(connection);
|
||||
} else {
|
||||
Class.forName(driver);
|
||||
if(ConfigManager.DatabaseConfig.use_mysql){
|
||||
connection = DriverManager.getConnection(ConfigManager.DatabaseConfig.url, ConfigManager.DatabaseConfig.user, ConfigManager.DatabaseConfig.password);
|
||||
}else {
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + userdata.toString());
|
||||
}
|
||||
}
|
||||
if (secon) {
|
||||
AdventureManager.consoleMessage("<gradient:#DDE4FF:#8DA2EE>[CustomNameplates]</gradient> <color:#F5F5F5>Successfully reconnect to SQL!");
|
||||
} else {
|
||||
secon = true;
|
||||
}
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to connect to SQL!</red>");
|
||||
e.printStackTrace();
|
||||
close();
|
||||
return false;
|
||||
} catch (ClassNotFoundException e) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to load JDBC driver</red>");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Connection getConnectionAndCheck() {
|
||||
if (!canConnect()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return getConnection();
|
||||
} catch (SQLException e) {
|
||||
if (isfirstry) {
|
||||
isfirstry = false;
|
||||
close();
|
||||
return getConnectionAndCheck();
|
||||
} else {
|
||||
isfirstry = true;
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to connect to SQL!</red>");
|
||||
close();
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
if (ConfigManager.DatabaseConfig.enable_pool) {
|
||||
return hikari.getConnection();
|
||||
} else {
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean canConnect() {
|
||||
try {
|
||||
if (ConfigManager.DatabaseConfig.enable_pool) {
|
||||
if (hikari == null) {
|
||||
return setGlobalConnection();
|
||||
}
|
||||
if (hikari.isClosed()) {
|
||||
return setGlobalConnection();
|
||||
}
|
||||
} else {
|
||||
if (connection == null) {
|
||||
return setGlobalConnection();
|
||||
}
|
||||
if (connection.isClosed()) {
|
||||
return setGlobalConnection();
|
||||
}
|
||||
if (ConfigManager.DatabaseConfig.use_mysql) {
|
||||
if (!connection.isValid(waitTimeOut)) {
|
||||
secon = false;
|
||||
return setGlobalConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void closeHikariConnection(Connection connection) {
|
||||
if (!ConfigManager.DatabaseConfig.enable_pool) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
if (hikari != null) {
|
||||
hikari.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
AdventureManager.consoleMessage("<red>[CustomNameplates] Error! Failed to close SQL!</red>");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user