Initial commit

This commit is contained in:
2021-09-10 22:52:05 +08:00
commit dd2ecca1a8
48 changed files with 3336 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
plugins {
id 'java'
}
group 'cn.hamster3'
version '2.0.6-SNAPSHOT'
repositories {
maven {
url = "https://maven.airgame.net/repository/maven-public/"
}
maven {
url = "https://repo.codemc.org/repository/maven-public"
}
}
dependencies {
compileOnly "org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT"
// https://mvnrepository.com/artifact/org.jetbrains/annotations
compileOnly group: 'org.jetbrains', name: 'annotations', version: '22.0.0'
compileOnly "cn.hamster3:HamsterService-Bukkit:2.6.2-SNAPSHOT"
compileOnly "cn.hamster3:HamsterAPI:2.4.0-SNAPSHOT"
compileOnly "com.github.MilkBowl:VaultAPI:1.7"
compileOnly "org.black_ixx:PlayerPoints:2.1.3"
compileOnly "me.clip:placeholderapi:2.10.9"
}
processResources {
filesMatching("plugin.yml") {
expand "version": project.version
}
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
jar {
archivesBaseName = "HamsterCurrency"
destinationDir(rootProject.buildDir)
}

View File

@@ -0,0 +1,159 @@
package cn.hamster3.currency;
import cn.hamster3.api.utils.LogUtils;
import cn.hamster3.currency.api.CurrencyAPI;
import cn.hamster3.currency.command.currency.CurrencyCommand;
import cn.hamster3.currency.command.vault.VaultCommand;
import cn.hamster3.currency.command.vault.VaultPayCommand;
import cn.hamster3.currency.command.vault.VaultSeeCommand;
import cn.hamster3.currency.command.vault.VaultTopCommand;
import cn.hamster3.currency.core.FileDataManager;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.SQLDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.hook.PlaceholderHook;
import cn.hamster3.currency.hook.VaultEconomyHook;
import cn.hamster3.currency.listener.CurrencyListener;
import cn.hamster3.currency.listener.SQLListener;
import cn.hamster3.service.bukkit.api.ServiceMessageAPI;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.SQLException;
public final class HamsterCurrency extends JavaPlugin {
private static LogUtils logUtils;
private IDataManager dataManager;
private CurrencyListener listener;
private boolean loaded;
public static LogUtils getLogUtils() {
return logUtils;
}
@Override
public void onLoad() {
FileManager.reload(this);
logUtils = new LogUtils(this);
logUtils.infoDividingLine();
if (FileManager.isUseBC()) {
logUtils.info("使用多服务器模式...");
try {
SQLDataManager sqlDataManager = new SQLDataManager(this);
logUtils.info("SQL存档管理器初始化完成!");
listener = new SQLListener(this, sqlDataManager);
logUtils.info("事件监听器初始化完成!");
dataManager = sqlDataManager;
} catch (SQLException | ClassNotFoundException e) {
logUtils.error(e, "插件加载时遇到了一个错误: ");
loaded = false;
}
} else {
logUtils.info("使用单服务器模式...");
FileDataManager fileDataManager = new FileDataManager(this);
logUtils.info("文件存档管理器初始化完成!");
listener = new CurrencyListener(this, fileDataManager);
logUtils.info("事件监听器初始化完成!");
dataManager = fileDataManager;
}
CurrencyAPI.setDataManager(dataManager);
logUtils.info("API初始化完成!");
loaded = true;
logUtils.infoDividingLine();
}
@Override
public void onEnable() {
logUtils.infoDividingLine();
if (!loaded) {
logUtils.warning("插件未能成功启动!");
setEnabled(false);
return;
}
dataManager.loadConfig();
PluginCommand command = getCommand("HamsterCurrency");
new CurrencyCommand(command, dataManager);
logUtils.info("插件命令已注册!");
Bukkit.getPluginManager().registerEvents(listener, this);
logUtils.info("事件监听器已注册!");
registerVault();
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
dataManager.onEnable();
for (Player player : Bukkit.getOnlinePlayers()) {
dataManager.loadPlayerData(player.getUniqueId());
}
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
logUtils.info("检测到 PlaceholderAPI 已启动...");
new PlaceholderHook(dataManager).register();
logUtils.info("已挂载 PlaceholderAPI 变量!");
} else {
logUtils.info("未检测到 PlaceholderAPI!");
}
});
ServiceMessageAPI.subscribeTag("HamsterCurrency");
logUtils.info("插件已启动!");
logUtils.infoDividingLine();
}
private void registerVault() {
logUtils.infoDividingLine();
if (!FileManager.isVaultHook()) {
Bukkit.getServicesManager().unregister(this);
logUtils.info("不使用Vault经济系统挂接...");
return;
}
if (!Bukkit.getPluginManager().isPluginEnabled("Vault")) {
logUtils.warning("未找到 Vault 插件! 取消注册Vault经济系统...");
return;
}
String type = FileManager.getVaultCurrencyType();
logUtils.info("尝试以 %s 注册Vault经济系统...", type);
CurrencyType currencyType = dataManager.getCurrencyType(type);
if (currencyType == null) {
logUtils.warning("未找到经济类型 %s! 取消注册Vault经济系统...", type);
return;
}
VaultEconomyHook hook = new VaultEconomyHook(dataManager);
logUtils.info("已初始化Vault连接器...");
Bukkit.getServicesManager().register(Economy.class, hook, this, ServicePriority.Normal);
logUtils.info("Vault经济系统注册成功!");
new VaultPayCommand(getCommand("payMoney"), dataManager);
new VaultSeeCommand(getCommand("balance"), dataManager);
new VaultTopCommand(getCommand("balanceTop"), dataManager);
new VaultCommand(getCommand("economy"), dataManager);
logUtils.infoDividingLine();
}
@Override
public void onDisable() {
logUtils.infoDividingLine();
if (dataManager != null) {
dataManager.onDisable();
}
Bukkit.getServicesManager().unregister(this);
logUtils.info("插件已关闭!");
logUtils.infoDividingLine();
logUtils.close();
}
}

View File

@@ -0,0 +1,88 @@
package cn.hamster3.currency.api;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.black_ixx.playerpoints.PlayerPoints;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.UUID;
/**
* 当 currencyID 为 PlayerPoints 且服务器安装了点券插件时,会自动更改为 PlayerPoints 接口
*/
@SuppressWarnings({"unused", "ConstantConditions"})
public abstract class CurrencyAPI {
private static IDataManager dataManager;
public static void setDataManager(IDataManager dataManager) {
CurrencyAPI.dataManager = dataManager;
}
public static double getPlayerCurrency(UUID uuid, String currencyID) {
if (currencyID.equals("PlayerPoints") && Bukkit.getPluginManager().isPluginEnabled("PlayerPoints")) {
return ((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI().look(uuid);
}
PlayerData data = dataManager.getPlayerData(uuid);
if (data == null) {
return 0;
}
return data.getPlayerCurrency(currencyID);
}
public static void setPlayerCurrency(UUID uuid, String currencyID, double amount) {
if (currencyID.equals("PlayerPoints") && Bukkit.getPluginManager().isPluginEnabled("PlayerPoints")) {
((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI().set(uuid, (int) amount);
return;
}
PlayerData data = dataManager.getPlayerData(uuid);
if (data == null) {
return;
}
data.setPlayerCurrency(currencyID, amount);
dataManager.savePlayerData(data);
}
public static void addPlayerCurrency(UUID uuid, String currencyID, double amount) {
if (currencyID.equals("PlayerPoints") && Bukkit.getPluginManager().isPluginEnabled("PlayerPoints")) {
((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI().give(uuid, (int) amount);
return;
}
PlayerData data = dataManager.getPlayerData(uuid);
if (data == null) {
return;
}
data.setPlayerCurrency(currencyID, data.getPlayerCurrency(currencyID) + amount);
dataManager.savePlayerData(data);
}
public static void takePlayerCurrency(UUID uuid, String currencyID, double amount) {
if (currencyID.equals("PlayerPoints") && Bukkit.getPluginManager().isPluginEnabled("PlayerPoints")) {
((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI().take(uuid, (int) amount);
return;
}
PlayerData data = dataManager.getPlayerData(uuid);
if (data == null) {
return;
}
data.setPlayerCurrency(currencyID, data.getPlayerCurrency(currencyID) - amount);
dataManager.savePlayerData(data);
}
public static boolean hasPlayerCurrency(UUID uuid, String currencyID, double amount) {
if (currencyID.equals("PlayerPoints") && Bukkit.getPluginManager().isPluginEnabled("PlayerPoints")) {
return ((PlayerPoints) Bukkit.getPluginManager().getPlugin("PlayerPoints")).getAPI().look(uuid) >= amount;
}
PlayerData data = dataManager.getPlayerData(uuid);
if (data == null) {
return false;
}
return data.getPlayerCurrency(currencyID) >= amount;
}
public ArrayList<CurrencyType> getAllCurrencyType() {
return new ArrayList<>(dataManager.getCurrencyTypes());
}
}

View File

@@ -0,0 +1,34 @@
package cn.hamster3.currency.command;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.IDataManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
public class ReloadCommand extends CommandExecutor {
private final IDataManager dataManager;
public ReloadCommand(IDataManager dataManager) {
super("reload", "重载服务器");
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
dataManager.reloadConfig();
sender.sendMessage("§a插件重载完成!");
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return null;
}
}

View File

@@ -0,0 +1,106 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
import java.util.stream.Collectors;
public abstract class CurrencyAdminSetCommand extends CommandExecutor {
protected final IDataManager dataManager;
public CurrencyAdminSetCommand(IDataManager dataManager, String name, String description, String permission) {
super(
name,
description,
permission,
Message.notHasPermission.toString(),
new String[]{
"玩家",
"货币类型",
"数额"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
public String getPermissionMessage() {
return Message.notHasPermission.toString();
}
protected abstract void doSet(PlayerData data, CurrencyType type, double amount);
@Override
@SuppressWarnings("DuplicatedCode")
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
PlayerData data = dataManager.getPlayerData(args[1]);
if (data == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
if (args.length < 3) {
sender.sendMessage(Message.notInputCurrencyType.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(args[2]);
if (type == null) {
sender.sendMessage(Message.currencyTypeNotFound.toString());
return true;
}
if (args.length < 4) {
sender.sendMessage(Message.notInputAmount.toString());
return true;
}
double amount;
try {
amount = Double.parseDouble(args[3]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
doSet(data, type, amount);
sender.sendMessage(
Message.playerCurrencySetSuccess.toString()
.replace("%player%", data.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(type.getId())))
);
dataManager.savePlayerData(data);
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 2: {
return HamsterAPI.getOnlinePlayersName(args[1]);
}
case 3: {
List<String> types = dataManager.getCurrencyTypes().stream().map(CurrencyType::getId).collect(Collectors.toList());
types = HamsterAPI.startWithIgnoreCase(types, args[2]);
if (types.size() > 10) {
types = types.subList(0, 9);
}
return types;
}
}
return null;
}
}

View File

@@ -0,0 +1,34 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.command.CommandManager;
import cn.hamster3.currency.command.ReloadCommand;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.SQLDataManager;
import org.bukkit.command.PluginCommand;
public class CurrencyCommand extends CommandManager {
public CurrencyCommand(PluginCommand command, IDataManager dataManager) {
super(command);
addCommandExecutor(
new CurrencyGiveCommand(dataManager),
new CurrencyPayCommand(dataManager),
new ReloadCommand(dataManager),
new CurrencySeeCommand(dataManager),
new CurrencySetCommand(dataManager),
new CurrencyTakeCommand(dataManager),
new CurrencyTopCommand(dataManager)
);
if (FileManager.isUseBC()) {
addCommandExecutor(new CurrencyImportCommand((SQLDataManager) dataManager));
}
command.setExecutor(this);
command.setTabCompleter(this);
}
@Override
public boolean isPlayerCommand() {
return false;
}
}

View File

@@ -0,0 +1,22 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class CurrencyGiveCommand extends CurrencyAdminSetCommand {
public CurrencyGiveCommand(IDataManager dataManager) {
super(
dataManager,
"give",
"为玩家货币添加余额",
"currency.give"
);
}
@Override
protected void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), data.getPlayerCurrency(type.getId()) + amount);
}
}

View File

@@ -0,0 +1,52 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.core.SQLDataManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
public class CurrencyImportCommand extends CommandExecutor {
private final SQLDataManager dataManager;
public CurrencyImportCommand(SQLDataManager dataManager) {
super(
"import",
"从其他插件中导入数据",
"currency.import",
Message.notHasPermission.toString(),
new String[]{
"数据库",
"数据表",
"uuid列名",
"name列名",
"money列名",
"货币类型"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 7) {
sender.sendMessage("§a/currency import [数据库] [数据表] [uuid列名] [name列名] [money列名] [货币类型]");
return true;
}
dataManager.importFromOtherPluginData(args[1], args[2], args[3], args[4], args[5], args[6]);
sender.sendMessage("§a已开始从其他插件的数据库存档中导入数据, 详情请查看控制台输出...");
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return null;
}
}

View File

@@ -0,0 +1,141 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import cn.hamster3.service.bukkit.api.ServiceMessageAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.stream.Collectors;
public class CurrencyPayCommand extends CommandExecutor {
private final IDataManager dataManager;
public CurrencyPayCommand(IDataManager dataManager) {
super(
"pay",
"向其他玩家转账",
"currency.pay",
Message.notHasPermission.toString(),
new String[]{
"玩家",
"货币类型",
"数额"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
PlayerData toData = dataManager.getPlayerData(args[1]);
if (toData == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
if (args.length < 3) {
sender.sendMessage(Message.notInputCurrencyType.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(args[2]);
if (type == null) {
sender.sendMessage(Message.currencyTypeNotFound.toString());
return true;
}
if (!type.isCanTransfer()) {
sender.sendMessage(Message.currencyTypeCantTransfer.toString().replace("%type%", type.getId()));
return true;
}
if (args.length < 4) {
sender.sendMessage(Message.notInputPayAmount.toString());
return true;
}
double amount;
try {
amount = Double.parseDouble(args[3]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
if (amount <= 0) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
Player player = (Player) sender;
PlayerData fromData = dataManager.getPlayerData(player.getUniqueId());
if (fromData.getPlayerCurrency(type.getId()) < amount) {
sender.sendMessage(
Message.currencyNotEnough.toString()
.replace("%type%", type.getId())
);
return true;
}
fromData.setPlayerCurrency(type.getId(), fromData.getPlayerCurrency(type.getId()) - amount);
toData.setPlayerCurrency(type.getId(), toData.getPlayerCurrency(type.getId()) + amount);
dataManager.savePlayerData(fromData);
dataManager.savePlayerData(toData);
sender.sendMessage(
Message.paySuccess.toString()
.replace("%player%", toData.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
if (FileManager.isUseBC()) {
ServiceMessageAPI.sendPlayerMessage(
toData.getUuid(),
Message.receivePay.toString()
.replace("%player%", player.getName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
} else {
Player toPlayer = Bukkit.getPlayer(toData.getUuid());
if (toPlayer != null) {
toPlayer.sendMessage(
Message.receivePay.toString()
.replace("%player%", player.getName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
}
}
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 2: {
return HamsterAPI.getOnlinePlayersName(args[1]);
}
case 3: {
List<String> types = dataManager.getCurrencyTypes().stream().map(CurrencyType::getId).collect(Collectors.toList());
types = HamsterAPI.startWithIgnoreCase(types, args[2]);
if (types.size() > 10) {
types = types.subList(0, 9);
}
return types;
}
}
return null;
}
}

View File

@@ -0,0 +1,89 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.stream.Collectors;
public class CurrencySeeCommand extends CommandExecutor {
private final IDataManager dataManager;
public CurrencySeeCommand(IDataManager dataManager) {
super(
"see",
"查看玩家的货币余额",
"currency.see",
Message.notHasPermission.toString(),
new String[]{
"货币类型",
"玩家"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
@SuppressWarnings("DuplicatedCode")
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
sender.sendMessage(Message.notInputCurrencyType.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(args[1]);
if (type == null) {
sender.sendMessage(Message.currencyTypeNotFound.toString());
return true;
}
PlayerData data;
if (args.length < 3) {
if (!(sender instanceof Player)) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
Player player = (Player) sender;
data = dataManager.getPlayerData(player.getUniqueId());
} else {
if (!sender.hasPermission("currency.see.other")) {
sender.sendMessage(Message.notHasPermission.toString());
return true;
}
data = dataManager.getPlayerData(args[2]);
if (data == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
}
sender.sendMessage(
Message.seeCurrency.toString()
.replace("%player%", data.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(type.getId())))
);
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 2) {
List<String> types = dataManager.getCurrencyTypes().stream().map(CurrencyType::getId).collect(Collectors.toList());
return HamsterAPI.startWith(types, args[1]);
}
if (args.length == 3) {
return HamsterAPI.getOnlinePlayersName(args[2]);
}
return null;
}
}

View File

@@ -0,0 +1,22 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class CurrencySetCommand extends CurrencyAdminSetCommand {
public CurrencySetCommand(IDataManager dataManager) {
super(
dataManager,
"set",
"为玩家货币设置余额",
"currency.set"
);
}
@Override
protected void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), amount);
}
}

View File

@@ -0,0 +1,22 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class CurrencyTakeCommand extends CurrencyAdminSetCommand {
public CurrencyTakeCommand(IDataManager dataManager) {
super(
dataManager,
"take",
"为玩家货币扣除余额",
"currency.take"
);
}
@Override
protected void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), data.getPlayerCurrency(type.getId()) - amount);
}
}

View File

@@ -0,0 +1,102 @@
package cn.hamster3.currency.command.currency;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class CurrencyTopCommand extends CommandExecutor {
private final IDataManager dataManager;
public CurrencyTopCommand(IDataManager dataManager) {
super(
"top",
"查看玩家的货币余额排行榜",
"currency.top",
Message.notHasPermission.toString(),
new String[]{
"货币类型",
"页码"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
@SuppressWarnings("DuplicatedCode")
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 2) {
sender.sendMessage(Message.notInputCurrencyType.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(args[1]);
if (type == null) {
sender.sendMessage(Message.currencyTypeNotFound.toString());
return true;
}
int page = 1;
if (args.length >= 3) {
try {
page = Integer.parseInt(args[2]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.pageError.toString());
return true;
}
}
page = page - 1;
String typeId = type.getId();
ArrayList<PlayerData> playerData = dataManager.getPlayerData();
playerData.sort((o1, o2) -> -Double.compare(o1.getPlayerCurrency(typeId), o2.getPlayerCurrency(typeId)));
sender.sendMessage(
Message.topRankPageHead.toString()
.replace("%type%", typeId)
.replace("%page%", String.valueOf(page + 1))
);
for (int i = page * 10; i < (page + 1) * 10; i++) {
if (i >= playerData.size()) {
break;
}
PlayerData data = playerData.get(i);
sender.sendMessage(
Message.topRankPageItem.toString()
.replace("%rank%", String.valueOf(i + 1))
.replace("%name%", data.getPlayerName())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(typeId)))
);
}
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 2) {
List<String> types = dataManager.getPlayerData()
.stream()
.map(PlayerData::getPlayerName)
.collect(Collectors.toList());
types = HamsterAPI.startWithIgnoreCase(types, args[1]);
if (types.size() > 10) {
types = types.subList(0, 9);
}
return types;
}
return null;
}
}

View File

@@ -0,0 +1,86 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandExecutor;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.List;
public abstract class VaultAdminSetCommand extends CommandExecutor {
protected final IDataManager dataManager;
public VaultAdminSetCommand(IDataManager dataManager, String name, String description, String permission) {
super(
name,
description,
permission,
Message.notHasPermission.toString(),
new String[]{
"玩家",
"数额"
}
);
this.dataManager = dataManager;
}
@Override
public boolean isPlayerCommand() {
return false;
}
public abstract void doSet(PlayerData data, CurrencyType type, double amount);
@Override
@SuppressWarnings("DuplicatedCode")
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
CurrencyType type = dataManager.getCurrencyType(FileManager.getVaultCurrencyType());
if (type == null) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
if (args.length < 2) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
PlayerData data = dataManager.getPlayerData(args[1]);
if (data == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
if (args.length < 3) {
sender.sendMessage(Message.notInputAmount.toString());
return true;
}
double amount;
try {
amount = Double.parseDouble(args[2]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
doSet(data, type, amount);
dataManager.savePlayerData(data);
sender.sendMessage(
Message.seeCurrency.toString()
.replace("%player%", data.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(type.getId())))
);
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 2) {
return HamsterAPI.getOnlinePlayersName(args[0]);
}
return null;
}
}

View File

@@ -0,0 +1,24 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.api.command.CommandManager;
import cn.hamster3.currency.core.IDataManager;
import org.bukkit.command.PluginCommand;
public class VaultCommand extends CommandManager {
public VaultCommand(PluginCommand command, IDataManager dataManager) {
super(command);
addCommandExecutor(
new VaultSetCommand(dataManager),
new VaultGiveCommand(dataManager),
new VaultTakeCommand(dataManager)
);
command.setExecutor(this);
command.setTabCompleter(this);
}
@Override
public boolean isPlayerCommand() {
return false;
}
}

View File

@@ -0,0 +1,22 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class VaultGiveCommand extends VaultAdminSetCommand {
public VaultGiveCommand(IDataManager dataManager) {
super(
dataManager,
"give",
"给予玩家金币",
"currency.give"
);
}
@Override
public void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), data.getPlayerCurrency(type.getId()) + amount);
}
}

View File

@@ -0,0 +1,132 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandManager;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import cn.hamster3.service.bukkit.api.ServiceMessageAPI;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import java.util.List;
public class VaultPayCommand extends CommandManager {
private final IDataManager dataManager;
public VaultPayCommand(PluginCommand command, IDataManager dataManager) {
super(command);
this.dataManager = dataManager;
command.setExecutor(this);
command.setTabCompleter(this);
}
@Override
public boolean isPlayerCommand() {
return true;
}
@Override
public boolean checkPermission(CommandSender sender) {
return sender.hasPermission("currency.pay");
}
@Override
@SuppressWarnings("DuplicatedCode")
protected boolean defaultCommand(CommandSender sender, Command command, String label, String[] args) {
if (!FileManager.isVaultHook()) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(FileManager.getVaultCurrencyType());
if (type == null) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
if (!type.isCanTransfer()) {
sender.sendMessage(Message.currencyTypeCantTransfer.toString().replace("%type%", type.getId()));
return true;
}
if (args.length < 1) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
if (args.length < 2) {
sender.sendMessage(Message.notInputPayAmount.toString());
return true;
}
PlayerData toData = dataManager.getPlayerData(args[0]);
if (toData == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
double amount;
try {
amount = Double.parseDouble(args[1]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
if (amount <= 0) {
sender.sendMessage(Message.amountNumberError.toString());
return true;
}
Player player = (Player) sender;
PlayerData fromData = dataManager.getPlayerData(player.getUniqueId());
if (fromData.getPlayerCurrency(type.getId()) < amount) {
sender.sendMessage(
Message.currencyNotEnough.toString()
.replace("%type%", type.getId())
);
return true;
}
fromData.setPlayerCurrency(type.getId(), fromData.getPlayerCurrency(type.getId()) - amount);
toData.setPlayerCurrency(type.getId(), toData.getPlayerCurrency(type.getId()) + amount);
dataManager.savePlayerData(fromData);
dataManager.savePlayerData(toData);
sender.sendMessage(
Message.paySuccess.toString()
.replace("%player%", toData.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
if (FileManager.isUseBC()) {
ServiceMessageAPI.sendPlayerMessage(
toData.getUuid(),
Message.receivePay.toString()
.replace("%player%", player.getName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
} else {
Player toPlayer = Bukkit.getPlayer(toData.getUuid());
if (toPlayer != null) {
toPlayer.sendMessage(
Message.receivePay.toString()
.replace("%player%", player.getName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", amount))
);
}
}
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) {
return HamsterAPI.getOnlinePlayersName(args[0]);
}
return null;
}
}

View File

@@ -0,0 +1,81 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.api.command.CommandManager;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import java.util.List;
public class VaultSeeCommand extends CommandManager {
private final IDataManager dataManager;
public VaultSeeCommand(PluginCommand command, IDataManager dataManager) {
super(command);
this.dataManager = dataManager;
command.setExecutor(this);
command.setTabCompleter(this);
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
@SuppressWarnings("DuplicatedCode")
protected boolean defaultCommand(CommandSender sender, Command command, String label, String[] args) {
if (!FileManager.isVaultHook()) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(FileManager.getVaultCurrencyType());
if (type == null) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
PlayerData data;
if (args.length < 1) {
if (!(sender instanceof Player)) {
sender.sendMessage(Message.notInputPlayerName.toString());
return true;
}
Player player = (Player) sender;
data = dataManager.getPlayerData(player.getUniqueId());
} else {
if (!sender.hasPermission("currency.see.other")) {
sender.sendMessage(Message.notHasPermission.toString());
return true;
}
data = dataManager.getPlayerData(args[0]);
if (data == null) {
sender.sendMessage(Message.playerNotFound.toString());
return true;
}
}
sender.sendMessage(
Message.seeCurrency.toString()
.replace("%player%", data.getPlayerName())
.replace("%type%", type.getId())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(type.getId())))
);
return true;
}
@Override
@SuppressWarnings("DuplicatedCode")
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) {
return HamsterAPI.getOnlinePlayersName(args[0]);
}
return null;
}
}

View File

@@ -0,0 +1,21 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class VaultSetCommand extends VaultAdminSetCommand {
public VaultSetCommand(IDataManager dataManager) {
super(
dataManager,
"set",
"设置玩家的金币",
"currency.set"
);
}
@Override
public void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), amount);
}
}

View File

@@ -0,0 +1,21 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
public class VaultTakeCommand extends VaultAdminSetCommand {
public VaultTakeCommand(IDataManager dataManager) {
super(
dataManager,
"take",
"扣除玩家金币",
"currency.take"
);
}
@Override
public void doSet(PlayerData data, CurrencyType type, double amount) {
data.setPlayerCurrency(type.getId(), data.getPlayerCurrency(type.getId()) - amount);
}
}

View File

@@ -0,0 +1,77 @@
package cn.hamster3.currency.command.vault;
import cn.hamster3.api.command.CommandManager;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import java.util.ArrayList;
public class VaultTopCommand extends CommandManager {
private final IDataManager dataManager;
public VaultTopCommand(PluginCommand command, IDataManager dataManager) {
super(command);
this.dataManager = dataManager;
command.setExecutor(this);
command.setTabCompleter(this);
}
@Override
public boolean isPlayerCommand() {
return false;
}
@Override
@SuppressWarnings("DuplicatedCode")
protected boolean defaultCommand(CommandSender sender, Command command, String label, String[] args) {
if (!FileManager.isVaultHook()) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
CurrencyType type = dataManager.getCurrencyType(FileManager.getVaultCurrencyType());
if (type == null) {
sender.sendMessage(Message.vaultEconomySetError.toString());
return true;
}
int page = 1;
if (args.length >= 1) {
try {
page = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
sender.sendMessage(Message.pageError.toString());
return true;
}
}
page = page - 1;
String typeId = type.getId();
ArrayList<PlayerData> playerData = dataManager.getPlayerData();
playerData.sort((o1, o2) -> -Double.compare(o1.getPlayerCurrency(typeId), o2.getPlayerCurrency(typeId)));
sender.sendMessage(
Message.topRankPageHead.toString()
.replace("%type%", typeId)
.replace("%page%", String.valueOf(page + 1))
);
for (int i = page * 10; i < (page + 1) * 10; i++) {
if (i >= playerData.size()) {
break;
}
PlayerData data = playerData.get(i);
sender.sendMessage(
Message.topRankPageItem.toString()
.replace("%rank%", String.valueOf(i + 1))
.replace("%name%", data.getPlayerName())
.replace("%amount%", String.format("%.2f", data.getPlayerCurrency(typeId)))
);
}
return true;
}
}

View File

@@ -0,0 +1,157 @@
package cn.hamster3.currency.core;
import cn.hamster3.currency.HamsterCurrency;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import static cn.hamster3.currency.HamsterCurrency.getLogUtils;
public class FileDataManager implements IDataManager {
private final HamsterCurrency plugin;
private final HashSet<PlayerData> playerData;
private final HashSet<CurrencyType> currencyTypes;
public FileDataManager(HamsterCurrency plugin) {
this.plugin = plugin;
playerData = new HashSet<>();
currencyTypes = new HashSet<>();
}
@Override
public void onEnable() {
getLogUtils().info("从本地磁盘中读取玩家数据...");
File dataFolder = new File(plugin.getDataFolder(), "PlayerData");
if (dataFolder.mkdirs()) {
getLogUtils().info("创建玩家存档文件夹...");
}
File[] files = dataFolder.listFiles();
if (files != null) {
for (File file : files) {
try {
PlayerData data = new PlayerData(YamlConfiguration.loadConfiguration(file));
playerData.add(data);
} catch (Exception e) {
getLogUtils().error(e, "加载玩家存档文件 %s 时出现了一个异常!", file.getName());
}
}
}
getLogUtils().info("从本地磁盘中读取玩家数据完成!");
}
@Override
public void onDisable() {
File dataFolder = new File(plugin.getDataFolder(), "PlayerData");
for (PlayerData data : playerData) {
File dataFile = new File(dataFolder, data.getUuid().toString() + ".yml");
try {
data.saveToConfig().save(dataFile);
} catch (IOException e) {
getLogUtils().error(e, "保存玩家 %s 的存档至文件时出现了一个异常!", data.getUuid());
}
}
}
@Override
public void loadConfig() {
reloadConfig();
}
@Override
@SuppressWarnings("ConstantConditions")
public void reloadConfig() {
getLogUtils().info("加载配置文件...");
plugin.saveDefaultConfig();
plugin.reloadConfig();
FileConfiguration config = plugin.getConfig();
currencyTypes.clear();
ConfigurationSection currencyTypesConfig = config.getConfigurationSection("currencyTypes");
for (String key : currencyTypesConfig.getKeys(false)) {
try {
currencyTypes.add(new CurrencyType(currencyTypesConfig.getConfigurationSection(key)));
getLogUtils().warning("已加载货币类型: %s", key);
} catch (Exception e) {
getLogUtils().error(e, "加载货币类型 %s 时出现了一个错误: ", key);
}
}
FileManager.setPluginConfig(config);
getLogUtils().info("配置文件加载完成!");
}
@Override
public void loadPlayerData(UUID uuid) {
// 由于服务器启动时已经加载了所有玩家的存档
// 所以当玩家进服时无需再加载
// 只需要给没有存档的新玩家初始化一个存档数据即可
PlayerData data = getPlayerData(uuid);
if (data == null) {
playerData.add(new PlayerData(uuid));
}
}
@Override
public void savePlayerData(PlayerData data) {
// 每一次修改存档都保存至磁盘一次会极大地浪费服务器性能
// 按照插件架构,我们只需要在关服的时候保存所有玩家的存档即可
// 所以这里什么都不做
}
@Override
public PlayerData getPlayerData(UUID uuid) {
synchronized (playerData) {
for (PlayerData data : playerData) {
if (uuid.equals(data.getUuid())) {
return data;
}
}
}
return null;
}
@Override
public PlayerData getPlayerData(String name) {
synchronized (playerData) {
for (PlayerData data : playerData) {
if (name.equalsIgnoreCase(data.getPlayerName())) {
return data;
}
}
}
return null;
}
@Override
public ArrayList<PlayerData> getPlayerData() {
synchronized (playerData) {
return new ArrayList<>(playerData);
}
}
@Override
public CurrencyType getCurrencyType(String id) {
for (CurrencyType type : currencyTypes) {
if (type.getId().equalsIgnoreCase(id)) {
return type;
}
}
return null;
}
@Override
public Set<CurrencyType> getCurrencyTypes() {
return currencyTypes;
}
}

View File

@@ -0,0 +1,61 @@
package cn.hamster3.currency.core;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.currency.HamsterCurrency;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
public abstract class FileManager {
private static boolean useBC;
private static boolean mainServer;
private static boolean vaultHook;
private static String vaultCurrencyType;
private static FileConfiguration pluginConfig;
public static void reload(HamsterCurrency plugin) {
plugin.saveDefaultConfig();
plugin.reloadConfig();
pluginConfig = plugin.getConfig();
useBC = pluginConfig.getBoolean("useBC", false);
mainServer = pluginConfig.getBoolean("datasource.template");
setPluginConfig(pluginConfig);
}
public static FileConfiguration getPluginConfig() {
return pluginConfig;
}
@SuppressWarnings("ConstantConditions")
public static void setPluginConfig(FileConfiguration pluginConfig) {
FileManager.pluginConfig = pluginConfig;
vaultHook = pluginConfig.getBoolean("vault.hook");
vaultCurrencyType = pluginConfig.getString("vault.type");
ConfigurationSection messagesConfig = pluginConfig.getConfigurationSection("messages");
for (String key : messagesConfig.getKeys(false)) {
try {
Message.valueOf(key).setMessage(HamsterAPI.replaceColorCode(messagesConfig.getString(key)));
} catch (IllegalArgumentException e) {
HamsterCurrency.getLogUtils().warning("初始化消息设置 %s 时发生了一个异常: ", key);
e.printStackTrace();
}
}
}
public static boolean isUseBC() {
return useBC;
}
public static boolean isMainServer() {
return mainServer;
}
public static boolean isVaultHook() {
return vaultHook;
}
public static String getVaultCurrencyType() {
return vaultCurrencyType;
}
}

View File

@@ -0,0 +1,54 @@
package cn.hamster3.currency.core;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public interface IDataManager {
/**
* 插件启动时调用
* 此时应该加载全部玩家的数据
*/
void onEnable();
/**
* 插件关闭时调用
* 此时应该保存全部玩家的数据
*/
void onDisable();
void loadConfig();
/**
* 重载服务器
*/
void reloadConfig();
/**
* 加载玩家的数据
*
* @param uuid -
*/
void loadPlayerData(UUID uuid);
/**
* 保存玩家的数据
*
* @param data -
*/
void savePlayerData(PlayerData data);
PlayerData getPlayerData(UUID uuid);
PlayerData getPlayerData(String name);
ArrayList<PlayerData> getPlayerData();
CurrencyType getCurrencyType(String id);
Set<CurrencyType> getCurrencyTypes();
}

View File

@@ -0,0 +1,43 @@
package cn.hamster3.currency.core;
public enum Message {
prefix("§a[仓鼠经济] "),
notHasPermission("§c你没有这个权限!"),
notInputPlayerName("请输入玩家名称!"),
playerNotFound("未找到该玩家!"),
notInputCurrencyType("请输入货币类型!"),
currencyTypeNotFound("未找到该货币类型!"),
notInputAmount("请输入货币额度!"),
notInputPayAmount("请输入转账金额!"),
amountNumberError("货币额度必须是一个数字!"),
playerCurrencySetSuccess("货币设置成功! 玩家 %player% 当前 %type% 余额为: %amount%"),
currencyTypeCantTransfer("%type% 不支持转账!"),
currencyNotEnough("你的 %type% 不足!"),
paySuccess("已将 %amount% %type% 转账至 %player% 账户!"),
receivePay("从 %player% 账户上收到 %amount% %type%."),
seeCurrency("玩家 %player% 当前货币 %type% 余额为: %amount%"),
pageError("页码必须是一个大于0的整数!"),
topRankPageHead("========== %type% 排行榜 第 %page% 页 =========="),
topRankPageItem("%rank%.%name% %amount%"),
currencyNamePlural("金币"),
currencyNameSingular("金币"),
vaultEconomySetError("服务器经济系统发生了一个错误, 请尝试联系服务器管理员汇报问题!");
private String message;
Message(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return prefix.message + message;
}
}

View File

@@ -0,0 +1,316 @@
package cn.hamster3.currency.core;
import cn.hamster3.api.HamsterAPI;
import cn.hamster3.currency.HamsterCurrency;
import cn.hamster3.currency.data.CurrencyType;
import cn.hamster3.currency.data.PlayerData;
import cn.hamster3.service.bukkit.api.ServiceMessageAPI;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
import static cn.hamster3.currency.HamsterCurrency.getLogUtils;
public class SQLDataManager implements IDataManager {
private final JsonParser parser;
private final Connection connection;
private final HamsterCurrency plugin;
private final HashSet<PlayerData> playerData;
private final HashSet<CurrencyType> currencyTypes;
@SuppressWarnings("ConstantConditions")
public SQLDataManager(HamsterCurrency plugin) throws SQLException, ClassNotFoundException {
this.plugin = plugin;
parser = new JsonParser();
playerData = new HashSet<>();
currencyTypes = new HashSet<>();
connection = HamsterAPI.getSQLConnection(FileManager.getPluginConfig().getConfigurationSection("datasource"));
Statement statement = connection.createStatement();
statement.execute("CREATE TABLE IF NOT EXISTS hamster_currency_player_data(" +
"uuid VARCHAR(36) PRIMARY KEY," +
"data TEXT" +
");");
statement.execute("CREATE TABLE IF NOT EXISTS hamster_currency_settings(" +
"title VARCHAR(64) PRIMARY KEY," +
"data TEXT" +
");");
statement.close();
}
public void uploadConfigToSQL() {
getLogUtils().info("重载配置文件...");
FileManager.reload(plugin);
FileConfiguration config = FileManager.getPluginConfig();
getLogUtils().info("配置文件重载完成!");
try {
getLogUtils().info("将配置文件上传至数据库...");
Statement statement = connection.createStatement();
String data = Base64.getEncoder().encodeToString(config.saveToString().getBytes(StandardCharsets.UTF_8));
statement.executeUpdate(String.format(
"REPLACE INTO hamster_currency_settings VALUES('%s', '%s');",
"pluginConfig",
data
));
statement.close();
getLogUtils().info("配置文件上传完成!");
} catch (SQLException e) {
getLogUtils().error(e, "插件上传 pluginConfig 至数据库时遇到了一个异常: ");
}
loadConfig(config);
ServiceMessageAPI.sendMessage("HamsterCurrency", "uploadConfigToSQL");
}
@SuppressWarnings("SwitchStatementWithTooFewBranches")
public void loadConfigFromSQL() {
try {
getLogUtils().info("从数据库中下载配置文件...");
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery("SELECT * FROM hamster_currency_settings;");
while (set.next()) {
String title = set.getString("title");
String data = new String(Base64.getDecoder().decode(set.getString("data")), StandardCharsets.UTF_8);
switch (title) {
case "pluginConfig": {
YamlConfiguration config = new YamlConfiguration();
try {
config.loadFromString(data);
} catch (InvalidConfigurationException e) {
getLogUtils().error(e, "插件加载 %s 时遇到了一个异常: ", title);
}
loadConfig(config);
}
}
}
statement.close();
getLogUtils().info("配置文件下载完成!");
} catch (SQLException e) {
getLogUtils().error(e, "插件从数据库中下载 pluginConfig 时遇到了一个异常: ");
}
}
@SuppressWarnings("ConstantConditions")
private void loadConfig(FileConfiguration config) {
getLogUtils().info("加载配置文件...");
currencyTypes.clear();
ConfigurationSection currencyTypesConfig = config.getConfigurationSection("currencyTypes");
for (String key : currencyTypesConfig.getKeys(false)) {
try {
currencyTypes.add(new CurrencyType(currencyTypesConfig.getConfigurationSection(key)));
getLogUtils().warning("已加载货币类型: %s", key);
} catch (Exception e) {
getLogUtils().error(e, "加载货币类型 %s 时出现了一个错误: ", key);
}
}
FileManager.setPluginConfig(config);
getLogUtils().info("配置文件加载完成!");
}
public void importFromOtherPluginData(String database, String table, String uuidCol, String nameCol, String moneyCol, String currencyType) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
getLogUtils().info("开始从其他插件的数据库存档中导入数据: ");
getLogUtils().info("数据库名: %s", database);
getLogUtils().info("数据表名: %s", table);
getLogUtils().info("玩家uuid列名: %s", uuidCol);
getLogUtils().info("玩家名称列名: %s", nameCol);
getLogUtils().info("玩家经济列名: %s", moneyCol);
getLogUtils().info("导入至经济类型: %s", currencyType);
try {
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(String.format("SELECT * FROM %s.%s;", database, table));
synchronized (playerData) {
while (set.next()) {
try {
UUID uuid = UUID.fromString(set.getString(uuidCol));
String name = set.getString(nameCol);
double money = set.getDouble(moneyCol);
PlayerData data = getPlayerData(uuid);
if (data == null) {
data = new PlayerData(uuid, name);
playerData.add(data);
}
data.setPlayerCurrency(currencyType, money);
getLogUtils().info("已从其他插件中加载了玩家 %s 的存档数据.", data.getUuid());
} catch (Exception e) {
getLogUtils().error(e, "导入某一条数据时发生了一个错误: ");
}
}
}
for (PlayerData data : playerData) {
statement.executeUpdate(String.format(
"REPLACE INTO hamster_currency_player_data VALUES('%s', '%s');",
data.getUuid().toString(),
data.saveToJson().toString()
));
getLogUtils().info("已保存玩家 %s 的存档数据.", data.getUuid());
ServiceMessageAPI.sendMessage("HamsterCurrency", "savedPlayerData", data.getUuid().toString());
}
statement.close();
} catch (SQLException e) {
getLogUtils().error(e, "从其他插件中导入数据时发生了一个异常:");
}
});
}
@Override
public void onEnable() {
getLogUtils().info("从数据库中读取玩家数据...");
try {
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery("SELECT * FROM hamster_currency_player_data;");
synchronized (playerData) {
while (set.next()) {
String uuid = set.getString("uuid");
String string = set.getString("data");
try {
PlayerData data = new PlayerData(parser.parse(string).getAsJsonObject());
playerData.add(data);
} catch (Exception e) {
getLogUtils().error(e, "从数据库中读取玩家 %s 的存档( %s )时出现了一个异常: ", uuid, string);
}
}
}
set.close();
statement.close();
} catch (SQLException e) {
getLogUtils().error(e, "从数据库中读取玩家数据时出现了一个异常:");
}
getLogUtils().info("从数据库中读取玩家数据完成!");
}
@Override
public void onDisable() {
// 因为SQL模式使用HamsterService前置
// 服务器之间数据实时同步
// 所以关服时无需保存任何数据
}
@Override
public void loadConfig() {
if (FileManager.isMainServer()) {
uploadConfigToSQL();
} else {
loadConfigFromSQL();
}
}
@Override
public void reloadConfig() {
ServiceMessageAPI.sendMessage("HamsterCurrency", "reload");
}
@Override
public void loadPlayerData(UUID uuid) {
try {
Statement statement = connection.createStatement();
ResultSet set = statement.executeQuery(String.format(
"SELECT * FROM hamster_currency_player_data WHERE uuid='%s';",
uuid
));
PlayerData data;
if (set.next()) {
String string = set.getString("data");
try {
data = new PlayerData(parser.parse(string).getAsJsonObject());
} catch (Exception e) {
getLogUtils().error(e, "从数据库中读取玩家 %s 的存档( %s )时出现了一个异常: ", uuid, string);
statement.close();
return;
}
} else {
data = new PlayerData(uuid);
getLogUtils().info("初始化玩家 %s 的存档数据.", data.getUuid());
}
synchronized (playerData) {
playerData.remove(data);
playerData.add(data);
}
set.close();
statement.close();
getLogUtils().info("已加载玩家 %s 的存档数据.", data.getUuid());
} catch (SQLException e) {
getLogUtils().error(e, "加载玩家 %s 的存档数据时出错!", uuid);
}
}
@Override
public void savePlayerData(PlayerData data) {
Bukkit.getScheduler().runTaskAsynchronously(plugin,
() -> {
try {
Statement statement = connection.createStatement();
statement.executeUpdate(String.format(
"REPLACE INTO hamster_currency_player_data VALUES('%s', '%s');",
data.getUuid().toString(),
data.saveToJson().toString()
));
statement.close();
} catch (SQLException e) {
getLogUtils().error(e, "保存玩家 %s 的存档数据时出错!", data.getUuid());
}
getLogUtils().info("已保存玩家 %s 的存档数据.", data.getUuid());
ServiceMessageAPI.sendMessage(
"HamsterCurrency",
"savedPlayerData",
data.getUuid().toString()
);
});
}
@Override
public PlayerData getPlayerData(UUID uuid) {
synchronized (playerData) {
for (PlayerData data : playerData) {
if (uuid.equals(data.getUuid())) {
return data;
}
}
}
return null;
}
@Override
public PlayerData getPlayerData(String name) {
synchronized (playerData) {
for (PlayerData data : playerData) {
if (name.equalsIgnoreCase(data.getPlayerName())) {
return data;
}
}
}
return null;
}
@Override
public ArrayList<PlayerData> getPlayerData() {
synchronized (playerData) {
return new ArrayList<>(playerData);
}
}
@Override
public CurrencyType getCurrencyType(String id) {
for (CurrencyType type : currencyTypes) {
if (type.getId().equalsIgnoreCase(id)) {
return type;
}
}
return null;
}
@Override
public Set<CurrencyType> getCurrencyTypes() {
return currencyTypes;
}
}

View File

@@ -0,0 +1,46 @@
package cn.hamster3.currency.data;
import org.bukkit.configuration.ConfigurationSection;
/**
* 货币类型
*/
public class CurrencyType {
/**
* 货币识别符
*/
private final String id;
/**
* 是否允许转账
*/
private final boolean canTransfer;
public CurrencyType(ConfigurationSection config) {
id = config.getName();
canTransfer = config.getBoolean("canTransfer");
}
public String getId() {
return id;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isCanTransfer() {
return canTransfer;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CurrencyType that = (CurrencyType) o;
return id.equalsIgnoreCase(that.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}

View File

@@ -0,0 +1,118 @@
package cn.hamster3.currency.data;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerData {
private final UUID uuid;
private final String playerName;
private final HashMap<String, Double> playerCurrencies;
public PlayerData(UUID uuid) {
this.uuid = uuid;
playerName = Bukkit.getOfflinePlayer(uuid).getName();
playerCurrencies = new HashMap<>();
}
public PlayerData(UUID uuid, String playerName) {
this.uuid = uuid;
this.playerName = playerName;
playerCurrencies = new HashMap<>();
}
public PlayerData(JsonObject object) {
uuid = UUID.fromString(object.get("uuid").getAsString());
OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
if (player.getName() != null) {
playerName = player.getName();
} else if (object.has("playerName") && !object.get("playerName").isJsonNull()) {
playerName = object.get("playerName").getAsString();
} else {
playerName = null;
}
playerCurrencies = new HashMap<>();
JsonObject playerCurrenciesJson = object.getAsJsonObject("playerCurrencies");
for (Map.Entry<String, JsonElement> entry : playerCurrenciesJson.entrySet()) {
playerCurrencies.put(entry.getKey(), entry.getValue().getAsDouble());
}
}
@SuppressWarnings("ConstantConditions")
public PlayerData(ConfigurationSection config) {
uuid = UUID.fromString(config.getString("uuid"));
OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
if (player.getName() != null) {
playerName = player.getName();
} else {
playerName = config.getString("playerName");
}
playerCurrencies = new HashMap<>();
ConfigurationSection playerCurrenciesConfig = config.getConfigurationSection("playerCurrencies");
for (String key : playerCurrenciesConfig.getKeys(false)) {
playerCurrencies.put(key, playerCurrenciesConfig.getDouble(key));
}
}
public JsonObject saveToJson() {
JsonObject object = new JsonObject();
object.addProperty("uuid", uuid.toString());
object.addProperty("playerName", playerName);
JsonObject playerCurrenciesJson = new JsonObject();
for (Map.Entry<String, Double> entry : playerCurrencies.entrySet()) {
playerCurrenciesJson.addProperty(entry.getKey(), entry.getValue());
}
object.add("playerCurrencies", playerCurrenciesJson);
return object;
}
public YamlConfiguration saveToConfig() {
YamlConfiguration config = new YamlConfiguration();
config.set("uuid", uuid.toString());
config.set("playerName", playerName);
YamlConfiguration playerCurrenciesConfig = new YamlConfiguration();
for (Map.Entry<String, Double> entry : playerCurrencies.entrySet()) {
playerCurrenciesConfig.set(entry.getKey(), entry.getValue());
}
config.set("playerCurrencies", playerCurrenciesConfig);
return config;
}
public UUID getUuid() {
return uuid;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerCurrency(String type, double amount) {
playerCurrencies.put(type, amount);
}
public double getPlayerCurrency(String type) {
return playerCurrencies.getOrDefault(type, 0D);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PlayerData that = (PlayerData) o;
return uuid.equals(that.uuid);
}
@Override
public int hashCode() {
return uuid.hashCode();
}
}

View File

@@ -0,0 +1,45 @@
package cn.hamster3.currency.hook;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.data.PlayerData;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class PlaceholderHook extends PlaceholderExpansion {
private final IDataManager dataManager;
public PlaceholderHook(IDataManager dataManager) {
this.dataManager = dataManager;
}
@Override
@NotNull
public String getIdentifier() {
return "Currency";
}
@Override
@NotNull
public String getAuthor() {
return "Hamster3";
}
@Override
@NotNull
public String getVersion() {
return "1.0";
}
@Override
public String onRequest(OfflinePlayer player, @NotNull String params) {
PlayerData data = dataManager.getPlayerData(player.getUniqueId());
return String.format("%.2f", data.getPlayerCurrency(params));
}
@Override
public String onPlaceholderRequest(Player player, @NotNull String params) {
return onRequest(player, params);
}
}

View File

@@ -0,0 +1,247 @@
package cn.hamster3.currency.hook;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.IDataManager;
import cn.hamster3.currency.core.Message;
import cn.hamster3.currency.data.PlayerData;
import net.milkbowl.vault.economy.AbstractEconomy;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.OfflinePlayer;
import java.util.ArrayList;
import java.util.List;
public class VaultEconomyHook extends AbstractEconomy {
private static final EconomyResponse NOT_IMPLEMENTED_RESPONSE =
new EconomyResponse(
0,
0,
EconomyResponse.ResponseType.NOT_IMPLEMENTED,
"HamsterCurrency未实现该功能~"
);
private final IDataManager dataManager;
public VaultEconomyHook(IDataManager dataManager) {
this.dataManager = dataManager;
}
protected EconomyResponse depositPlayer(PlayerData data, double amount) {
if (data == null) {
return new EconomyResponse(amount, 0, EconomyResponse.ResponseType.FAILURE, "玩家账户不存在");
}
String type = FileManager.getVaultCurrencyType();
if (data.getPlayerCurrency(type) > 0 && data.getPlayerCurrency(type) + amount < 0) {
return new EconomyResponse(amount, 0, EconomyResponse.ResponseType.FAILURE, "玩家金额超出上限");
}
data.setPlayerCurrency(type, data.getPlayerCurrency(type) + amount);
dataManager.savePlayerData(data);
return new EconomyResponse(amount, data.getPlayerCurrency(type), EconomyResponse.ResponseType.SUCCESS, "");
}
protected EconomyResponse withdrawPlayer(PlayerData data, double amount) {
if (data == null) {
return new EconomyResponse(amount, 0, EconomyResponse.ResponseType.FAILURE, "玩家账户不存在");
}
String type = FileManager.getVaultCurrencyType();
if (data.getPlayerCurrency(type) < amount) {
return new EconomyResponse(amount, data.getPlayerCurrency(type), EconomyResponse.ResponseType.FAILURE, "余额不足");
}
data.setPlayerCurrency(type, data.getPlayerCurrency(type) - amount);
dataManager.savePlayerData(data);
return new EconomyResponse(amount, data.getPlayerCurrency(type), EconomyResponse.ResponseType.SUCCESS, "扣款成功");
}
private boolean has(PlayerData data, double amount) {
if (data == null) {
return false;
}
return data.getPlayerCurrency(FileManager.getVaultCurrencyType()) >= amount;
}
private double getBalance(PlayerData data) {
if (data == null) {
return 0;
}
return data.getPlayerCurrency(FileManager.getVaultCurrencyType());
}
@Override
public boolean isEnabled() {
return FileManager.isVaultHook();
}
@Override
public String getName() {
return "HamsterCurrency";
}
@Override
public int fractionalDigits() {
return 2;
}
@Override
public String format(double amount) {
return String.format("%.2f", amount);
}
@Override
public String currencyNamePlural() {
return Message.currencyNamePlural.getMessage();
}
@Override
public String currencyNameSingular() {
return Message.currencyNameSingular.getMessage();
}
@Override
public double getBalance(String playerName) {
return getBalance(dataManager.getPlayerData(playerName));
}
@Override
public double getBalance(OfflinePlayer player) {
return getBalance(dataManager.getPlayerData(player.getUniqueId()));
}
@Override
public double getBalance(String playerName, String world) {
return getBalance(dataManager.getPlayerData(playerName));
}
@Override
public double getBalance(OfflinePlayer player, String world) {
return getBalance(dataManager.getPlayerData(player.getUniqueId()));
}
@Override
public boolean has(String playerName, double amount) {
return has(dataManager.getPlayerData(playerName), amount);
}
@Override
public boolean has(OfflinePlayer player, double amount) {
return has(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public boolean has(String playerName, String worldName, double amount) {
return has(dataManager.getPlayerData(playerName), amount);
}
@Override
public boolean has(OfflinePlayer player, String worldName, double amount) {
return has(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public EconomyResponse withdrawPlayer(String playerName, double amount) {
return withdrawPlayer(dataManager.getPlayerData(playerName), amount);
}
@Override
public EconomyResponse withdrawPlayer(OfflinePlayer player, double amount) {
return withdrawPlayer(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public EconomyResponse withdrawPlayer(String playerName, String worldName, double amount) {
return withdrawPlayer(dataManager.getPlayerData(playerName), amount);
}
@Override
public EconomyResponse withdrawPlayer(OfflinePlayer player, String worldName, double amount) {
return withdrawPlayer(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public EconomyResponse depositPlayer(String playerName, double amount) {
return depositPlayer(dataManager.getPlayerData(playerName), amount);
}
@Override
public EconomyResponse depositPlayer(OfflinePlayer player, double amount) {
return depositPlayer(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public EconomyResponse depositPlayer(String playerName, String worldName, double amount) {
return depositPlayer(dataManager.getPlayerData(playerName), amount);
}
@Override
public EconomyResponse depositPlayer(OfflinePlayer player, String worldName, double amount) {
return depositPlayer(dataManager.getPlayerData(player.getUniqueId()), amount);
}
@Override
public boolean hasBankSupport() {
return false;
}
@Override
public boolean hasAccount(String playerName) {
return true;
}
@Override
public boolean hasAccount(String playerName, String worldName) {
return true;
}
@Override
public EconomyResponse createBank(String name, String player) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse deleteBank(String name) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse bankBalance(String name) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse bankHas(String name, double amount) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse bankWithdraw(String name, double amount) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse bankDeposit(String name, double amount) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse isBankOwner(String name, String playerName) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public EconomyResponse isBankMember(String name, String playerName) {
return NOT_IMPLEMENTED_RESPONSE;
}
@Override
public List<String> getBanks() {
return new ArrayList<>();
}
@Override
public boolean createPlayerAccount(String playerName) {
return true;
}
@Override
public boolean createPlayerAccount(String playerName, String worldName) {
return true;
}
}

View File

@@ -0,0 +1,23 @@
package cn.hamster3.currency.listener;
import cn.hamster3.currency.HamsterCurrency;
import cn.hamster3.currency.core.IDataManager;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class CurrencyListener implements Listener {
protected final HamsterCurrency plugin;
protected final IDataManager dataManager;
public CurrencyListener(HamsterCurrency plugin, IDataManager dataManager) {
this.plugin = plugin;
this.dataManager = dataManager;
}
@EventHandler(ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent event) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> dataManager.loadPlayerData(event.getPlayer().getUniqueId()));
}
}

View File

@@ -0,0 +1,55 @@
package cn.hamster3.currency.listener;
import cn.hamster3.currency.HamsterCurrency;
import cn.hamster3.currency.core.FileManager;
import cn.hamster3.currency.core.SQLDataManager;
import cn.hamster3.service.bukkit.api.ServiceInfoAPI;
import cn.hamster3.service.bukkit.event.MessageReceivedEvent;
import cn.hamster3.service.common.entity.ServiceMessageInfo;
import org.bukkit.event.EventHandler;
import java.util.UUID;
/**
* 跨服模式时使用这个监听器
*/
public class SQLListener extends CurrencyListener {
public SQLListener(HamsterCurrency plugin, SQLDataManager dataManager) {
super(plugin, dataManager);
}
@EventHandler(ignoreCancelled = true)
public void onServiceReceive(MessageReceivedEvent event) {
ServiceMessageInfo info = event.getMessageInfo();
if (!"HamsterCurrency".equals(info.getTag())) {
return;
}
SQLDataManager dataManager = (SQLDataManager) super.dataManager;
switch (info.getAction()) {
case "reload": {
if (!FileManager.isMainServer()) {
return;
}
HamsterCurrency.getLogUtils().info("收到重载指令,开始重载服务器...");
dataManager.uploadConfigToSQL();
break;
}
case "uploadConfigToSQL": {
if (ServiceInfoAPI.getLocalSenderInfo().equals(info.getSenderInfo())) {
return;
}
HamsterCurrency.getLogUtils().info("主服务器已上传 pluginConfig, 准备从数据库中下载配置并重载插件...");
dataManager.loadConfigFromSQL();
break;
}
case "savedPlayerData": {
if (ServiceInfoAPI.getLocalSenderInfo().equals(info.getSenderInfo())) {
return;
}
UUID uuid = UUID.fromString(info.getContentAsString());
dataManager.loadPlayerData(uuid);
break;
}
}
}
}

View File

@@ -0,0 +1,60 @@
# 是否开启跨服模式
# 若false则使用本地文件存储模式
# 若true则需要HamsterService前置
useBC: true
# 若开启跨服模式则需要配置datasource
datasource:
driver: "com.mysql.jdbc.Driver"
url: "jdbc:mysql://test3.hamster3.cn:3306?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false"
user: Test
password: Test123..
database: Test
# 是否将这个服务器的配置文件设为模板
# 若设为trueconfig将会在服务器启动时自动上传至数据库
# 其他template为false的服务器将会在启动和重载时自动从数据库上下载config
# 可以节省一些config配置时的麻烦事情
# 但是请先保证template为true的服务器完全启动了再启动子服
# 如果觉得这样反而更麻烦也可以直接把所有服务器的template设为true
# 这样每个服务器都会使用自己本地的config文件了
template: true
currencyTypes:
# 货币ID
"金币":
# 是否允许转账
canTransfer: true
"一周年活动代币":
canTransfer: false
"比特币":
canTransfer: true
# 开启这个选项前请先确保服务器安装了Vault前置
vault:
# 是否挂接 Vault 经济系统
hook: true
# 使用哪一个货币来支持Vault的经济系统
type: "金币"
messages:
prefix: "§a[仓鼠经济] "
notHasPermission: "§c你没有这个权限!"
notInputPlayerName: "请输入玩家名称!"
playerNotFound: "未找到该玩家!"
notInputCurrencyType: "请输入货币类型!"
currencyTypeNotFound: "未找到该货币类型!"
notInputAmount: "请输入货币额度!"
notInputPayAmount: "请输入转账金额!"
amountNumberError: "货币额度必须是一个数字!"
playerCurrencySetSuccess: "货币设置成功! 玩家 %player% 当前 %type% 余额为: %amount%"
currencyTypeCantTransfer: "%type% 不支持转账!"
currencyNotEnough: "你的 %type% 不足!"
paySuccess: "已将 %amount% %type% 转账至 %player% 账户!"
receivePay: "从 %player% 账户上收到 %amount% %type%."
seeCurrency: "玩家 %player% 当前货币 %type% 余额为: %amount%"
pageError: "页码必须是一个大于0的整数!"
topRankPageHead: "========== %type% 排行榜 第 %page% 页 =========="
topRankPageItem: "%rank%.%name% %amount%"
currencyNamePlural: "金币"
currencyNameSingular: "金币"
vaultEconomySetError: "服务器经济系统发生了一个错误, 请尝试联系服务器管理员汇报问题!"

View File

@@ -0,0 +1,46 @@
name: HamsterCurrency
version: ${version}
main: cn.hamster3.currency.HamsterCurrency
authors: [ Hamster3 ]
description: 仓鼠的多货币支持
website: https://www.hamster3.cn/
load: STARTUP
api-version: "1.16"
depend:
- HamsterAPI
softdepend:
- HasmterService-Bukkit
- PlaceholderAPI
- PlayerPoints
- Vault
commands:
HamsterCurrency:
aliases: [ hcurrency, currency ]
balance:
aliases: [ bal, seemoney ]
balanceTop:
aliases: [ baltop ]
payMoney:
aliases: [ pay ]
economy:
aliases: [ eco, money ]
permissions:
currency.import:
default: op
currency.give:
default: op
currency.take:
default: op
currency.set:
default: op
currency.look:
default: true
currency.look.other:
default: op
currency.top:
default: op