From c99f186a20c5671af575ac37036769c2b170e5f2 Mon Sep 17 00:00:00 2001 From: YuTian <2953516620@qq.com> Date: Tue, 5 Aug 2025 12:53:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E5=92=8C=E4=B8=BB=E8=A6=81?= =?UTF-8?q?=E7=B1=BB=E6=96=87=E4=BB=B6=EF=BC=8C=E5=8C=85=E6=8B=AC=20`.giti?= =?UTF-8?q?gnore`=E3=80=81`AttributeUtil.java`=E3=80=81`AuMaster.java`?= =?UTF-8?q?=E3=80=81`AuMaster.yml`=E3=80=81`Config.java`=E3=80=81`config.y?= =?UTF-8?q?ml`=E3=80=81`gui.yml`=E3=80=81`GuiConfig.java`=E3=80=81`InviteD?= =?UTF-8?q?ata.java`=E3=80=81`InviteManager.java`=E3=80=81`MasterCommand.j?= =?UTF-8?q?ava`=E3=80=81`MasterGui.java`=E3=80=81`PlayerData.java`?= =?UTF-8?q?=E3=80=81`PlayerListener.java`=E3=80=81`PlayerManager.java`?= =?UTF-8?q?=E3=80=81`plugin.yml`=E3=80=81`pom.xml`=E3=80=81`RewardGui.java?= =?UTF-8?q?`=20=E5=92=8C=20`RewardUtil.java`=20=E7=9A=84=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + pom.xml | 116 ++++++ .../java/com/io/yutian/aumaster/AuMaster.java | 47 +++ .../com/io/yutian/aumaster/MasterCommand.java | 241 ++++++++++++ .../com/io/yutian/aumaster/config/Config.java | 159 ++++++++ .../io/yutian/aumaster/config/GuiConfig.java | 116 ++++++ .../io/yutian/aumaster/data/InviteData.java | 20 + .../io/yutian/aumaster/data/PlayerData.java | 345 ++++++++++++++++++ .../com/io/yutian/aumaster/gui/MasterGui.java | 80 ++++ .../com/io/yutian/aumaster/gui/RewardGui.java | 67 ++++ .../aumaster/listener/PlayerListener.java | 52 +++ .../aumaster/manager/InviteManager.java | 133 +++++++ .../aumaster/manager/PlayerManager.java | 52 +++ .../yutian/aumaster/util/AttributeUtil.java | 42 +++ .../io/yutian/aumaster/util/RewardUtil.java | 23 ++ src/main/resources/config.yml | 42 +++ src/main/resources/gui.yml | 39 ++ src/main/resources/lang/AuMaster.yml | 51 +++ src/main/resources/plugin.yml | 15 + .../com/io/yutian/aumaster/AuMaster.class | Bin 0 -> 2814 bytes .../io/yutian/aumaster/MasterCommand.class | Bin 0 -> 10823 bytes .../io/yutian/aumaster/config/Config.class | Bin 0 -> 5090 bytes .../io/yutian/aumaster/config/GuiConfig.class | Bin 0 -> 3583 bytes .../io/yutian/aumaster/data/InviteData.class | Bin 0 -> 646 bytes .../io/yutian/aumaster/data/PlayerData.class | Bin 0 -> 11225 bytes .../io/yutian/aumaster/gui/MasterGui.class | Bin 0 -> 5889 bytes .../io/yutian/aumaster/gui/RewardGui.class | Bin 0 -> 4692 bytes .../aumaster/listener/PlayerListener.class | Bin 0 -> 3079 bytes .../aumaster/manager/InviteManager.class | Bin 0 -> 5900 bytes .../aumaster/manager/PlayerManager.class | Bin 0 -> 2164 bytes .../yutian/aumaster/util/AttributeUtil.class | Bin 0 -> 2303 bytes .../io/yutian/aumaster/util/RewardUtil.class | Bin 0 -> 1539 bytes target/classes/config.yml | 42 +++ target/classes/gui.yml | 39 ++ target/classes/lang/AuMaster.yml | 51 +++ target/classes/plugin.yml | 15 + 36 files changed, 1789 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/io/yutian/aumaster/AuMaster.java create mode 100644 src/main/java/com/io/yutian/aumaster/MasterCommand.java create mode 100644 src/main/java/com/io/yutian/aumaster/config/Config.java create mode 100644 src/main/java/com/io/yutian/aumaster/config/GuiConfig.java create mode 100644 src/main/java/com/io/yutian/aumaster/data/InviteData.java create mode 100644 src/main/java/com/io/yutian/aumaster/data/PlayerData.java create mode 100644 src/main/java/com/io/yutian/aumaster/gui/MasterGui.java create mode 100644 src/main/java/com/io/yutian/aumaster/gui/RewardGui.java create mode 100644 src/main/java/com/io/yutian/aumaster/listener/PlayerListener.java create mode 100644 src/main/java/com/io/yutian/aumaster/manager/InviteManager.java create mode 100644 src/main/java/com/io/yutian/aumaster/manager/PlayerManager.java create mode 100644 src/main/java/com/io/yutian/aumaster/util/AttributeUtil.java create mode 100644 src/main/java/com/io/yutian/aumaster/util/RewardUtil.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/gui.yml create mode 100644 src/main/resources/lang/AuMaster.yml create mode 100644 src/main/resources/plugin.yml create mode 100644 target/classes/com/io/yutian/aumaster/AuMaster.class create mode 100644 target/classes/com/io/yutian/aumaster/MasterCommand.class create mode 100644 target/classes/com/io/yutian/aumaster/config/Config.class create mode 100644 target/classes/com/io/yutian/aumaster/config/GuiConfig.class create mode 100644 target/classes/com/io/yutian/aumaster/data/InviteData.class create mode 100644 target/classes/com/io/yutian/aumaster/data/PlayerData.class create mode 100644 target/classes/com/io/yutian/aumaster/gui/MasterGui.class create mode 100644 target/classes/com/io/yutian/aumaster/gui/RewardGui.class create mode 100644 target/classes/com/io/yutian/aumaster/listener/PlayerListener.class create mode 100644 target/classes/com/io/yutian/aumaster/manager/InviteManager.class create mode 100644 target/classes/com/io/yutian/aumaster/manager/PlayerManager.class create mode 100644 target/classes/com/io/yutian/aumaster/util/AttributeUtil.class create mode 100644 target/classes/com/io/yutian/aumaster/util/RewardUtil.class create mode 100644 target/classes/config.yml create mode 100644 target/classes/gui.yml create mode 100644 target/classes/lang/AuMaster.yml create mode 100644 target/classes/plugin.yml 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 0000000000000000000000000000000000000000..5454ad401b651b32cae852bf8946a0baaabc0502 GIT binary patch literal 2814 zcma)8>2nih9Dd$5bm?YGOD(k=r4&k=6lA#sw1}2aj*e6 zJgTA-ht}hWilaED;xRlfhbg%{uHXq3Dh{P_0#B-V3ezf1%Hb$-{gicf9S8n8uBCAf zvntLbFNZlvaUqS1xRl1zxGaZ)f_W8Ja8W~PFa2|Bqd!C*p()whS%`AhBxr0z)(Bz6uhP3ZM-8e z(#HBabj-pgAyqppS&lB@)Mq(diq_1oXop#9>*tuDM&Nn^8=DwUMiHcsB{PVblGG76 zlF3Khw&9fYLf~0WX)46rd85&(TB~&Gi}#k8<-%zYc-;T{!D1qSu_T? zP+T$>Lt8qZX?5POpXhNytWvVEzKi!%HsANz%Dm7K7$j>WF)oKr)S?L0SQAuj1qx`C zGH>|hd8;BVDYT%~5{0R?^vuq-gzcY-q-5H%w+%2%SQ-7K_E&R3@r`A3+O`=@B2g@J z8h3}dGA=qc`*ys;01wp>hzcv`+O}B?EZ3plfkweK_T}ZVT79eVwNxcpl_kT!VBThf z=9O`SSB4WU2I|V9I=r}Wi@HdiZR21hbvj_VE`))3g_X~0i+rj(G~5DsYwynTy8A%G zhxk;(UW^LtY(&~}mffx6j{D2lwWDA6nxJ7%)4$mtTNW;9Cq5AZTP-P z;C^jxDT%zer=Ddau}yz0W^4|8(s`Ovp@ngNrD`^l|Np~S<%4;fGd+=>6=mCmn_yOVbyzT>0=yEt}5n;OPA z*J1+fj@bD`SY`ei3hDX&nfw7A_tAO%4pRC4bv1PD`4LKevc87y`%rn9p1cdK6E*bI zu%U+D$$RJnx(BfFE*|20sG)xx-IUvp6b7h&6aRxWe+c`qg)VL7>unfkXq~igFt#DF zPs4FcAQQQjUA6Qe>7<*f8U`9#)QB^~mtVHY(^Mj<8R_rbN1A*^_#zblg4yLkPk94pp%`1 zd4v(#MUmrFUJtAwNc9RrsD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..066eb533a91c439c4c56aaf9b7598d5570acb9f1 GIT binary patch literal 10823 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 J+9<)h{|B$@Gcf=F literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e300c1f8b62ce472a5a2f546134e520ee122cbf0 GIT binary patch literal 3583 zcma)8`EwLi5dJ2F>|_}r3?U!_0YZ+=NY-4afRW39umnvoN>FrmGg&6t17~Lgc;PMH z;w|2y_=`WNl!4MJ{{a6c%kq0~59R`_RBd;EudmmyyC;AD`^R4ZhVWAyTVcg86Gs*& z#gDCGHjW0&iJzQ6@^KVURB4wO{5f|gax3wm0`89~pgcv{eBR6Hx_b1I$} z^qh(p1btD(OTx*^LU={RtAf6!;&nmKt9V1uH&whP=-VpZ5%gUZ?+N<8iVK2%5W|Nt ze57DWy6n2e!kC%2`W5J@S##b@=FCDiIpI2XA-lt;GT@U2ebSIm8dk8vu}+)L^d4`3 z5Jrz7jDEFBTB)LAm6%scC9kq;=aMPA z@-E&}UPkv`rj}M1q}wn^=S@59g6)ndSk#l4RM5D$IL*A5r|g0?R?ep_=ct*^5z$k{ zjG3D>9b3p%u+cqfmlPyYnPNU^7n5gM2eXhg%XzcpT23-kEX>&1d~S8}{+lVjzI z<}@SC*uw9!N=0ZqN|_2vD@J9#s^|Jwarr}NxHdw{_J=jnc8}MMmRcugTD=Ra&wXz#3AvNyb&`~YoaQLVe zc$+v{TJw|>dq%^LxUAtW++9Bz=&PRW@PLCgaHj_xs)6@EWh0p3? zcZJXD(RYip?*F+GxI(XQ_9N+8E8{9?zk%`Y@?p7HxIOGbiHaTU{#)pZb-szOz$G?Zdt3hnXChH7$d`T|LDYj9`oVUiUl5AuJZB-xMkJOYfOWu5g z9W(Pe-v;BCN9@P|wmXnwf|GZ%#TatSO57q7F^qwz&8%JJgR7t`;)0P&R1~~oB)*CK z4BpuA`YyvJe*U-e|CScS#h8+di_w&n<0vUdP*RSaq?|EHIZ%>vdL-qnK*2ra8?c>z zI3_-s6XKIO96p(I;gdNFKAHXRliBkgStrj8#@~I+AW5o_F7CYwu|5 zwTc4v;{c^*JWw-M4xo`&02cm4!?9~vw17r^@l`Y(>RmwWA~Zt!VxnsAH8iITJ-&b? zSD+dCQpqec^yQLiG4vIZ(G7j2WLgbe zjgr}9=$j?eVdz^V(`o2klIb?|9?2vOo!Qac5Vu_faob6(;_n7NZaY?EBmXv|6CHf$ zEnIA!*o7|Mx*Ox@!Eq!ojb7woV4h8Jj%{(Cnip8gi)@KY=*Q0(!0#B8)oWvgT5uT$ zafmTGsh7fGR&BE*i)^Fjc$DU{pyqaJ zPDE+81T{yfc{EB>4{GkA=EG5%twGIEYEDLJwgoj0QuC20%{4*IF={>eV63~@qsS2mM?A0;R#f(Jjq zj}m((Ld1BGf$r*_uIk#^kI%Pv0EgIdk-}OQNvxZ&k-=sLTMTX>LmkBp5lDtoeIO=+ z4@KDLO&zPSf5ed0Dv%>Bf;$Fw$&fx)q0%P|Wq*GBvf5@yo<==VE7Vme8{?oOcupyY38R zS2NJQHg@T)Q}hEIIwWfmDN{~>%wUnCN7W70Ny>%VD_Cv+1x~HA<%j!!lN= VV?1&zHYFz>evwOml2`3i`3rzLcxeCt literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..0b7e7ecb4325d3cc03a866c618933a6275a22638 GIT binary patch literal 11225 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 G_kRI%iE|nN literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..5e01142484f6342e77cbd849f5b3a0a7259696d6 GIT binary patch literal 4692 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..201fb4fbedb1bc755128786fe7bfdf0ff465be00 GIT binary patch literal 5900 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..67e6d59be21a088790ac214e16263f7f017d48b1 GIT binary patch literal 2303 zcmb7FZBrXn6n-uVY*?12rl7S-X%T1=XxFN(Qm}0xsnUiQ37~CNyxCmBg=9Cg*)Z@^ z>L2J=UuN3a8U5%7f0H_%ySpTzO=d73cJDp=oaels{PpjvKLC6JM@Ix7>vX!M;kJ5z zs^c@v>9~V=9Sit;2zPN$$9-f5F^WYUOUUZT;ek%qFVy2p4a@5NP{$+WmC}lOtj4gW zVVz+#v$?skytuWQ+bOJVZ7k(>Rx>L(hD3g!A9Az8?Xp?$Txpl*83q=lExo%8kz{I{ zA-d$01VcP8ZL!*@7KOXXixrY2@{YwT+uW7v9txx0o~$#>Se~{KTOw_c(*;gX_XQ6s|?IZheoN`z5mlYe%3IC;~mO z6R0P91z#d?=v}C1?D2XlZU***oGEzRI#}T~KcgDH(y+l`@KQTLR1H^DokP)~8e6a` zVcqnC({L^EK>Af`VN|kjsCpZ?h<7y<3~b^G!})d(tQGf#YhJR*;6UWIt_oAv_oELh_zjs)nvA_@dE(0*wkrHTrTa3ECvG= zBvuue`e)a1tK3_*OX5hB80M01j?vQ&QBd>wPMfV&Fws4&tuQm|%M3#lrIM(YW_Z+X zB6I#=l8x?s{AB#zn5&Durkg<{v#Y#Hn_~8KW=^`uta6)|Y3Bs{U?sRwf=DqC1s*SS zNl@zSBdkiFsmWGO@=_IgvMZ@SY5odSD780aJuB;$tf^6@eM|EnjH3_AxGq1YZ92f~ z0qaz1?{zCe5c7OT>BBk)lD58Dobi&V2(NR&nE#72wT-LvhZLc|IEqs32s#bW znN|-yFVW4UH=}od`X$)Ubm+r-AqW`8`*bz}0LE~cZi8xZgvzr-rhX$$^hJM1g`^9%GB82S@h^f{uDyR$D~ zJj1!MACVyB@N*1}J%dKabIR9<&p%Dfpy2u`yf}q6PQgu6aB2E_lf1q~e$SE5DwcF$ z6(3-dZvFIaim;Sv%-|Z51CgRDxDbl6}n>REJU1cH%ZoqkNyK#*H3i- literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f11bb0be022c6fc6bcb56e3ef80f854b03d857b2 GIT binary patch literal 1539 zcma)6U31$+6g?ZuR$?nj^U*+nmKKuWBu&Lfpv^~1Tc<4n$0>CvL*F*?)=?u%W-S-| zQ}_iu_k}hv!|=>Izk_$C1DutWS_v?NA9nAay?6JVvseE0&mVsVu!?#S6Id!@8JBFV z6p_PH376s8c(;TC-ZR7dC47KYGkj>{qhVYrqJ*nOtYO^@8#Xp=ToWj4`k^0R7s!j^7vPD(HX%R)7>1QXDt9~aY*_o4? zd+lT0bEk4QGdHD#uCso$9!u|VN468Y_&PRdbg>?FwWsd*#@6wHJC}_p2a}kx@v(y& zxJe0#(1g=Xt!2*;vvJEo1zQ4RgI%-X;5P0!xQkDCkArQq_!OT}+G)Eee7+sXp3?IU zs@SnnbFhnh4nD_yfrbC~oF@+6-G8jSm~S)Sw9OWfv|3>9KMwSw@R8qiE6F5qwyEN( zdAmKS8TPH=(@c~XGltVoBl(@% zt#-^l<0tWuR{1Y=%$y){tdDH$1KFvmZ+Wp5Ce!qB=Bcx_qVFCbek)6`av*hGece@| zr?NCp;90USyM7|lO?SV0c<9IOtz_b>&-A?=&o?F^Y2- z!+A" + 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