重写了边界显示、日志、消息提示、数据库中间件

This commit is contained in:
zhangyuheng 2024-05-16 18:07:43 +08:00
parent 0370b52475
commit 8b94db63f3
38 changed files with 483 additions and 1844 deletions

17
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>cn.lunadeer</groupId>
<artifactId>Dominion</artifactId>
<version>1.23.12-beta</version>
<version>1.24.0-beta</version>
<packaging>jar</packaging>
<name>Dominion</name>
@ -66,6 +66,10 @@
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>lunadeer-repo</id>
<url>https://ssl.lunadeer.cn:14454/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
@ -76,14 +80,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.41.2.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.2</version>
<groupId>cn.lunadeer</groupId>
<artifactId>MinecraftPluginUtils</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.github.BlueMap-Minecraft</groupId>

View File

@ -2,7 +2,6 @@ package cn.lunadeer.dominion;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.XLogger;
import java.util.List;
@ -11,15 +10,15 @@ public class AutoClean {
if (Dominion.config.getAutoCleanAfterDays() < 0) {
return;
}
XLogger.info("开始自动清理长时间未登录玩家领地数据");
Dominion.logger.info("开始自动清理长时间未登录玩家领地数据");
int auto_clean_after_days = Dominion.config.getAutoCleanAfterDays();
List<PlayerDTO> players = PlayerController.allPlayers();
for (PlayerDTO p : players) {
if (p.getLastJoinAt() + (long) auto_clean_after_days * 24 * 60 * 60 * 1000 < System.currentTimeMillis()) {
PlayerDTO.delete(p);
XLogger.info("已清理玩家 " + p.getLastKnownName() + " 的领地数据");
Dominion.logger.info("已清理玩家 %s 的领地数据", p.getLastKnownName());
}
}
XLogger.info("自动清理完成");
Dominion.logger.info("自动清理完成");
}
}

View File

@ -1,7 +1,6 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.XLogger;
import com.flowpowered.math.vector.Vector2d;
import de.bluecolored.bluemap.api.BlueMapAPI;
import de.bluecolored.bluemap.api.BlueMapMap;
@ -64,8 +63,8 @@ public class BlueMapConnect {
}
});
} catch (NoClassDefFoundError e) {
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
XLogger.err(e.getMessage());
Dominion.logger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
Dominion.logger.err(e.getMessage());
}
}
@ -118,8 +117,8 @@ public class BlueMapConnect {
}
});
} catch (NoClassDefFoundError e) {
XLogger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
XLogger.err(e.getMessage());
Dominion.logger.warn("无法连接 BlueMap 插件,如果你不打算使用卫星地图渲染建议前往配置文件关闭此功能以避免下方的报错。");
Dominion.logger.err(e.getMessage());
}
}
}

View File

@ -2,9 +2,7 @@ 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.ParticleRender;
import cn.lunadeer.dominion.utils.XLogger;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import net.kyori.adventure.text.Component;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -30,14 +28,14 @@ public class Cache {
*/
public void loadDominions() {
if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadDominionsExecution directly");
Dominion.logger.debug("run loadDominionsExecution directly");
loadDominionsExecution();
} else {
if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution");
Dominion.logger.debug("schedule loadDominionsExecution");
_update_dominion_is_scheduled.set(true);
Dominion.scheduler.async.runDelayed(Dominion.instance, (instance) -> {
XLogger.debug("run loadDominionsExecution scheduled");
Dominion.logger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution();
_update_dominion_is_scheduled.set(false);
},
@ -92,7 +90,7 @@ public class Cache {
private void loadPlayerPrivilegesExecution() {
List<PlayerPrivilegeDTO> all_privileges = PlayerPrivilegeDTO.selectAll();
if (all_privileges == null) {
XLogger.err("加载玩家特权失败");
Dominion.logger.err("加载玩家特权失败");
return;
}
player_uuid_to_privilege = new ConcurrentHashMap<>();
@ -126,12 +124,12 @@ public class Cache {
// glow
player.setGlowing(false);
if (dominion.getParentDomId() == -1) {
Notification.info(player, "您已离开领地:" + dominion.getName());
Dominion.notification.info(player, "您已离开领地:%s", dominion.getName());
player.sendMessage(Component.text(dominion.getLeaveMessage()));
update_player_current_dominion(player, null);
dominion = null;
} else {
Notification.info(player, "您已离开子领地:" + dominion.getName());
Dominion.notification.info(player, "您已离开子领地:%s", dominion.getName());
player.sendMessage(Component.text(dominion.getLeaveMessage()));
dominion = id_dominions.get(dominion.getParentDomId());
update_player_current_dominion(player, dominion);
@ -143,7 +141,7 @@ public class Cache {
DominionDTO child = id_dominions.get(child_id);
if (isInDominion(child, player)) {
dominion = child;
Notification.info(player, "您正在进入子领地:" + dominion.getName());
Dominion.notification.info(player, "您正在进入子领地:%s", dominion.getName());
player.sendMessage(Component.text(dominion.getJoinMessage()));
update_player_current_dominion(player, dominion);
break;
@ -165,7 +163,7 @@ public class Cache {
if (in_dominions.size() == 0) return null;
in_dominions.sort(Comparator.comparingInt(DominionDTO::getId));
dominion = in_dominions.get(0);
Notification.info(player, "您正在进入领地:" + dominion.getName());
Dominion.notification.info(player, "您正在进入领地:%s", dominion.getName());
player.sendMessage(Component.text(dominion.getJoinMessage()));
update_player_current_dominion(player, dominion);
}
@ -181,7 +179,9 @@ public class Cache {
player_current_dominion_id.put(player.getUniqueId(), dominion.getId());
// show border
if (dominion.getShowBorder()) {
ParticleRender.showBoxBorder(dominion);
ParticleRender.showBoxFace(Dominion.instance, player,
dominion.getLocation1(),
dominion.getLocation2());
}
// glow
PlayerPrivilegeDTO privilege = getPlayerPrivilege(player, dominion);

View File

@ -4,7 +4,6 @@ import cn.lunadeer.dominion.commands.*;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.tuis.*;
import cn.lunadeer.dominion.tuis.Apis;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;

View File

@ -4,15 +4,13 @@ import cn.lunadeer.dominion.events.EnvironmentEvents;
import cn.lunadeer.dominion.events.PlayerEvents;
import cn.lunadeer.dominion.events.SelectPointEvents;
import cn.lunadeer.dominion.managers.ConfigManager;
import cn.lunadeer.dominion.managers.DatabaseManager;
import cn.lunadeer.dominion.utils.GiteaReleaseCheck;
import cn.lunadeer.dominion.managers.DatabaseTables;
import cn.lunadeer.dominion.utils.Scheduler;
import cn.lunadeer.dominion.utils.XLogger;
import cn.lunadeer.minecraftpluginutils.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@ -25,9 +23,17 @@ public final class Dominion extends JavaPlugin {
public void onEnable() {
// Plugin startup logic
instance = this;
notification = new Notification(this);
logger = new XLogger(this);
config = new ConfigManager(this);
dbConnection = DatabaseManager.createConnection();
DatabaseManager.migrate();
database = new DatabaseManager(this,
config.getDbType().equals("pgsql") ? DatabaseManager.TYPE.POSTGRESQL : DatabaseManager.TYPE.SQLITE,
config.getDbHost(),
config.getDbPort(),
config.getDbName(),
config.getDbUser(),
config.getDbPass());
DatabaseTables.migrate();
scheduler = new Scheduler(this);
AutoClean.run();
Cache.instance = new Cache();
@ -35,7 +41,7 @@ public final class Dominion extends JavaPlugin {
if (config.getEconomyEnable()) {
vault = new VaultConnect(this);
if (vault.getEconomy() == null) {
XLogger.err("你没有安装 Vault 前置插件,无法使用经济功能。");
logger.err("你没有安装 Vault 前置插件,无法使用经济功能。");
config.setEconomyEnable(false);
}
}
@ -45,7 +51,7 @@ public final class Dominion extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new SelectPointEvents(), this);
Objects.requireNonNull(Bukkit.getPluginCommand("dominion")).setExecutor(new Commands());
Metrics metrics = new Metrics(this, 21445);
bStatsMetrics metrics = new bStatsMetrics(this, 21445);
if (config.getCheckUpdate()) {
giteaReleaseCheck = new GiteaReleaseCheck(this,
"https://ssl.lunadeer.cn:14446",
@ -53,16 +59,16 @@ public final class Dominion extends JavaPlugin {
"Dominion");
}
XLogger.info("领地插件已启动");
XLogger.info("版本:" + this.getPluginMeta().getVersion());
logger.info("领地插件已启动");
logger.info("版本:" + this.getPluginMeta().getVersion());
// http://patorjk.com/software/taag/#p=display&f=Big&t=Dominion
XLogger.info(" _____ _ _");
XLogger.info(" | __ \\ (_) (_)");
XLogger.info(" | | | | ___ _ __ ___ _ _ __ _ ___ _ __");
XLogger.info(" | | | |/ _ \\| '_ ` _ \\| | '_ \\| |/ _ \\| '_ \\");
XLogger.info(" | |__| | (_) | | | | | | | | | | | (_) | | | |");
XLogger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|");
XLogger.info(" ");
logger.info(" _____ _ _");
logger.info(" | __ \\ (_) (_)");
logger.info(" | | | | ___ _ __ ___ _ _ __ _ ___ _ __");
logger.info(" | | | |/ _ \\| '_ ` _ \\| | '_ \\| |/ _ \\| '_ \\");
logger.info(" | |__| | (_) | | | | | | | | | | | (_) | | | |");
logger.info(" |_____/ \\___/|_| |_| |_|_|_| |_|_|\\___/|_| |_|");
logger.info(" ");
scheduler.async.runDelayed(this, scheduledTask -> {
BlueMapConnect.render();
@ -76,7 +82,9 @@ public final class Dominion extends JavaPlugin {
public static Dominion instance;
public static ConfigManager config;
public static Connection dbConnection;
public static XLogger logger;
public static Notification notification;
public static DatabaseManager database;
public static Map<UUID, Map<Integer, Location>> pointsSelect = new HashMap<>();
public static Scheduler scheduler;
private GiteaReleaseCheck giteaReleaseCheck;

View File

@ -1,863 +0,0 @@
package cn.lunadeer.dominion;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;
public class Metrics {
private final Plugin plugin;
private final MetricsBase metricsBase;
/**
* Creates a new Metrics instance.
*
* @param plugin Your plugin instance.
* @param serviceId The id of the service. It can be found at <a
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
*/
public Metrics(JavaPlugin plugin, int serviceId) {
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", true);
config.addDefault("serverUuid", UUID.randomUUID().toString());
config.addDefault("logFailedRequests", false);
config.addDefault("logSentData", false);
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config
.options()
.header(
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
+ "anonymous.")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) {
}
}
// Load the data
boolean enabled = config.getBoolean("enabled", true);
String serverUUID = config.getString("serverUuid");
boolean logErrors = config.getBoolean("logFailedRequests", false);
boolean logSentData = config.getBoolean("logSentData", false);
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
metricsBase =
new MetricsBase(
"bukkit",
serverUUID,
serviceId,
enabled,
this::appendPlatformData,
this::appendServiceData,
null,
//submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
plugin::isEnabled,
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
(message) -> this.plugin.getLogger().log(Level.INFO, message),
logErrors,
logSentData,
logResponseStatusText);
}
/**
* Shuts down the underlying scheduler service.
*/
public void shutdown() {
metricsBase.shutdown();
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
metricsBase.addCustomChart(chart);
}
private void appendPlatformData(JsonObjectBuilder builder) {
builder.appendField("playerAmount", getPlayerAmount());
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
builder.appendField("bukkitVersion", Bukkit.getVersion());
builder.appendField("bukkitName", Bukkit.getName());
builder.appendField("javaVersion", System.getProperty("java.version"));
builder.appendField("osName", System.getProperty("os.name"));
builder.appendField("osArch", System.getProperty("os.arch"));
builder.appendField("osVersion", System.getProperty("os.version"));
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
}
private void appendServiceData(JsonObjectBuilder builder) {
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
}
private int getPlayerAmount() {
try {
// Around MC 1.8 the return type was changed from an array to a collection,
// This fixes java.lang.NoSuchMethodError:
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
return onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
// Just use the new method if the reflection failed
return Bukkit.getOnlinePlayers().size();
}
}
public static class MetricsBase {
/**
* The version of the Metrics class.
*/
public static final String METRICS_VERSION = "3.0.2";
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
private final ScheduledExecutorService scheduler;
private final String platform;
private final String serverUuid;
private final int serviceId;
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
private final Consumer<Runnable> submitTaskConsumer;
private final Supplier<Boolean> checkServiceEnabledSupplier;
private final BiConsumer<String, Throwable> errorLogger;
private final Consumer<String> infoLogger;
private final boolean logErrors;
private final boolean logSentData;
private final boolean logResponseStatusText;
private final Set<CustomChart> customCharts = new HashSet<>();
private final boolean enabled;
/**
* Creates a new MetricsBase class instance.
*
* @param platform The platform of the service.
* @param serviceId The id of the service.
* @param serverUuid The server uuid.
* @param enabled Whether or not data sending is enabled.
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all platform-specific data.
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all service-specific data.
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
* used to delegate the data collection to a another thread to prevent errors caused by
* concurrency. Can be {@code null}.
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
* @param errorLogger A consumer that accepts log message and an error.
* @param infoLogger A consumer that accepts info log messages.
* @param logErrors Whether or not errors should be logged.
* @param logSentData Whether or not the sent data should be logged.
* @param logResponseStatusText Whether or not the response status text should be logged.
*/
public MetricsBase(
String platform,
String serverUuid,
int serviceId,
boolean enabled,
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
Consumer<Runnable> submitTaskConsumer,
Supplier<Boolean> checkServiceEnabledSupplier,
BiConsumer<String, Throwable> errorLogger,
Consumer<String> infoLogger,
boolean logErrors,
boolean logSentData,
boolean logResponseStatusText) {
ScheduledThreadPoolExecutor scheduler =
new ScheduledThreadPoolExecutor(1, task -> new Thread(task, "bStats-Metrics"));
// We want delayed tasks (non-periodic) that will execute in the future to be
// cancelled when the scheduler is shutdown.
// Otherwise, we risk preventing the server from shutting down even when
// MetricsBase#shutdown() is called
scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.scheduler = scheduler;
this.platform = platform;
this.serverUuid = serverUuid;
this.serviceId = serviceId;
this.enabled = enabled;
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
this.appendServiceDataConsumer = appendServiceDataConsumer;
this.submitTaskConsumer = submitTaskConsumer;
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
this.errorLogger = errorLogger;
this.infoLogger = infoLogger;
this.logErrors = logErrors;
this.logSentData = logSentData;
this.logResponseStatusText = logResponseStatusText;
checkRelocation();
if (enabled) {
// WARNING: Removing the option to opt-out will get your plugin banned from
// bStats
startSubmitting();
}
}
public void addCustomChart(CustomChart chart) {
this.customCharts.add(chart);
}
public void shutdown() {
scheduler.shutdown();
}
private void startSubmitting() {
final Runnable submitTask =
() -> {
if (!enabled || !checkServiceEnabledSupplier.get()) {
// Submitting data or service is disabled
scheduler.shutdown();
return;
}
if (submitTaskConsumer != null) {
submitTaskConsumer.accept(this::submitData);
} else {
this.submitData();
}
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven
// distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into
// the initial and second delay.
// WARNING: You must not modify and part of this Metrics class, including the
// submit delay or frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just
// don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
scheduler.scheduleAtFixedRate(
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
private void submitData() {
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
appendPlatformDataConsumer.accept(baseJsonBuilder);
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
appendServiceDataConsumer.accept(serviceJsonBuilder);
JsonObjectBuilder.JsonObject[] chartData =
customCharts.stream()
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
.filter(Objects::nonNull)
.toArray(JsonObjectBuilder.JsonObject[]::new);
serviceJsonBuilder.appendField("id", serviceId);
serviceJsonBuilder.appendField("customCharts", chartData);
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
baseJsonBuilder.appendField("serverUUID", serverUuid);
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
scheduler.execute(
() -> {
try {
// Send the data
sendData(data);
} catch (Exception e) {
// Something went wrong! :(
if (logErrors) {
errorLogger.accept("Could not submit bStats metrics data", e);
}
}
});
}
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
if (logSentData) {
infoLogger.accept("Sent bStats metrics data: " + data.toString());
}
String url = String.format(REPORT_URL, platform);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
infoLogger.accept("Sent data to bStats and received response: " + builder);
}
}
/**
* Checks that the class was properly relocated.
*/
private void checkRelocation() {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this
// little "trick" ... :D
final String defaultPackage =
new String(new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
final String examplePackage =
new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure no one just copy & pastes the example and uses the wrong
// package names
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
/**
* Gzips the given string.
*
* @param str The string to gzip.
* @return The gzipped string.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
}
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
valuesBuilder.appendField(entry.getKey(), new int[]{entry.getValue()});
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public abstract static class CustomChart {
private final String chartId;
protected CustomChart(String chartId) {
if (chartId == null) {
throw new IllegalArgumentException("chartId must not be null");
}
this.chartId = chartId;
}
public JsonObjectBuilder.JsonObject getRequestJsonObject(
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
JsonObjectBuilder builder = new JsonObjectBuilder();
builder.appendField("chartId", chartId);
try {
JsonObjectBuilder.JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
builder.appendField("data", data);
} catch (Throwable t) {
if (logErrors) {
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return builder.build();
}
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
}
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
/**
* An extremely simple JSON builder.
*
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
* for its use-case.
*/
public static class JsonObjectBuilder {
private StringBuilder builder = new StringBuilder();
private boolean hasAtLeastOneField = false;
public JsonObjectBuilder() {
builder.append("{");
}
/**
* Appends a null field to the JSON.
*
* @param key The key of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendNull(String key) {
appendFieldUnescaped(key, "null");
return this;
}
/**
* Appends a string field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String value) {
if (value == null) {
throw new IllegalArgumentException("JSON value must not be null");
}
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
return this;
}
/**
* Appends an integer field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int value) {
appendFieldUnescaped(key, String.valueOf(value));
return this;
}
/**
* Appends an object to the JSON.
*
* @param key The key of the field.
* @param object The object.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject object) {
if (object == null) {
throw new IllegalArgumentException("JSON object must not be null");
}
appendFieldUnescaped(key, object.toString());
return this;
}
/**
* Appends a string array to the JSON.
*
* @param key The key of the field.
* @param values The string array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values)
.map(value -> "\"" + escape(value) + "\"")
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an integer array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an object array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends a field to the object.
*
* @param key The key of the field.
* @param escapedValue The escaped value of the field.
*/
private void appendFieldUnescaped(String key, String escapedValue) {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
if (key == null) {
throw new IllegalArgumentException("JSON key must not be null");
}
if (hasAtLeastOneField) {
builder.append(",");
}
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
hasAtLeastOneField = true;
}
/**
* Builds the JSON string and invalidates this builder.
*
* @return The built JSON string.
*/
public JsonObject build() {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
JsonObject object = new JsonObject(builder.append("}").toString());
builder = null;
return object;
}
/**
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
*
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
*
* @param value The value to escape.
* @return The escaped value.
*/
private static String escape(String value) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '"') {
builder.append("\\\"");
} else if (c == '\\') {
builder.append("\\\\");
} else if (c <= '\u000F') {
builder.append("\\u000").append(Integer.toHexString(c));
} else if (c <= '\u001F') {
builder.append("\\u00").append(Integer.toHexString(c));
} else {
builder.append(c);
}
}
return builder.toString();
}
/**
* A super simple representation of a JSON object.
*
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
* JsonObject)}.
*/
public static class JsonObject {
private final String value;
private JsonObject(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
}

View File

@ -1,6 +1,5 @@
package cn.lunadeer.dominion;
import cn.lunadeer.dominion.utils.XLogger;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
@ -17,7 +16,7 @@ public class VaultConnect {
public VaultConnect(JavaPlugin plugin) {
this.plugin = plugin;
if (!setupEconomy() ) {
XLogger.err("你没有安装 Vault 前置插件,无法使用经济功能,如果不需要使用经济功能请前往配置文件关闭。");
Dominion.logger.err("你没有安装 Vault 前置插件,无法使用经济功能,如果不需要使用经济功能请前往配置文件关闭。");
return;
}
setupPermissions();

View File

@ -2,7 +2,6 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -13,7 +12,7 @@ import java.util.Map;
public class Apis {
public static Player playerOnly(CommandSender sender) {
if (!(sender instanceof Player)) {
Notification.error(sender, "该命令只能由玩家执行");
Dominion.notification.error(sender, "该命令只能由玩家执行");
return null;
}
return (Player) sender;
@ -26,14 +25,14 @@ public class Apis {
Integer x2 = dominionDTO.getX2();
Integer y2 = dominionDTO.getY2();
Integer z2 = dominionDTO.getZ2();
Notification.info(sender, "领地 " + dominionDTO.getName() + " 的尺寸信息:");
Notification.info(sender, " 大小" + (x2 - x1) + " x" + (y2 - y1) + " x" + (z2 - z1));
Notification.info(sender, " 中心坐标" + (x1 + (x2 - x1) / 2) + " " + (y1 + (y2 - y1) / 2) + " " + (z1 + (z2 - z1) / 2));
Notification.info(sender, " 高度" + (y2 - y1));
Notification.info(sender, " Y1=" + y1 + " Y2=" + y2);
Notification.info(sender, " 体积" + (x2 - x1) * (y2 - y1) * (z2 - z1));
Notification.info(sender, " 领地的世界为 " + dominionDTO.getWorld());
Notification.info(sender, " 领地的对角点坐标为 x1=" + x1 + " y1=" + y1 + " z1=" + z1 + " x2=" + x2 + " y2=" + y2 + " z2=" + z2);
Dominion.notification.info(sender, "领地 %s 的尺寸信息:", dominionDTO.getName());
Dominion.notification.info(sender, " 大小 %d x %d x %d", x2 - x1, y2 - y1, z2 - z1);
Dominion.notification.info(sender, " 中心坐标 %d %d %d", x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2, z1 + (z2 - z1) / 2);
Dominion.notification.info(sender, " 高度 %d", y2 - y1);
Dominion.notification.info(sender, " Y坐标范围 %d ~ %d", y1, y2);
Dominion.notification.info(sender, " 体积 %d", (x2 - x1) * (y2 - y1) * (z2 - z1));
Dominion.notification.info(sender, " 领地所在世界: %s", dominionDTO.getWorld());
Dominion.notification.info(sender, " 领地的对角点坐标 x1=%d y1=%d z1=%d, x2=%d y2=%d z2=%d", x1, y1, z1, x2, y2, z2);
}
public static void autoPoints(Player player) {
@ -55,7 +54,7 @@ public class Apis {
if (sender instanceof Player) {
Player player = (Player) sender;
if (!player.isOp()) {
Notification.warn(player, "你没有权限使用此命令");
Dominion.notification.warn(player, "你没有权限使用此命令");
return true;
}
}

View File

@ -1,8 +1,8 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.FlagsController;
import cn.lunadeer.dominion.tuis.DominionFlagInfo;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -22,15 +22,15 @@ public class DominionFlag {
if (player == null) return;
if (args.length == 3) {
if (FlagsController.setFlag(player, args[1], Boolean.parseBoolean(args[2])) == null) {
Notification.error(sender, "设置领地权限失败");
Dominion.notification.error(sender, "设置领地权限失败");
}
} else if (args.length == 4) {
if (FlagsController.setFlag(player, args[1], Boolean.parseBoolean(args[2]), args[3]) == null) {
Notification.error(sender, "设置领地权限失败");
Dominion.notification.error(sender, "设置领地权限失败");
}
} else if (args.length == 5) {
if (FlagsController.setFlag(player, args[1], Boolean.parseBoolean(args[2]), args[3]) == null) {
Notification.error(sender, "设置领地权限失败");
Dominion.notification.error(sender, "设置领地权限失败");
}
String[] newArgs = new String[3];
newArgs[0] = "flag_info";
@ -39,10 +39,10 @@ public class DominionFlag {
DominionFlagInfo.show(sender, newArgs);
return;
} else {
Notification.error(sender, "用法: /dominion set <权限名称> <true/false> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion set <权限名称> <true/false> [领地名称]");
return;
}
Notification.info(sender, "设置领地权限 " + args[1] + "" + args[2]);
Dominion.notification.info(sender, "设置领地权限 %s 为 %s", args[1], args[2]);
}
}

View File

@ -5,17 +5,11 @@ import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.DominionController;
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 cn.lunadeer.minecraftpluginutils.Teleport;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wolf;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.time.LocalDateTime;
import java.util.Map;
@ -34,20 +28,20 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2) {
Notification.error(sender, "用法: /dominion create <领地名称>");
Dominion.notification.error(sender, "用法: /dominion create <领地名称>");
return;
}
Map<Integer, Location> points = Dominion.pointsSelect.get(player.getUniqueId());
if (points == null || points.get(0) == null || points.get(1) == null) {
Notification.error(sender, "请先使用工具选择领地的对角线两点,或使用 /dominion auto_create <领地名称> 创建自动领地");
Dominion.notification.error(sender, "请先使用工具选择领地的对角线两点,或使用 /dominion auto_create <领地名称> 创建自动领地");
return;
}
String name = args[1];
if (DominionController.create(player, name, points.get(0), points.get(1)) == null) {
Notification.error(sender, "创建领地失败");
Dominion.notification.error(sender, "创建领地失败");
return;
}
Notification.info(sender, "成功创建: " + name);
Dominion.notification.info(sender, "成功创建: %s", name);
}
/**
@ -61,26 +55,26 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3) {
Notification.error(sender, "用法: /dominion create_sub <子领地名称> [父领地名称]");
Dominion.notification.error(sender, "用法: /dominion create_sub <子领地名称> [父领地名称]");
return;
}
Map<Integer, Location> points = Dominion.pointsSelect.get(player.getUniqueId());
if (points == null || points.get(0) == null || points.get(1) == null) {
Notification.error(sender, "请先使用工具选择子领地的对角线两点,或使用 /dominion auto_create_sub <子领地名称> [父领地名称] 创建自动子领地");
Dominion.notification.error(sender, "请先使用工具选择子领地的对角线两点,或使用 /dominion auto_create_sub <子领地名称> [父领地名称] 创建自动子领地");
return;
}
if (args.length == 2) {
if (DominionController.create(player, args[1], points.get(0), points.get(1)) != null) {
Notification.info(sender, "成功创建子领地: " + args[1]);
Dominion.notification.info(sender, "成功创建子领地: %s", args[1]);
return;
}
} else {
if (DominionController.create(player, args[1], points.get(0), points.get(1), args[2]) != null) {
Notification.info(sender, "成功创建子领地: " + args[1]);
Dominion.notification.info(sender, "成功创建子领地: %s", args[1]);
return;
}
}
Notification.error(sender, "创建子领地失败");
Dominion.notification.error(sender, "创建子领地失败");
}
/**
@ -95,11 +89,11 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2) {
Notification.error(sender, "用法: /dominion auto_create <领地名称>");
Dominion.notification.error(sender, "用法: /dominion auto_create <领地名称>");
return;
}
if (Dominion.config.getAutoCreateRadius() < 0) {
Notification.error(sender, "自动创建领地功能已关闭");
Dominion.notification.error(sender, "自动创建领地功能已关闭");
return;
}
autoPoints(player);
@ -118,11 +112,11 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3) {
Notification.error(sender, "用法: /dominion auto_create_sub <子领地名称> [父领地名称]");
Dominion.notification.error(sender, "用法: /dominion auto_create_sub <子领地名称> [父领地名称]");
return;
}
if (Dominion.config.getAutoCreateRadius() < 0) {
Notification.error(sender, "自动创建领地功能已关闭");
Dominion.notification.error(sender, "自动创建领地功能已关闭");
return;
}
autoPoints(player);
@ -140,7 +134,7 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3) {
Notification.error(sender, "用法: /dominion expand [大小] [领地名称]");
Dominion.notification.error(sender, "用法: /dominion expand [大小] [领地名称]");
return;
}
int size = 10;
@ -148,11 +142,11 @@ public class DominionOperate {
try {
size = Integer.parseInt(args[1]);
} catch (Exception e) {
Notification.error(sender, "大小格式错误");
Dominion.notification.error(sender, "大小格式错误");
return;
}
if (size <= 0) {
Notification.error(sender, "大小必须大于0");
Dominion.notification.error(sender, "大小必须大于0");
return;
}
if (args.length == 3) {
@ -165,9 +159,9 @@ public class DominionOperate {
dominionDTO = DominionController.expand(player, size, name);
}
if (dominionDTO == null) {
Notification.error(sender, "扩展领地失败");
Dominion.notification.error(sender, "扩展领地失败");
} else {
Notification.info(sender, "成功扩展领地: " + dominionDTO.getName() + " " + size);
Dominion.notification.info(sender, "成功扩展领地: %s %d", dominionDTO.getName(), size);
sizeInfo(sender, dominionDTO);
}
}
@ -183,7 +177,7 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3) {
Notification.error(sender, "用法: /dominion contract [大小] [领地名称]");
Dominion.notification.error(sender, "用法: /dominion contract [大小] [领地名称]");
return;
}
int size = 10;
@ -191,11 +185,11 @@ public class DominionOperate {
try {
size = Integer.parseInt(args[1]);
} catch (Exception e) {
Notification.error(sender, "大小格式错误");
Dominion.notification.error(sender, "大小格式错误");
return;
}
if (size <= 0) {
Notification.error(sender, "大小必须大于0");
Dominion.notification.error(sender, "大小必须大于0");
return;
}
if (args.length == 3) {
@ -208,9 +202,9 @@ public class DominionOperate {
dominionDTO = DominionController.contract(player, size, name);
}
if (dominionDTO == null) {
Notification.error(sender, "缩小领地失败");
Dominion.notification.error(sender, "缩小领地失败");
} else {
Notification.info(sender, "成功缩小领地: " + dominionDTO.getName() + " " + size);
Dominion.notification.info(sender, "成功缩小领地: %s %d", dominionDTO.getName(), size);
sizeInfo(sender, dominionDTO);
}
}
@ -237,7 +231,7 @@ public class DominionOperate {
return;
}
}
Notification.error(sender, "用法: /dominion delete <领地名称>");
Dominion.notification.error(sender, "用法: /dominion delete <领地名称>");
}
/**
@ -258,7 +252,7 @@ public class DominionOperate {
DominionController.setJoinMessage(player, args[1], args[2]);
return;
}
Notification.error(sender, "用法: /dominion set_enter_msg <提示语> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion set_enter_msg <提示语> [领地名称]");
}
/**
@ -279,7 +273,7 @@ public class DominionOperate {
DominionController.setLeaveMessage(player, args[1], args[2]);
return;
}
Notification.error(sender, "用法: /dominion set_leave_msg <提示语> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion set_leave_msg <提示语> [领地名称]");
}
/**
@ -300,7 +294,7 @@ public class DominionOperate {
DominionController.setTpLocation(player, args[1]);
return;
}
Notification.error(sender, "用法: /dominion set_tp_location [领地名称]");
Dominion.notification.error(sender, "用法: /dominion set_tp_location [领地名称]");
}
/**
@ -314,7 +308,7 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 3) {
Notification.error(sender, "用法: /dominion rename <原领地名称> <新领地名称>");
Dominion.notification.error(sender, "用法: /dominion rename <原领地名称> <新领地名称>");
return;
}
DominionController.rename(player, args[1], args[2]);
@ -344,7 +338,7 @@ public class DominionOperate {
return;
}
}
Notification.error(sender, "用法: /dominion give <领地名称> <玩家名称>");
Dominion.notification.error(sender, "用法: /dominion give <领地名称> <玩家名称>");
}
/**
@ -358,27 +352,27 @@ public class DominionOperate {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2) {
Notification.error(sender, "用法: /dominion tp <领地名称>");
Dominion.notification.error(sender, "用法: /dominion tp <领地名称>");
return;
}
if (!Dominion.config.getTpEnable()) {
Notification.error(sender, "管理员没有开启领地传送功能");
Dominion.notification.error(sender, "管理员没有开启领地传送功能");
return;
}
DominionDTO dominionDTO = DominionDTO.select(args[1]);
if (dominionDTO == null) {
Notification.error(sender, "领地不存在");
Dominion.notification.error(sender, "领地不存在");
return;
}
PlayerPrivilegeDTO privilegeDTO = PlayerPrivilegeDTO.select(player.getUniqueId(), dominionDTO.getId());
if (privilegeDTO == null) {
if (!dominionDTO.getTeleport()) {
Notification.error(sender, "此领地禁止传送");
Dominion.notification.error(sender, "此领地禁止传送");
return;
}
} else {
if (!privilegeDTO.getTeleport()) {
Notification.error(sender, "你不被允许传送到这个领地");
Dominion.notification.error(sender, "你不被允许传送到这个领地");
return;
}
}
@ -388,12 +382,12 @@ public class DominionOperate {
if (next_time != null) {
if (now.isBefore(next_time)) {
long secs_until_next = now.until(next_time, java.time.temporal.ChronoUnit.SECONDS);
Notification.error(player, "请等待 " + secs_until_next + " 秒后再次传送");
Dominion.notification.error(player, "请等待 %d 秒后再传送", secs_until_next);
return;
}
}
if (Dominion.config.getTpDelay() > 0) {
Notification.info(player, "传送将在 " + Dominion.config.getTpDelay() + " 秒后执行");
Dominion.notification.info(player, "传送将在 %d 秒后执行", Dominion.config.getTpDelay());
}
Cache.instance.NextTimeAllowTeleport.put(player.getUniqueId(), now.plusSeconds(Dominion.config.getTpCoolDown()));
Dominion.scheduler.region.runDelayed(Dominion.instance, (instance) -> {
@ -403,45 +397,12 @@ public class DominionOperate {
int z = (dominionDTO.getZ1() + dominionDTO.getZ2()) / 2;
World world = Dominion.instance.getServer().getWorld(dominionDTO.getWorld());
location = new Location(world, x, player.getY(), z);
XLogger.warn("领地 " + dominionDTO.getName() + " 没有设置传送点,将传送到中心点");
Dominion.logger.warn("领地 %s 没有设置传送点,将尝试传送到中心点", dominionDTO.getName());
}
if (player.isOnline()) {
doTeleportSafely(player, location);
Notification.info(player, "已将你传送到 " + dominionDTO.getName());
Teleport.doTeleportSafely(Dominion.instance, player, location);
Dominion.notification.info(player, "已将你传送到 " + dominionDTO.getName());
}
}, Dominion.config.getTpDelay() == 0 ? 1 : 20L * Dominion.config.getTpDelay());
}
private static void doTeleportSafely(Player player, Location location) {
location.getWorld().getChunkAtAsyncUrgently(location).thenAccept((chunk) -> {
int max_attempts = 512;
while (location.getBlock().isPassable()) {
location.setY(location.getY() - 1);
max_attempts--;
if (max_attempts <= 0) {
Notification.error(player, "传送目的地不安全,已取消传送");
return;
}
}
Block up1 = location.getBlock().getRelative(BlockFace.UP);
Block up2 = up1.getRelative(BlockFace.UP);
max_attempts = 512;
while (!(up1.isPassable() && !up1.isLiquid()) || !(up2.isPassable() && !up2.isLiquid())) {
location.setY(location.getY() + 1);
up1 = location.getBlock().getRelative(BlockFace.UP);
up2 = up1.getRelative(BlockFace.UP);
max_attempts--;
if (max_attempts <= 0) {
Notification.error(player, "传送目的地不安全,已取消传送");
return;
}
}
location.setY(location.getY() + 1);
if (location.getBlock().getRelative(BlockFace.DOWN).getType() == Material.LAVA) {
Notification.error(player, "传送目的地不安全,已取消传送");
return;
}
player.teleportAsync(location, PlayerTeleportEvent.TeleportCause.PLUGIN);
});
}
}

View File

@ -29,8 +29,8 @@ public class Helper {
"mob_drop_item", "monster_killing", "move",
"place", "pressure",
"riding", "repeater",
"shear", "shoot",
"tnt_explode", "trade", "trample",
"shear", "shoot", "show_border",
"teleport", "tnt_explode", "trade", "trample",
"vehicle_destroy",
"vehicle_spawn",
"wither_spawn");
@ -51,7 +51,7 @@ public class Helper {
"monster_killing", "move",
"place", "pressure", "riding", "repeater",
"shear", "shoot",
"trade",
"teleport", "trade",
"vehicle_destroy",
"vehicle_spawn");
}

View File

@ -4,8 +4,6 @@ import cn.lunadeer.dominion.BlueMapConnect;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.XLogger;
import org.bukkit.command.CommandSender;
import java.io.File;
@ -21,21 +19,21 @@ public class Operator {
public static void reloadCache(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return;
Dominion.scheduler.async.runNow(Dominion.instance, ScheduledTask -> {
Notification.info(sender, "正在从数据库重新加载领地缓存...");
Dominion.notification.info(sender, "正在从数据库重新加载领地缓存...");
Cache.instance.loadDominions();
Notification.info(sender, "领地缓存已重新加载");
Dominion.notification.info(sender, "领地缓存已重新加载");
});
Dominion.scheduler.async.runNow(Dominion.instance, ScheduledTask -> {
Notification.info(sender, "正在从数据库重新加载玩家权限缓存...");
Dominion.notification.info(sender, "正在从数据库重新加载玩家权限缓存...");
Cache.instance.loadPlayerPrivileges();
Notification.info(sender, "玩家权限缓存已重新加载");
Dominion.notification.info(sender, "玩家权限缓存已重新加载");
});
}
public static void exportMca(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return;
Dominion.scheduler.async.runNow(Dominion.instance, ScheduledTask -> {
Notification.info(sender, "正在导出拥有领地的MCA文件列表...");
Dominion.notification.info(sender, "正在导出拥有领地的MCA文件列表...");
Map<String, List<String>> mca_cords = new HashMap<>();
List<DominionDTO> doms = Cache.instance.getDominions();
for (DominionDTO dom : doms) {
@ -64,51 +62,51 @@ public class Operator {
if (!folder.exists()) {
boolean success = folder.mkdirs();
if (!success) {
Notification.error(sender, "创建导出文件夹失败");
Dominion.notification.error(sender, "创建导出文件夹失败");
return;
}
}
for (String world : mca_cords.keySet()) {
File file = new File(folder, world + ".txt");
Notification.info(sender, "正在导出 " + world + " 的MCA文件列表...");
Dominion.notification.info(sender, "正在导出 %s 的MCA文件列表...", world);
try {
if (file.exists()) {
boolean success = file.delete();
if (!success) {
Notification.error(sender, "删除 " + world + " 的MCA文件列表失败");
Dominion.notification.error(sender, "删除 %s 的MCA文件列表失败", world);
continue;
}
}
boolean success = file.createNewFile();
if (!success) {
Notification.error(sender, "创建 " + world + " 的MCA文件列表失败");
Dominion.notification.error(sender, "创建 %s 的MCA文件列表失败", world);
continue;
}
List<String> cords = mca_cords.get(world);
for (String cord : cords) {
XLogger.debug("正在写入 " + cord + "...");
Dominion.logger.debug("正在写入 %s...", cord);
try {
java.nio.file.Files.write(file.toPath(), (cord + "\n").getBytes(), java.nio.file.StandardOpenOption.APPEND);
} catch (Exception e) {
Notification.error(sender, "写入 " + cord + " 失败");
Dominion.notification.error(sender, "写入 %s 失败", cord);
}
}
} catch (Exception e) {
Notification.error(sender, "导出 " + world + " 的MCA文件列表失败");
Notification.error(sender, e.getMessage());
Dominion.notification.error(sender, "导出 %s 的MCA文件列表失败", world);
Dominion.notification.error(sender, e.getMessage());
}
}
BlueMapConnect.renderMCA(mca_cords);
Notification.info(sender, "MCA文件列表已导出到 " + folder.getAbsolutePath());
Dominion.notification.info(sender, "MCA文件列表已导出到 %s", folder.getAbsolutePath());
});
}
public static void reloadConfig(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return;
Dominion.scheduler.async.runNow(Dominion.instance, ScheduledTask -> {
Notification.info(sender, "正在重新加载配置文件...");
Dominion.notification.info(sender, "正在重新加载配置文件...");
Dominion.config.reload();
Notification.info(sender, "配置文件已重新加载");
Dominion.notification.info(sender, "配置文件已重新加载");
});
}

View File

@ -1,8 +1,8 @@
package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.tuis.DominionPrivilegeList;
import cn.lunadeer.dominion.tuis.PrivilegeInfo;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -22,21 +22,21 @@ public class PlayerPrivilege {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion create_privilege <玩家名称> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion create_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
if (!createPrivilege(player, args[1])) {
Notification.error(sender, "创建玩家特权失败");
Dominion.notification.error(sender, "创建玩家特权失败");
return;
}
} else {
if (!createPrivilege(player, args[1], args[2])) {
Notification.error(sender, "创建玩家特权失败");
Dominion.notification.error(sender, "创建玩家特权失败");
return;
}
}
Notification.info(sender, "成功创建玩家特权 " + args[1]);
Dominion.notification.info(sender, "成功创建玩家特权 %s", args[1]);
if (args.length == 4) {
String[] newArgs = new String[2];
newArgs[0] = "privilege_list";
@ -58,17 +58,17 @@ public class PlayerPrivilege {
if (args.length == 4) {
if (!setPrivilege(player, args[1], args[2], Boolean.parseBoolean(args[3]))) {
Notification.error(sender, "设置玩家权限失败");
Dominion.notification.error(sender, "设置玩家权限失败");
return;
}
} else if (args.length == 5) {
if (!setPrivilege(player, args[1], args[2], Boolean.parseBoolean(args[3]), args[4])) {
Notification.error(sender, "设置玩家权限失败");
Dominion.notification.error(sender, "设置玩家权限失败");
return;
}
} else if (args.length == 6) {
if (!setPrivilege(player, args[1], args[2], Boolean.parseBoolean(args[3]), args[4])) {
Notification.error(sender, "设置玩家权限失败");
Dominion.notification.error(sender, "设置玩家权限失败");
return;
}
String[] newArgs = new String[4];
@ -79,10 +79,10 @@ public class PlayerPrivilege {
PrivilegeInfo.show(sender, newArgs);
return;
} else {
Notification.error(sender, "用法: /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
return;
}
Notification.info(sender, "设置玩家权限 " + args[1] + "" + args[2]);
Dominion.notification.info(sender, "设置玩家的 %s 权限为 %s", args[2], args[3]);
}
/**
@ -96,21 +96,21 @@ public class PlayerPrivilege {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length != 2 && args.length != 3 && args.length != 4) {
Notification.error(sender, "用法: /dominion clear_privilege <玩家名称> [领地名称]");
Dominion.notification.error(sender, "用法: /dominion clear_privilege <玩家名称> [领地名称]");
return;
}
if (args.length == 2) {
if (!clearPrivilege(player, args[1])) {
Notification.error(sender, "重置玩家权限失败");
Dominion.notification.error(sender, "重置玩家权限失败");
return;
}
} else {
if (!clearPrivilege(player, args[1], args[2])) {
Notification.error(sender, "重置玩家权限失败");
Dominion.notification.error(sender, "重置玩家权限失败");
return;
}
}
Notification.info(sender, "成功清除玩家权限 " + args[1]);
Dominion.notification.info(sender, "成功清除玩家 %s 的权限", args[1]);
if (args.length == 4) {
String[] newArgs = new String[3];
newArgs[0] = "privilege_list";

View File

@ -2,9 +2,7 @@ package cn.lunadeer.dominion.commands;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.tuis.DominionConfig;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.notOpOrConsole;
@ -13,7 +11,7 @@ public class SetConfig {
public static void handler(CommandSender sender, String[] args) {
if (notOpOrConsole(sender)) return;
if (args.length < 2) {
Notification.error(sender, "参数错误");
Dominion.notification.error(sender, "参数错误");
return;
}
switch (args[1]) {
@ -69,7 +67,7 @@ public class SetConfig {
setEconomyRefund(sender, args);
break;
default:
Notification.error(sender, "未知参数");
Dominion.notification.error(sender, "未知参数");
}
}
@ -87,7 +85,7 @@ public class SetConfig {
int size = Integer.parseInt(args[2]);
if (size < 2) {
Dominion.config.setAutoCreateRadius(2);
Notification.error(sender, "自动创建半径不能小于2");
Dominion.notification.error(sender, "自动创建半径不能小于2");
} else {
Dominion.config.setAutoCreateRadius(size);
}
@ -103,7 +101,7 @@ public class SetConfig {
private static void setLimitMaxY(CommandSender sender, String[] args) {
int maxY = Integer.parseInt(args[2]);
if (maxY <= Dominion.config.getLimitMinY()) {
Notification.error(sender, "最高Y坐标限制不能小于最低Y坐标限制");
Dominion.notification.error(sender, "最高Y坐标限制不能小于最低Y坐标限制");
return;
}
Dominion.config.setLimitMaxY(maxY);
@ -114,7 +112,7 @@ public class SetConfig {
private static void setLimitMinY(CommandSender sender, String[] args) {
int minY = Integer.parseInt(args[2]);
if (minY >= Dominion.config.getLimitMaxY()) {
Notification.error(sender, "最低Y坐标限制不能大于最高Y坐标限制");
Dominion.notification.error(sender, "最低Y坐标限制不能大于最高Y坐标限制");
return;
}
Dominion.config.setLimitMinY(minY);
@ -126,7 +124,7 @@ public class SetConfig {
int sizeX = Integer.parseInt(args[2]);
if (sizeX != -1 && sizeX < 4) {
Dominion.config.setLimitSizeX(4);
Notification.error(sender, "X轴(东西)最大尺寸不能小于4");
Dominion.notification.error(sender, "X轴(东西)最大尺寸不能小于4");
} else {
Dominion.config.setLimitSizeX(sizeX);
}
@ -137,7 +135,7 @@ public class SetConfig {
int sizeZ = Integer.parseInt(args[2]);
if (sizeZ != -1 && sizeZ < 4) {
Dominion.config.setLimitSizeZ(4);
Notification.error(sender, "Z轴(南北)最大尺寸不能小于4");
Dominion.notification.error(sender, "Z轴(南北)最大尺寸不能小于4");
return;
} else {
Dominion.config.setLimitSizeZ(sizeZ);
@ -149,7 +147,7 @@ public class SetConfig {
int sizeY = Integer.parseInt(args[2]);
if (sizeY != -1 && sizeY < 4) {
Dominion.config.setLimitSizeY(4);
Notification.error(sender, "Y轴(垂直)最大尺寸不能小于4");
Dominion.notification.error(sender, "Y轴(垂直)最大尺寸不能小于4");
} else {
Dominion.config.setLimitSizeY(sizeY);
}
@ -160,7 +158,7 @@ public class SetConfig {
int amount = Integer.parseInt(args[2]);
if (amount != -1 && amount < 0) {
Dominion.config.setLimitAmount(0);
Notification.error(sender, "每个玩家领地数量限制不能小于0");
Dominion.notification.error(sender, "每个玩家领地数量限制不能小于0");
} else {
Dominion.config.setLimitAmount(amount);
}
@ -171,7 +169,7 @@ public class SetConfig {
int depth = Integer.parseInt(args[2]);
if (depth != -1 && depth < 0) {
Dominion.config.setLimitDepth(0);
Notification.error(sender, "领地深度限制不能小于0");
Dominion.notification.error(sender, "领地深度限制不能小于0");
} else {
Dominion.config.setLimitDepth(depth);
}
@ -201,7 +199,7 @@ public class SetConfig {
int tpDelay = Integer.parseInt(args[2]);
if (tpDelay < 0) {
Dominion.config.setTpDelay(0);
Notification.error(sender, "传送延迟不能小于0");
Dominion.notification.error(sender, "传送延迟不能小于0");
} else {
Dominion.config.setTpDelay(tpDelay);
}
@ -212,7 +210,7 @@ public class SetConfig {
int tpCoolDown = Integer.parseInt(args[2]);
if (tpCoolDown < 0) {
Dominion.config.setTpCoolDown(0);
Notification.error(sender, "传送冷却时间不能小于0");
Dominion.notification.error(sender, "传送冷却时间不能小于0");
} else {
Dominion.config.setTpCoolDown(tpCoolDown);
}
@ -229,7 +227,7 @@ public class SetConfig {
float economyPrice = Float.parseFloat(args[2]);
if (economyPrice < 0) {
Dominion.config.setEconomyPrice(0.0f);
Notification.error(sender, "每方块单价不能小于0");
Dominion.notification.error(sender, "每方块单价不能小于0");
} else {
Dominion.config.setEconomyPrice(economyPrice);
}
@ -246,7 +244,7 @@ public class SetConfig {
float economyRefund = Float.parseFloat(args[2]);
if (economyRefund < 0) {
Dominion.config.setEconomyRefund(0.0f);
Notification.error(sender, "领地退款比例不能小于0");
Dominion.notification.error(sender, "领地退款比例不能小于0");
} else {
Dominion.config.setEconomyRefund(economyRefund);
}

View File

@ -1,8 +1,8 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
@ -14,7 +14,7 @@ public class Apis {
public static boolean notOwner(Player player, DominionDTO dominion) {
if (player.isOp()) return false;
if (dominion.getOwner().equals(player.getUniqueId())) return false;
Notification.error(player, "你不是领地 " + dominion.getName() + " 的拥有者,无法执行此操作");
Dominion.notification.error(player, "你不是领地 %s 的拥有者,无法执行此操作", dominion.getName());
return true;
}
@ -23,7 +23,7 @@ public class Apis {
if (!dominion.getOwner().equals(player.getUniqueId())) {
PlayerPrivilegeDTO privileges = PlayerPrivilegeDTO.select(player.getUniqueId(), dominion.getId());
if (privileges == null || !privileges.getAdmin()) {
Notification.error(player, "你不是领地 " + dominion.getName() + " 的拥有者或管理员,无权修改权限");
Dominion.notification.error(player, "你不是领地 %s 的拥有者或管理员,无权修改权限", dominion.getName());
return true;
}
}
@ -43,7 +43,7 @@ public class Apis {
(int) location.getX(), (int) location.getY(), (int) location.getZ());
if (dominions.size() != 1) {
if (show_warning) {
Notification.error(player, "你不在一个领地内或在子领地内,无法确定你要操作的领地,请手动指定要操作的领地名称");
Dominion.notification.error(player, "你不在一个领地内或在子领地内,无法确定你要操作的领地,请手动指定要操作的领地名称");
}
return null;
}

View File

@ -4,9 +4,8 @@ import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.Time;
import cn.lunadeer.dominion.utils.XLogger;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
@ -16,7 +15,6 @@ import java.util.List;
import java.util.Objects;
import static cn.lunadeer.dominion.controllers.Apis.*;
import static cn.lunadeer.dominion.utils.ParticleRender.showBoxBorder;
public class DominionController {
@ -60,19 +58,19 @@ public class DominionController {
Location loc1, Location loc2,
String parent_dominion_name) {
if (name.contains(" ")) {
Notification.error(owner, "领地名称不能包含空格");
Dominion.notification.error(owner, "领地名称不能包含空格");
return null;
}
if (DominionDTO.select(name) != null) {
Notification.error(owner, "已经存在名称为 " + name + " 的领地");
Dominion.notification.error(owner, "已经存在名称为 %s 的领地", name);
return null;
}
if (!loc1.getWorld().equals(loc2.getWorld())) {
Notification.error(owner, "禁止跨世界操作");
Dominion.notification.error(owner, "禁止跨世界操作");
return null;
}
if (!owner.getWorld().equals(loc1.getWorld())) {
Notification.error(owner, "禁止跨世界操作");
Dominion.notification.error(owner, "禁止跨世界操作");
return null;
}
// 检查世界是否可以创建
@ -100,9 +98,9 @@ public class DominionController {
parent_dominion = DominionDTO.select(parent_dominion_name);
}
if (parent_dominion == null) {
Notification.error(owner, "父领地 " + parent_dominion_name + " 不存在");
Dominion.notification.error(owner, "父领地 %s 不存在", parent_dominion_name);
if (parent_dominion_name.isEmpty()) {
XLogger.err("根领地丢失!");
Dominion.logger.err("根领地丢失!");
}
return null;
}
@ -114,7 +112,7 @@ public class DominionController {
}
// 如果parent_dominion不为-1 检查是否在同一世界
if (parent_dominion.getId() != -1 && !parent_dominion.getWorld().equals(dominion.getWorld())) {
Notification.error(owner, "禁止跨世界操作");
Dominion.notification.error(owner, "禁止跨世界操作");
return null;
}
// 检查深度是否达到上限
@ -123,7 +121,7 @@ public class DominionController {
}
// 检查是否超出父领地范围
if (!isContained(dominion, parent_dominion)) {
Notification.error(owner, "超出父领地 " + parent_dominion_name + " 范围");
Dominion.notification.error(owner, "超出父领地 %s 范围", parent_dominion.getName());
return null;
}
// 获取此领地的所有同级领地
@ -131,7 +129,7 @@ public class DominionController {
// 检查是否与其他子领地冲突
for (DominionDTO sub_dominion : sub_dominions) {
if (isIntersect(sub_dominion, dominion)) {
Notification.error(owner, "与领地 " + sub_dominion.getName() + " 冲突");
Dominion.notification.error(owner, "与领地 %s 冲突", sub_dominion.getName());
return null;
}
}
@ -143,20 +141,20 @@ public class DominionController {
} else {
count = (loc2.getBlockX() - loc1.getBlockX() + 1) * (loc2.getBlockY() - loc1.getBlockY() + 1) * (loc2.getBlockZ() - loc1.getBlockZ() + 1);
}
double price = count * Dominion.config.getEconomyPrice();
float price = count * Dominion.config.getEconomyPrice();
if (Dominion.vault.getEconomy().getBalance(owner) < price) {
Notification.error(owner, "你的余额不足,创建此领地需要 " + price + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.error(owner, "你的余额不足,创建此领地需要 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
return null;
}
Notification.info(owner, "已扣除 " + price + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.info(owner, "已扣除 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
Dominion.vault.getEconomy().withdrawPlayer(owner, price);
}
dominion = DominionDTO.insert(dominion);
if (dominion == null) {
Notification.error(owner, "创建失败,详细错误请联系管理员查询日志(当前时间:" + Time.nowStr() + "");
Dominion.notification.error(owner, "创建失败,详细错误请联系管理员查询日志(当前时间:%s", Time.nowStr());
return null;
}
showBoxBorder(dominion.getWorld(), dominion.getX1(), dominion.getY1(), dominion.getZ1(), dominion.getX2(), dominion.getY2(), dominion.getZ2());
ParticleRender.showBoxFace(Dominion.instance, owner, loc1, loc2);
return dominion.setParentDomId(parent_dominion.getId());
}
@ -188,16 +186,12 @@ public class DominionController {
public static DominionDTO expand(Player operator, Integer size, String dominion_name) {
Location location = operator.getLocation();
BlockFace face = getFace(operator);
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return null;
}
if (notOwner(operator, dominion)) {
return null;
}
if (!location.getWorld().getName().equals(dominion.getWorld())) {
Notification.error(operator, "禁止跨世界操作");
Dominion.notification.error(operator, "禁止跨世界操作");
return null;
}
Integer x1 = dominion.getX1();
@ -226,7 +220,7 @@ public class DominionController {
y1 -= size;
break;
default:
Notification.error(operator, "无效的方向");
Dominion.notification.error(operator, "无效的方向");
return null;
}
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
@ -235,11 +229,11 @@ public class DominionController {
// 校验是否超出父领地范围
DominionDTO parent_dominion = DominionDTO.select(dominion.getParentDomId());
if (parent_dominion == null) {
Notification.error(operator, "父领地丢失");
Dominion.notification.error(operator, "父领地丢失");
return null;
}
if (!isContained(x1, y1, z1, x2, y2, z2, parent_dominion)) {
Notification.error(operator, "超出父领地 " + parent_dominion.getName() + " 范围");
Dominion.notification.error(operator, "超出父领地 %s 范围", parent_dominion.getName());
return null;
}
// 获取同世界下的所有同级领地
@ -248,7 +242,7 @@ public class DominionController {
if (isIntersect(exist_dominion, x1, y1, z1, x2, y2, z2)) {
// 如果是自己跳过
if (exist_dominion.getId().equals(dominion.getId())) continue;
Notification.error(operator, "" + exist_dominion.getName() + " 冲突");
Dominion.notification.error(operator, "%s 冲突", exist_dominion.getName());
return null;
}
}
@ -260,15 +254,17 @@ public class DominionController {
} else {
count = (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1) - dominion.getVolume();
}
double price = count * Dominion.config.getEconomyPrice();
float price = count * Dominion.config.getEconomyPrice();
if (Dominion.vault.getEconomy().getBalance(operator) < price) {
Notification.error(operator, "你的余额不足,扩展此领地需要 " + price + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.error(operator, "你的余额不足,扩展此领地需要 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
return null;
}
Notification.info(operator, "已扣除 " + price + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.info(operator, "已扣除 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
Dominion.vault.getEconomy().withdrawPlayer(operator, price);
}
showBoxBorder(dominion.getWorld(), x1, y1, z1, x2, y2, z2);
ParticleRender.showBoxFace(Dominion.instance, operator,
new Location(location.getWorld(), x1, y1, z1),
new Location(location.getWorld(), x2, y2, z2));
return dominion.setXYZ(x1, y1, z1, x2, y2, z2);
}
@ -300,16 +296,12 @@ public class DominionController {
public static DominionDTO contract(Player operator, Integer size, String dominion_name) {
Location location = operator.getLocation();
BlockFace face = getFace(operator);
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return null;
}
if (notOwner(operator, dominion)) {
return null;
}
if (!location.getWorld().getName().equals(dominion.getWorld())) {
Notification.error(operator, "禁止跨世界操作");
Dominion.notification.error(operator, "禁止跨世界操作");
return null;
}
Integer x1 = dominion.getX1();
@ -338,12 +330,12 @@ public class DominionController {
y1 += size;
break;
default:
Notification.error(operator, "无效的方向");
Dominion.notification.error(operator, "无效的方向");
return null;
}
// 校验第二组坐标是否小于第一组坐标
if (x1 >= x2 || y1 >= y2 || z1 >= z2) {
Notification.error(operator, "缩小后的领地无效");
Dominion.notification.error(operator, "缩小后的领地无效");
return null;
}
if (sizeNotValid(operator, x1, y1, z1, x2, y2, z2)) {
@ -353,7 +345,7 @@ public class DominionController {
List<DominionDTO> sub_dominions = DominionDTO.selectByParentId(dominion.getWorld(), dominion.getId());
for (DominionDTO sub_dominion : sub_dominions) {
if (!isContained(sub_dominion, x1, y1, z1, x2, y2, z2)) {
Notification.error(operator, "缩小后的领地 " + dominion_name + " 无法包含子领地 " + sub_dominion.getName());
Dominion.notification.error(operator, "缩小后的领地 %s 无法包含子领地 %s", dominion_name, sub_dominion.getName());
return null;
}
}
@ -365,11 +357,13 @@ public class DominionController {
} else {
count = dominion.getVolume() - (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1);
}
double refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund();
float refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund();
Dominion.vault.getEconomy().depositPlayer(operator, refund);
Notification.info(operator, "已经退还 " + refund + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.info(operator, "已经退还 %.2f %s", refund, Dominion.vault.getEconomy().currencyNamePlural());
}
showBoxBorder(dominion.getWorld(), x1, y1, z1, x2, y2, z2);
ParticleRender.showBoxFace(Dominion.instance, operator,
new Location(location.getWorld(), x1, y1, z1),
new Location(location.getWorld(), x2, y2, z2));
return dominion.setXYZ(x1, y1, z1, x2, y2, z2);
}
@ -381,26 +375,22 @@ public class DominionController {
* @param force 是否强制删除
*/
public static void delete(Player operator, String dominion_name, boolean force) {
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
return;
}
List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion);
if (!force) {
Notification.warn(operator, "删除领地 " + dominion_name + " 会同时删除其所有子领地,是否继续?");
Dominion.notification.warn(operator, "删除领地 %s 会同时删除其所有子领地,是否继续?", dominion_name);
String sub_names = "";
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (sub_dominions.size() > 0) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
Notification.warn(operator, "当前子领地:" + sub_names);
Dominion.notification.warn(operator, "当前子领地:" + sub_names);
}
Notification.warn(operator, "输入 /dominion delete " + dominion_name + " force 确认删除");
Dominion.notification.warn(operator, "输入 /dominion delete %s force 确认删除", dominion_name);
return;
}
DominionDTO.delete(dominion);
@ -416,11 +406,11 @@ public class DominionController {
count += sub_dominion.getVolume();
}
}
double refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund();
float refund = count * Dominion.config.getEconomyPrice() * Dominion.config.getEconomyRefund();
Dominion.vault.getEconomy().depositPlayer(operator, refund);
Notification.info(operator, "已经退还 " + refund + " " + Dominion.vault.getEconomy().currencyNamePlural());
Dominion.notification.info(operator, "已经退还 %.2f %s", refund, Dominion.vault.getEconomy().currencyNamePlural());
}
Notification.info(operator, "领地 " + dominion_name + " 及其所有子领地已删除");
Dominion.notification.info(operator, "领地 %s 及其所有子领地已删除", dominion_name);
}
/**
@ -445,17 +435,12 @@ public class DominionController {
* @param message 消息
*/
public static void setJoinMessage(Player operator, String message, String dominion_name) {
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
Notification.error(operator, "你不是领地 " + dominion_name + " 的拥有者,无法执行此操作");
return;
}
dominion.setJoinMessage(message);
Notification.info(operator, "成功设置领地 " + dominion_name + " 的进入消息");
Dominion.notification.info(operator, "成功设置领地 %s 的进入消息", dominion_name);
}
/**
@ -480,17 +465,12 @@ public class DominionController {
* @param message 消息
*/
public static void setLeaveMessage(Player operator, String message, String dominion_name) {
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
Notification.error(operator, "你不是领地 " + dominion_name + " 的拥有者,无法执行此操作");
return;
}
dominion.setLeaveMessage(message);
Notification.info(operator, "成功设置领地 " + dominion_name + " 的离开消息");
Dominion.notification.info(operator, "成功设置领地 %s 的离开消息", dominion_name);
}
/**
@ -513,13 +493,8 @@ public class DominionController {
* @param dominion_name 领地名称
*/
public static void setTpLocation(Player operator, String dominion_name) {
DominionDTO dominion = DominionDTO.select(dominion_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dominion_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dominion_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
Notification.error(operator, "你不是领地 " + dominion_name + " 的拥有者,无法执行此操作");
return;
}
// 检查是否在领地内
@ -533,12 +508,10 @@ public class DominionController {
Location loc = operator.getLocation();
loc.setY(loc.getY() + 1.5);
dominion.setTpLocation(loc);
Notification.info(operator, "成功设置领地 " + dominion_name + " 的传送点," +
"当前位置为 " + operator.getLocation().getBlockX() + " " +
operator.getLocation().getBlockY() + 1 + " " +
operator.getLocation().getBlockZ());
Dominion.notification.info(operator, "成功设置领地 %s 的传送点,坐标:%d %d %d",
dominion_name, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
} else {
Notification.error(operator, "你不在领地 " + dominion_name + " 内,无法设置传送点");
Dominion.notification.error(operator, "你不在领地 %s 内,无法设置传送点", dominion_name);
}
}
@ -551,24 +524,19 @@ public class DominionController {
*/
public static void rename(Player operator, String old_name, String new_name) {
if (new_name.contains(" ")) {
Notification.error(operator, "领地名称不能包含空格");
Dominion.notification.error(operator, "领地名称不能包含空格");
return;
}
DominionDTO dominion = DominionDTO.select(old_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, old_name);
if (dominion == null) {
Notification.error(operator, "领地 " + old_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
Notification.error(operator, "你不是领地 " + old_name + " 的拥有者,无法执行此操作");
return;
}
if (DominionDTO.select(new_name) != null) {
Notification.error(operator, "已经存在名称为 " + new_name + " 的领地");
Dominion.notification.error(operator, "已经存在名称为 %s 的领地", new_name);
return;
}
dominion.setName(new_name);
Notification.info(operator, "成功将领地 " + old_name + " 重命名为 " + new_name);
Dominion.notification.info(operator, "成功将领地 %s 重命名为 %s", old_name, new_name);
}
/**
@ -581,45 +549,41 @@ public class DominionController {
*/
public static void give(Player operator, String dom_name, String player_name, boolean force) {
if (Objects.equals(player_name, operator.getName())) {
Notification.error(operator, "你不能将领地转让给自己");
Dominion.notification.error(operator, "你不能将领地转让给自己");
return;
}
DominionDTO dominion = DominionDTO.select(dom_name);
DominionDTO dominion = getExistDomAndIsOwner(operator, dom_name);
if (dominion == null) {
Notification.error(operator, "领地 " + dom_name + " 不存在");
return;
}
if (notOwner(operator, dominion)) {
return;
}
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
Notification.error(operator, "玩家 " + player_name + " 不存在");
Dominion.notification.error(operator, "玩家 %s 不存在", player_name);
return;
}
if (dominion.getParentDomId() != -1) {
Notification.error(operator, "子领地无法转让,你可以通过将玩家设置为管理员来让其管理子领地");
Dominion.notification.error(operator, "子领地无法转让,你可以通过将玩家设置为管理员来让其管理子领地");
return;
}
List<DominionDTO> sub_dominions = getSubDominionsRecursive(dominion);
if (!force) {
Notification.warn(operator, "转让领地 " + dom_name + "" + player_name + " 会同时转让其所有子领地,是否继续?");
Dominion.notification.warn(operator, "转让领地 %s 给 %s 会同时转让其所有子领地,是否继续?", dom_name, player_name);
String sub_names = "";
for (DominionDTO sub_dominion : sub_dominions) {
sub_names = sub_dominion.getName() + ", ";
}
if (sub_dominions.size() > 0) {
sub_names = sub_names.substring(0, sub_names.length() - 2);
Notification.warn(operator, "当前子领地:" + sub_names);
Dominion.notification.warn(operator, "当前子领地:%s", sub_names);
}
Notification.warn(operator, "输入 /dominion give " + dom_name + " " + player_name + " force 确认转让");
Dominion.notification.warn(operator, "输入 /dominion give %s %s force 确认转让", dom_name, player_name);
return;
}
dominion.setOwner(player.getUuid());
for (DominionDTO sub_dominion : sub_dominions) {
sub_dominion.setOwner(player.getUuid());
}
Notification.info(operator, "成功将领地 " + dom_name + " 及其所有子领地转让给 " + player_name);
Dominion.notification.info(operator, "成功将领地 %s 及其所有子领地转让给 %s", dom_name, player_name);
}
/**
@ -698,27 +662,27 @@ public class DominionController {
int y_length = y2 - y1;
int z_length = z2 - z1;
if (x_length < 4 || y_length < 4 || z_length < 4) {
Notification.error(operator, "领地的任意一边长度不得小于4");
Dominion.notification.error(operator, "领地的任意一边长度不得小于4");
return true;
}
if (x_length > Dominion.config.getLimitSizeX() && Dominion.config.getLimitSizeX() > 0) {
Notification.error(operator, "领地X方向长度不能超过 " + Dominion.config.getLimitSizeX());
Dominion.notification.error(operator, "领地X方向长度不能超过 %s", Dominion.config.getLimitSizeX());
return true;
}
if (y_length > Dominion.config.getLimitSizeY() && Dominion.config.getLimitSizeY() > 0) {
Notification.error(operator, "领地Y方向高度不能超过 " + Dominion.config.getLimitSizeY());
Dominion.notification.error(operator, "领地Y方向高度不能超过 %s", Dominion.config.getLimitSizeY());
return true;
}
if (z_length > Dominion.config.getLimitSizeZ() && Dominion.config.getLimitSizeZ() > 0) {
Notification.error(operator, "领地Z方向长度不能超过 " + Dominion.config.getLimitSizeZ());
Dominion.notification.error(operator, "领地Z方向长度不能超过 %s", Dominion.config.getLimitSizeZ());
return true;
}
if (y2 > Dominion.config.getLimitMaxY()) {
Notification.error(operator, "领地Y坐标不能超过 " + Dominion.config.getLimitMaxY());
Dominion.notification.error(operator, "领地Y坐标不能超过 %s", Dominion.config.getLimitMaxY());
return true;
}
if (y1 < Dominion.config.getLimitMinY()) {
Notification.error(operator, "领地Y坐标不能低于 " + Dominion.config.getLimitMinY());
Dominion.notification.error(operator, "领地Y坐标不能低于 %s", Dominion.config.getLimitMinY());
return true;
}
return false;
@ -732,7 +696,7 @@ public class DominionController {
return false;
}
if (parent_dom.getId() != -1 && Dominion.config.getLimitDepth() == 0) {
Notification.error(operator, "不允许创建子领地");
Dominion.notification.error(operator, "不允许创建子领地");
return true;
}
if (parent_dom.getId() == -1) {
@ -744,7 +708,7 @@ public class DominionController {
level++;
}
if (level >= Dominion.config.getLimitDepth()) {
Notification.error(operator, "子领地嵌套深度不能超过 " + Dominion.config.getLimitDepth());
Dominion.notification.error(operator, "子领地嵌套深度不能超过 %s", Dominion.config.getLimitDepth());
return true;
}
return false;
@ -755,7 +719,7 @@ public class DominionController {
return false;
}
if (Cache.instance.getPlayerDominionCount(operator) >= Dominion.config.getLimitAmount() && Dominion.config.getLimitAmount() != -1) {
Notification.error(operator, "你的领地数量已达上限,当前上限为 " + Dominion.config.getLimitAmount());
Dominion.notification.error(operator, "你的领地数量已达上限,当前上限为 %s", Dominion.config.getLimitAmount());
return true;
}
return false;
@ -766,9 +730,23 @@ public class DominionController {
return false;
}
if (Dominion.config.getWorldBlackList().contains(operator.getWorld().getName())) {
Notification.error(operator, "禁止在世界 " + operator.getWorld().getName() + " 创建领地");
Dominion.notification.error(operator, "禁止在世界 %s 创建领地", operator.getWorld().getName());
return true;
}
return false;
}
private static DominionDTO getExistDomAndIsOwner(Player operator, String dominion_name) {
DominionDTO dominion = DominionDTO.select(dominion_name);
if (dominion == null) {
Dominion.notification.error(operator, "领地 %s 不存在", dominion_name);
return null;
}
if (notOwner(operator, dominion)) {
Dominion.notification.error(operator, "你不是领地 %s 的拥有者,无法执行此操作", dominion_name);
return null;
}
return dominion;
}
}

View File

@ -1,7 +1,7 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.controllers.Apis.noAuthToChangeFlags;
@ -10,12 +10,13 @@ public class FlagsController {
/**
* 设置领地权限
*
* @param operator 操作者
* @param flag 权限名称
* @param value 权限值
* @param flag 权限名称
* @param value 权限值
* @return 设置后的领地信息
*/
public static DominionDTO setFlag(Player operator, String flag, boolean value){
public static DominionDTO setFlag(Player operator, String flag, boolean value) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) return null;
return setFlag(operator, flag, value, dominion.getName());
@ -23,68 +24,115 @@ public class FlagsController {
/**
* 设置领地权限
* @param operator 操作者
* @param flag 权限名称
* @param value 权限值
*
* @param operator 操作者
* @param flag 权限名称
* @param value 权限值
* @param dominionName 领地名称
* @return 设置后的领地信息
*/
public static DominionDTO setFlag(Player operator, String flag, boolean value, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
Notification.error(operator, "领地 " + dominionName + " 不存在");
Dominion.notification.error(operator, "领地 %s 不存在", dominionName);
return null;
}
if (noAuthToChangeFlags(operator, dominion)) return null;
switch (flag) {
case "anchor": return dominion.setAnchor(value);
case "animal_killing": return dominion.setAnimalKilling(value);
case "anvil": return dominion.setAnvil(value);
case "beacon": return dominion.setBeacon(value);
case "bed": return dominion.setBed(value);
case "brew": return dominion.setBrew(value);
case "break": return dominion.setBreak(value);
case "button": return dominion.setButton(value);
case "cake": return dominion.setCake(value);
case "container": return dominion.setContainer(value);
case "craft": return dominion.setCraft(value);
case "creeper_explode": return dominion.setCreeperExplode(value);
case "comparer": return dominion.setComparer(value);
case "door": return dominion.setDoor(value);
case "dye": return dominion.setDye(value);
case "egg": return dominion.setEgg(value);
case "enchant": return dominion.setEnchant(value);
case "ender_man": return dominion.setEnderMan(value);
case "ender_pearl": return dominion.setEnderPearl(value);
case "feed": return dominion.setFeed(value);
case "fire_spread": return dominion.setFireSpread(value);
case "flow_in_protection": return dominion.setFlowInProtection(value);
case "glow": return dominion.setGlow(value);
case "harvest": return dominion.setHarvest(value);
case "honey": return dominion.setHoney(value);
case "hook": return dominion.setHook(value);
case "hopper": return dominion.setHopper(value);
case "ignite": return dominion.setIgnite(value);
case "lever": return dominion.setLever(value);
case "mob_drop_item": return dominion.setMobDropItem(value);
case "monster_killing": return dominion.setMonsterKilling(value);
case "move": return dominion.setMove(value);
case "place": return dominion.setPlace(value);
case "pressure": return dominion.setPressure(value);
case "riding": return dominion.setRiding(value);
case "repeater": return dominion.setRepeater(value);
case "shear": return dominion.setShear(value);
case "shoot": return dominion.setShoot(value);
case "show_border": return dominion.setShowBorder(value);
case "teleport": return dominion.setTeleport(value);
case "tnt_explode": return dominion.setTntExplode(value);
case "trade": return dominion.setTrade(value);
case "trample": return dominion.setTrample(value);
case "vehicle_destroy": return dominion.setVehicleDestroy(value);
case "vehicle_spawn": return dominion.setVehicleSpawn(value);
case "wither_spawn": return dominion.setWitherSpawn(value);
case "anchor":
return dominion.setAnchor(value);
case "animal_killing":
return dominion.setAnimalKilling(value);
case "anvil":
return dominion.setAnvil(value);
case "beacon":
return dominion.setBeacon(value);
case "bed":
return dominion.setBed(value);
case "brew":
return dominion.setBrew(value);
case "break":
return dominion.setBreak(value);
case "button":
return dominion.setButton(value);
case "cake":
return dominion.setCake(value);
case "container":
return dominion.setContainer(value);
case "craft":
return dominion.setCraft(value);
case "creeper_explode":
return dominion.setCreeperExplode(value);
case "comparer":
return dominion.setComparer(value);
case "door":
return dominion.setDoor(value);
case "dye":
return dominion.setDye(value);
case "egg":
return dominion.setEgg(value);
case "enchant":
return dominion.setEnchant(value);
case "ender_man":
return dominion.setEnderMan(value);
case "ender_pearl":
return dominion.setEnderPearl(value);
case "feed":
return dominion.setFeed(value);
case "fire_spread":
return dominion.setFireSpread(value);
case "flow_in_protection":
return dominion.setFlowInProtection(value);
case "glow":
return dominion.setGlow(value);
case "harvest":
return dominion.setHarvest(value);
case "honey":
return dominion.setHoney(value);
case "hook":
return dominion.setHook(value);
case "hopper":
return dominion.setHopper(value);
case "ignite":
return dominion.setIgnite(value);
case "lever":
return dominion.setLever(value);
case "mob_drop_item":
return dominion.setMobDropItem(value);
case "monster_killing":
return dominion.setMonsterKilling(value);
case "move":
return dominion.setMove(value);
case "place":
return dominion.setPlace(value);
case "pressure":
return dominion.setPressure(value);
case "riding":
return dominion.setRiding(value);
case "repeater":
return dominion.setRepeater(value);
case "shear":
return dominion.setShear(value);
case "shoot":
return dominion.setShoot(value);
case "show_border":
return dominion.setShowBorder(value);
case "teleport":
return dominion.setTeleport(value);
case "tnt_explode":
return dominion.setTntExplode(value);
case "trade":
return dominion.setTrade(value);
case "trample":
return dominion.setTrample(value);
case "vehicle_destroy":
return dominion.setVehicleDestroy(value);
case "vehicle_spawn":
return dominion.setVehicleSpawn(value);
case "wither_spawn":
return dominion.setWitherSpawn(value);
default:
Notification.error(operator, "未知的领地权限 " + flag);
Dominion.notification.error(operator, "未知的领地权限 %s", flag);
return null;
}
}

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.controllers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import org.bukkit.entity.Player;
import java.util.UUID;
@ -23,7 +23,7 @@ public class PrivilegeController {
public static boolean clearPrivilege(Player operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion clear_privilege <玩家名称> <领地名称>");
Dominion.notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion clear_privilege <玩家名称> <领地名称>");
return false;
}
return clearPrivilege(operator, player_name, dominion.getName());
@ -40,13 +40,13 @@ public class PrivilegeController {
public static boolean clearPrivilege(Player operator, String player_name, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
Notification.error(operator, "领地 " + dominionName + " 不存在");
Dominion.notification.error(operator, "领地 %s 不存在", dominionName);
return false;
}
if (noAuthToChangeFlags(operator, dominion)) return false;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
Notification.error(operator, "玩家 " + player_name + " 不存在或没有登录过");
Dominion.notification.error(operator, "玩家 %s 不存在或没有登录过", player_name);
return false;
}
PlayerPrivilegeDTO.delete(player.getUuid(), dominion.getId());
@ -65,7 +65,7 @@ public class PrivilegeController {
public static boolean setPrivilege(Player operator, String player_name, String flag, boolean value) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
Dominion.notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion set_privilege <玩家名称> <权限名称> <true/false> [领地名称]");
return false;
}
return setPrivilege(operator, player_name, flag, value, dominion.getName());
@ -84,13 +84,13 @@ public class PrivilegeController {
public static boolean setPrivilege(Player operator, String player_name, String flag, boolean value, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
Notification.error(operator, "领地 " + dominionName + " 不存在,无法设置特权");
Dominion.notification.error(operator, "领地 %s 不存在,无法设置特权", dominionName);
return false;
}
if (noAuthToChangeFlags(operator, dominion)) return false;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
Notification.error(operator, "玩家 " + player_name + " 不存在或没有登录过");
Dominion.notification.error(operator, "玩家 %s 不存在或没有登录过", player_name);
return false;
}
PlayerPrivilegeDTO privilege = PlayerPrivilegeDTO.select(player.getUuid(), dominion.getId());
@ -101,7 +101,7 @@ public class PrivilegeController {
switch (flag) {
case "admin":
if (notOwner(operator, dominion)) {
Notification.error(operator, "你不是领地 " + dominionName + " 的拥有者,无法设置其他玩家为管理员");
Dominion.notification.error(operator, "你不是领地 %s 的拥有者,无法设置其他玩家为管理员", dominionName);
return false;
}
privilege.setAdmin(value);
@ -218,17 +218,17 @@ public class PrivilegeController {
privilege.setVehicleSpawn(value);
break;
default:
Notification.error(operator, "未知的领地权限 " + flag);
Dominion.notification.error(operator, "未知的领地权限 %s", flag);
return false;
}
Notification.info(operator, "设置玩家在领地 " + dominionName + " 的权限 " + flag + "" + value);
Dominion.notification.info(operator, "设置玩家在领地 %s 的权限 %s 为 %s", dominionName, flag, value);
return true;
}
public static boolean createPrivilege(Player operator, String player_name) {
DominionDTO dominion = Apis.getPlayerCurrentDominion(operator);
if (dominion == null) {
Notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion create_privilege <玩家名称> <领地名称>");
Dominion.notification.error(operator, "你不在任何领地内,请指定领地名称 /dominion create_privilege <玩家名称> <领地名称>");
return false;
}
return createPrivilege(operator, player_name, dominion.getName());
@ -237,13 +237,13 @@ public class PrivilegeController {
public static boolean createPrivilege(Player operator, String player_name, String dominionName) {
DominionDTO dominion = DominionDTO.select(dominionName);
if (dominion == null) {
Notification.error(operator, "领地 " + dominionName + " 不存在,无法创建特权");
Dominion.notification.error(operator, "领地 %s 不存在,无法创建特权", dominionName);
return false;
}
if (noAuthToChangeFlags(operator, dominion)) return false;
PlayerDTO player = PlayerController.getPlayerDTO(player_name);
if (player == null) {
Notification.error(operator, "玩家 " + player_name + " 不存在或没有登录过");
Dominion.notification.error(operator, "玩家 %s 不存在或没有登录过", player_name);
return false;
}
return createPlayerPrivilege(operator, player.getUuid(), dominion) != null;
@ -251,7 +251,7 @@ public class PrivilegeController {
private static PlayerPrivilegeDTO createPlayerPrivilege(Player operator, UUID player, DominionDTO dom) {
if (operator.getUniqueId() == player) {
Notification.error(operator, "你不能给自己设置特权");
Dominion.notification.error(operator, "你不能给自己设置特权");
return null;
}
PlayerPrivilegeDTO privilege = new PlayerPrivilegeDTO(player, dom.getId(),
@ -274,7 +274,7 @@ public class PrivilegeController {
dom.getVehicleSpawn());
privilege = PlayerPrivilegeDTO.insert(privilege);
if (privilege == null) {
Notification.error(operator, "创建玩家特权失败,可能是此玩家已存在特权");
Dominion.notification.error(operator, "创建玩家特权失败,可能是此玩家已存在特权");
return null;
}
return privilege;

View File

@ -2,8 +2,6 @@ package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.managers.DatabaseManager;
import cn.lunadeer.dominion.utils.XLogger;
import org.bukkit.Location;
import org.bukkit.World;
@ -18,7 +16,7 @@ public class DominionDTO {
private static List<DominionDTO> query(String sql) {
List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = DatabaseManager.query(sql)) {
try (ResultSet rs = Dominion.database.query(sql)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
@ -91,8 +89,7 @@ public class DominionDTO {
dominions.add(dominion);
}
} catch (SQLException e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);
Dominion.database.handleDatabaseError("数据库操作失败: ", e, sql);
}
return dominions;
}
@ -341,7 +338,7 @@ public class DominionDTO {
if (loc.length == 3 && w != null) {
this.tp_location = new Location(w, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2]));
} else {
XLogger.warn("领地传送点数据异常: " + tp_location);
Dominion.logger.warn("领地传送点数据异常: %s", tp_location);
this.tp_location = null;
}
}
@ -983,4 +980,12 @@ public class DominionDTO {
this.tp_location = loc;
return update(this);
}
public Location getLocation1() {
return new Location(Dominion.instance.getServer().getWorld(world), x1, y1, z1);
}
public Location getLocation2() {
return new Location(Dominion.instance.getServer().getWorld(world), x2, y2, z2);
}
}

View File

@ -1,7 +1,6 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.managers.DatabaseManager;
import cn.lunadeer.dominion.utils.XLogger;
import cn.lunadeer.dominion.Dominion;
import org.bukkit.entity.Player;
import java.sql.ResultSet;
@ -31,7 +30,7 @@ public class PlayerDTO {
private static List<PlayerDTO> query(String sql) {
List<PlayerDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.query(sql)) {
try (ResultSet rs = Dominion.database.query(sql)) {
if (rs == null) return players;
while (rs.next()) {
Integer id = rs.getInt("id");
@ -42,8 +41,7 @@ public class PlayerDTO {
players.add(player);
}
} catch (SQLException e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);
Dominion.database.handleDatabaseError("查询玩家信息失败: ", e, sql);
}
return players;
}

View File

@ -1,8 +1,7 @@
package cn.lunadeer.dominion.dtos;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.managers.DatabaseManager;
import cn.lunadeer.dominion.utils.XLogger;
import cn.lunadeer.dominion.Dominion;
import java.sql.ResultSet;
import java.util.ArrayList;
@ -582,7 +581,7 @@ public class PlayerPrivilegeDTO {
private static List<PlayerPrivilegeDTO> query(String sql) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.query(sql)) {
try (ResultSet rs = Dominion.database.query(sql)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
@ -635,8 +634,7 @@ public class PlayerPrivilegeDTO {
players.add(player);
}
} catch (Exception e) {
XLogger.err("Database query failed: " + e.getMessage());
XLogger.err("SQL: " + sql);
Dominion.database.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}

View File

@ -1,10 +1,10 @@
package cn.lunadeer.dominion.events;
import cn.lunadeer.dominion.Cache;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import io.papermc.paper.event.entity.EntityDyeEvent;
import org.bukkit.Location;
import org.bukkit.Material;
@ -54,7 +54,7 @@ public class PlayerEvents implements Listener {
PlayerPrivilegeDTO privilege = Cache.instance.getPlayerPrivilege(bukkitPlayer, dom);
if (privilege != null) {
if (!privilege.getAnchor()) {
Notification.error(bukkitPlayer, "你没有锚点重生权限");
Dominion.notification.error(bukkitPlayer, "你没有锚点重生权限");
return;
} else {
if (bukkitPlayer.getBedSpawnLocation() != null) {
@ -65,7 +65,7 @@ public class PlayerEvents implements Listener {
}
} else {
if (dom.getAnchor()) {
Notification.error(bukkitPlayer, "你没有锚点重生权限");
Dominion.notification.error(bukkitPlayer, "你没有锚点重生权限");
return;
} else {
if (bukkitPlayer.getBedSpawnLocation() != null) {
@ -104,7 +104,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有动物击杀权限");
Dominion.notification.error(bukkitPlayer, "你没有动物击杀权限");
event.setCancelled(true);
}
@ -134,7 +134,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用铁砧的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用铁砧的权限");
event.setCancelled(true);
}
@ -164,7 +164,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用信标的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用信标的权限");
event.setCancelled(true);
}
@ -188,7 +188,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用床的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用床的权限");
event.setCancelled(true);
}
@ -218,7 +218,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用酿造台的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用酿造台的权限");
event.setCancelled(true);
}
@ -267,7 +267,7 @@ public class PlayerEvents implements Listener {
return true;
}
}
Notification.error(player, "你没有破坏方块的权限");
Dominion.notification.error(player, "你没有破坏方块的权限");
return false;
}
@ -310,7 +310,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用按钮的权限");
Dominion.notification.error(player, "你没有使用按钮的权限");
event.setCancelled(true);
}
@ -342,7 +342,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有吃蛋糕权限");
Dominion.notification.error(player, "你没有吃蛋糕权限");
event.setCancelled(true);
}
@ -370,7 +370,7 @@ public class PlayerEvents implements Listener {
return true;
}
}
Notification.error(player, "你没有使用容器/盔甲架/展示框的权限");
Dominion.notification.error(player, "你没有使用容器/盔甲架/展示框的权限");
return false;
}
@ -456,7 +456,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用工作台的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用工作台的权限");
event.setCancelled(true);
}
@ -487,7 +487,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用红石比较器的权限");
Dominion.notification.error(player, "你没有使用红石比较器的权限");
event.setCancelled(true);
}
@ -552,7 +552,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用门的权限");
Dominion.notification.error(player, "你没有使用门的权限");
event.setCancelled(true);
}
@ -579,7 +579,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有染色的权限");
Dominion.notification.error(player, "你没有染色的权限");
event.setCancelled(true);
}
@ -609,7 +609,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有扔鸡蛋的权限");
Dominion.notification.error(player, "你没有扔鸡蛋的权限");
event.setCancelled(true);
}
@ -639,7 +639,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用附魔台的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用附魔台的权限");
event.setCancelled(true);
}
@ -669,7 +669,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用末影珍珠的权限");
Dominion.notification.error(player, "你没有使用末影珍珠的权限");
event.setCancelled(true);
}
@ -696,7 +696,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有喂养动物的权限");
Dominion.notification.error(player, "你没有喂养动物的权限");
event.setCancelled(true);
}
@ -739,7 +739,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有收获的权限");
Dominion.notification.error(player, "你没有收获的权限");
event.setCancelled(true);
}
@ -771,7 +771,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有与蜜蜂交互的权限");
Dominion.notification.error(player, "你没有与蜜蜂交互的权限");
event.setCancelled(true);
}
@ -799,7 +799,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用钓钩的权限");
Dominion.notification.error(player, "你没有使用钓钩的权限");
event.setCancelled(true);
}
@ -835,7 +835,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有使用漏斗/熔炉/发射器等特殊容器的权限");
Dominion.notification.error(bukkitPlayer, "你没有使用漏斗/熔炉/发射器等特殊容器的权限");
event.setCancelled(true);
}
@ -862,7 +862,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有点火的权限");
Dominion.notification.error(player, "你没有点火的权限");
event.setCancelled(true);
}
@ -894,7 +894,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用拉杆的权限");
Dominion.notification.error(player, "你没有使用拉杆的权限");
event.setCancelled(true);
}
@ -926,7 +926,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有击杀怪物的权限");
Dominion.notification.error(bukkitPlayer, "你没有击杀怪物的权限");
event.setCancelled(true);
}
@ -950,7 +950,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有移动的权限");
Dominion.notification.error(player, "你没有移动的权限");
event.setCancelled(true);
}
@ -1006,7 +1006,7 @@ public class PlayerEvents implements Listener {
return true;
}
}
Notification.error(player, "你没有放置方块的权限");
Dominion.notification.error(player, "你没有放置方块的权限");
return false;
}
@ -1052,7 +1052,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用压力板的权限");
Dominion.notification.error(player, "你没有使用压力板的权限");
event.setCancelled(true);
}
@ -1079,7 +1079,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有骑乘交通工具的权限");
Dominion.notification.error(player, "你没有骑乘交通工具的权限");
event.setCancelled(true);
}
@ -1111,7 +1111,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有使用红石中继器的权限");
Dominion.notification.error(player, "你没有使用红石中继器的权限");
event.setCancelled(true);
}
@ -1135,7 +1135,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有剪羊毛的权限");
Dominion.notification.error(player, "你没有剪羊毛的权限");
event.setCancelled(true);
}
@ -1167,7 +1167,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有发射弓箭、三叉戟或雪球的权限");
Dominion.notification.error(player, "你没有发射弓箭、三叉戟或雪球的权限");
event.setCancelled(true);
}
@ -1197,7 +1197,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(bukkitPlayer, "你没有交易的权限");
Dominion.notification.error(bukkitPlayer, "你没有交易的权限");
event.setCancelled(true);
}
@ -1224,7 +1224,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有破坏交通工具的权限");
Dominion.notification.error(player, "你没有破坏交通工具的权限");
event.setCancelled(true);
}
@ -1255,7 +1255,7 @@ public class PlayerEvents implements Listener {
return;
}
}
Notification.error(player, "你没有放置交通工具的权限");
Dominion.notification.error(player, "你没有放置交通工具的权限");
event.setCancelled(true);
}
}

View File

@ -1,9 +1,8 @@
package cn.lunadeer.dominion.events;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -17,9 +16,6 @@ import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
import static cn.lunadeer.dominion.utils.ParticleRender.showBoxBorder;
public class SelectPointEvents implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void selectPoint(PlayerInteractEvent event) {
@ -42,11 +38,11 @@ public class SelectPointEvents implements Listener {
if (action == Action.LEFT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第一个点: " + block.getX() + " " + block.getY() + " " + block.getZ());
Dominion.notification.info(player, "已选择第一个点: %d %d %d", block.getX(), block.getY(), block.getZ());
points.put(0, block.getLocation());
} else if (action == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
Notification.info(player, "已选择第二个点: " + block.getX() + " " + block.getY() + " " + block.getZ());
Dominion.notification.info(player, "已选择第二个点: %d %d %d", block.getX(), block.getY(), block.getZ());
points.put(1, block.getLocation());
} else {
return;
@ -58,10 +54,10 @@ public class SelectPointEvents implements Listener {
return;
}
if (!points.get(0).getWorld().equals(points.get(1).getWorld())) {
Notification.error(player, "两个点不在同一个世界");
Dominion.notification.error(player, "两个点不在同一个世界");
return;
}
Dominion.notification.info(player, "已选择两个点,可以使用 /dominion create <领地名称> 创建领地");
Location loc1 = points.get(0);
Location loc2 = points.get(1);
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
@ -81,25 +77,14 @@ public class SelectPointEvents implements Listener {
} else {
count = (maxX - minX) * (maxY - minY) * (maxZ - minZ);
}
double price = count * Dominion.config.getEconomyPrice();
Notification.info(player, "预计领地创建价格为 " + price + " " + Dominion.vault.getEconomy().currencyNamePlural());
float price = count * Dominion.config.getEconomyPrice();
Dominion.notification.info(player, "预计领地创建价格为 %.2f %s", price, Dominion.vault.getEconomy().currencyNamePlural());
}
showBoxBorder(loc1, loc2);
Notification.info(player, "已选择两个点,可以使用 /dominion create <领地名称> 创建领地");
Notification.info(player, "尺寸为 " +
Math.abs(points.get(1).getX() - points.get(0).getX()) + " x " +
Math.abs(points.get(1).getY() - points.get(0).getY()) + " x " +
Math.abs(points.get(1).getZ() - points.get(0).getZ()));
Notification.info(player, "面积为 " +
Math.abs(points.get(1).getX() - points.get(0).getX()) *
Math.abs(points.get(1).getZ() - points.get(0).getZ()));
Notification.info(player, "高度为 " +
Math.abs(points.get(1).getY() - points.get(0).getY()));
Notification.info(player, "体积为 " +
Math.abs(points.get(1).getX() - points.get(0).getX()) *
Math.abs(points.get(1).getY() - points.get(0).getY()) *
Math.abs(points.get(1).getZ() - points.get(0).getZ()));
ParticleRender.showBoxFace(Dominion.instance, player, loc1, loc2);
Dominion.notification.info(player, "尺寸: %d x %d x %d", Math.abs(points.get(1).getX() - points.get(0).getX()), Math.abs(points.get(1).getY() - points.get(0).getY()), Math.abs(points.get(1).getZ() - points.get(0).getZ()));
Dominion.notification.info(player, "面积: %d", Math.abs(points.get(1).getX() - points.get(0).getX()) * Math.abs(points.get(1).getZ() - points.get(0).getZ()));
Dominion.notification.info(player, "高度: %d", Math.abs(points.get(1).getY() - points.get(0).getY()));
Dominion.notification.info(player, "体积: %d", Math.abs(points.get(1).getX() - points.get(0).getX()) * Math.abs(points.get(1).getY() - points.get(0).getY()) * Math.abs(points.get(1).getZ() - points.get(0).getZ()));
}
Dominion.pointsSelect.put(player.getUniqueId(), points);
}

View File

@ -1,7 +1,6 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.XLogger;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
@ -19,9 +18,10 @@ public class ConfigManager {
_plugin.reloadConfig();
_file = _plugin.getConfig();
_debug = _file.getBoolean("Debug", false);
Dominion.logger.setDebug(_debug);
_db_type = _file.getString("Database.Type", "sqlite");
if (!_db_type.equals("pgsql") && !_db_type.equals("sqlite")) {
XLogger.err("当前数据库只支持 pgsql 或 sqlite已重置为 sqlite");
Dominion.logger.err("当前数据库只支持 pgsql 或 sqlite已重置为 sqlite");
setDbType("sqlite");
}
_db_host = _file.getString("Database.Host", "localhost");
@ -31,34 +31,34 @@ public class ConfigManager {
_db_pass = _file.getString("Database.Pass", "postgres");
_auto_create_radius = _file.getInt("AutoCreateRadius", 10);
if (_auto_create_radius == 0) {
XLogger.err("AutoCreateRadius 不能等于 0已重置为 10");
Dominion.logger.err("AutoCreateRadius 不能等于 0已重置为 10");
setAutoCreateRadius(10);
}
_limit_size_x = _file.getInt("Limit.SizeX", 128);
if (_limit_size_x <= 4 && _limit_size_x != -1) {
XLogger.err("Limit.SizeX 尺寸不能小于 4已重置为 128");
Dominion.logger.err("Limit.SizeX 尺寸不能小于 4已重置为 128");
setLimitSizeX(128);
}
_limit_size_y = _file.getInt("Limit.SizeY", 64);
if (_limit_size_y <= 4 && _limit_size_y != -1) {
XLogger.err("Limit.SizeY 尺寸不能小于 4已重置为 64");
Dominion.logger.err("Limit.SizeY 尺寸不能小于 4已重置为 64");
setLimitSizeY(64);
}
_limit_size_z = _file.getInt("Limit.SizeZ", 128);
if (_limit_size_z <= 4 && _limit_size_z != -1) {
XLogger.err("Limit.SizeZ 尺寸不能小于 4已重置为 128");
Dominion.logger.err("Limit.SizeZ 尺寸不能小于 4已重置为 128");
setLimitSizeZ(128);
}
_blue_map = _file.getBoolean("BlueMap", true);
_auto_clean_after_days = _file.getInt("AutoCleanAfterDays", 180);
if (_auto_clean_after_days == 0) {
XLogger.err("AutoCleanAfterDays 不能等于 0已重置为 180");
Dominion.logger.err("AutoCleanAfterDays 不能等于 0已重置为 180");
setAutoCleanAfterDays(180);
}
_limit_min_y = _file.getInt("Limit.MinY", -64);
_limit_max_y = _file.getInt("Limit.MaxY", 320);
if (_limit_min_y >= _limit_max_y) {
XLogger.err("Limit.MinY 不能大于或等于 Limit.MaxY已重置为 -64 320");
Dominion.logger.err("Limit.MinY 不能大于或等于 Limit.MaxY已重置为 -64 320");
setLimitMinY(-64);
setLimitMaxY(320);
}
@ -67,7 +67,7 @@ public class ConfigManager {
_limit_vert = _file.getBoolean("Limit.Vert", false);
if (_limit_vert && _limit_size_y <= _limit_max_y - _limit_min_y) {
setLimitSizeY(_limit_max_y - _limit_min_y + 1);
XLogger.warn("启用 Limit.Vert 时 Limit.SizeY 不能小于 Limit.MaxY - Limit.MinY已自动调整为 " + (_limit_max_y - _limit_min_y + 1));
Dominion.logger.warn("启用 Limit.Vert 时 Limit.SizeY 不能小于 Limit.MaxY - Limit.MinY已自动调整为 " + (_limit_max_y - _limit_min_y + 1));
}
_limit_op_bypass = _file.getBoolean("Limit.OpByPass", true);
_world_black_list = _file.getStringList("Limit.WorldBlackList");
@ -77,7 +77,7 @@ public class ConfigManager {
_tp_cool_down = _file.getInt("Teleport.CoolDown", 0);
_tool = _file.getString("Tool", "ARROW");
if (Material.getMaterial(_tool) == null) {
XLogger.err("工具名称设置错误,已重置为 ARROW");
Dominion.logger.err("工具名称设置错误,已重置为 ARROW");
setTool("ARROW");
}
_economy_enable = _file.getBoolean("Economy.Enable", false);
@ -94,6 +94,7 @@ public class ConfigManager {
_debug = debug;
_file.set("Debug", debug);
_plugin.saveConfig();
Dominion.logger.setDebug(debug);
}
public String getDbType() {

View File

@ -1,92 +1,8 @@
package cn.lunadeer.dominion.managers;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.XLogger;
import java.sql.*;
public class DatabaseManager {
public static Connection createConnection() {
try {
String connectionUrl;
if (Dominion.config.getDbType().equals("pgsql")) {
XLogger.info("正在连接到 PostgreSQL 数据库");
Class.forName("org.postgresql.Driver");
connectionUrl = "jdbc:postgresql://" + Dominion.config.getDbHost() + ":" + Dominion.config.getDbPort();
connectionUrl += "/" + Dominion.config.getDbName();
return DriverManager.getConnection(connectionUrl, Dominion.config.getDbUser(), Dominion.config.getDbPass());
} else if (Dominion.config.getDbType().equals("sqlite")) {
XLogger.info("正在连接到 SQLite 数据库");
Class.forName("org.sqlite.JDBC");
connectionUrl = "jdbc:sqlite:" + Dominion.instance.getDataFolder() + "/" + Dominion.config.getDbName() + ".db";
return DriverManager.getConnection(connectionUrl);
} else {
XLogger.err("=== 严重错误 ===");
XLogger.err("数据库类型错误,只能为 pgsql 或 sqlite");
XLogger.err("===============");
return null;
}
} catch (ClassNotFoundException | SQLException e) {
XLogger.err("=== 严重错误 ===");
XLogger.err("Database connection failed: " + e.getMessage());
XLogger.err("===============");
return null;
}
}
public static ResultSet query(String sql) {
Connection conn = Dominion.dbConnection;
if (conn == null) {
return null;
}
try {
Statement stmt = conn.createStatement();
if (sql.contains("SERIAL PRIMARY KEY") && Dominion.config.getDbType().equals("sqlite")) {
sql = sql.replace("SERIAL PRIMARY KEY", "INTEGER PRIMARY KEY AUTOINCREMENT");
}
// if query with no result return null
if (stmt.execute(sql)) {
return stmt.getResultSet();
}
} catch (SQLException e) {
handleDatabaseError("Database query failed: ", e, sql);
}
return null;
}
private static void handleDatabaseError(String errorMessage, SQLException e, String sql) {
XLogger.err("=== 严重错误 ===");
XLogger.err(errorMessage + e.getMessage());
XLogger.err("SQL: " + sql);
XLogger.err("===============");
}
private static void addColumnIfNotExists(String tableName, String columnName, String columnDefinition) {
if (Dominion.config.getDbType().equals("pgsql")) {
String sql = "ALTER TABLE " + tableName + " ADD COLUMN IF NOT EXISTS " + columnName + " " + columnDefinition + ";";
query(sql);
} else if (Dominion.config.getDbType().equals("sqlite")) {
try {
ResultSet rs = query("PRAGMA table_info(" + tableName + ");");
boolean columnExists = false;
if (rs != null) {
while (rs.next()) {
if (columnName.equals(rs.getString("name"))) {
columnExists = true;
break;
}
}
}
if (!columnExists) {
query("ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " " + columnDefinition + ";");
}
} catch (SQLException e) {
handleDatabaseError("Database operation failed: ", e, "");
}
}
}
public class DatabaseTables {
public static void migrate() {
String sql = "";
@ -97,7 +13,7 @@ public class DatabaseManager {
" last_known_name TEXT NOT NULL," +
" last_join_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP" +
");";
query(sql);
Dominion.database.query(sql);
// dominion table
sql = "CREATE TABLE IF NOT EXISTS dominion (" +
@ -158,7 +74,7 @@ public class DatabaseManager {
" FOREIGN KEY (owner) REFERENCES player_name(uuid) ON DELETE CASCADE," +
" FOREIGN KEY (parent_dom_id) REFERENCES dominion(id) ON DELETE CASCADE" +
");";
query(sql);
Dominion.database.query(sql);
// player privilege
sql = "CREATE TABLE IF NOT EXISTS player_privilege (" +
@ -206,14 +122,14 @@ public class DatabaseManager {
" FOREIGN KEY (player_uuid) REFERENCES player_name(uuid) ON DELETE CASCADE," +
" FOREIGN KEY (dom_id) REFERENCES dominion(id) ON DELETE CASCADE" +
");";
query(sql);
Dominion.database.query(sql);
sql = "INSERT INTO player_name (" +
"id, uuid, last_known_name" +
") VALUES (" +
"-1, '00000000-0000-0000-0000-000000000000', 'server'" +
") ON CONFLICT DO NOTHING;";
query(sql);
Dominion.database.query(sql);
sql = "INSERT INTO dominion (" +
"id, owner, name, world, x1, y1, z1, x2, y2, z2, parent_dom_id, join_message, leave_message" +
@ -223,31 +139,31 @@ public class DatabaseManager {
"2147483647, 2147483647, 2147483647, -1, " +
"'欢迎', '再见'" +
") ON CONFLICT DO NOTHING;";
query(sql);
Dominion.database.query(sql);
// 1.5.0
addColumnIfNotExists("dominion", "hopper", "BOOLEAN NOT NULL DEFAULT FALSE");
addColumnIfNotExists("player_privilege", "hopper", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("dominion", "hopper", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("player_privilege", "hopper", "BOOLEAN NOT NULL DEFAULT FALSE");
// 1.9.0
addColumnIfNotExists("dominion", "vehicle_spawn", "BOOLEAN NOT NULL DEFAULT FALSE");
addColumnIfNotExists("player_privilege", "vehicle_spawn", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("dominion", "vehicle_spawn", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("player_privilege", "vehicle_spawn", "BOOLEAN NOT NULL DEFAULT FALSE");
// 1.10.0
addColumnIfNotExists("dominion", "trample", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("dominion", "trample", "BOOLEAN NOT NULL DEFAULT FALSE");
// 1.11.0
addColumnIfNotExists("dominion", "mob_drop_item", "BOOLEAN NOT NULL DEFAULT TRUE");
Dominion.database.addColumnIfNotExists("dominion", "mob_drop_item", "BOOLEAN NOT NULL DEFAULT TRUE");
// 1.12.0
addColumnIfNotExists("dominion", "ender_man", "BOOLEAN NOT NULL DEFAULT FAlSE");
Dominion.database.addColumnIfNotExists("dominion", "ender_man", "BOOLEAN NOT NULL DEFAULT FAlSE");
// 1.18.0
addColumnIfNotExists("dominion", "tp_location", "TEXT NOT NULL DEFAULT 'default'");
addColumnIfNotExists("dominion", "teleport", "BOOLEAN NOT NULL DEFAULT FALSE");
addColumnIfNotExists("player_privilege", "teleport", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("dominion", "tp_location", "TEXT NOT NULL DEFAULT 'default'");
Dominion.database.addColumnIfNotExists("dominion", "teleport", "BOOLEAN NOT NULL DEFAULT FALSE");
Dominion.database.addColumnIfNotExists("player_privilege", "teleport", "BOOLEAN NOT NULL DEFAULT FALSE");
// 1.21
addColumnIfNotExists("dominion", "show_border", "BOOLEAN NOT NULL DEFAULT TRUE");
Dominion.database.addColumnIfNotExists("dominion", "show_border", "BOOLEAN NOT NULL DEFAULT TRUE");
}
}

View File

@ -1,8 +1,8 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
@ -63,7 +63,7 @@ public class Apis {
if (!dominion.getOwner().equals(player.getUniqueId())) {
PlayerPrivilegeDTO privileges = PlayerPrivilegeDTO.select(player.getUniqueId(), dominion.getId());
if (privileges == null || !privileges.getAdmin()) {
Notification.error(player, "你不是领地 " + dominion.getName() + " 的拥有者或管理员,无权访问此页面");
Dominion.notification.error(player, "你不是领地 %s 的拥有者或管理员,无权访问此页面", dominion.getName());
return true;
}
}

View File

@ -2,9 +2,9 @@ package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.NumChanger;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
import cn.lunadeer.dominion.utils.STUI.NumChanger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;

View File

@ -1,7 +1,7 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
@ -16,12 +16,12 @@ public class DominionFlagInfo {
Player player = playerOnly(sender);
if (player == null) return;
if (args.length < 2) {
Notification.error(sender, "用法: /dominion flag_info <领地名称> [页码]");
Dominion.notification.error(sender, "用法: /dominion flag_info <领地名称> [页码]");
return;
}
DominionDTO dominion = DominionDTO.select(args[1]);
if (dominion == null) {
Notification.error(sender, "领地 " + args[1] + " 不存在");
Dominion.notification.error(sender, "领地 %s 不存在", args[1]);
return;
}
int page = 1;

View File

@ -1,7 +1,7 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
@ -18,7 +18,7 @@ public class DominionManage {
if (player == null) return;
DominionDTO dominion = getDominionNameArg_1(player, args);
if (dominion == null) {
Notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion manage <领地名称>");
Dominion.notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion manage <领地名称>");
return;
}
if (noAuthToManage(player, dominion)) return;

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
@ -30,7 +30,7 @@ public class DominionPrivilegeList {
if (player == null) return;
DominionDTO dominion = getDominionNameArg_1(player, args);
if (dominion == null) {
Notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion privilege_list <领地名称>");
Dominion.notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion privilege_list <领地名称>");
return;
}
ListView view = ListView.create(10, "/dominion privilege_list " + dominion.getName());

View File

@ -1,18 +1,18 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.controllers.PlayerController;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.View;
import cn.lunadeer.minecraftpluginutils.ParticleRender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static cn.lunadeer.dominion.commands.Apis.playerOnly;
import static cn.lunadeer.dominion.tuis.Apis.getDominionNameArg_1;
import static cn.lunadeer.dominion.utils.ParticleRender.showBoxBorder;
public class DominionSizeInfo {
public static void show(CommandSender sender, String[] args) {
@ -20,7 +20,7 @@ public class DominionSizeInfo {
if (player == null) return;
DominionDTO dominion = getDominionNameArg_1(player, args);
if (dominion == null) {
Notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion info <领地名称>");
Dominion.notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion info <领地名称>");
return;
}
PlayerDTO owner = PlayerController.getPlayerDTO(dominion.getOwner());
@ -48,6 +48,8 @@ public class DominionSizeInfo {
.append(Button.create("管理界面", "/dominion manage " + dominion.getName()))
.append(Button.create("权限列表", "/dominion flag_info " + dominion.getName())))
.showOn(player);
showBoxBorder(dominion.getWorld(), x1, y1, z1, x2, y2, z2);
ParticleRender.showBoxFace(Dominion.instance, player,
dominion.getLocation1(),
dominion.getLocation2());
}
}

View File

@ -1,9 +1,9 @@
package cn.lunadeer.dominion.tuis;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import cn.lunadeer.dominion.dtos.PlayerDTO;
import cn.lunadeer.dominion.dtos.PlayerPrivilegeDTO;
import cn.lunadeer.dominion.utils.Notification;
import cn.lunadeer.dominion.utils.STUI.Button;
import cn.lunadeer.dominion.utils.STUI.Line;
import cn.lunadeer.dominion.utils.STUI.ListView;
@ -29,19 +29,19 @@ public class PrivilegeInfo {
}
String playerName = args[1];
if (dominion == null) {
Notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion privilege_info <玩家名称> [领地名称]");
Dominion.notification.error(sender, "你不在任何领地内,请指定领地名称 /dominion privilege_info <玩家名称> [领地名称]");
return;
}
ListView view = ListView.create(10, "/dominion privilege_info " + playerName + " " + dominion.getName());
if (noAuthToManage(player, dominion)) return;
PlayerDTO playerDTO = PlayerDTO.select(playerName);
if (playerDTO == null) {
Notification.error(sender, "玩家 " + playerName + " 不存在");
Dominion.notification.error(sender, "玩家 %s 不存在", playerName);
return;
}
PlayerPrivilegeDTO privilege = PlayerPrivilegeDTO.select(playerDTO.getUuid(), dominion.getId());
if (privilege == null) {
Notification.warn(sender, "玩家 " + playerName + " 没有任何特权");
Dominion.notification.warn(sender, "玩家 %s 没有任何特权", playerName);
return;
}
view.title("玩家 " + playerName + " 在领地 " + dominion.getName() + " 的特权信息");
@ -161,7 +161,7 @@ public class PrivilegeInfo {
.append(Button.createRed("", "/dominion set_privilege " + playerName + " craft true " + dominion.getName() + " " + page))
.append("使用工作台"));
}
if (privilege.getComparer()){
if (privilege.getComparer()) {
view.add(Line.create()
.append(Button.createGreen("", "/dominion set_privilege " + playerName + " comparer false " + dominion.getName() + " " + page))
.append("比较器交互"));
@ -278,7 +278,7 @@ public class PrivilegeInfo {
.append(Button.createRed("", "/dominion set_privilege " + playerName + " ignite true " + dominion.getName() + " " + page))
.append("点燃"));
}
if (privilege.getLever()){
if (privilege.getLever()) {
view.add(Line.create()
.append(Button.createGreen("", "/dominion set_privilege " + playerName + " lever false " + dominion.getName() + " " + page))
.append("使用拉杆"));

View File

@ -1,201 +0,0 @@
package cn.lunadeer.dominion.utils;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class GiteaReleaseCheck {
private static class GiteaRelease {
public String tag_name;
public String message;
public String html_url;
public String download_url;
}
public GiteaReleaseCheck(JavaPlugin plugin, String giteaServer, String owner, String repo) {
this.gitea_server = giteaServer;
this.owner = owner;
this.repo = repo;
this.plugin = plugin;
this.current_version = plugin.getPluginMeta().getVersion();
// 异步每12小时检查一次更新
plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, (instance) -> {
getLatestRelease();
if (auto_update) {
downloadUpdate();
}
}, 10 + new Random().nextInt(10), 60 * 60 * 12 + new Random().nextInt(60),
TimeUnit.SECONDS);
}
public void enableAutoUpdate() {
auto_update = true;
}
private String repoReleases() {
return gitea_server + "/api/v1/repos/" + owner + "/" + repo + "/releases";
}
private String tag(String tagName) {
return gitea_server + "/api/v1/repos/" + owner + "/" + repo + "/tags/" + tagName;
}
private void getLatestRelease() {
XLogger.info("================================");
XLogger.info("正在检查更新...");
// send get request to repoReleases()
try {
// 发送 GET 请求
HttpsURLConnection connection = (HttpsURLConnection) new URL(repoReleases()).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
// 获取响应
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
JSONArray releaseList = (JSONArray) new JSONParser().parse(builder.toString());
JSONObject latestRelease = (JSONObject) releaseList.get(0);
GiteaRelease release = new GiteaRelease();
release.tag_name = (String) latestRelease.get("tag_name");
release.message = (String) latestRelease.get("body");
release.html_url = (String) latestRelease.get("html_url");
JSONArray assets = (JSONArray) latestRelease.get("assets");
if (assets.size() > 0) {
JSONObject asset = (JSONObject) assets.get(0);
release.download_url = (String) asset.get("browser_download_url");
}
latest_release = release;
XLogger.debug("Latest release: " + latest_release.tag_name);
XLogger.debug("Message: " + latest_release.message);
XLogger.debug("Download URL: " + latest_release.download_url);
XLogger.debug("HTML URL: " + latest_release.html_url);
if (isNewVersion(current_version, latest_release.tag_name)) {
XLogger.info("发现新版本:" + latest_release.tag_name);
XLogger.info("版本信息:");
String[] message = latest_release.message.split("\n");
for (String line : message) {
XLogger.info("\t" + line);
}
XLogger.info("下载页面:" + latest_release.html_url);
} else {
XLogger.info("当前已是最新版本:" + current_version);
}
XLogger.info("================================");
} catch (Exception e) {
XLogger.err("Failed to get latest release: " + e.getMessage());
}
}
private String getTagMessage(String tagName) {
try {
// 发送 GET 请求
HttpsURLConnection connection = (HttpsURLConnection) new URL(tag(tagName)).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
// 获取响应
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
JSONObject tag = (JSONObject) new JSONParser().parse(builder.toString());
return (String) tag.get("message");
} catch (Exception e) {
XLogger.debug("Failed to get tag message: " + e.getMessage());
return "null";
}
}
private void downloadUpdate() {
if (latest_release == null) {
getLatestRelease();
if (latest_release == null)
return;
}
if (!isNewVersion(current_version, latest_release.tag_name)) {
XLogger.info("当前已是最新版本");
return;
}
if (latest_release.download_url == null) {
XLogger.err("下载地址不可用");
return;
}
try {
XLogger.info("================================");
XLogger.info("正在下载更新...");
File pluginsFolder = plugin.getDataFolder().getParentFile();
File newJarFile = new File(pluginsFolder, latest_release.download_url.substring(latest_release.download_url.lastIndexOf("/") + 1));
// send get request to download_url
HttpsURLConnection connection = (HttpsURLConnection) new URL(latest_release.download_url).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
// 获取响应写入文件到 newJarFile
try (DataOutputStream outputStream = new DataOutputStream(Files.newOutputStream(newJarFile.toPath()))) {
byte[] buffer = new byte[1024];
int length;
while ((length = connection.getInputStream().read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
}
XLogger.info("更新下载完成");
XLogger.info("新版本:" + latest_release.tag_name);
XLogger.info("请删除旧版本插件,然后重启服务器。");
XLogger.info("================================");
} catch (Exception e) {
XLogger.err("Failed to auto update: " + e.getMessage());
}
}
private String gitea_server;
private String owner;
private String repo;
private JavaPlugin plugin;
private String current_version;
private GiteaRelease latest_release = null;
private boolean auto_update = false;
private boolean isNewVersion(String current, String in_coming) {
// 只保留数字和点号
current = current.replaceAll("[^0-9.]", "");
in_coming = in_coming.replaceAll("[^0-9.]", "");
XLogger.debug("Current version: " + current);
XLogger.debug("In-coming version: " + in_coming);
String[] current_version = current.split("\\.");
String[] in_coming_version = in_coming.split("\\.");
for (int i = 0; i < Math.min(current_version.length, in_coming_version.length); i++) {
int current_v = Integer.parseInt(current_version[i]);
int in_coming_v = Integer.parseInt(in_coming_version[i]);
if (current_v < in_coming_v) {
return true;
} else if (current_v > in_coming_v) {
return false;
}
}
return current_version.length < in_coming_version.length;
}
}

View File

@ -1,64 +0,0 @@
package cn.lunadeer.dominion.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Notification {
private static final Style i_style = Style.style(TextColor.color(139, 255, 123));
private static final Style w_style = Style.style(TextColor.color(255, 185, 69));
private static final Style e_style = Style.style(TextColor.color(255, 96, 72));
private static final Style d_style = Style.style(TextColor.color(0, 255, 255));
private static final String prefix = "[Dominion] ";
public static void info(Player player, String msg) {
player.sendMessage(Component.text(prefix + msg, i_style));
}
public static void warn(Player player, String msg) {
player.sendMessage(Component.text(prefix + msg, w_style));
}
public static void error(Player player, String msg) {
player.sendMessage(Component.text(prefix + msg, e_style));
}
public static void info(CommandSender sender, String msg) {
sender.sendMessage(Component.text(prefix + msg, i_style));
}
public static void warn(CommandSender sender, String msg) {
sender.sendMessage(Component.text(prefix + msg, w_style));
}
public static void error(CommandSender sender, String msg) {
sender.sendMessage(Component.text(prefix + msg, e_style));
}
public static void info(Player player, Component msg) {
player.sendMessage(Component.text(prefix, i_style).append(msg));
}
public static void warn(Player player, Component msg) {
player.sendMessage(Component.text(prefix, w_style).append(msg));
}
public static void error(Player player, Component msg) {
player.sendMessage(Component.text(prefix, e_style).append(msg));
}
public static void info(CommandSender player, Component msg) {
player.sendMessage(Component.text(prefix, i_style).append(msg));
}
public static void warn(CommandSender player, Component msg) {
player.sendMessage(Component.text(prefix, w_style).append(msg));
}
public static void error(CommandSender player, Component msg) {
player.sendMessage(Component.text(prefix, e_style).append(msg));
}
}

View File

@ -1,64 +0,0 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import cn.lunadeer.dominion.dtos.DominionDTO;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
public class ParticleRender {
public static void showBoxBorder(DominionDTO dominion) {
showBoxBorder(dominion.getWorld(), dominion.getX1(), dominion.getY1(), dominion.getZ1(), dominion.getX2(), dominion.getY2(), dominion.getZ2());
}
public static void showBoxBorder(String world, int x1, int y1, int z1, int x2, int y2, int z2) {
showBoxBorder(new Location(Dominion.instance.getServer().getWorld(world), x1, y1, z1), new Location(Dominion.instance.getServer().getWorld(world), x2, y2, z2));
}
public static void showBoxBorder(Location loc1, Location loc2) {
int deltaX = Math.abs(loc1.getBlockX() - loc2.getBlockX());
int deltaY = Math.abs(loc1.getBlockY() - loc2.getBlockY());
int deltaZ = Math.abs(loc1.getBlockZ() - loc2.getBlockZ());
if (deltaX > 256 || deltaY > 256 || deltaZ > 256) {
XLogger.debug("渲染区域过大,为避免卡顿此渲染已跳过");
XLogger.debug("loc1: " + loc1.toString());
XLogger.debug("loc2: " + loc2.toString());
return;
}
Dominion.scheduler.region.run(Dominion.instance, (instance) -> {
if (!loc1.getWorld().equals(loc2.getWorld())) {
return;
}
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY());
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()) + 1;
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()) + 1;
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()) + 1;
World world = loc1.getWorld();
for (int x = minX; x <= maxX; x++) {
spawnParticle(world, x, minY, minZ);
spawnParticle(world, x, minY, maxZ);
spawnParticle(world, x, maxY, minZ);
spawnParticle(world, x, maxY, maxZ);
}
for (int y = minY; y <= maxY; y++) {
spawnParticle(world, minX, y, minZ);
spawnParticle(world, minX, y, maxZ);
spawnParticle(world, maxX, y, minZ);
spawnParticle(world, maxX, y, maxZ);
}
for (int z = minZ; z <= maxZ; z++) {
spawnParticle(world, minX, minY, z);
spawnParticle(world, minX, maxY, z);
spawnParticle(world, maxX, minY, z);
spawnParticle(world, maxX, maxY, z);
}
});
}
private static void spawnParticle(World world, double x, double y, double z) {
world.spawnParticle(Particle.FLAME, x, y, z, 10, 0, 0, 0, 0);
}
}

View File

@ -1,6 +1,5 @@
package cn.lunadeer.dominion.utils.STUI;
import cn.lunadeer.dominion.utils.Notification;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
@ -64,11 +63,9 @@ public class ListView {
public void showOn(Player player, Integer page) {
int offset = (page - 1) * page_size;
if (lines.isEmpty()) {
Notification.warn(player, "没有数据");
return;
}
if (offset >= lines.size() || offset < 0) {
Notification.error(player, "页数超出范围");
return;
}
for (int i = offset; i < offset + page_size; i++) {

View File

@ -1,56 +0,0 @@
package cn.lunadeer.dominion.utils;
import cn.lunadeer.dominion.Dominion;
import org.bukkit.entity.Player;
import java.util.logging.Logger;
public class XLogger {
private static final Dominion _plugin = Dominion.instance;
private static final Logger _logger = _plugin.getLogger();
private static final String prefix = "[Dominion] ";
public static void info(Player player, String message) {
Notification.info(player, prefix + "I | " + message);
if (Dominion.config.isDebug())
debug("来自玩家[ " + player.getName() + " ] 的信息 | " + message);
}
public static void info(String message) {
_logger.info(" I | " + message);
}
public static void warn(Player player, String message) {
Notification.warn(player, prefix + "W | " + message);
if (Dominion.config.isDebug())
debug("来自玩家[ " + player.getName() + " ] 的警告 | " + message);
}
public static void warn(String message) {
_logger.warning(" W | " + message);
}
public static void err(Player player, String message) {
Notification.error(player, prefix + "E | " + message);
if (Dominion.config.isDebug())
debug("来自玩家[ " + player.getName() + " ] 的报错 | " + message);
}
public static void err(String message) {
_logger.severe(" E | " + message);
}
public static void debug(Player player, String message) {
if (!Dominion.config.isDebug()) return;
if (player.isOp())
Notification.info(player, prefix + "D | " + message);
else
debug("来自玩家[ " + player.getName() + " ] 的调试 | " + message);
}
public static void debug(String message) {
if (!Dominion.config.isDebug()) return;
_logger.info(" D | " + message);
}
}