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