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