commit c99f186a20c5671af575ac37036769c2b170e5f2
Author: YuTian <2953516620@qq.com>
Date: Tue Aug 5 12:53:01 2025 +0800
更新了多个配置文件和主要类文件,包括 `.gitignore`、`AttributeUtil.java`、`AuMaster.java`、`AuMaster.yml`、`Config.java`、`config.yml`、`gui.yml`、`GuiConfig.java`、`InviteData.java`、`InviteManager.java`、`MasterCommand.java`、`MasterGui.java`、`PlayerData.java`、`PlayerListener.java`、`PlayerManager.java`、`plugin.yml`、`pom.xml`、`RewardGui.java` 和 `RewardUtil.java` 的修改。
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43a63ab
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/.idea/
+/AuMaster.iml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ba82e2a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,116 @@
+
+
+ 4.0.0
+
+ com.io.yutian
+ AuMaster
+ 1.0-SNAPSHOT
+ jar
+
+ AuMaster
+
+
+ 1.8
+ UTF-8
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ ${java.version}
+ ${java.version}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ public-rpg
+ https://repo.aurora-pixels.com/repository/public-rpg/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.12.2
+
+
+ me.Demon.DemonPlugin
+ DemonAPI
+ 2.2.9
+
+
+ me.clip.placeholderapi
+ PlaceholderAPI
+ 2.9.2
+
+
+ com.io.yaohun.itemlibrary
+ AuItemStackLibrary
+ 1.5.2
+
+
+ me.Demon.DemonCoins
+ DemonCoins
+ 2.0.5
+
+
+ me.Demon.DemonBanK
+ DemonBanK
+ 1.4.1
+
+
+ me.Demon.DemonLevels
+ DemonLevels
+ 2.2.2
+
+
+ com.yaohun.onlinereward
+ AuOnlineReward
+ 1.3.2
+
+
+ org.serverct.ersha.jd
+ AttributePlus
+ 2.3.7
+
+
+ com.yaohun.aurechargedata
+ AuRechargeData
+ 2.0.3
+
+
+ com.io.yutian.rainlib
+ RainLib
+ 1.0.5
+
+
+
diff --git a/src/main/java/com/io/yutian/aumaster/AuMaster.java b/src/main/java/com/io/yutian/aumaster/AuMaster.java
new file mode 100644
index 0000000..3fb2314
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/AuMaster.java
@@ -0,0 +1,47 @@
+package com.io.yutian.aumaster;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.config.GuiConfig;
+import com.io.yutian.aumaster.listener.PlayerListener;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.aumaster.util.AttributeUtil;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public final class AuMaster extends JavaPlugin {
+
+ private static AuMaster instance;
+
+ @Override
+ public void onEnable() {
+ instance = this;
+
+ MasterCommand masterCommand = new MasterCommand();
+ Bukkit.getPluginCommand("aumaster").setExecutor(masterCommand);
+ Bukkit.getPluginCommand("aumaster").setTabCompleter(masterCommand);
+
+ Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
+
+ Config.reload();
+ GuiConfig.reload();
+
+ Bukkit.getScheduler().runTaskTimer(this, ()-> {
+ PlayerManager.checkAllPlayer();
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ AttributeUtil.checkPlayer(player1);
+ }
+ }, 0L, 600L);
+
+ }
+
+ @Override
+ public void onDisable() {
+ PlayerManager.saveAll();
+ }
+
+ public static AuMaster inst() {
+ return instance;
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/MasterCommand.java b/src/main/java/com/io/yutian/aumaster/MasterCommand.java
new file mode 100644
index 0000000..dc5ca70
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/MasterCommand.java
@@ -0,0 +1,241 @@
+package com.io.yutian.aumaster;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.config.GuiConfig;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.gui.MasterGui;
+import com.io.yutian.aumaster.gui.RewardGui;
+import com.io.yutian.aumaster.manager.InviteManager;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.aumaster.util.AttributeUtil;
+import com.io.yutian.rainlib.util.StringUtil;
+import me.Demon.DemonLevels.api.DLevelAPI;
+import me.Demon.DemonPlugin.DemonAPI;
+import me.Demon.DemonPlugin.data.LangData;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class MasterCommand implements CommandExecutor, TabCompleter {
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ LangData lang = Config.getLangData();
+
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("§cOnly players can use this command.");
+ return true;
+ }
+
+ Player player = (Player) sender;
+ PlayerData data = PlayerManager.getPlayerData(player.getName());
+
+ if (args.length == 0) {
+ sender.sendMessage("§e======= §6"+lang.getMessage("Command-Help-Title")+" §e=======");
+ player.sendMessage("§2/" + label + " invite <玩家> §f- §a邀请对方成为徒弟");
+ player.sendMessage("§2/" + label + " accept §f- §a接受拜师邀请");
+ player.sendMessage("§2/" + label + " deny §f- §a拒绝拜师邀请");
+ player.sendMessage("§2/" + label + " jiechu §f- §a徒弟主动解除关系");
+ player.sendMessage("§2/" + label + " list §f- §a查看徒弟列表");
+ player.sendMessage("§2/" + label + " leveltop §f- §a查看徒弟等级排行");
+ player.sendMessage("§2/" + label + " reward §f- §a领取奖励");
+ player.sendMessage("§2/" + label + " remove <玩家> §f- §a解除某个徒弟");
+ player.sendMessage("§2/" + label + " cancel <玩家> §f- §a取消拜师邀请");
+ if (player.isOp()) {
+ player.sendMessage("§2/" + label + " reload §f- §a重载配置文件");
+ }
+ sender.sendMessage("§e======= §6"+lang.getMessage("Command-Help-Title")+" §e=======");
+ return true;
+ }
+
+ String sub = args[0].toLowerCase();
+
+ if (sub.equals("invite")) {
+ if (args.length < 2) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Command-Usage-Invite"), label));
+ return true;
+ }
+ int mePlayerLevel = DLevelAPI.getPlayerLevel(player);
+ if (mePlayerLevel < Config.getMentorMinLevel()) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Target-Master-MinLevel"), Config.getMentorMinLevel()));
+ return true;
+ }
+ if (player.getFirstPlayed() + 1000L * 60 * 60 * 24 * Config.getMentorMinJoinDays() > System.currentTimeMillis()) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Target-Master-MinJoinDays"), Config.getMentorMinJoinDays()));
+ return true;
+ }
+ PlayerData playerData = PlayerManager.getPlayerData(player.getName());
+ if (playerData.getDiscipleNames().size() >= Config.getMentorMaxDisciples()) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Target-Master-MaxDisciples"), Config.getMentorMaxDisciples()));
+ return true;
+ }
+ Player target = Bukkit.getPlayerExact(args[1]);
+ if (target == null || target == player) {
+ player.sendMessage(lang.getMessage("Invite-Target-Invalid"));
+ return true;
+ }
+ PlayerData playerData1 = PlayerManager.getPlayerData(target.getName());
+ if (playerData1.hasMentor()) {
+ player.sendMessage(lang.getMessage("Invite-Target-HasMentor"));
+ return true;
+ }
+ int playerLevel = DLevelAPI.getPlayerLevel(target);
+ if (playerLevel > Config.getDiscipleMaxLevel()) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Target-MaxLevel"), target.getName(), Config.getDiscipleMaxLevel()));
+ return true;
+ }
+ if (target.getFirstPlayed() + 1000L * 60 * 60 * 24 * Config.getDiscipleMaxJoinDays() < System.currentTimeMillis()) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Target-Newbie"), target.getName(), Config.getDiscipleMaxJoinDays()));
+ return true;
+ }
+ InviteManager.sendInvite(player, target);
+ return true;
+ } else if (sub.equals("accept")) {
+ InviteManager.acceptInvite(player);
+ return true;
+ } else if (sub.equals("deny")) {
+ InviteManager.denyInvite(player);
+ return true;
+
+ } else if (sub.equals("jiechu")) {
+ if (!data.isDisciple()) {
+ player.sendMessage(lang.getMessage("Mentor-NotFound"));
+ return true;
+ }
+
+ String mentorName = data.getMentorName();
+ PlayerData mentorData = PlayerManager.getPlayerData(mentorName);
+
+ data.setMentorName(null);
+ data.setBindStartTime(0L);
+ data.save();
+
+ if (mentorData != null) {
+ mentorData.removeDiscipleName(player.getName());
+ mentorData.save();
+
+ Player mentorPlayer = Bukkit.getPlayerExact(mentorName);
+ if (mentorPlayer != null && mentorPlayer.isOnline()) {
+ mentorPlayer.sendMessage(StringUtil.formatIndexed(lang.getMessage("Disciple-Removed"), player.getName()));
+ }
+ }
+
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Unbind-Success"), mentorName));
+ return true;
+ }
+ else if (sub.equals("list")) {
+ if (!data.isMentor()) {
+ player.sendMessage(lang.getMessage("Disciple-NotFound"));
+ return true;
+ }
+ new MasterGui(player).open();
+ return true;
+
+ } else if (sub.equals("leveltop")) {
+ List sorted = data.getDiscipleNames().stream()
+ .sorted(Comparator.comparingDouble(n -> -DLevelAPI.getOffPlayer_Level(n)))
+ .collect(Collectors.toList());
+ player.sendMessage(lang.getMessage("Disciple-LevelTop-Header"));
+ int i = 1;
+ for (String name : sorted) {
+ int level = (int) DLevelAPI.getOffPlayer_Level(name);
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Disciple-LevelTop-Entry"), i++, name, level));
+ }
+ return true;
+ } else if (sub.equals("reward")) {
+ new RewardGui(player).open();
+ return true;
+
+ } else if (sub.equals("remove")) {
+ if (args.length < 2) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Command-Usage-Remove"), label));
+ return true;
+ }
+
+ String discipleName = args[1];
+ if (!data.getDiscipleNames().contains(discipleName)) {
+ player.sendMessage(lang.getMessage("Disciple-NotFound-ByName"));
+ return true;
+ }
+
+ if (Bukkit.getPlayerExact(discipleName) != null) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Remove-Fail-Online"), discipleName));
+ return true;
+ }
+
+ OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(discipleName);
+ long lastSeen = offlinePlayer.getLastPlayed();
+ long offlineMillis = System.currentTimeMillis() - lastSeen;
+ long requiredMillis = 72L * 60 * 60 * 1000;
+
+ if (offlineMillis < requiredMillis) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Remove-Fail-NotOfflineLongEnough"), offlinePlayer.getName()));
+ return true;
+ }
+
+ PlayerData discipleData = PlayerManager.getPlayerData(discipleName);
+ data.removeDiscipleName(discipleName);
+ discipleData.setMentorName(null);
+ discipleData.setBindStartTime(0L);
+ discipleData.setLastUnbindTime(System.currentTimeMillis());
+
+ data.save();
+ discipleData.save();
+
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Disciple-Removed"), discipleName));
+ return true;
+ } else if (sub.equals("cancel")) {
+ if (args.length < 2) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Command-Usage-Cancel"), label));
+ return true;
+ }
+ InviteManager.cancelInvite(player, args[1]);
+ return true;
+
+ } else if (sub.equals("reload")) {
+ Config.reload();
+ GuiConfig.reload();
+
+ for (Player player1 : Bukkit.getOnlinePlayers()) {
+ AttributeUtil.checkPlayer(player1);
+ }
+
+ DemonAPI.sendMessage(sender, "§a配置文件已重载。");
+ return true;
+ }
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Command-Unknown"), label));
+ return true;
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player) || !sender.isOp()) return Collections.emptyList();
+
+ if (args.length == 1) {
+ return Arrays.asList("invite", "accept", "deny", "jiechu", "list", "leveltop", "reward", "remove", "cancel").stream()
+ .filter(s -> s.startsWith(args[0].toLowerCase()))
+ .collect(Collectors.toList());
+ }
+
+ String sub = args[0].toLowerCase();
+ if (args.length == 2) {
+ if (sub.equals("invite") || sub.equals("remove") || sub.equals("cancel")) {
+ return Bukkit.getOnlinePlayers().stream()
+ .map(Player::getName)
+ .filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase()))
+ .collect(Collectors.toList());
+ }
+ }
+
+ return Collections.emptyList();
+ }
+}
diff --git a/src/main/java/com/io/yutian/aumaster/config/Config.java b/src/main/java/com/io/yutian/aumaster/config/Config.java
new file mode 100644
index 0000000..f7b180d
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/config/Config.java
@@ -0,0 +1,159 @@
+package com.io.yutian.aumaster.config;
+
+import com.io.yutian.aumaster.AuMaster;
+import me.Demon.DemonPlugin.DemonAPI;
+import me.Demon.DemonPlugin.data.LangData;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Config {
+
+ private static LangData langData;
+
+ /** 徒弟允许的最大等级(≤) */
+ private static int discipleMaxLevel = 70;
+ /** 徒弟最大入服天数(≤),单位:天 */
+ private static int discipleMaxJoinDays = 5;
+ /** 徒弟解除关系后再次拜师的冷却时间,单位:天 */
+ private static int discipleCooldownDays = 7;
+
+ /** 师傅最低等级要求(≥) */
+ private static int mentorMinLevel = 100;
+ /** 师傅注册时间要求(≥),单位:天 */
+ private static int mentorMinJoinDays = 60;
+ /** 每位师傅最大徒弟数量 */
+ private static int mentorMaxDisciples = 27;
+ /** 离线时间超过此数值(小时)才可被师傅解除 */
+ private static int mentorCanRemoveAfterOfflineHours = 72;
+
+ /** 徒弟入服超过此天数自动解除关系 */
+ private static int relationshipAutoRemoveDays = 30;
+
+ /** 徒弟每日在线时长达标的奖励触发时间(单位:秒) */
+ private static int dailyOnlineRewardSeconds = 7200;
+ /** 每日在线达标后给予师傅的积分奖励 */
+ private static int dailyOnlineRewardPoints = 15;
+ /** 徒弟单笔充值门槛(元) */
+ private static double chargeThreshold = 30.0;
+ /** 徒弟充值分成比例(如0.05即5%) */
+ private static double chargeBonusPercent = 0.05;
+
+ private static int levelTargetReward = 80;
+
+ /** 徒弟达到指定等级数量时,奖励给师傅的指令列表,如 "3:give %player% key" */
+ private static Map> levelTargetRewards = new HashMap<>();
+
+ /** 徒弟拜师成功后经验加成比例(如0.2表示20%加成) */
+ private static double joinExpBoost = 0.2;
+
+ private static String expAttributeLore = "经验加成: {0}%";
+
+ public static void reload() {
+
+ langData = DemonAPI.getLangData(AuMaster.inst().getName());
+
+ AuMaster.inst().saveDefaultConfig();
+ AuMaster.inst().reloadConfig();
+ FileConfiguration config = AuMaster.inst().getConfig();
+
+ discipleMaxLevel = config.getInt("disciple.max-level", 70);
+ discipleMaxJoinDays = config.getInt("disciple.max-join-days", 5);
+ discipleCooldownDays = config.getInt("disciple.cooldown-days", 7);
+
+ mentorMinLevel = config.getInt("mentor.min-level", 100);
+ mentorMinJoinDays = config.getInt("mentor.min-join-days", 60);
+ mentorMaxDisciples = config.getInt("mentor.max-disciples", 27);
+ mentorCanRemoveAfterOfflineHours = config.getInt("mentor.remove-after-offline-hours", 72);
+
+ relationshipAutoRemoveDays = config.getInt("relationship.auto-remove-days", 30);
+
+ dailyOnlineRewardSeconds = config.getInt("rewards.daily-online-seconds", 7200);
+ dailyOnlineRewardPoints = config.getInt("rewards.daily-points", 15);
+ chargeThreshold = config.getDouble("rewards.charge-threshold", 30.0);
+ chargeBonusPercent = config.getDouble("rewards.charge-bonus-percent", 0.05);
+
+ levelTargetReward = config.getInt("rewards.level-target", 80);
+ ConfigurationSection rewardsSection = config.getConfigurationSection("rewards.level-target-rewards");
+ if (rewardsSection != null) {
+ for (String key : rewardsSection.getKeys(false)) {
+ int level = Integer.parseInt(key);
+ levelTargetRewards.put(level, rewardsSection.getStringList(key));
+ }
+ }
+
+ joinExpBoost = config.getDouble("rewards.join-exp-boost", 0.2);
+ expAttributeLore = config.getString("rewards.exp-attribute-lore", "经验加成: {0}%");
+ }
+
+ public static LangData getLangData() {
+ return langData;
+ }
+
+ public static int getDiscipleMaxLevel() {
+ return discipleMaxLevel;
+ }
+
+ public static int getDiscipleMaxJoinDays() {
+ return discipleMaxJoinDays;
+ }
+
+ public static int getDiscipleCooldownDays() {
+ return discipleCooldownDays;
+ }
+
+ public static int getMentorMinLevel() {
+ return mentorMinLevel;
+ }
+
+ public static int getMentorMinJoinDays() {
+ return mentorMinJoinDays;
+ }
+
+ public static int getMentorMaxDisciples() {
+ return mentorMaxDisciples;
+ }
+
+ public static int getMentorCanRemoveAfterOfflineHours() {
+ return mentorCanRemoveAfterOfflineHours;
+ }
+
+ public static int getRelationshipAutoRemoveDays() {
+ return relationshipAutoRemoveDays;
+ }
+
+ public static int getDailyOnlineRewardSeconds() {
+ return dailyOnlineRewardSeconds;
+ }
+
+ public static int getDailyOnlineRewardPoints() {
+ return dailyOnlineRewardPoints;
+ }
+
+ public static double getChargeThreshold() {
+ return chargeThreshold;
+ }
+
+ public static double getChargeBonusPercent() {
+ return chargeBonusPercent;
+ }
+
+ public static int getLevelTargetReward() {
+ return levelTargetReward;
+ }
+
+ public static Map> getLevelTargetRewards() {
+ return levelTargetRewards;
+ }
+
+ public static double getJoinExpBoost() {
+ return joinExpBoost;
+ }
+
+ public static String getExpAttributeLore() {
+ return expAttributeLore;
+ }
+}
diff --git a/src/main/java/com/io/yutian/aumaster/config/GuiConfig.java b/src/main/java/com/io/yutian/aumaster/config/GuiConfig.java
new file mode 100644
index 0000000..9a35d2a
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/config/GuiConfig.java
@@ -0,0 +1,116 @@
+package com.io.yutian.aumaster.config;
+
+import com.io.yutian.aumaster.AuMaster;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.util.List;
+
+public class GuiConfig {
+
+ private static String buttonName1;
+ private static String buttonName2;
+ private static String buttonName3;
+ private static String buttonName4;
+ private static String buttonName5;
+ private static String rewardButtonName1;
+ private static String rewardButtonName2;
+ private static String rewardButtonName3;
+ private static List buttonLores1;
+ private static List buttonLores2;
+ private static List buttonLores3;
+ private static List buttonLores4;
+ private static List buttonLores5;
+ private static List rewardButtonLores1;
+ private static List rewardButtonLores2;
+ private static List rewardButtonLores3;
+
+ public static void reload() {
+ File file = new File(AuMaster.inst().getDataFolder(), "gui.yml");
+ if (!file.exists()) {
+ AuMaster.inst().saveResource("gui.yml", false);
+ }
+ FileConfiguration configuration = YamlConfiguration.loadConfiguration(file);
+ buttonName1 = configuration.getString("button1.name");
+ buttonName2 = configuration.getString("button2.name");
+ buttonName3 = configuration.getString("button3.name");
+ buttonName4 = configuration.getString("button4.name");
+ buttonName5 = configuration.getString("button5.name");
+ rewardButtonName1 = configuration.getString("reward-button1.name");
+ rewardButtonName2 = configuration.getString("reward-button2.name");
+ rewardButtonName3 = configuration.getString("reward-button3.name");
+ buttonLores1 = configuration.getStringList("button1.lores");
+ buttonLores2 = configuration.getStringList("button2.lores");
+ buttonLores3 = configuration.getStringList("button3.lores");
+ buttonLores4 = configuration.getStringList("button4.lores");
+ buttonLores5 = configuration.getStringList("button5.lores");
+ rewardButtonLores1 = configuration.getStringList("reward-button1.lores");
+ rewardButtonLores2 = configuration.getStringList("reward-button2.lores");
+ rewardButtonLores3 = configuration.getStringList("reward-button3.lores");
+ }
+
+ public static String getButtonName1() {
+ return buttonName1;
+ }
+
+ public static String getButtonName2() {
+ return buttonName2;
+ }
+
+ public static String getButtonName3() {
+ return buttonName3;
+ }
+
+ public static String getButtonName4() {
+ return buttonName4;
+ }
+
+ public static String getButtonName5() {
+ return buttonName5;
+ }
+
+ public static String getRewardButtonName1() {
+ return rewardButtonName1;
+ }
+
+ public static String getRewardButtonName2() {
+ return rewardButtonName2;
+ }
+
+ public static String getRewardButtonName3() {
+ return rewardButtonName3;
+ }
+
+ public static List getButtonLores1() {
+ return buttonLores1;
+ }
+
+ public static List getButtonLores2() {
+ return buttonLores2;
+ }
+
+ public static List getButtonLores3() {
+ return buttonLores3;
+ }
+
+ public static List getButtonLores4() {
+ return buttonLores4;
+ }
+
+ public static List getButtonLores5() {
+ return buttonLores5;
+ }
+
+ public static List getRewardButtonLores1() {
+ return rewardButtonLores1;
+ }
+
+ public static List getRewardButtonLores2() {
+ return rewardButtonLores2;
+ }
+
+ public static List getRewardButtonLores3() {
+ return rewardButtonLores3;
+ }
+}
diff --git a/src/main/java/com/io/yutian/aumaster/data/InviteData.java b/src/main/java/com/io/yutian/aumaster/data/InviteData.java
new file mode 100644
index 0000000..5cbe4f9
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/data/InviteData.java
@@ -0,0 +1,20 @@
+package com.io.yutian.aumaster.data;
+
+public class InviteData {
+
+ private String mentorName;
+ private long timestamp;
+
+ public InviteData(String mentorName, long timestamp) {
+ this.mentorName = mentorName;
+ this.timestamp = timestamp;
+ }
+
+ public String getMentorName() {
+ return mentorName;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+}
diff --git a/src/main/java/com/io/yutian/aumaster/data/PlayerData.java b/src/main/java/com/io/yutian/aumaster/data/PlayerData.java
new file mode 100644
index 0000000..763d725
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/data/PlayerData.java
@@ -0,0 +1,345 @@
+package com.io.yutian.aumaster.data;
+
+import com.io.yutian.aumaster.AuMaster;
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.aumaster.util.AttributeUtil;
+import com.io.yutian.aumaster.util.RewardUtil;
+import com.io.yutian.rainlib.util.StringUtil;
+import com.io.yutian.rainlib.util.TimeUtil;
+import com.yaohun.onlinereward.AuOnlineReward;
+import com.yaohun.onlinereward.api.OnlineAPI;
+import me.Demon.DemonBanK.BankAPI;
+import me.Demon.DemonLevels.api.DLevelAPI;
+import me.Demon.DemonPlugin.DemonAPI;
+import org.bukkit.Bukkit;
+import org.bukkit.Sound;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PlayerData {
+
+ private final String name;
+ private final File file;
+ private final FileConfiguration configuration;
+
+ private String mentorName;
+ private long bindStartTime;
+
+ private int activePoints;
+
+ private List discipleNames = new ArrayList<>();
+ private List discipleNamesHistory = new ArrayList<>();
+
+ private long lastUnbindTime = 0;
+ private int disciplesReachedTargetLevel;
+
+ private List receivedLevelRewards = new ArrayList<>();
+
+ private List onlineRewardDiscipleNames = new ArrayList<>();
+ private long rewardUpdateTime;
+ private long activePointsUpdateTime;
+
+ public PlayerData(String name) {
+ this.name = name;
+ File path = new File(AuMaster.inst().getDataFolder(), "PlayerData");
+ if (!path.exists()) {
+ path.mkdirs();
+ }
+ this.file = new File(path, name + ".yml");
+ if (!file.exists()) {
+ try {
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ this.configuration = YamlConfiguration.loadConfiguration(file);
+ load();
+ check();
+ }
+
+ public void check() {
+ boolean changed = false;
+ if (rewardUpdateTime == 0) {
+ rewardUpdateTime = System.currentTimeMillis();
+ changed = true;
+ }
+ if (activePointsUpdateTime == 0) {
+ activePointsUpdateTime = System.currentTimeMillis();
+ changed = true;
+ }
+ if (shouldAutoUnbind()) {
+ String oldMentor = this.mentorName;
+ unbind();
+ Player disciple = Bukkit.getPlayerExact(this.name);
+ Player mentor = Bukkit.getPlayerExact(oldMentor);
+ int relationshipAutoRemoveDays = Config.getRelationshipAutoRemoveDays();
+ if (disciple != null && disciple.isOnline()) {
+ disciple.sendMessage(StringUtil.formatIndexed(Config.getLangData().getMessage("AutoUnbind-Disciple-Message"), oldMentor, relationshipAutoRemoveDays));
+ }
+ if (mentor != null && mentor.isOnline()) {
+ mentor.sendMessage(StringUtil.formatIndexed(Config.getLangData().getMessage("AutoUnbind-Mentor-Message"), this.name, relationshipAutoRemoveDays));
+ }
+ changed = true;
+ }
+ if (isDisciple()) {
+ Player player = Bukkit.getPlayerExact(this.name);
+ if (player!= null && player.isOnline()) {
+ AttributeUtil.addAttribute(player);
+ }
+ }
+ if (isMentor()) {
+ if (!TimeUtil.isSameDay(rewardUpdateTime, System.currentTimeMillis())) {
+ onlineRewardDiscipleNames.clear();
+ }
+ for (String discipleName : discipleNames) {
+ if (!discipleNamesHistory.contains(discipleName)) {
+ double playerLevel = DLevelAPI.getOffPlayer_Level(discipleName);
+ if (playerLevel >= Config.getLevelTargetReward()) {
+ discipleNamesHistory.add(discipleName);
+ disciplesReachedTargetLevel++;
+ changed = true;
+ }
+ }
+ if (!onlineRewardDiscipleNames.contains(discipleName)) {
+ com.yaohun.onlinereward.data.PlayerData playerData = AuOnlineReward.getDataManager().getPlayerData(discipleName);
+ int onlineTime = playerData.todayOnline;
+ if (onlineTime >= Config.getDailyOnlineRewardSeconds()) {
+ onlineRewardDiscipleNames.add(discipleName);
+ addActivePoints(Config.getDailyOnlineRewardPoints());
+ Player player = Bukkit.getPlayerExact(name);
+ if (player != null && player.isOnline()) {
+ DemonAPI.sendMessage(player, StringUtil.formatIndexed(Config.getLangData().getMessage("ActivePoint-OnlineTime-Got"), discipleName, Config.getDailyOnlineRewardPoints()));
+ }
+ rewardUpdateTime = System.currentTimeMillis();
+ changed = true;
+ }
+ }
+ }
+ if (!TimeUtil.isSameMonth(activePointsUpdateTime, System.currentTimeMillis())) {
+ Player player = Bukkit.getPlayerExact(name);
+ if (player != null && player.isOnline()) {
+ int coins = Math.round(activePoints / 10.0f);
+ BankAPI.addCoins(name, coins);
+ player.sendMessage(StringUtil.formatIndexed(Config.getLangData().getMessage("Reward-ActivePoints-Got"), coins));
+ player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
+ activePointsUpdateTime = System.currentTimeMillis();
+ activePoints = 0;
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ save();
+ }
+ }
+
+ public void unbind() {
+ if (!hasMentor()) {
+ return;
+ }
+
+ String oldMentor = this.mentorName;
+ this.mentorName = null;
+ this.bindStartTime = 0;
+ this.lastUnbindTime = System.currentTimeMillis();
+ this.save();
+
+ PlayerData mentorData = PlayerManager.getPlayerData(oldMentor);
+ mentorData.removeDiscipleName(this.name);
+ mentorData.save();
+ }
+
+ public boolean shouldAutoUnbind() {
+ return hasMentor() && bindStartTime > 0 &&
+ (bindStartTime + 1000L * 60 * 60 * 24 * Config.getRelationshipAutoRemoveDays() <= System.currentTimeMillis());
+ }
+
+ public void receiveReward(Integer level) {
+ if (receivedLevelRewards.contains(level)) {
+ return;
+ }
+ RewardUtil.runReward(level, name);
+ receivedLevelRewards.add(level);
+ save();
+ }
+
+ public boolean canReceiveReward(int amount) {
+ if (receivedLevelRewards.contains(amount)) {
+ return false;
+ }
+ return disciplesReachedTargetLevel >= amount;
+ }
+
+ public boolean isDisciple() {
+ return mentorName != null;
+ }
+
+ public boolean isMentor() {
+ return !discipleNames.isEmpty();
+ }
+
+ public boolean hasMentor() {
+ return mentorName != null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getMentorName() {
+ return mentorName;
+ }
+
+ public void setMentorName(String mentorName) {
+ this.mentorName = mentorName;
+ }
+
+ public long getBindStartTime() {
+ return bindStartTime;
+ }
+
+ public void setBindStartTime(long bindStartTime) {
+ this.bindStartTime = bindStartTime;
+ }
+
+ public List getDiscipleNames() {
+ return discipleNames;
+ }
+
+ public void addDiscipleName(String discipleName) {
+ discipleNames.add(discipleName);
+ }
+
+ public void removeDiscipleName(String discipleName) {
+ discipleNames.remove(discipleName);
+ }
+
+ public void setDiscipleNames(List discipleNames) {
+ this.discipleNames = discipleNames;
+ }
+
+ public void addDiscipleNameHistory(String discipleName) {
+ discipleNamesHistory.add(discipleName);
+ }
+
+ public void removeDiscipleNameHistory(String discipleName) {
+ discipleNamesHistory.remove(discipleName);
+ }
+
+ public void setDiscipleNamesHistory(List discipleNamesHistory) {
+ this.discipleNamesHistory = discipleNamesHistory;
+ }
+
+ public int getDisciplesReachedTargetLevel() {
+ return disciplesReachedTargetLevel;
+ }
+
+ public void setDisciplesReachedTargetLevel(int disciplesReachedTargetLevel) {
+ this.disciplesReachedTargetLevel = disciplesReachedTargetLevel;
+ }
+
+ public List getDiscipleNamesHistory() {
+ return discipleNamesHistory;
+ }
+
+ public int getActivePoints() {
+ return activePoints;
+ }
+
+ public void addActivePoints(int points) {
+ this.activePoints += points;
+ }
+
+ public void takeActivePoints(int points) {
+ this.activePoints -= points;
+ }
+
+ public void setActivePoints(int activePoints) {
+ this.activePoints = activePoints;
+ }
+
+ public long getLastUnbindTime() {
+ return lastUnbindTime;
+ }
+
+ public void setLastUnbindTime(long lastUnbindTime) {
+ this.lastUnbindTime = lastUnbindTime;
+ }
+
+ public List getReceivedLevelRewards() {
+ return receivedLevelRewards;
+ }
+
+ public void setReceivedLevelRewards(List receivedLevelRewards) {
+ this.receivedLevelRewards = receivedLevelRewards;
+ }
+
+ public List getOnlineRewardDiscipleNames() {
+ return onlineRewardDiscipleNames;
+ }
+
+ public void setOnlineRewardDiscipleNames(List onlineRewardDiscipleNames) {
+ this.onlineRewardDiscipleNames = onlineRewardDiscipleNames;
+ }
+
+ public long getRewardUpdateTime() {
+ return rewardUpdateTime;
+ }
+
+ public void setRewardUpdateTime(long rewardUpdateTime) {
+ this.rewardUpdateTime = rewardUpdateTime;
+ }
+
+ public long getActivePointsUpdateTime() {
+ return activePointsUpdateTime;
+ }
+
+ public void setActivePointsUpdateTime(long activePointsUpdateTime) {
+ this.activePointsUpdateTime = activePointsUpdateTime;
+ }
+
+ public void load() {
+ this.mentorName = configuration.getString("mentorName", null);
+ this.bindStartTime = configuration.getLong("bindStartTime", 0);
+
+ this.discipleNames = new ArrayList<>();
+ this.discipleNamesHistory = new ArrayList<>();
+ this.lastUnbindTime = configuration.getLong("lastUnbindTime", 0);
+ this.discipleNames = configuration.getStringList("discipleNames");
+ this.discipleNamesHistory = configuration.getStringList("discipleNamesHistory");
+ this.disciplesReachedTargetLevel = configuration.getInt("disciplesReachedTargetLevel", 0);
+ this.activePoints = configuration.getInt("activePoints", 0);
+ this.receivedLevelRewards = configuration.getIntegerList("receivedLevelRewards");
+ this.onlineRewardDiscipleNames = configuration.getStringList("onlineRewardDiscipleNames");
+ this.rewardUpdateTime = configuration.getLong("rewardUpdateTime", 0);
+ this.activePointsUpdateTime = configuration.getLong("activePointsUpdateTime", 0);
+ }
+
+ public void save() {
+ configuration.set("mentorName", this.mentorName);
+ configuration.set("bindStartTime", this.bindStartTime);
+ configuration.set("discipleNames", this.discipleNames);
+ configuration.set("discipleNamesHistory", this.discipleNamesHistory);
+ configuration.set("disciplesReachedTargetLevel", this.disciplesReachedTargetLevel);
+ configuration.set("activePoints", activePoints);
+ configuration.set("lastUnbindTime", this.lastUnbindTime);
+ configuration.set("receivedLevelRewards", receivedLevelRewards);
+ configuration.set("onlineRewardDiscipleNames", onlineRewardDiscipleNames);
+ configuration.set("rewardUpdateTime", rewardUpdateTime);
+ configuration.set("activePointsUpdateTime", activePointsUpdateTime);
+ try {
+ configuration.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/gui/MasterGui.java b/src/main/java/com/io/yutian/aumaster/gui/MasterGui.java
new file mode 100644
index 0000000..8baffcb
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/gui/MasterGui.java
@@ -0,0 +1,80 @@
+package com.io.yutian.aumaster.gui;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.config.GuiConfig;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.rainlib.gui.Gui;
+import com.io.yutian.rainlib.gui.button.Button;
+import com.io.yutian.rainlib.util.ItemStackBuilder;
+import com.yaohun.onlinereward.AuOnlineReward;
+import com.yaohun.onlinereward.api.OnlineAPI;
+import me.Demon.DemonLevels.api.DLevelAPI;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MasterGui extends Gui {
+
+ public MasterGui(Player player) {
+ super(player, Config.getLangData().getMessage("Gui-Title"), 54);
+ init();
+ initButton();
+ }
+
+ @Override
+ public void init() {
+ Button button0 = new Button(new ItemStackBuilder(Material.STAINED_GLASS_PANE).setData((short) 2).setDisplayName(" ").build()).noSound();
+ Button button1 = new Button(new ItemStackBuilder(Material.STAINED_GLASS_PANE).setDisplayName(" ").build()).noSound();
+ Button button2 = new Button(new ItemStackBuilder(Material.STAINED_GLASS_PANE).setData((short) 1).setDisplayName(" ").build()).noSound();
+ Button button3 = new Button(new ItemStackBuilder(Material.STAINED_GLASS_PANE).setData((short) 5).setDisplayName(" ").build()).noSound();
+ Button button4 = new Button(new ItemStackBuilder(Material.STAINED_GLASS_PANE).setData((short) 15).setDisplayName(GuiConfig.getButtonName4()).build()).noSound();
+
+ Button button5 = new Button(new ItemStackBuilder(Material.BOOK).setDisplayName(GuiConfig.getButtonName1()).setLore(GuiConfig.getButtonLores1()).build()).noSound();
+ Button button6 = new Button(new ItemStackBuilder(Material.TOTEM).setDisplayName(GuiConfig.getButtonName2()).setLore(GuiConfig.getButtonLores2()).build()).click((player1, clickType) -> {
+ new RewardGui(player1).open();
+ });
+ PlayerData playerData = PlayerManager.getPlayerData(player.getName());
+ List lores1 = new ArrayList<>();
+ for (String s : GuiConfig.getButtonLores3()) {
+ lores1.add(s.replace("{points}", String.valueOf(playerData.getActivePoints())));
+ }
+ Button button7 = new Button(new ItemStackBuilder(Material.WATCH).setDisplayName(GuiConfig.getButtonName3()).setLore(lores1).build()).noSound();
+
+ addButton(0, button0);
+ addButton(1, button0);
+ addButton(2, button5);
+ addButton(3, button2);
+ addButton(4, button6);
+ addButton(5, button2);
+ addButton(6, button7);
+ addButton(7, button3);
+ addButton(8, button3);
+ for (int i = 9; i < 18; i++) {
+ addButton(i, button4);
+ }
+ int i = 0;
+ for (String name : playerData.getDiscipleNames()) {
+ addButton(18 + i, buildButton(name));
+ }
+ }
+
+ private Button buildButton(String name) {
+ PlayerData playerData = PlayerManager.getPlayerData(name);
+ double level = DLevelAPI.getOffPlayer_Level(name);
+ com.yaohun.onlinereward.data.PlayerData playerData1 = AuOnlineReward.getDataManager().getPlayerData(name);
+ int time = playerData1.todayOnline;
+ List lores1 = new ArrayList<>();
+ for (String s : GuiConfig.getButtonLores5()) {
+ lores1.add(s.replace("{level}", String.valueOf(level)).replace("{time_online}", String.valueOf(time)));
+ }
+ ItemStackBuilder itemStackBuilder = new ItemStackBuilder(Material.SKULL_ITEM)
+ .setData((short) 3)
+ .setDisplayName(GuiConfig.getButtonName5().replace("{name}", name))
+ .setLore(lores1);
+ return new Button(itemStackBuilder.build()).noSound();
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/gui/RewardGui.java b/src/main/java/com/io/yutian/aumaster/gui/RewardGui.java
new file mode 100644
index 0000000..59115ff
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/gui/RewardGui.java
@@ -0,0 +1,67 @@
+package com.io.yutian.aumaster.gui;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.config.GuiConfig;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.rainlib.gui.Gui;
+import com.io.yutian.rainlib.gui.button.Button;
+import com.io.yutian.rainlib.util.ItemStackBuilder;
+import com.io.yutian.rainlib.util.StringUtil;
+import me.Demon.DemonPlugin.DemonAPI;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RewardGui extends Gui {
+
+ public RewardGui(Player player) {
+ super(player, Config.getLangData().getMessage("Gui-Reward-Title"), 27);
+ init();
+ initButton();
+ }
+
+ @Override
+ public void init() {
+ Button button1 = buildButton(3);
+ Button button2 = buildButton(5);
+ Button button3 = buildButton(8);
+ addButton(11, button1);
+ addButton(13, button2);
+ addButton(15, button3);
+ }
+
+ private Button buildButton(int amount) {
+ String name = "";
+ List lores = new ArrayList<>();
+ if (amount == 3) {
+ name = GuiConfig.getRewardButtonName1();
+ lores = GuiConfig.getRewardButtonLores1();
+ } else if (amount == 5) {
+ name = GuiConfig.getRewardButtonName2();
+ lores = GuiConfig.getRewardButtonLores2();
+ } else if (amount == 8) {
+ name = GuiConfig.getRewardButtonName3();
+ lores = GuiConfig.getRewardButtonLores3();
+ }
+ return new Button(new ItemStackBuilder(Material.CHEST).setDisplayName(name).setLore(lores).build()).click((player1, clickType) -> {
+ PlayerData playerData = PlayerManager.getPlayerData(player1.getName());
+ if (playerData.getReceivedLevelRewards().contains(amount)) {
+ DemonAPI.sendMessage(player1, StringUtil.formatIndexed(Config.getLangData().getMessage("Reward-Already-Got")));
+ return;
+ }
+ if (playerData.getDisciplesReachedTargetLevel() < amount) {
+ DemonAPI.sendMessage(player1, StringUtil.formatIndexed(Config.getLangData().getMessage("Reward-Not-Enough"), playerData.getDisciplesReachedTargetLevel(), amount));
+ return;
+ }
+ playerData.receiveReward(amount);
+ DemonAPI.sendMessage(player1, StringUtil.formatIndexed(Config.getLangData().getMessage("Reward-Got")));
+ player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
+ });
+ }
+
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/listener/PlayerListener.java b/src/main/java/com/io/yutian/aumaster/listener/PlayerListener.java
new file mode 100644
index 0000000..9b54a08
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/listener/PlayerListener.java
@@ -0,0 +1,52 @@
+package com.io.yutian.aumaster.listener;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.aumaster.util.AttributeUtil;
+import com.io.yutian.rainlib.util.StringUtil;
+import com.yaohun.aurechargedata.event.RechargeEvent;
+import me.Demon.DemonCoins.util.CoinsAPI;
+import me.Demon.DemonPlugin.DemonAPI;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+public class PlayerListener implements Listener {
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+ PlayerData playerData = PlayerManager.getPlayerData(player.getName());
+ if (playerData.isDisciple()) {
+ AttributeUtil.addAttribute(player);
+ }
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ Player player = event.getPlayer();
+ AttributeUtil.removeAttribute(player);
+ PlayerManager.save(player.getName(), true);
+ }
+
+ @EventHandler
+ public void onRecharge(RechargeEvent event) {
+ String playerName = event.getPlayerName();
+ PlayerData playerData = PlayerManager.getPlayerData(playerName);
+ if (playerData.isDisciple()) {
+ String mentor = playerData.getMentorName();
+ PlayerData mentorData = PlayerManager.getPlayerData(mentor);
+ int points = (int) Math.round(event.getMoney() * 0.05);
+ mentorData.addActivePoints(points);
+ Player mentorPlayer = Bukkit.getPlayerExact(mentor);
+ if (mentorPlayer != null && mentorPlayer.isOnline()) {
+ DemonAPI.sendMessage(mentorPlayer, StringUtil.formatIndexed(Config.getLangData().getMessage("Reward-Disciple-Recharge-Got"), playerName, event.getMoney(), points));
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/manager/InviteManager.java b/src/main/java/com/io/yutian/aumaster/manager/InviteManager.java
new file mode 100644
index 0000000..99995f1
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/manager/InviteManager.java
@@ -0,0 +1,133 @@
+package com.io.yutian.aumaster.manager;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.data.InviteData;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.util.AttributeUtil;
+import com.io.yutian.rainlib.util.StringUtil;
+import me.Demon.DemonPlugin.data.LangData;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class InviteManager {
+
+ private static final Map inviteMap = new HashMap<>();
+
+ private static final long EXPIRE_TIME = 1000L * 60 * 5;
+
+ public static void sendInvite(Player mentor, Player target) {
+ String targetName = target.getName();
+ String mentorName = mentor.getName();
+ LangData lang = Config.getLangData();
+
+ InviteData existing = inviteMap.get(targetName);
+ if (existing != null && System.currentTimeMillis() - existing.getTimestamp() < EXPIRE_TIME) {
+ mentor.sendMessage(lang.getMessage("Invite-Exists"));
+ return;
+ }
+
+ inviteMap.put(targetName, new InviteData(mentorName, System.currentTimeMillis()));
+ mentor.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Sent"), targetName));
+ target.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Received"), mentorName));
+ }
+
+ public static boolean acceptInvite(Player player) {
+ String playerName = player.getName();
+ InviteData invite = inviteMap.remove(playerName);
+ LangData lang = Config.getLangData();
+
+ if (invite == null || System.currentTimeMillis() - invite.getTimestamp() > EXPIRE_TIME) {
+ player.sendMessage(lang.getMessage("Invite-Expired"));
+ return false;
+ }
+
+ PlayerData discipleData = PlayerManager.getPlayerData(playerName);
+ PlayerData mentorData = PlayerManager.getPlayerData(invite.getMentorName());
+
+ if (playerName.equalsIgnoreCase(invite.getMentorName())) {
+ player.sendMessage(lang.getMessage("Invite-Target-Invalid"));
+ return true;
+ }
+
+ if (discipleData.isDisciple()) {
+ player.sendMessage(lang.getMessage("Invite-Accept-SelfHasMentor"));
+ return false;
+ }
+
+ if (mentorData.getDiscipleNames().size() >= Config.getMentorMaxDisciples()) {
+ player.sendMessage(lang.getMessage("Invite-Accept-MentorFull"));
+ return false;
+ }
+
+ discipleData.setMentorName(invite.getMentorName());
+ discipleData.setBindStartTime(System.currentTimeMillis());
+ mentorData.addDiscipleName(playerName);
+
+ discipleData.save();
+ mentorData.save();
+
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Accept-Success"), invite.getMentorName()));
+
+ Player mentor = Bukkit.getPlayerExact(invite.getMentorName());
+ if (mentor != null && mentor.isOnline()) {
+ mentor.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Accept-Notify-Mentor"), playerName));
+ }
+
+ AttributeUtil.addAttribute(player);
+ return true;
+ }
+
+ public static boolean denyInvite(Player player) {
+ String playerName = player.getName();
+ InviteData invite = inviteMap.remove(playerName);
+ LangData lang = Config.getLangData();
+
+ if (invite != null) {
+ player.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Deny-Success"), invite.getMentorName()));
+
+ Player mentor = Bukkit.getPlayerExact(invite.getMentorName());
+ if (mentor != null && mentor.isOnline()) {
+ mentor.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Deny-Notify-Mentor"), playerName));
+ }
+
+ return true;
+ } else {
+ player.sendMessage(lang.getMessage("Invite-Deny-NotFound"));
+ return false;
+ }
+ }
+
+ public static boolean cancelInvite(Player mentor, String targetName) {
+ InviteData invite = inviteMap.get(targetName);
+ LangData lang = Config.getLangData();
+
+ if (invite != null && invite.getMentorName().equals(mentor.getName())) {
+ inviteMap.remove(targetName);
+ mentor.sendMessage(StringUtil.formatIndexed(lang.getMessage("Invite-Cancel-Success"), targetName));
+ return true;
+ }
+
+ mentor.sendMessage(lang.getMessage("Invite-Cancel-NotFound"));
+ return false;
+ }
+
+ public static void clearExpired() {
+ long now = System.currentTimeMillis();
+ inviteMap.entrySet().removeIf(entry -> now - entry.getValue().getTimestamp() > EXPIRE_TIME);
+ }
+
+ public static boolean hasInvite(String playerName) {
+ return inviteMap.containsKey(playerName);
+ }
+
+ public static InviteData getInvite(String playerName) {
+ return inviteMap.get(playerName);
+ }
+
+ public static Map getInviteMap() {
+ return inviteMap;
+ }
+}
diff --git a/src/main/java/com/io/yutian/aumaster/manager/PlayerManager.java b/src/main/java/com/io/yutian/aumaster/manager/PlayerManager.java
new file mode 100644
index 0000000..0a6822c
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/manager/PlayerManager.java
@@ -0,0 +1,52 @@
+package com.io.yutian.aumaster.manager;
+
+import com.io.yutian.aumaster.data.PlayerData;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PlayerManager {
+
+ private static Map playerDatas = new HashMap<>();
+
+ public static void checkAllPlayer() {
+ for (PlayerData playerData : playerDatas.values()) {
+ playerData.check();
+ }
+ }
+
+ public static PlayerData getPlayerData(String playerName) {
+ if (!playerDatas.containsKey(playerName)) {
+ loadPlayerData(playerName);
+ }
+ return playerDatas.get(playerName);
+ }
+
+ public static void loadPlayerData(String playerName) {
+ if (!playerDatas.containsKey(playerName)) {
+ playerDatas.put(playerName, new PlayerData(playerName));
+ }
+ }
+
+ public static void setPlayerData(String playerName, PlayerData playerData) {
+ playerDatas.put(playerName, playerData);
+ }
+
+ public static void save(String playerName, boolean unload) {
+ if (!playerDatas.containsKey(playerName)) {
+ return;
+ }
+ PlayerData playerData = playerDatas.remove(playerName);
+ playerData.save();
+ if (unload) {
+ playerDatas.remove(playerName);
+ }
+ }
+
+ public static void saveAll() {
+ for (PlayerData playerData : playerDatas.values()) {
+ playerData.save();
+ }
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/util/AttributeUtil.java b/src/main/java/com/io/yutian/aumaster/util/AttributeUtil.java
new file mode 100644
index 0000000..981fb26
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/util/AttributeUtil.java
@@ -0,0 +1,42 @@
+package com.io.yutian.aumaster.util;
+
+import com.io.yutian.aumaster.config.Config;
+import com.io.yutian.aumaster.data.PlayerData;
+import com.io.yutian.aumaster.manager.PlayerManager;
+import com.io.yutian.rainlib.util.StringUtil;
+import org.bukkit.entity.Player;
+import org.serverct.ersha.jd.AttributeAPI;
+import org.serverct.ersha.jd.attribute.AttributeData;
+
+import java.util.Arrays;
+
+public class AttributeUtil {
+
+ private static String ATTRIBUTE_SOURCE_NAME = "aumaster_exp";
+
+ public static String buildAttributeLore() {
+ return StringUtil.formatIndexed(Config.getExpAttributeLore(), Config.getJoinExpBoost());
+ }
+
+ public static void checkPlayer(Player player) {
+ AttributeData attributeData = AttributeAPI.getAttrData(player);
+ PlayerData playerData = PlayerManager.getPlayerData(player.getName());
+ boolean hasAttribute = attributeData.getApiAttributeList(ATTRIBUTE_SOURCE_NAME) != null;
+ if (playerData.isDisciple()) {
+ if (!hasAttribute) {
+ addAttribute(player);
+ }
+ } else if (hasAttribute) {
+ removeAttribute(player);
+ }
+ }
+
+ public static void addAttribute(Player player) {
+ AttributeAPI.addAttribute(player, ATTRIBUTE_SOURCE_NAME, Arrays.asList(buildAttributeLore()));
+ }
+
+ public static void removeAttribute(Player player) {
+ AttributeAPI.deleteAttribute(player, ATTRIBUTE_SOURCE_NAME);
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/aumaster/util/RewardUtil.java b/src/main/java/com/io/yutian/aumaster/util/RewardUtil.java
new file mode 100644
index 0000000..1bd83cd
--- /dev/null
+++ b/src/main/java/com/io/yutian/aumaster/util/RewardUtil.java
@@ -0,0 +1,23 @@
+package com.io.yutian.aumaster.util;
+
+import com.io.yutian.aumaster.config.Config;
+import org.bukkit.Bukkit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RewardUtil {
+
+ public static void runReward(Integer level, String mentorName) {
+ List commands = Config.getLevelTargetRewards().getOrDefault(level, new ArrayList<>());
+ if (commands.isEmpty()) {
+ return;
+ }
+ for (String command : commands) {
+ String commandCopy = command;
+ commandCopy = commandCopy.replace("%player%", mentorName);
+ Bukkit.dispatchCommand(Bukkit.getConsoleSender(), commandCopy);
+ }
+ }
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..12adb8d
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,42 @@
+disciple:
+ # 玩家等级 ≤ 该值时才允许拜师
+ max-level: 70
+ # 玩家入服时间 ≤ N 天(单位:天)才允许拜师
+ max-join-days: 5
+ # 徒弟主动解除关系后,N天内不能再次拜师(冷却期)
+ cooldown-days: 7
+mentor:
+ # 玩家等级 ≥ 该值时才可收徒
+ min-level: 100
+ # 玩家注册时间 ≥ N 天时才可收徒
+ min-join-days: 60
+ # 每位师傅最多拥有的徒弟数量
+ max-disciples: 27
+ # 徒弟离线超过 N 小时后,师傅可解除关系
+ remove-after-offline-hours: 72
+relationship:
+ # 徒弟入服超过 N 天后自动解除关系
+ auto-remove-days: 30
+rewards:
+ # 徒弟当日在线 ≥ N 秒时,触发活跃奖励(给师傅)
+ daily-online-seconds: 7200
+ # 师傅每日获得的积分奖励
+ daily-points: 15
+ # 徒弟单笔充值 ≥ N 元时触发分成
+ charge-threshold: 30.0
+ # 师傅获得徒弟充值金额的百分比积分(0.05 表示 5%)
+ charge-bonus-percent: 0.05
+ #徒弟到达的等级
+ level-target: 80
+ # 徒弟达到指定等级人数时给予师傅的奖励指令(%player% 替换为师傅名)
+ level-target-rewards:
+ 3:
+ - "give %player% stone"
+ 5:
+ - "give %player% stone"
+ 8:
+ - "give %player% stone"
+ # 徒弟拜师成功后获得经验加成(20 表示 20% 加成)
+ join-exp-boost: 20
+ # 属性Lore
+ exp-attribute-lore: "经验加成: {0}%"
\ No newline at end of file
diff --git a/src/main/resources/gui.yml b/src/main/resources/gui.yml
new file mode 100644
index 0000000..d56bb7e
--- /dev/null
+++ b/src/main/resources/gui.yml
@@ -0,0 +1,39 @@
+button1:
+ name: "§a师徒系统玩法介绍"
+ lores:
+ - "§7了解师徒系统的详细规则"
+ - "§7XXX"
+button2:
+ name: "§b徒弟成长奖励"
+ lores:
+ - "§7领取徒弟成长奖励"
+ - "§7点击查看可领取内容"
+button3:
+ name: "§e徒弟活跃奖励"
+ lores:
+ - "§7领取徒弟活跃奖励"
+ - "§7当徒弟当日累积在线达到2小时,获得15积分"
+ - "§7当玩家充值单笔超过30 5%分成积分"
+ - " "
+ - "§6当前积分: §e{points}"
+button4:
+ name: "§a↓↓§6徒弟列表§a↓↓"
+ lores:
+ - ""
+button5:
+ name: "§f徒弟: §a{name}"
+ lores:
+ - "§f等级: §a{level}"
+ - "§f今日累计在线: §a{time_online}"
+reward-button1:
+ name: "§a徒弟成长奖励 - 3名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
+reward-button2:
+ name: "§a徒弟成长奖励 - 5名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
+reward-button3:
+ name: "§a徒弟成长奖励 - 8名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
\ No newline at end of file
diff --git a/src/main/resources/lang/AuMaster.yml b/src/main/resources/lang/AuMaster.yml
new file mode 100644
index 0000000..e4f13dd
--- /dev/null
+++ b/src/main/resources/lang/AuMaster.yml
@@ -0,0 +1,51 @@
+Gui:
+ Gui-Title: "师徒系统 - 管理系统"
+ Gui-Reward-Title: "奖励"
+Message:
+ Command-Usage-Invite: "§c用法: /{0} invite <玩家>"
+ Command-Usage-Remove: "§c用法: /{0} remove <玩家>"
+ Command-Usage-Cancel: "§c用法: /{0} cancel <玩家>"
+ Command-Unknown: "§c未知子命令,使用 /{0} 查看帮助"
+ Command-Help-Title: "师徒系统"
+ Disciple-List-Header: "§e你的徒弟列表:"
+ Disciple-List-Entry: "§6- §b{0}"
+ Disciple-LevelTop-Header: "§e徒弟等级排行:"
+ Disciple-LevelTop-Entry: "§6{0}. §b{1} §7- §aLv.{2}"
+ Disciple-NotFound-ByName: "§c该玩家不是你的徒弟"
+ Invite-Target-MaxLevel: "§c玩家{0}已超过{1}级,无法收他为徒弟"
+ Invite-Target-Newbie: "§c玩家{0}加入服务器已经超过{1}天,无法收他为徒弟"
+ Invite-Sent: "§a你已向 §e{0} §a发送拜师邀请"
+ Invite-Target-Invalid: "§c目标玩家无效,可能离线或是你自己"
+ Invite-Target-HasMentor: "§c目标玩家已有师傅,无法收他为徒弟"
+ Invite-Received: "§e你收到了 §b{0} §e的拜师邀请,输入 §a/shitu accept §e接受或输入 §c/shitu deny §e拒绝"
+ Invite-Exists: "§c该玩家已有未过期的拜师邀请"
+ Invite-Expired: "§c该邀请已过期"
+ Invite-Accept-SelfHasMentor: "§c你已经有师傅了"
+ Invite-Accept-MentorFull: "§c对方徒弟数量已满"
+ Invite-Accept-Success: "§a你已拜 §e{0} §a为师"
+ Invite-Accept-Notify-Mentor: "§a你的徒弟 §e{0} §a已接受拜师邀请"
+ Invite-Deny-Notify-Mentor: "§c玩家 §e{0} §a拒绝了你的拜师邀请"
+ Invite-Cancel-Success: "§a你已取消对 §e{0} §a的拜师邀请"
+ Invite-Cancel-NotFound: "§c你没有对该玩家发出过拜师邀请"
+ Invite-Deny-Success: "§a你已拒绝来自 §e{0} §a的拜师邀请"
+ Invite-Deny-NotFound: "§c你没有可拒绝的拜师邀请"
+ Invite-Target-Master-MinLevel: "§c你需要{0}级才能收徒弟"
+ Invite-Target-Master-MinJoinDays: "§c你需要加入服务器{0}天后才能收徒弟"
+ Invite-Target-Master-MaxDisciples: "§c你最多只能收{0}个徒弟"
+ Mentor-NotFound: "§c你还没有师傅"
+ Disciple-NotFound: "§c你当前没有徒弟"
+ Bind-Success: "§a你与 §e{0} §a建立了师徒关系"
+ Unbind-Success: "§a你已与玩家{0}已经解除师徒关系"
+ Already-Disciple: "§c该玩家已有师傅,无法拜你为师"
+ AutoUnbind-Disciple-Message: "你与师傅 §6{0}§e 的关系因超过{1}天已自动解除"
+ AutoUnbind-Mentor-Message: "你的徒弟 §6{0}§e 因超过{1}天已自动解除关系"
+ AutoUnbind-Message: "你与 §6{0}§e 的师徒关系因超过{1}天已自动解除"
+ Unbind-Cooldown: "§c你最近解除过师徒关系,还需等待 §e{0}天{1}小时§c 才能再次拜师"
+ Remove-Fail-Online: "§c徒弟 {0} 当前在线,无法解除关系"
+ Remove-Fail-NotOfflineLongEnough: "§c徒弟 {0} 离线不足72小时,无法解除关系"
+ Reward-Already-Got: "§c你已经领取过该奖励了"
+ Reward-Not-Enough: "§c未满足要求,无法领取奖励 ({0}/{1})"
+ Reward-Got: "§a成功领取该奖励"
+ Reward-ActivePoints-Got: "§a上个月的活跃奖励为:{0}软"
+ ActivePoint-OnlineTime-Got: "§a徒弟 {0} 今日在线时长已满足要求, 你获得了 {1} 积分"
+ Reward-Disciple-Recharge-Got: "§a徒弟 {0} 充值了 {1} 软 你获得了 {2} 积分"
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..cf266ab
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,15 @@
+name: AuMaster
+version: '1.0.0'
+main: com.io.yutian.aumaster.AuMaster
+author: SuperYuTian
+depend:
+ - RainLib
+ - DemonAPI
+ - DemonCoins
+ - AuRechargeData
+ - AuOnlineReward
+ - AuItemStackLibrary
+ - AttributePlus
+commands:
+ aumaster:
+ aliases: [amaster, shitu, st]
\ No newline at end of file
diff --git a/target/classes/com/io/yutian/aumaster/AuMaster.class b/target/classes/com/io/yutian/aumaster/AuMaster.class
new file mode 100644
index 0000000..5454ad4
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/AuMaster.class differ
diff --git a/target/classes/com/io/yutian/aumaster/MasterCommand.class b/target/classes/com/io/yutian/aumaster/MasterCommand.class
new file mode 100644
index 0000000..066eb53
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/MasterCommand.class differ
diff --git a/target/classes/com/io/yutian/aumaster/config/Config.class b/target/classes/com/io/yutian/aumaster/config/Config.class
new file mode 100644
index 0000000..9e98371
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/config/Config.class differ
diff --git a/target/classes/com/io/yutian/aumaster/config/GuiConfig.class b/target/classes/com/io/yutian/aumaster/config/GuiConfig.class
new file mode 100644
index 0000000..e300c1f
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/config/GuiConfig.class differ
diff --git a/target/classes/com/io/yutian/aumaster/data/InviteData.class b/target/classes/com/io/yutian/aumaster/data/InviteData.class
new file mode 100644
index 0000000..4dc8aa9
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/data/InviteData.class differ
diff --git a/target/classes/com/io/yutian/aumaster/data/PlayerData.class b/target/classes/com/io/yutian/aumaster/data/PlayerData.class
new file mode 100644
index 0000000..0b7e7ec
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/data/PlayerData.class differ
diff --git a/target/classes/com/io/yutian/aumaster/gui/MasterGui.class b/target/classes/com/io/yutian/aumaster/gui/MasterGui.class
new file mode 100644
index 0000000..fae0ce7
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/gui/MasterGui.class differ
diff --git a/target/classes/com/io/yutian/aumaster/gui/RewardGui.class b/target/classes/com/io/yutian/aumaster/gui/RewardGui.class
new file mode 100644
index 0000000..5e01142
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/gui/RewardGui.class differ
diff --git a/target/classes/com/io/yutian/aumaster/listener/PlayerListener.class b/target/classes/com/io/yutian/aumaster/listener/PlayerListener.class
new file mode 100644
index 0000000..982960f
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/listener/PlayerListener.class differ
diff --git a/target/classes/com/io/yutian/aumaster/manager/InviteManager.class b/target/classes/com/io/yutian/aumaster/manager/InviteManager.class
new file mode 100644
index 0000000..201fb4f
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/manager/InviteManager.class differ
diff --git a/target/classes/com/io/yutian/aumaster/manager/PlayerManager.class b/target/classes/com/io/yutian/aumaster/manager/PlayerManager.class
new file mode 100644
index 0000000..6e4ed74
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/manager/PlayerManager.class differ
diff --git a/target/classes/com/io/yutian/aumaster/util/AttributeUtil.class b/target/classes/com/io/yutian/aumaster/util/AttributeUtil.class
new file mode 100644
index 0000000..67e6d59
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/util/AttributeUtil.class differ
diff --git a/target/classes/com/io/yutian/aumaster/util/RewardUtil.class b/target/classes/com/io/yutian/aumaster/util/RewardUtil.class
new file mode 100644
index 0000000..f11bb0b
Binary files /dev/null and b/target/classes/com/io/yutian/aumaster/util/RewardUtil.class differ
diff --git a/target/classes/config.yml b/target/classes/config.yml
new file mode 100644
index 0000000..12adb8d
--- /dev/null
+++ b/target/classes/config.yml
@@ -0,0 +1,42 @@
+disciple:
+ # 玩家等级 ≤ 该值时才允许拜师
+ max-level: 70
+ # 玩家入服时间 ≤ N 天(单位:天)才允许拜师
+ max-join-days: 5
+ # 徒弟主动解除关系后,N天内不能再次拜师(冷却期)
+ cooldown-days: 7
+mentor:
+ # 玩家等级 ≥ 该值时才可收徒
+ min-level: 100
+ # 玩家注册时间 ≥ N 天时才可收徒
+ min-join-days: 60
+ # 每位师傅最多拥有的徒弟数量
+ max-disciples: 27
+ # 徒弟离线超过 N 小时后,师傅可解除关系
+ remove-after-offline-hours: 72
+relationship:
+ # 徒弟入服超过 N 天后自动解除关系
+ auto-remove-days: 30
+rewards:
+ # 徒弟当日在线 ≥ N 秒时,触发活跃奖励(给师傅)
+ daily-online-seconds: 7200
+ # 师傅每日获得的积分奖励
+ daily-points: 15
+ # 徒弟单笔充值 ≥ N 元时触发分成
+ charge-threshold: 30.0
+ # 师傅获得徒弟充值金额的百分比积分(0.05 表示 5%)
+ charge-bonus-percent: 0.05
+ #徒弟到达的等级
+ level-target: 80
+ # 徒弟达到指定等级人数时给予师傅的奖励指令(%player% 替换为师傅名)
+ level-target-rewards:
+ 3:
+ - "give %player% stone"
+ 5:
+ - "give %player% stone"
+ 8:
+ - "give %player% stone"
+ # 徒弟拜师成功后获得经验加成(20 表示 20% 加成)
+ join-exp-boost: 20
+ # 属性Lore
+ exp-attribute-lore: "经验加成: {0}%"
\ No newline at end of file
diff --git a/target/classes/gui.yml b/target/classes/gui.yml
new file mode 100644
index 0000000..d56bb7e
--- /dev/null
+++ b/target/classes/gui.yml
@@ -0,0 +1,39 @@
+button1:
+ name: "§a师徒系统玩法介绍"
+ lores:
+ - "§7了解师徒系统的详细规则"
+ - "§7XXX"
+button2:
+ name: "§b徒弟成长奖励"
+ lores:
+ - "§7领取徒弟成长奖励"
+ - "§7点击查看可领取内容"
+button3:
+ name: "§e徒弟活跃奖励"
+ lores:
+ - "§7领取徒弟活跃奖励"
+ - "§7当徒弟当日累积在线达到2小时,获得15积分"
+ - "§7当玩家充值单笔超过30 5%分成积分"
+ - " "
+ - "§6当前积分: §e{points}"
+button4:
+ name: "§a↓↓§6徒弟列表§a↓↓"
+ lores:
+ - ""
+button5:
+ name: "§f徒弟: §a{name}"
+ lores:
+ - "§f等级: §a{level}"
+ - "§f今日累计在线: §a{time_online}"
+reward-button1:
+ name: "§a徒弟成长奖励 - 3名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
+reward-button2:
+ name: "§a徒弟成长奖励 - 5名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
+reward-button3:
+ name: "§a徒弟成长奖励 - 8名徒弟到达80级"
+ lores:
+ - "§7领取徒弟成长奖励"
\ No newline at end of file
diff --git a/target/classes/lang/AuMaster.yml b/target/classes/lang/AuMaster.yml
new file mode 100644
index 0000000..e4f13dd
--- /dev/null
+++ b/target/classes/lang/AuMaster.yml
@@ -0,0 +1,51 @@
+Gui:
+ Gui-Title: "师徒系统 - 管理系统"
+ Gui-Reward-Title: "奖励"
+Message:
+ Command-Usage-Invite: "§c用法: /{0} invite <玩家>"
+ Command-Usage-Remove: "§c用法: /{0} remove <玩家>"
+ Command-Usage-Cancel: "§c用法: /{0} cancel <玩家>"
+ Command-Unknown: "§c未知子命令,使用 /{0} 查看帮助"
+ Command-Help-Title: "师徒系统"
+ Disciple-List-Header: "§e你的徒弟列表:"
+ Disciple-List-Entry: "§6- §b{0}"
+ Disciple-LevelTop-Header: "§e徒弟等级排行:"
+ Disciple-LevelTop-Entry: "§6{0}. §b{1} §7- §aLv.{2}"
+ Disciple-NotFound-ByName: "§c该玩家不是你的徒弟"
+ Invite-Target-MaxLevel: "§c玩家{0}已超过{1}级,无法收他为徒弟"
+ Invite-Target-Newbie: "§c玩家{0}加入服务器已经超过{1}天,无法收他为徒弟"
+ Invite-Sent: "§a你已向 §e{0} §a发送拜师邀请"
+ Invite-Target-Invalid: "§c目标玩家无效,可能离线或是你自己"
+ Invite-Target-HasMentor: "§c目标玩家已有师傅,无法收他为徒弟"
+ Invite-Received: "§e你收到了 §b{0} §e的拜师邀请,输入 §a/shitu accept §e接受或输入 §c/shitu deny §e拒绝"
+ Invite-Exists: "§c该玩家已有未过期的拜师邀请"
+ Invite-Expired: "§c该邀请已过期"
+ Invite-Accept-SelfHasMentor: "§c你已经有师傅了"
+ Invite-Accept-MentorFull: "§c对方徒弟数量已满"
+ Invite-Accept-Success: "§a你已拜 §e{0} §a为师"
+ Invite-Accept-Notify-Mentor: "§a你的徒弟 §e{0} §a已接受拜师邀请"
+ Invite-Deny-Notify-Mentor: "§c玩家 §e{0} §a拒绝了你的拜师邀请"
+ Invite-Cancel-Success: "§a你已取消对 §e{0} §a的拜师邀请"
+ Invite-Cancel-NotFound: "§c你没有对该玩家发出过拜师邀请"
+ Invite-Deny-Success: "§a你已拒绝来自 §e{0} §a的拜师邀请"
+ Invite-Deny-NotFound: "§c你没有可拒绝的拜师邀请"
+ Invite-Target-Master-MinLevel: "§c你需要{0}级才能收徒弟"
+ Invite-Target-Master-MinJoinDays: "§c你需要加入服务器{0}天后才能收徒弟"
+ Invite-Target-Master-MaxDisciples: "§c你最多只能收{0}个徒弟"
+ Mentor-NotFound: "§c你还没有师傅"
+ Disciple-NotFound: "§c你当前没有徒弟"
+ Bind-Success: "§a你与 §e{0} §a建立了师徒关系"
+ Unbind-Success: "§a你已与玩家{0}已经解除师徒关系"
+ Already-Disciple: "§c该玩家已有师傅,无法拜你为师"
+ AutoUnbind-Disciple-Message: "你与师傅 §6{0}§e 的关系因超过{1}天已自动解除"
+ AutoUnbind-Mentor-Message: "你的徒弟 §6{0}§e 因超过{1}天已自动解除关系"
+ AutoUnbind-Message: "你与 §6{0}§e 的师徒关系因超过{1}天已自动解除"
+ Unbind-Cooldown: "§c你最近解除过师徒关系,还需等待 §e{0}天{1}小时§c 才能再次拜师"
+ Remove-Fail-Online: "§c徒弟 {0} 当前在线,无法解除关系"
+ Remove-Fail-NotOfflineLongEnough: "§c徒弟 {0} 离线不足72小时,无法解除关系"
+ Reward-Already-Got: "§c你已经领取过该奖励了"
+ Reward-Not-Enough: "§c未满足要求,无法领取奖励 ({0}/{1})"
+ Reward-Got: "§a成功领取该奖励"
+ Reward-ActivePoints-Got: "§a上个月的活跃奖励为:{0}软"
+ ActivePoint-OnlineTime-Got: "§a徒弟 {0} 今日在线时长已满足要求, 你获得了 {1} 积分"
+ Reward-Disciple-Recharge-Got: "§a徒弟 {0} 充值了 {1} 软 你获得了 {2} 积分"
\ No newline at end of file
diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml
new file mode 100644
index 0000000..cf266ab
--- /dev/null
+++ b/target/classes/plugin.yml
@@ -0,0 +1,15 @@
+name: AuMaster
+version: '1.0.0'
+main: com.io.yutian.aumaster.AuMaster
+author: SuperYuTian
+depend:
+ - RainLib
+ - DemonAPI
+ - DemonCoins
+ - AuRechargeData
+ - AuOnlineReward
+ - AuItemStackLibrary
+ - AttributePlus
+commands:
+ aumaster:
+ aliases: [amaster, shitu, st]
\ No newline at end of file