mirror of
https://github.com/MiniDay/HamsterCurrency-Parent.git
synced 2025-08-22 12:15:31 +08:00
Initial commit
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/.gradle
|
||||||
|
/.idea
|
||||||
|
/build
|
||||||
|
*/build
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 叁只仓鼠
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
63
README.MD
Normal file
63
README.MD
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# HamsterCurrency
|
||||||
|
|
||||||
|
[](https://jitpack.io/#cn.hamster3/HamsterCurrency)
|
||||||
|
仓鼠的多货币经济插件
|
||||||
|
|
||||||
|
# 依赖前置
|
||||||
|
|
||||||
|
- [HamsterAPI](https://github.com/MiniDay/HamsterAPI/releases)
|
||||||
|
- [HamsterService](https://github.com/MiniDay/HamsterService/releases) (仅跨服模式需要)
|
||||||
|
- [Vault](https://www.spigotmc.org/resources/vault.34315/) (仅开启Vault经济系统时需要)
|
||||||
|
- [PlaceholderAPI](https://www.spigotmc.org/resources/placeholderapi.6245/) (非必须)
|
||||||
|
|
||||||
|
# 开发者
|
||||||
|
|
||||||
|
## 依赖导入
|
||||||
|
|
||||||
|
### Maven
|
||||||
|
|
||||||
|
添加仓库:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
```
|
||||||
|
|
||||||
|
添加导入:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hamster3</groupId>
|
||||||
|
<artifactId>HamsterCurrency</artifactId>
|
||||||
|
<version>2.0.6-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gradle
|
||||||
|
|
||||||
|
添加仓库:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
添加导入:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
dependencies {
|
||||||
|
implementation 'cn.hamster3:HamsterCurrency:1.3.7-SNAPSHOT'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
请参考[CurrencyAPI](/currency-plugin/src/main/java/cn/hamster3/currency/api/CurrencyAPI.java)
|
||||||
|
|
0
build.gradle
Normal file
0
build.gradle
Normal file
42
currency-plugin/build.gradle
Normal file
42
currency-plugin/build.gradle
Normal 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)
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
@@ -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()));
|
||||||
|
}
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
currency-plugin/src/main/resources/config.yml
Normal file
60
currency-plugin/src/main/resources/config.yml
Normal 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
|
||||||
|
# 是否将这个服务器的配置文件设为模板
|
||||||
|
# 若设为true,config将会在服务器启动时自动上传至数据库
|
||||||
|
# 其他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: "服务器经济系统发生了一个错误, 请尝试联系服务器管理员汇报问题!"
|
46
currency-plugin/src/main/resources/plugin.yml
Normal file
46
currency-plugin/src/main/resources/plugin.yml
Normal 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
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
gradlew
vendored
Normal file
185
gradlew
vendored
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MSYS* | MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
4
settings.gradle
Normal file
4
settings.gradle
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
rootProject.name = 'HamsterCurrency-Parent'
|
||||||
|
include 'currency-plugin'
|
||||||
|
include 'transform-essentials'
|
||||||
|
|
3
transform-essentials/README.md
Normal file
3
transform-essentials/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
essentials 转换插件
|
||||||
|
|
||||||
|
放入服务端根目录的**上一级目录**,然后使用控制台启动即可
|
48
transform-essentials/build.gradle
Normal file
48
transform-essentials/build.gradle
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'cn.hamster3'
|
||||||
|
version '1.0.0-SNAPSHOT'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = "https://maven.airgame.net/repository/maven-public/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
|
||||||
|
implementationShade
|
||||||
|
implementation.extendsFrom implementationShade
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// https://mvnrepository.com/artifact/com.electronwill.night-config/core
|
||||||
|
implementationShade group: 'com.electronwill.night-config', name: 'core', version: '3.6.4'
|
||||||
|
// https://mvnrepository.com/artifact/com.electronwill.night-config/yaml
|
||||||
|
implementationShade group: 'com.electronwill.night-config', name: 'yaml', version: '3.6.4'
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||||
|
implementationShade group: 'com.google.code.gson', name: 'gson', version: '2.8.8'
|
||||||
|
// https://mvnrepository.com/artifact/mysql/mysql-connector-java
|
||||||
|
implementationShade group: 'mysql', name: 'mysql-connector-java', version: '8.0.26'
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
archivesBaseName = "HamsterCurrency-Transform-Essentials"
|
||||||
|
manifest.attributes('Main-Class': 'cn.hamster3.transform.essentials.Main')
|
||||||
|
from([
|
||||||
|
configurations.implementationShade.collect {
|
||||||
|
it.isDirectory() ? it : zipTree(it)
|
||||||
|
},
|
||||||
|
rootProject.file("LICENSE")
|
||||||
|
])
|
||||||
|
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||||
|
destinationDir(rootProject.buildDir)
|
||||||
|
}
|
@@ -0,0 +1,159 @@
|
|||||||
|
package cn.hamster3.transform.essentials;
|
||||||
|
|
||||||
|
import cn.hamster3.transform.essentials.data.PlayerData;
|
||||||
|
import com.electronwill.nightconfig.core.Config;
|
||||||
|
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
|
||||||
|
import com.electronwill.nightconfig.yaml.YamlFormat;
|
||||||
|
import com.electronwill.nightconfig.yaml.YamlParser;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
private static final YamlParser parser = new YamlParser(YamlFormat.defaultInstance());
|
||||||
|
private static final HashSet<PlayerData> playerData = new HashSet<>();
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
System.out.println("请输入数据库主机名: ");
|
||||||
|
String host = scanner.nextLine();
|
||||||
|
System.out.println("请输入数据库端口号: ");
|
||||||
|
String port = scanner.nextLine();
|
||||||
|
System.out.println("请输入数据库用户名: ");
|
||||||
|
String user = scanner.nextLine();
|
||||||
|
System.out.println("请输入数据库密码: ");
|
||||||
|
String password = scanner.nextLine();
|
||||||
|
System.out.println("请输入数据库库名: ");
|
||||||
|
String database = scanner.nextLine();
|
||||||
|
|
||||||
|
File file = new File(System.getProperty("user.dir"));
|
||||||
|
File[] files = file.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (File subFile : files) {
|
||||||
|
System.out.println("开始扫描文件夹: " + subFile.getAbsolutePath());
|
||||||
|
if (!subFile.isDirectory()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scanServer(subFile);
|
||||||
|
System.out.println("文件夹扫描完成: " + subFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
System.out.println("加载 MySQL 数据库驱动...");
|
||||||
|
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||||
|
System.out.println("建立 MySQL 数据库连接...");
|
||||||
|
|
||||||
|
Connection connection = DriverManager.getConnection(
|
||||||
|
"jdbc:mysql://" + host + ":" + port + "?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false",
|
||||||
|
user,
|
||||||
|
password
|
||||||
|
);
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
System.out.println("切换至数据库...");
|
||||||
|
statement.execute(String.format("CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARACTER SET ='UTF8';", database));
|
||||||
|
statement.execute(String.format("USE %s;", database));
|
||||||
|
System.out.println("检查数据表...");
|
||||||
|
statement.execute("CREATE TABLE IF NOT EXISTS hamster_currency_player_data(" +
|
||||||
|
"uuid VARCHAR(36) PRIMARY KEY," +
|
||||||
|
"data TEXT" +
|
||||||
|
");");
|
||||||
|
System.out.println("开始更新数据库...");
|
||||||
|
for (PlayerData data : playerData) {
|
||||||
|
String sql = String.format(
|
||||||
|
"REPLACE INTO hamster_currency_player_data VALUES('%s', '%s');",
|
||||||
|
data.getUuid().toString(),
|
||||||
|
data.saveToJson().toString().replace("'", "\\'")
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
statement.executeUpdate(sql);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("执行 sql " + sql + " 时遇到了一个异常:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statement.close();
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void scanServer(File folder) {
|
||||||
|
if (!folder.isDirectory()) {
|
||||||
|
System.out.println(folder.getAbsolutePath() + " 不是一个文件夹. 跳过扫描.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File pluginFolder = new File(folder, "plugins");
|
||||||
|
if (!pluginFolder.isDirectory()) {
|
||||||
|
System.out.println(pluginFolder.getAbsolutePath() + " 不是一个文件夹. 跳过扫描.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File essentialFolder = new File(pluginFolder, "Essentials");
|
||||||
|
if (!essentialFolder.isDirectory()) {
|
||||||
|
System.out.println(essentialFolder.getAbsolutePath() + " 不是一个文件夹. 跳过扫描.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File userdataFolder = new File(essentialFolder, "userdata");
|
||||||
|
if (!userdataFolder.isDirectory()) {
|
||||||
|
System.out.println(userdataFolder.getAbsolutePath() + " 不是一个文件夹. 跳过扫描.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File[] files = userdataFolder.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
File file = files[i];
|
||||||
|
try {
|
||||||
|
scanUserData(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("读取文件 " + file.getAbsolutePath() + " 时出现了一个异常:");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
System.out.println("已完成: (" + i + "/" + files.length + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void scanUserData(File file) {
|
||||||
|
UUID uuid = UUID.fromString(file.getName().substring(0, 36));
|
||||||
|
Config config = parser.parse(file, FileNotFoundAction.THROW_ERROR, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
if (config.contains("npc")) {
|
||||||
|
boolean isNPC = config.get("npc");
|
||||||
|
if (isNPC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!config.contains("lastAccountName")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!config.contains("money")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String lastAccountName = config.get("lastAccountName");
|
||||||
|
double money = Double.parseDouble(config.get("money"));
|
||||||
|
PlayerData data = getPlayerData(uuid, lastAccountName);
|
||||||
|
if (data.getPlayerCurrency("金币") >= money) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data.setPlayerCurrency("金币", money);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PlayerData getPlayerData(UUID uuid, String name) {
|
||||||
|
for (PlayerData data : playerData) {
|
||||||
|
if (data.getUuid().equals(uuid)) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlayerData data = new PlayerData(uuid, name);
|
||||||
|
playerData.add(data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
package cn.hamster3.transform.essentials.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 货币类型
|
||||||
|
*/
|
||||||
|
public class CurrencyType {
|
||||||
|
/**
|
||||||
|
* 货币识别符
|
||||||
|
*/
|
||||||
|
private final String id;
|
||||||
|
/**
|
||||||
|
* 是否允许转账
|
||||||
|
*/
|
||||||
|
private final boolean canTransfer;
|
||||||
|
|
||||||
|
public CurrencyType(String id, boolean canTransfer) {
|
||||||
|
this.id = id;
|
||||||
|
this.canTransfer = 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,63 @@
|
|||||||
|
package cn.hamster3.transform.essentials.data;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
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, String playerName) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.playerName = playerName;
|
||||||
|
playerCurrencies = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 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();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user