From 6bb272d5fa47753f2bfba21807e476d9e2ea81f2 Mon Sep 17 00:00:00 2001 From: M_Viper Date: Thu, 5 Feb 2026 10:14:28 +0100 Subject: [PATCH] Update from Git Manager GUI --- src/main/java/com/taxes/TaxesPlugin.java | 110 +++++++++ .../com/taxes/commands/CollectAllCommand.java | 30 +++ .../com/taxes/commands/CollectCommand.java | 30 +++ .../com/taxes/commands/InfoAllCommand.java | 58 +++++ .../java/com/taxes/commands/InfoCommand.java | 44 ++++ .../com/taxes/commands/ListAllCommand.java | 16 ++ .../java/com/taxes/commands/ListCommand.java | 16 ++ .../com/taxes/commands/ReloadCommand.java | 17 ++ .../java/com/taxes/commands/TaxesCommand.java | 83 +++++++ .../com/taxes/commands/TaxesTabCompleter.java | 79 ++++++ .../com/taxes/config/BatchProcessing.java | 29 +++ .../com/taxes/config/RuntimeConfigData.java | 51 ++++ .../java/com/taxes/config/TaxConfigData.java | 184 ++++++++++++++ src/main/java/com/taxes/config/TaxData.java | 105 ++++++++ src/main/java/com/taxes/core/TaxesCore.java | 198 +++++++++++++++ .../java/com/taxes/core/TaxesCoreRun.java | 15 ++ .../com/taxes/core/command/EnderCommand.java | 29 +++ .../com/taxes/core/command/HelpCommand.java | 71 ++++++ .../com/taxes/core/config/EnderConfig.java | 83 +++++++ .../com/taxes/core/config/LanguageConfig.java | 105 ++++++++ .../taxes/core/config/LanguageMessage.java | 75 ++++++ .../taxes/core/messages/BroadcastMessage.java | 22 ++ .../core/messages/CommandSenderMessage.java | 21 ++ .../java/com/taxes/core/messages/Message.java | 39 +++ .../taxes/core/messages/PlayerMessage.java | 11 + .../com/taxes/core/tag/EconTagValues.java | 14 ++ .../com/taxes/core/tag/PlayerTagValues.java | 15 ++ src/main/java/com/taxes/core/tag/Tag.java | 52 ++++ .../java/com/taxes/core/tag/TagValues.java | 24 ++ src/main/java/com/taxes/core/tag/Value.java | 53 ++++ .../java/com/taxes/core/task/EnderTask.java | 15 ++ .../com/taxes/core/util/NumberFormat.java | 25 ++ src/main/java/com/taxes/core/util/Time.java | 48 ++++ .../java/com/taxes/data/PermissionString.java | 20 ++ src/main/java/com/taxes/tag/TaxTagValues.java | 61 +++++ .../tasks/PlayerBalanceTaxCollector.java | 228 ++++++++++++++++++ .../java/com/taxes/tasks/TaxCollector.java | 146 +++++++++++ .../com/taxes/tasks/TaxCollectorFactory.java | 16 ++ src/main/java/com/taxes/tax/Collection.java | 41 ++++ .../java/com/taxes/tax/PlayerBalanceTax.java | 24 ++ src/main/java/com/taxes/tax/Tax.java | 68 ++++++ src/main/java/com/taxes/tax/TaxBracket.java | 91 +++++++ .../java/com/taxes/tax/TaxBracketGroup.java | 55 +++++ src/main/java/com/taxes/tax/TaxFactory.java | 17 ++ src/main/java/com/taxes/tax/TaxNames.java | 60 +++++ src/main/resources/config.yml | 130 ++++++++++ src/main/resources/data.yml | 0 src/main/resources/language.yml | 213 ++++++++++++++++ src/main/resources/plugin.yml | 128 ++++++++++ 49 files changed, 3065 insertions(+) create mode 100644 src/main/java/com/taxes/TaxesPlugin.java create mode 100644 src/main/java/com/taxes/commands/CollectAllCommand.java create mode 100644 src/main/java/com/taxes/commands/CollectCommand.java create mode 100644 src/main/java/com/taxes/commands/InfoAllCommand.java create mode 100644 src/main/java/com/taxes/commands/InfoCommand.java create mode 100644 src/main/java/com/taxes/commands/ListAllCommand.java create mode 100644 src/main/java/com/taxes/commands/ListCommand.java create mode 100644 src/main/java/com/taxes/commands/ReloadCommand.java create mode 100644 src/main/java/com/taxes/commands/TaxesCommand.java create mode 100644 src/main/java/com/taxes/commands/TaxesTabCompleter.java create mode 100644 src/main/java/com/taxes/config/BatchProcessing.java create mode 100644 src/main/java/com/taxes/config/RuntimeConfigData.java create mode 100644 src/main/java/com/taxes/config/TaxConfigData.java create mode 100644 src/main/java/com/taxes/config/TaxData.java create mode 100644 src/main/java/com/taxes/core/TaxesCore.java create mode 100644 src/main/java/com/taxes/core/TaxesCoreRun.java create mode 100644 src/main/java/com/taxes/core/command/EnderCommand.java create mode 100644 src/main/java/com/taxes/core/command/HelpCommand.java create mode 100644 src/main/java/com/taxes/core/config/EnderConfig.java create mode 100644 src/main/java/com/taxes/core/config/LanguageConfig.java create mode 100644 src/main/java/com/taxes/core/config/LanguageMessage.java create mode 100644 src/main/java/com/taxes/core/messages/BroadcastMessage.java create mode 100644 src/main/java/com/taxes/core/messages/CommandSenderMessage.java create mode 100644 src/main/java/com/taxes/core/messages/Message.java create mode 100644 src/main/java/com/taxes/core/messages/PlayerMessage.java create mode 100644 src/main/java/com/taxes/core/tag/EconTagValues.java create mode 100644 src/main/java/com/taxes/core/tag/PlayerTagValues.java create mode 100644 src/main/java/com/taxes/core/tag/Tag.java create mode 100644 src/main/java/com/taxes/core/tag/TagValues.java create mode 100644 src/main/java/com/taxes/core/tag/Value.java create mode 100644 src/main/java/com/taxes/core/task/EnderTask.java create mode 100644 src/main/java/com/taxes/core/util/NumberFormat.java create mode 100644 src/main/java/com/taxes/core/util/Time.java create mode 100644 src/main/java/com/taxes/data/PermissionString.java create mode 100644 src/main/java/com/taxes/tag/TaxTagValues.java create mode 100644 src/main/java/com/taxes/tasks/PlayerBalanceTaxCollector.java create mode 100644 src/main/java/com/taxes/tasks/TaxCollector.java create mode 100644 src/main/java/com/taxes/tasks/TaxCollectorFactory.java create mode 100644 src/main/java/com/taxes/tax/Collection.java create mode 100644 src/main/java/com/taxes/tax/PlayerBalanceTax.java create mode 100644 src/main/java/com/taxes/tax/Tax.java create mode 100644 src/main/java/com/taxes/tax/TaxBracket.java create mode 100644 src/main/java/com/taxes/tax/TaxBracketGroup.java create mode 100644 src/main/java/com/taxes/tax/TaxFactory.java create mode 100644 src/main/java/com/taxes/tax/TaxNames.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/data.yml create mode 100644 src/main/resources/language.yml create mode 100644 src/main/resources/plugin.yml diff --git a/src/main/java/com/taxes/TaxesPlugin.java b/src/main/java/com/taxes/TaxesPlugin.java new file mode 100644 index 0000000..5f76967 --- /dev/null +++ b/src/main/java/com/taxes/TaxesPlugin.java @@ -0,0 +1,110 @@ +package com.taxes; + +import com.taxes.core.TaxesCore; +import com.taxes.core.command.HelpCommand; +import com.taxes.commands.CollectAllCommand; +import com.taxes.commands.CollectCommand; +import com.taxes.commands.InfoAllCommand; +import com.taxes.commands.InfoCommand; +import com.taxes.commands.ListAllCommand; +import com.taxes.commands.ListCommand; +import com.taxes.commands.ReloadCommand; +import com.taxes.commands.TaxesTabCompleter; +import com.taxes.config.RuntimeConfigData; +import com.taxes.config.TaxConfigData; +import com.taxes.tasks.TaxCollector; +import com.taxes.tasks.TaxCollectorFactory; +import com.taxes.tax.Tax; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.bukkit.Bukkit; + +public class TaxesPlugin extends TaxesCore { + private TaxConfigData taxConfigData = null; + private RuntimeConfigData runtimeData = null; + + protected boolean load() { + boolean loaded = true; + if (this.setupVaultPlugin()) { + this.runtimeData = new RuntimeConfigData(this); + this.taxConfigData = new TaxConfigData(this, this.runtimeData); + this.getLogger().finest(this.taxConfigData.toString()); + this.getLogger().finest(this.runtimeData.toString()); + this.registerCommands(); + this.scheduleTasks(); + } + + return loaded; + } + + protected boolean unload() { + boolean unloaded = true; + Bukkit.getServer().getScheduler().cancelTasks(this); + return unloaded; + } + + protected boolean registerCommands() { + TaxesTabCompleter tabCompleter = new TaxesTabCompleter(this); + + this.getCommand("taxes").setExecutor(new HelpCommand(this)); + this.getCommand("taxes-collect").setExecutor(new CollectCommand(this)); + this.getCommand("taxes-collect").setTabCompleter(tabCompleter); + + this.getCommand("taxes-collectall").setExecutor(new CollectAllCommand(this)); + + this.getCommand("taxes-list").setExecutor(new ListCommand(this)); + this.getCommand("taxes-listall").setExecutor(new ListAllCommand(this)); + + this.getCommand("taxes-info").setExecutor(new InfoCommand(this)); + this.getCommand("taxes-info").setTabCompleter(tabCompleter); + + this.getCommand("taxes-infoall").setExecutor(new InfoAllCommand(this)); + this.getCommand("taxes-infoall").setTabCompleter(tabCompleter); + + this.getCommand("taxes-reload").setExecutor(new ReloadCommand(this)); + return true; + } + + protected boolean scheduleTasks() { + Iterator var1 = this.getTaxConfigData().getTaxes().iterator(); + + while(var1.hasNext()) { + Tax tax = (Tax)var1.next(); + this.getLogger().finest(String.format("taxName: %s", tax.getTaxData().getName())); + this.getLogger().finest(String.format("tax: %s", tax.toString())); + if (tax.getTaxData().isEnabled()) { + this.getLogger().finest("Tax Enabled"); + TaxCollector taxCollector = TaxCollectorFactory.getTaxCollector(this, tax); + if (taxCollector != null) { + this.getLogger().finest("Tax Collector not null."); + long firstRun = tax.getTimeTilNextTaxTicks(); + this.getLogger().finest(String.format("firstRun: %d", firstRun)); + this.addTask(taxCollector, firstRun, tax.getTaxData().getTaxFrequencyTicks()); + } + } + } + + return true; + } + + public RuntimeConfigData getRuntimeData() { + return this.runtimeData; + } + + public TaxConfigData getTaxConfigData() { + return this.taxConfigData; + } + + public String getTaxNames() { + List taxNames = new ArrayList(); + Iterator var2 = this.taxConfigData.getTaxes().iterator(); + + while(var2.hasNext()) { + Tax tax = (Tax)var2.next(); + taxNames.add(tax.getTaxData().getName().getName()); + } + + return taxNames.toString(); + } +} diff --git a/src/main/java/com/taxes/commands/CollectAllCommand.java b/src/main/java/com/taxes/commands/CollectAllCommand.java new file mode 100644 index 0000000..3c61bcb --- /dev/null +++ b/src/main/java/com/taxes/commands/CollectAllCommand.java @@ -0,0 +1,30 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import com.taxes.TaxesPlugin; +import com.taxes.tasks.TaxCollector; +import com.taxes.tasks.TaxCollectorFactory; +import com.taxes.tax.Tax; +import java.util.Iterator; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class CollectAllCommand extends TaxesCommand { + public CollectAllCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + boolean validFormat = true; + Iterator var6 = ((TaxesPlugin)this.getPlugin()).getTaxConfigData().getTaxes().iterator(); + + while(var6.hasNext()) { + Tax tax = (Tax)var6.next(); + TaxCollector taxCollector = TaxCollectorFactory.getTaxCollector((TaxesPlugin)this.getPlugin(), tax); + taxCollector.run(); + } + + this.getPlugin().restartAllTasks(); + return validFormat; + } +} diff --git a/src/main/java/com/taxes/commands/CollectCommand.java b/src/main/java/com/taxes/commands/CollectCommand.java new file mode 100644 index 0000000..e1c9025 --- /dev/null +++ b/src/main/java/com/taxes/commands/CollectCommand.java @@ -0,0 +1,30 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import com.taxes.TaxesPlugin; +import com.taxes.tasks.TaxCollector; +import com.taxes.tasks.TaxCollectorFactory; +import com.taxes.tax.Tax; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class CollectCommand extends TaxesCommand { + public CollectCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + boolean validFormat = false; + if (args.length == 1) { + validFormat = true; + Tax tax = this.getValidTax(sender, args[0]); + if (tax != null) { + TaxCollector taxCollector = TaxCollectorFactory.getTaxCollector((TaxesPlugin)this.getPlugin(), tax); + taxCollector.run(); + this.getPlugin().restartAllTasks(); + } + } + + return validFormat; + } +} diff --git a/src/main/java/com/taxes/commands/InfoAllCommand.java b/src/main/java/com/taxes/commands/InfoAllCommand.java new file mode 100644 index 0000000..281395c --- /dev/null +++ b/src/main/java/com/taxes/commands/InfoAllCommand.java @@ -0,0 +1,58 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import com.taxes.core.messages.PlayerMessage; +import com.taxes.core.tag.TagValues; +import com.taxes.tag.TaxTagValues; +import com.taxes.tax.Collection; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import java.util.Iterator; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class InfoAllCommand extends TaxesCommand { + public InfoAllCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + boolean validFormat = false; + if (this.isPlayer(sender)) { + Player player = (Player)sender; + if (args.length == 1) { + validFormat = true; + Tax tax = this.getValidTax(sender, args[0]); + if (tax != null) { + TagValues taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, (TaxBracketGroup)null, (TaxBracket)null, (Double)null, (Double)null); + PlayerMessage pm = new PlayerMessage(player, this.getPlugin().getLanguageConfig().getMessage("PlayerTaxInfoAll"), taxTagValues); + pm.addMessage("TaxInfo", taxTagValues); + Collection collection = tax.getCollection(); + Iterator var11 = collection.getTaxBracketGroups().iterator(); + + while(var11.hasNext()) { + TaxBracketGroup taxBracketGroup = (TaxBracketGroup)var11.next(); + taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, taxBracketGroup, (TaxBracket)null, (Double)null, (Double)null); + pm.addMessage("EachTaxBracketGroup", taxTagValues); + Iterator var13 = taxBracketGroup.getTaxBrackets().iterator(); + + while(var13.hasNext()) { + TaxBracket taxBracket = (TaxBracket)var13.next(); + taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, taxBracketGroup, taxBracket, (Double)null, (Double)null); + pm.addMessage("EachTaxBracket", taxTagValues); + } + } + + pm.addMessage("Footer", taxTagValues); + pm.sendMessage(); + } + } + } else { + validFormat = true; + } + + return validFormat; + } +} diff --git a/src/main/java/com/taxes/commands/InfoCommand.java b/src/main/java/com/taxes/commands/InfoCommand.java new file mode 100644 index 0000000..1307016 --- /dev/null +++ b/src/main/java/com/taxes/commands/InfoCommand.java @@ -0,0 +1,44 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import com.taxes.core.messages.PlayerMessage; +import com.taxes.core.tag.TagValues; +import com.taxes.tag.TaxTagValues; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class InfoCommand extends TaxesCommand { + public InfoCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + boolean validFormat = false; + if (this.isPlayer(sender)) { + Player player = (Player)sender; + if (args.length == 1) { + validFormat = true; + Tax tax = this.getValidTax(sender, args[0]); + if (tax != null) { + TaxBracketGroup taxBracketGroup = tax.getTaxBracketGroup(player); + TaxBracket taxBracket = null; + if (taxBracketGroup != null) { + taxBracket = tax.getTaxBracket(player); + } + + TagValues taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, taxBracketGroup, taxBracket, (Double)null, (Double)null); + PlayerMessage pm = new PlayerMessage(player, this.getPlugin().getLanguageConfig().getMessage("PlayerTaxInfo"), taxTagValues); + pm.sendMessage(); + } + } + } else { + validFormat = true; + } + + return validFormat; + } +} diff --git a/src/main/java/com/taxes/commands/ListAllCommand.java b/src/main/java/com/taxes/commands/ListAllCommand.java new file mode 100644 index 0000000..58b5359 --- /dev/null +++ b/src/main/java/com/taxes/commands/ListAllCommand.java @@ -0,0 +1,16 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class ListAllCommand extends TaxesCommand { + public ListAllCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + this.sendTaxListPlayerMessage(sender, "PlayerTaxListAll", true); + return true; + } +} diff --git a/src/main/java/com/taxes/commands/ListCommand.java b/src/main/java/com/taxes/commands/ListCommand.java new file mode 100644 index 0000000..19c010e --- /dev/null +++ b/src/main/java/com/taxes/commands/ListCommand.java @@ -0,0 +1,16 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class ListCommand extends TaxesCommand { + public ListCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + this.sendTaxListPlayerMessage(sender, "PlayerTaxList", false); + return true; + } +} diff --git a/src/main/java/com/taxes/commands/ReloadCommand.java b/src/main/java/com/taxes/commands/ReloadCommand.java new file mode 100644 index 0000000..03413d4 --- /dev/null +++ b/src/main/java/com/taxes/commands/ReloadCommand.java @@ -0,0 +1,17 @@ +package com.taxes.commands; + +import com.taxes.core.command.EnderCommand; +import com.taxes.TaxesPlugin; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class ReloadCommand extends EnderCommand { + public ReloadCommand(TaxesPlugin plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + this.getPlugin().reloadPlugin(sender); + return true; + } +} diff --git a/src/main/java/com/taxes/commands/TaxesCommand.java b/src/main/java/com/taxes/commands/TaxesCommand.java new file mode 100644 index 0000000..0910113 --- /dev/null +++ b/src/main/java/com/taxes/commands/TaxesCommand.java @@ -0,0 +1,83 @@ +package com.taxes.commands; + +import com.taxes.core.TaxesCore; +import com.taxes.core.command.EnderCommand; +import com.taxes.core.config.LanguageMessage; +import com.taxes.core.messages.CommandSenderMessage; +import com.taxes.core.messages.PlayerMessage; +import com.taxes.core.tag.TagValues; +import com.taxes.TaxesPlugin; +import com.taxes.tag.TaxTagValues; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import com.taxes.tax.TaxNames; +import java.util.Iterator; +import java.util.List; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public abstract class TaxesCommand extends EnderCommand { + public TaxesCommand(TaxesCore plugin) { + super(plugin); + } + + protected void sendTaxListPlayerMessage(CommandSender sender, String messageKey, boolean allTaxes) { + if (this.isPlayer(sender)) { + Player player = (Player)sender; + + List taxesList = ((TaxesPlugin)this.getPlugin()).getTaxConfigData().getTaxes(); + + TagValues tagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), (Tax)null, (TaxBracketGroup)null, (TaxBracket)null, (Double)null, (Double)null); + LanguageMessage langMessage = this.getPlugin().getLanguageConfig().getMessage(messageKey); + PlayerMessage pm = new PlayerMessage(player, langMessage, tagValues); + pm.addMessage("Header", tagValues); + Iterator var8 = taxesList.iterator(); + + while(true) { + Tax tax; + do { + if (!var8.hasNext()) { + pm.addMessage("Footer", tagValues); + pm.sendMessage(); + return; + } + + tax = (Tax)var8.next(); + } while(!allTaxes && !tax.getTaxData().isEnabled()); + + if (allTaxes) { + // Für /taxes-listall: Zeige ALLE Steuern, auch ohne Bracket + TagValues taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, null, null, (Double)null, (Double)null); + pm.addMessage("EachTax", taxTagValues); + } else { + // Für /taxes-list: Nur Steuern mit passendem Bracket + TaxBracketGroup taxBracketGroup = tax.getTaxBracketGroup(player); + if (taxBracketGroup != null) { + TaxBracket taxBracket = tax.getTaxBracket(player); + if (taxBracket != null) { + TagValues taxTagValues = new TaxTagValues(player, this.getPlugin().getEconomy(), tax, taxBracketGroup, taxBracket, (Double)null, (Double)null); + pm.addMessage("EachTax", taxTagValues); + } + } + } + } + } + } + + protected Tax getValidTax(CommandSender commandSender, String strTaxName) { + Tax retTax = null; + TaxNames taxName = TaxNames.getValidTaxName(strTaxName); + if (taxName != null) { + retTax = ((TaxesPlugin)this.getPlugin()).getTaxConfigData().getTax(taxName); + } + + if (retTax == null) { + TagValues tagValues = new TaxTagValues(); + CommandSenderMessage pm = new CommandSenderMessage(commandSender, this.getPlugin().getLanguageConfig().getMessage("PlayerInvalidTaxName"), tagValues); + pm.sendMessage(); + } + + return retTax; + } +} diff --git a/src/main/java/com/taxes/commands/TaxesTabCompleter.java b/src/main/java/com/taxes/commands/TaxesTabCompleter.java new file mode 100644 index 0000000..649540c --- /dev/null +++ b/src/main/java/com/taxes/commands/TaxesTabCompleter.java @@ -0,0 +1,79 @@ +package com.taxes.commands; + +import com.taxes.TaxesPlugin; +import com.taxes.tax.Tax; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TaxesTabCompleter implements TabCompleter { + private final TaxesPlugin plugin; + + public TaxesTabCompleter(TaxesPlugin plugin) { + this.plugin = plugin; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + List completions = new ArrayList<>(); + + if (args.length == 1) { + String cmdName = command.getName().toLowerCase(); + + if (cmdName.equals("taxes-collect") || cmdName.equals("tax-collect")) { + return getAvailableTaxes(sender, args[0], false); + } else if (cmdName.equals("taxes-info") || cmdName.equals("tax-info")) { + return getAvailableTaxes(sender, args[0], false); + } else if (cmdName.equals("taxes-infoall") || cmdName.equals("tax-infoall")) { + return getAvailableTaxes(sender, args[0], true); + } else if (cmdName.equals("taxes-list") || cmdName.equals("tax-list")) { + return Collections.emptyList(); + } else if (cmdName.equals("taxes-listall") || cmdName.equals("tax-listall")) { + return Collections.emptyList(); + } else if (cmdName.equals("taxes-collectall") || cmdName.equals("tax-collectall")) { + return Collections.emptyList(); + } else if (cmdName.equals("taxes-reload") || cmdName.equals("tax-reload")) { + return Collections.emptyList(); + } else if (cmdName.equals("taxes") || cmdName.equals("tax")) { + return Collections.emptyList(); + } + } + + return completions; + } + + /** + * Gibt alle verfügbaren Steuern für Tab-Completion zurück + * @param sender Der Command-Sender (Player oder Console) + * @param input Das aktuelle Input-String für Partial Matching + * @param showAll Alle Steuern zeigen (true) oder nur aktivierte (false) + * @return Liste der Steuernamen zum Completen + */ + private List getAvailableTaxes(CommandSender sender, String input, boolean showAll) { + List completions = new ArrayList<>(); + + for (Tax tax : this.plugin.getTaxConfigData().getTaxes()) { + // Wenn showAll=false, nur aktivierte Steuern zeigen + if (!showAll && !tax.getTaxData().isEnabled()) { + continue; + } + + String taxName = tax.getTaxData().getName().getConfigTag(); + + // StringUtil.copyPartialMatches für Partial String Matching + if (StringUtil.startsWithIgnoreCase(taxName, input)) { + completions.add(taxName); + } + } + + // Alphabetisch sortieren für bessere UX + Collections.sort(completions); + return completions; + } +} diff --git a/src/main/java/com/taxes/config/BatchProcessing.java b/src/main/java/com/taxes/config/BatchProcessing.java new file mode 100644 index 0000000..ac2b946 --- /dev/null +++ b/src/main/java/com/taxes/config/BatchProcessing.java @@ -0,0 +1,29 @@ +package com.taxes.config; + +public class BatchProcessing { + private boolean enabled; + private long batchSize; + private long batchDelay; + + public BatchProcessing(boolean enabled, long batchSize, long batchDelay) { + this.enabled = enabled; + this.batchSize = batchSize; + this.batchDelay = batchDelay; + } + + public boolean isEnabled() { + return this.enabled; + } + + public long getBatchSize() { + return this.batchSize; + } + + public long getBatchDelay() { + return this.batchDelay; + } + + public String toString() { + return "BatchProcessing [enabled=" + this.enabled + ", batchSize=" + this.batchSize + ", batchDelay=" + this.batchDelay + "]"; + } +} diff --git a/src/main/java/com/taxes/config/RuntimeConfigData.java b/src/main/java/com/taxes/config/RuntimeConfigData.java new file mode 100644 index 0000000..6fc7600 --- /dev/null +++ b/src/main/java/com/taxes/config/RuntimeConfigData.java @@ -0,0 +1,51 @@ +package com.taxes.config; + +import com.taxes.core.config.EnderConfig; +import com.taxes.core.util.Time; +import com.taxes.TaxesPlugin; +import com.taxes.tax.TaxNames; +import java.util.HashMap; +import java.util.Map; + +public class RuntimeConfigData extends EnderConfig { + private static final String PLUGIN_DATA_FILE = "data.yml"; + private static final String LAST_TIME_TAXED = "Taxes.%s.LastTimeTaxed"; + private Map lastTimeTaxedTicks = new HashMap(); + + public RuntimeConfigData(TaxesPlugin plugin) { + super(plugin, "data.yml"); + this.loadConfigData(); + } + + public void saveLastTimeTaxed(TaxNames tax, long timeTicks) { + this.lastTimeTaxedTicks.put(tax, timeTicks); + this.config.set(String.format("Taxes.%s.LastTimeTaxed", tax.getConfigTag()), timeTicks); + this.saveConfig(); + } + + public long getLastTimeTaxedTicks(TaxNames tax) { + return (Long)this.lastTimeTaxedTicks.get(tax); + } + + protected boolean loadConfigData() { + boolean configRead = false; + this.lastTimeTaxedTicks.clear(); + TaxNames[] var2 = TaxNames.values(); + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + TaxNames tax = var2[var4]; + long configLastTimeTaxed = this.config.getLong(String.format("Taxes.%s.LastTimeTaxed", tax.getConfigTag()), Time.getCurrentTimeInTicks()); + this.saveLastTimeTaxed(tax, configLastTimeTaxed); + } + + return configRead; + } + + public String toString() { + return "RuntimeConfigData [lastTimeTaxedTicks=" + this.lastTimeTaxedTicks + "]"; + } + + protected void updateConfigToCurrentVersion() { + } +} diff --git a/src/main/java/com/taxes/config/TaxConfigData.java b/src/main/java/com/taxes/config/TaxConfigData.java new file mode 100644 index 0000000..51f44c3 --- /dev/null +++ b/src/main/java/com/taxes/config/TaxConfigData.java @@ -0,0 +1,184 @@ +package com.taxes.config; + +import com.taxes.core.config.EnderConfig; +import com.taxes.TaxesPlugin; +import com.taxes.tax.Collection; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import com.taxes.tax.TaxFactory; +import com.taxes.tax.TaxNames; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.bukkit.configuration.ConfigurationSection; + +public final class TaxConfigData extends EnderConfig { + private static final String RELATIVE_PATH_FILE_NAME = "config.yml"; + private static final String TAXES = "Taxes"; + private static final String TOWNY_TAX = "TownyTax"; + private static final String TAX_TOWNY = "Taxes.TownyTax"; + private static final String TAX_ENABLED = "Taxes.%s.Enabled"; + private static final String TAX_FREQUENCY = "Taxes.%s.TaxFrequency"; + private static final String TAX_DEPOSIT_ACCOUNT = "Taxes.%s.TaxDepositAccount"; + private static final String TAX_DEPOSIT_ACCOUNT_ENABLED = "Taxes.%s.TaxDepositAccount.Enabled"; + private static final String TAX_DEPOSIT_ACCOUNT_NAME = "Taxes.%s.TaxDepositAccount.Name"; + private static final String TAX_COLLECTION = "Taxes.%s.TaxCollection"; + private static final String TAX_BATCH = "Taxes.%s.BatchProcessing"; + private static final String TAX_BATCH_ENABLED = "Taxes.%s.BatchProcessing.Enabled"; + private static final String TAX_BATCH_SIZE = "Taxes.%s.BatchProcessing.Size"; + private static final String TAX_BATCH_DELAY = "Taxes.%s.BatchProcessing.Delay"; + private static final String TAX_WITHDRAW_SOURCE = "Taxes.%s.WithdrawSource"; + private static final String TAX_COLLECTIONS = "TaxCollections"; + private static final String TAX_BRACKETS = "TaxBrackets"; + private static final String TAX_BRACKETS_GROUPS = "Groups"; + private static final String TAX_BRACKET_MAX_BALANCE = "%s.MaxBalance"; + private static final String TAX_BRACKET_TAX_AMOUNT = "%s.TaxAmount"; + private static final String TAX_BRACKET_TAX_TYPE = "%s.TaxType"; + private RuntimeConfigData runtimeData = null; + private final Map taxes = new HashMap(); + + public TaxConfigData(TaxesPlugin plugin, RuntimeConfigData runtimeData) { + super(plugin, "config.yml"); + this.runtimeData = runtimeData; + this.loadConfigData(); + } + + protected boolean loadConfigData() { + this.getPlugin().getLogger().info("=== Starting Config Load ==="); + boolean configLoaded = true; + ConfigurationSection collectionsSection = this.config.getConfigurationSection("TaxCollections"); + + if (collectionsSection == null) { + this.getPlugin().getLogger().severe("TaxCollections section is NULL! Config structure is invalid."); + return false; + } + + this.getPlugin().getLogger().info("Found TaxCollections section with keys: " + collectionsSection.getKeys(false)); + + Map collections = new HashMap(); + Iterator var4 = collectionsSection.getKeys(false).iterator(); + + String collectionName; + while(var4.hasNext()) { + collectionName = (String)var4.next(); + List taxBracketGroups = new ArrayList(); + ConfigurationSection collectionSection = collectionsSection.getConfigurationSection(collectionName); + Iterator var8 = collectionSection.getKeys(false).iterator(); + + while(var8.hasNext()) { + String bracketName = (String)var8.next(); + double minBalance = 0.0D; + double maxBalance = 0.0D; + double taxAmount = 0.0D; + List taxBrackets = new ArrayList(); + ConfigurationSection bracketGroupSection = collectionSection.getConfigurationSection(bracketName); + ConfigurationSection bracketsSection = bracketGroupSection.getConfigurationSection("TaxBrackets"); + + for(Iterator var20 = bracketsSection.getKeys(false).iterator(); var20.hasNext(); minBalance = maxBalance) { + String taxBracket = (String)var20.next(); + maxBalance = bracketsSection.getDouble(String.format("%s.MaxBalance", taxBracket)); + taxAmount = bracketsSection.getDouble(String.format("%s.TaxAmount", taxBracket)); + TaxBracket.TaxAmountType taxType = TaxBracket.TaxAmountType.valueOf(bracketsSection.getString(String.format("%s.TaxType", taxBracket))); + taxBrackets.add(new TaxBracket(taxBracket, minBalance, maxBalance, taxType, taxAmount)); + } + + taxBracketGroups.add(new TaxBracketGroup(collectionName, bracketGroupSection.getStringList("Groups"), taxBrackets)); + } + + collections.put(collectionName, new Collection(collectionName, taxBracketGroups)); + } + + TaxNames[] var22 = TaxNames.values(); + int var23 = var22.length; + + this.getPlugin().getLogger().info("Checking " + var23 + " tax types from TaxNames enum"); + + for(int var24 = 0; var24 < var23; ++var24) { + TaxNames taxName = var22[var24]; + this.getPlugin().getLogger().info("Checking tax: " + taxName.getConfigTag()); + + boolean taxEnabled = this.config.getBoolean(String.format("Taxes.%s.Enabled", taxName.getConfigTag())); + this.getPlugin().getLogger().info("Tax " + taxName.getConfigTag() + " enabled: " + taxEnabled); + + if (taxEnabled) { + collectionName = this.config.getString(String.format("Taxes.%s.TaxCollection", taxName.getConfigTag())); + Collection collection = (Collection)collections.get(collectionName); + if (collection == null) { + this.getPlugin().getLogger().severe(String.format("Invalid Collection '%s' specified for Tax '%s'. %s tax will be disabled.", collectionName, taxName.getConfigTag(), taxName.getConfigTag())); + taxEnabled = false; + } else { + BatchProcessing batchProcessing = new BatchProcessing(this.config.getBoolean(String.format("Taxes.%s.BatchProcessing.Enabled", taxName.getConfigTag())), (long)this.config.getInt(String.format("Taxes.%s.BatchProcessing.Size", taxName.getConfigTag())), (long)this.config.getInt(String.format("Taxes.%s.BatchProcessing.Delay", taxName.getConfigTag()))); + String withdrawSourceStr = this.config.getString(String.format("Taxes.%s.WithdrawSource", taxName.getConfigTag()), "PLAYER"); + TaxData.WithdrawSource withdrawSource = TaxData.WithdrawSource.PLAYER; + try { + withdrawSource = TaxData.WithdrawSource.valueOf(withdrawSourceStr.toUpperCase()); + } catch (IllegalArgumentException e) { + this.getPlugin().getLogger().warning("Invalid WithdrawSource '" + withdrawSourceStr + "' for tax '" + taxName.getConfigTag() + "'. Defaulting to PLAYER."); + } + TaxData taxData = new TaxData(taxName, taxEnabled, this.config.getString(String.format("Taxes.%s.TaxFrequency", taxName.getConfigTag())), this.config.getBoolean(String.format("Taxes.%s.TaxDepositAccount.Enabled", taxName.getConfigTag()), false), this.config.getString(String.format("Taxes.%s.TaxDepositAccount.Name", taxName.getConfigTag()), ""), batchProcessing, withdrawSource); + this.getPlugin().getLogger().finest("TAX_DEPOSIT_ACCOUNT_ENABLED = " + String.format("Taxes.%s.TaxDepositAccount.Enabled", taxName.getConfigTag())); + this.getPlugin().getLogger().finest("taxData = " + taxData.toString()); + Tax tax = TaxFactory.getTax(taxData, this.runtimeData.getLastTimeTaxedTicks(taxName), collection, this.getPlugin()); + if (tax != null) { + this.taxes.put(taxName, tax); + this.getPlugin().getLogger().info("Successfully loaded tax: " + taxName.getConfigTag()); + } else { + this.getPlugin().getLogger().severe("TaxFactory.getTax returned NULL for: " + taxName.getConfigTag()); + } + } + } + } + + this.getPlugin().getLogger().info("=== Config Load Complete. Total taxes loaded: " + this.taxes.size() + " ==="); + return configLoaded; + } + + protected void updateConfigToCurrentVersion() { + this.getPlugin().getLogger().finest("Entered updateConfigToCurrentVersion()"); + TaxNames[] var1 = TaxNames.values(); + int var2 = var1.length; + + for(int var3 = 0; var3 < var2; ++var3) { + TaxNames taxName = var1[var3]; + this.getPlugin().getLogger().finest(String.format("Taxes.%s.BatchProcessing", taxName.getConfigTag())); + if (!this.config.contains(String.format("Taxes.%s.BatchProcessing", taxName.getConfigTag()))) { + this.getPlugin().getLogger().finest("Adding Batch Processing to the config."); + this.config.set(String.format("Taxes.%s.BatchProcessing.Enabled", taxName.getConfigTag()), Boolean.FALSE); + this.config.set(String.format("Taxes.%s.BatchProcessing.Size", taxName.getConfigTag()), new Integer(500)); + this.config.set(String.format("Taxes.%s.BatchProcessing.Delay", taxName.getConfigTag()), new Integer(20)); + } + if (!this.config.contains(String.format("Taxes.%s.WithdrawSource", taxName.getConfigTag()))) { + this.getPlugin().getLogger().finest("Adding WithdrawSource to the config."); + this.config.set(String.format("Taxes.%s.WithdrawSource", taxName.getConfigTag()), "PLAYER"); + } + } + + } + + public Tax getTax(TaxNames tax) { + return (Tax)this.taxes.get(tax); + } + + public TaxesPlugin getPlugin() { + return (TaxesPlugin)super.getPlugin(); + } + + public String toString() { + return "TaxConfigData [runtimeData=" + this.runtimeData + ", taxes=" + this.taxes + "]"; + } + + public List getTaxes() { + List retTaxes = new ArrayList(); + Iterator var2 = this.taxes.values().iterator(); + + while(var2.hasNext()) { + Tax tax = (Tax)var2.next(); + retTaxes.add(tax); + } + + return retTaxes; + } +} diff --git a/src/main/java/com/taxes/config/TaxData.java b/src/main/java/com/taxes/config/TaxData.java new file mode 100644 index 0000000..b986ecc --- /dev/null +++ b/src/main/java/com/taxes/config/TaxData.java @@ -0,0 +1,105 @@ +package com.taxes.config; + +import com.taxes.tax.TaxNames; +import java.util.concurrent.TimeUnit; + +public class TaxData { + public enum WithdrawSource { + PLAYER, + BANK, + BANK_IF_AVAILABLE + } + + private TaxNames name; + private boolean enabled; + private long taxFrequencyTicks; + private String taxFrequencyFormatted; + private boolean depositAccountEnabled; + private String depositAccountName; + private BatchProcessing batchProcessing; + private WithdrawSource withdrawSource; + + public TaxData(TaxNames name, boolean enabled, String taxFrequency, boolean depositAccountEnabled, String depositAccountName, BatchProcessing batchProcessing) { + this(name, enabled, taxFrequency, depositAccountEnabled, depositAccountName, batchProcessing, WithdrawSource.PLAYER); + } + + public TaxData(TaxNames name, boolean enabled, String taxFrequency, boolean depositAccountEnabled, String depositAccountName, BatchProcessing batchProcessing, WithdrawSource withdrawSource) { + this.name = name; + this.enabled = enabled; + this.taxFrequencyTicks = this.getTaxFrequencyTicks(taxFrequency); + this.depositAccountEnabled = depositAccountEnabled; + this.depositAccountName = depositAccountName; + this.batchProcessing = batchProcessing; + this.withdrawSource = withdrawSource; + } + + private long getTaxFrequencyTicks(String taxFrequency) { + long taxFrequencyTicks = 0L; + long taxFrequencySeconds = 0L; + String strTaxFrequency = taxFrequency.replaceAll(" ", ""); + this.taxFrequencyFormatted = strTaxFrequency.substring(0, strTaxFrequency.length() - 1); + long lTaxFrequency = Long.valueOf(this.taxFrequencyFormatted, 10); + if (strTaxFrequency.endsWith("s")) { + taxFrequencySeconds = lTaxFrequency; + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " second"; + } else if (strTaxFrequency.endsWith("m")) { + taxFrequencySeconds = TimeUnit.SECONDS.convert(lTaxFrequency, TimeUnit.MINUTES); + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " minute"; + } else if (strTaxFrequency.endsWith("h")) { + taxFrequencySeconds = TimeUnit.SECONDS.convert(lTaxFrequency, TimeUnit.HOURS); + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " hour"; + } else if (strTaxFrequency.endsWith("d")) { + taxFrequencySeconds = TimeUnit.SECONDS.convert(lTaxFrequency, TimeUnit.DAYS); + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " day"; + } else if (strTaxFrequency.endsWith("w")) { + taxFrequencySeconds = TimeUnit.SECONDS.convert(lTaxFrequency, TimeUnit.DAYS) * 7L; + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " week"; + } else { + taxFrequencySeconds = TimeUnit.SECONDS.convert(1L, TimeUnit.DAYS); + this.taxFrequencyFormatted = this.taxFrequencyFormatted + " day"; + } + + taxFrequencyTicks = taxFrequencySeconds * 20L; + if (lTaxFrequency > 1L) { + this.taxFrequencyFormatted = this.taxFrequencyFormatted + "s"; + } + + return taxFrequencyTicks; + } + + public TaxNames getName() { + return this.name; + } + + public boolean isEnabled() { + return this.enabled; + } + + public long getTaxFrequencyTicks() { + return this.taxFrequencyTicks; + } + + public boolean isDepositAccountEnabled() { + return this.depositAccountEnabled; + } + + public String getDepositAccountName() { + return this.depositAccountName; + } + + public String getTaxFrequencyFormated() { + return this.taxFrequencyFormatted; + } + + public BatchProcessing getBatchProcessing() { + return this.batchProcessing; + } + + public WithdrawSource getWithdrawSource() { + return this.withdrawSource; + } + + public String toString() { + return "TaxData [name=" + this.name + ", enabled=" + this.enabled + ", taxFrequencyTicks=" + this.taxFrequencyTicks + ", taxFrequencyFormatted=" + this.taxFrequencyFormatted + ", depositAccountEnabled=" + this.depositAccountEnabled + ", depositAccountName=" + this.depositAccountName + ", batchProcessing=" + this.batchProcessing + ", withdrawSource=" + this.withdrawSource + "]"; + } +} diff --git a/src/main/java/com/taxes/core/TaxesCore.java b/src/main/java/com/taxes/core/TaxesCore.java new file mode 100644 index 0000000..2476ea4 --- /dev/null +++ b/src/main/java/com/taxes/core/TaxesCore.java @@ -0,0 +1,198 @@ +package com.taxes.core; + +import com.taxes.core.config.LanguageConfig; +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.bukkit.scheduler.BukkitTask; + +public abstract class TaxesCore extends JavaPlugin { + private static final String DEFAULT_CONFIG_FILE = "defaultConfig.yml"; + private static final int MAX_TASK_WAIT_TRIES = 5; + private static final int TASK_WAIT_SLEEP_SECONDS = 1; + private Permission permission = null; + private Economy economy = null; + private LanguageConfig languageConfig = null; + protected static TaxesCore instance = null; + private List taskList = new ArrayList(); + + public TaxesCore() { + instance = this; + } + + public TaxesCore(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + instance = this; + } + + public void onDisable() { + this.unload(); + this.getLogger().info(String.format("[%s] Disabled Version %s", this.getDescription().getName(), this.getDescription().getVersion())); + } + + public void onEnable() { + this.languageConfig = new LanguageConfig(this); + // Verzögere das Laden um 20 Ticks (1 Sekunde), damit CMI Economy Zeit hat sich zu registrieren + Bukkit.getScheduler().runTaskLater(this, () -> { + this.load(); + }, 20L); + } + + private void disablePlugin() { + this.getServer().getPluginManager().disablePlugin(this); + } + + protected boolean setupVaultPlugin() { + boolean isSetup = false; + if (this.isVaultLoaded() && this.setupEconomy() && this.setupPermissions()) { + isSetup = true; + } + + if (!isSetup) { + this.disablePlugin(); + } + + return isSetup; + } + + private boolean isVaultLoaded() { + boolean isLoaded = this.getServer().getPluginManager().getPlugin("Vault") != null; + if (!isLoaded) { + this.getLogger().severe("Vault plugin is not loaded."); + } + + return isLoaded; + } + + private boolean setupPermissions() { + if (this.permission == null) { + RegisteredServiceProvider permissionProvider = this.getServer().getServicesManager().getRegistration(Permission.class); + if (permissionProvider != null) { + this.permission = (Permission)permissionProvider.getProvider(); + } + + if (this.permission != null) { + this.getLogger().info("Vault permissions was initialized"); + } else { + this.getLogger().warning("Vault permissions failed to initialize."); + } + } + + return this.permission != null; + } + + private boolean setupEconomy() { + if (this.economy == null) { + RegisteredServiceProvider economyProvider = this.getServer().getServicesManager().getRegistration(Economy.class); + if (economyProvider != null) { + this.economy = (Economy)economyProvider.getProvider(); + } + + if (this.economy != null) { + this.getLogger().info("Vault economy was initialized"); + } else { + this.getLogger().warning("Vault economy failed to initialize."); + } + } + + return this.economy != null; + } + + public boolean reloadPlugin(CommandSender sender) { + this.waitForRunningTasks(); + boolean success = this.unload(); + if (success) { + this.stopAllTasks(); + this.languageConfig = new LanguageConfig(this); + success = this.load(); + } + + if (success) { + sender.sendMessage(String.format(ChatColor.DARK_PURPLE + "%s configs reloaded.", this.getName())); + } else { + sender.sendMessage(String.format(ChatColor.RED + "%s configs failed to reload.", this.getName())); + } + + return success; + } + + protected void addTask(Runnable task, long delay, long frequency) { + this.taskList.add(Bukkit.getServer().getScheduler().runTaskTimer(this, task, delay, frequency)); + } + + protected boolean waitForRunningTasks() { + boolean tasksRunning = false; + int tries = 1; + + do { + Iterator var3 = this.taskList.iterator(); + + while(var3.hasNext()) { + BukkitTask task = (BukkitTask)var3.next(); + if (Bukkit.getServer().getScheduler().isCurrentlyRunning(task.getTaskId())) { + tasksRunning = true; + break; + } + } + + if (tasksRunning) { + try { + Thread.sleep(1000L); + } catch (InterruptedException var5) { + var5.printStackTrace(); + } + } + + ++tries; + } while(tasksRunning && tries <= 5); + + return tasksRunning; + } + + protected boolean stopAllTasks() { + this.waitForRunningTasks(); + Bukkit.getServer().getScheduler().cancelTasks(this); + this.taskList.clear(); + return true; + } + + public boolean restartAllTasks() { + this.stopAllTasks(); + this.scheduleTasks(); + return true; + } + + public Permission getPermission() { + return this.permission; + } + + public Economy getEconomy() { + return this.economy; + } + + public LanguageConfig getLanguageConfig() { + return this.languageConfig; + } + + public static TaxesCore getInstance() { + return instance; + } + + protected abstract boolean load(); + + protected abstract boolean unload(); + + protected abstract boolean registerCommands(); + + protected abstract boolean scheduleTasks(); +} diff --git a/src/main/java/com/taxes/core/TaxesCoreRun.java b/src/main/java/com/taxes/core/TaxesCoreRun.java new file mode 100644 index 0000000..05fc0f6 --- /dev/null +++ b/src/main/java/com/taxes/core/TaxesCoreRun.java @@ -0,0 +1,15 @@ +package com.taxes.core; + +import org.bukkit.plugin.java.JavaPlugin; + +public class TaxesCoreRun extends JavaPlugin { + public void onDisable() { + this.getLogger().info("Plugin Disabled."); + super.onDisable(); + } + + public void onEnable() { + this.getLogger().info("Plugin Enabled."); + super.onEnable(); + } +} diff --git a/src/main/java/com/taxes/core/command/EnderCommand.java b/src/main/java/com/taxes/core/command/EnderCommand.java new file mode 100644 index 0000000..4319466 --- /dev/null +++ b/src/main/java/com/taxes/core/command/EnderCommand.java @@ -0,0 +1,29 @@ +package com.taxes.core.command; + +import com.taxes.core.TaxesCore; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public abstract class EnderCommand implements CommandExecutor { + private TaxesCore plugin = null; + + public EnderCommand(TaxesCore plugin) { + this.plugin = plugin; + } + + protected TaxesCore getPlugin() { + return this.plugin; + } + + protected Boolean isPlayer(CommandSender sender) { + Boolean ret = true; + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.GOLD + "This command can only be run by a player."); + ret = false; + } + + return ret; + } +} diff --git a/src/main/java/com/taxes/core/command/HelpCommand.java b/src/main/java/com/taxes/core/command/HelpCommand.java new file mode 100644 index 0000000..90f5ff0 --- /dev/null +++ b/src/main/java/com/taxes/core/command/HelpCommand.java @@ -0,0 +1,71 @@ +package com.taxes.core.command; + +import com.taxes.core.TaxesCore; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class HelpCommand extends EnderCommand { + public HelpCommand(TaxesCore plugin) { + super(plugin); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (this.isPlayer(sender)) { + List output = new ArrayList(); + output.add(ChatColor.GOLD.toString()); + output.add(ChatColor.GOLD + this.getPlugin().getDescription().getName() + " v" + this.getPlugin().getDescription().getVersion() + " Help:"); + Iterator var6 = this.getPlugin().getDescription().getCommands().entrySet().iterator(); + + while(var6.hasNext()) { + Entry> pluginCommand = (Entry)var6.next(); + String commandUsage = ""; + String commandDescription = ""; + String commandAliases = ""; + String commandPerm = ""; + String commandName = (String)pluginCommand.getKey(); + Iterator var13 = ((Map)pluginCommand.getValue()).entrySet().iterator(); + + while(var13.hasNext()) { + Entry commandAttr = (Entry)var13.next(); + String attrName = ((String)commandAttr.getKey()).substring(0, 1).toUpperCase() + ((String)commandAttr.getKey()).substring(1); + if (attrName.equalsIgnoreCase("permission") && !this.getPlugin().getPermission().has(sender, commandAttr.getValue().toString())) { + break; + } + + if (attrName.equalsIgnoreCase("description")) { + commandDescription = ChatColor.GOLD + commandAttr.getValue().toString(); + } + + if (attrName.equalsIgnoreCase("usage")) { + commandUsage = commandAttr.getValue().toString().replace("", commandName); + int index = commandUsage.indexOf(47); + commandUsage = ChatColor.DARK_PURPLE + commandUsage.substring(index); + } + + if (attrName.equalsIgnoreCase("aliases")) { + commandAliases = ChatColor.GOLD + " " + attrName + ChatColor.WHITE + ": " + ChatColor.DARK_PURPLE + commandAttr.getValue().toString(); + } + + if (attrName.equalsIgnoreCase("permission")) { + commandPerm = ChatColor.GOLD + " " + attrName + ChatColor.WHITE + ": " + ChatColor.DARK_PURPLE + commandAttr.getValue().toString(); + } + } + + output.add(commandUsage + ChatColor.WHITE + " - " + commandDescription); + output.add(commandAliases); + output.add(commandPerm); + } + + output.add(ChatColor.GOLD.toString()); + sender.sendMessage((String[])output.toArray(new String[0])); + } + + return true; + } +} diff --git a/src/main/java/com/taxes/core/config/EnderConfig.java b/src/main/java/com/taxes/core/config/EnderConfig.java new file mode 100644 index 0000000..9319eb3 --- /dev/null +++ b/src/main/java/com/taxes/core/config/EnderConfig.java @@ -0,0 +1,83 @@ +package com.taxes.core.config; + +import com.taxes.core.TaxesCore; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.logging.Level; +import org.bukkit.configuration.file.YamlConfiguration; + +public abstract class EnderConfig { + public static final String DEBUG_PATH = "Debug"; + private TaxesCore plugin; + private File configFile; + private String defaultFile; + protected YamlConfiguration config; + + public EnderConfig(TaxesCore plugin, String relativePathFileName) { + this.plugin = plugin; + this.defaultFile = relativePathFileName; + this.configFile = new File(plugin.getDataFolder() + "/" + relativePathFileName); + if (!this.configFile.exists()) { + plugin.saveResource(relativePathFileName, false); + this.configFile = new File(plugin.getDataFolder() + "/" + relativePathFileName); + } + + this.config = YamlConfiguration.loadConfiguration(this.configFile); + this.updateConfigToCurrentVersion(); + this.config.options().indent(4); + this.config.options().copyHeader(true); + + try { + this.config.save(this.configFile); + } catch (IOException var4) { + var4.printStackTrace(); + } + + if (this.config.getBoolean("Debug", false)) { + plugin.getLogger().setLevel(Level.FINEST); + } + + } + + public boolean reloadConfigData() { + this.config = YamlConfiguration.loadConfiguration(this.configFile); + return this.loadConfigData(); + } + + protected void copyDefaults() { + this.config.options().copyDefaults(true); + InputStreamReader defConfigStream = null; + + try { + defConfigStream = new InputStreamReader(this.plugin.getResource(this.defaultFile), "UTF8"); + } catch (UnsupportedEncodingException var3) { + var3.printStackTrace(); + } + + if (defConfigStream != null) { + YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream); + this.config.setDefaults(defConfig); + } + + this.saveConfig(); + } + + public void saveConfig() { + try { + this.config.save(this.configFile); + } catch (IOException var2) { + var2.printStackTrace(); + } + + } + + protected TaxesCore getPlugin() { + return this.plugin; + } + + protected abstract void updateConfigToCurrentVersion(); + + protected abstract boolean loadConfigData(); +} diff --git a/src/main/java/com/taxes/core/config/LanguageConfig.java b/src/main/java/com/taxes/core/config/LanguageConfig.java new file mode 100644 index 0000000..6f8ad3d --- /dev/null +++ b/src/main/java/com/taxes/core/config/LanguageConfig.java @@ -0,0 +1,105 @@ +package com.taxes.core.config; + +import com.taxes.core.TaxesCore; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.bukkit.ChatColor; +import org.bukkit.configuration.ConfigurationSection; + +public class LanguageConfig extends EnderConfig { + private static final String CONFIG_FILE = "language.yml"; + private static final String SETTINGS_KEY = "Settings"; + private static final String MESSAGES_KEY = "Messages"; + private static final String MESSAGE_ENABLED = "Messages.%s.Enabled"; + private static final String MESSAGE_CONTENTS = "Messages.%s.Contents"; + private static final String SUBMESSAGES_KEY = "Messages.%s.Contents"; + private static final String SUBMESSAGE_CONTENTS = "Messages.%s.Contents.%s"; + private static final String INVALID_MESSAGE_KEY = "Invalid message key: %s"; + private static final String INVALID_SETTING_KEY = "Invalid setting key: %s"; + private final Map messageMap = new HashMap(); + + public LanguageConfig(TaxesCore plugin) { + super(plugin, "language.yml"); + this.copyDefaults(); + this.loadConfigData(); + } + + protected boolean loadConfigData() { + Iterator var1 = this.config.getConfigurationSection("Messages").getKeys(false).iterator(); + + while(true) { + String keyMessage; + LanguageMessage langMessage; + ConfigurationSection subMessageSection; + do { + if (!var1.hasNext()) { + return true; + } + + keyMessage = (String)var1.next(); + boolean enabled = this.config.getBoolean(String.format("Messages.%s.Enabled", keyMessage)); + List messages = new ArrayList(); + Iterator var5 = this.config.getStringList(String.format("Messages.%s.Contents", keyMessage)).iterator(); + + while(var5.hasNext()) { + String message = (String)var5.next(); + messages.add(ChatColor.translateAlternateColorCodes('&', message)); + } + + langMessage = new LanguageMessage(keyMessage, enabled, messages); + this.messageMap.put(keyMessage, langMessage); + subMessageSection = this.config.getConfigurationSection(String.format("Messages.%s.Contents", keyMessage)); + } while(subMessageSection == null); + + Iterator var7 = subMessageSection.getKeys(false).iterator(); + + while(var7.hasNext()) { + String keySubMessage = (String)var7.next(); + List subMessages = new ArrayList(); + Iterator var10 = this.config.getStringList(String.format("Messages.%s.Contents.%s", keyMessage, keySubMessage)).iterator(); + + while(var10.hasNext()) { + String subMessage = (String)var10.next(); + subMessages.add(ChatColor.translateAlternateColorCodes('&', subMessage)); + } + + langMessage.addSubMessage(keySubMessage, subMessages); + } + } + } + + public LanguageMessage getMessage(String msgKey) { + LanguageMessage langMessage = (LanguageMessage)this.messageMap.get(msgKey); + if (langMessage == null) { + this.getPlugin().getLogger().warning(String.format("Invalid message key: %s", msgKey)); + langMessage = new LanguageMessage(msgKey, false, new ArrayList()); + } + + return langMessage; + } + + protected void updateConfigToCurrentVersion() { + Iterator var1 = this.config.getConfigurationSection("Messages").getKeys(false).iterator(); + + while(var1.hasNext()) { + String keyMessage = (String)var1.next(); + if (!this.config.contains(String.format("Messages.%s.Enabled", keyMessage))) { + List messages = this.config.getStringList("Messages." + keyMessage); + Boolean enabled = !messages.isEmpty(); + if (keyMessage.equals("PlayerTaxCollected") && ((String)messages.get(0)).equals("&6Taxes were collected from your balance.")) { + messages.set(0, "&5{TAX_NAME} &6taxes were collected from you."); + } + + this.config.set("Messages." + keyMessage, (Object)null); + this.config.set(String.format("Messages.%s.Enabled", keyMessage), enabled); + this.config.set(String.format("Messages.%s.Contents", keyMessage), messages); + } + } + + this.config.set("Messages.PlayerNationTaxCollected", (Object)null); + this.config.set("Messages.PlayerTownTaxCollected", (Object)null); + } +} diff --git a/src/main/java/com/taxes/core/config/LanguageMessage.java b/src/main/java/com/taxes/core/config/LanguageMessage.java new file mode 100644 index 0000000..0e7d331 --- /dev/null +++ b/src/main/java/com/taxes/core/config/LanguageMessage.java @@ -0,0 +1,75 @@ +package com.taxes.core.config; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LanguageMessage { + private boolean enabled = false; + private String messageName = ""; + private final Map> contents = new HashMap(); + + public LanguageMessage(String messageName, boolean enabled, List messages) { + this.messageName = messageName; + this.enabled = enabled; + this.addSubMessage(messageName, messages); + } + + public void addSubMessage(String messageKey, List messages) { + this.contents.put(messageKey, messages); + } + + public boolean isEnabled() { + return this.enabled; + } + + public String getName() { + return this.messageName; + } + + public List getMessage() { + return this.getMessage(this.messageName); + } + + public List getMessage(String subMessageName) { + List message = (List)this.contents.get(subMessageName); + if (message == null) { + message = new ArrayList(); + } + + return (List)message; + } + + public int hashCode() { + int prime = 31; + int result = 1; + result = prime * result + (this.messageName == null ? 0 : this.messageName.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (this.getClass() != obj.getClass()) { + return false; + } else { + LanguageMessage other = (LanguageMessage)obj; + if (this.messageName == null) { + if (other.messageName != null) { + return false; + } + } else if (!this.messageName.equals(other.messageName)) { + return false; + } + + return true; + } + } + + public String toString() { + return "LanguageMessage [enabled=" + this.enabled + ", messageName=" + this.messageName + ", contents=" + this.contents + "]"; + } +} diff --git a/src/main/java/com/taxes/core/messages/BroadcastMessage.java b/src/main/java/com/taxes/core/messages/BroadcastMessage.java new file mode 100644 index 0000000..fd9973e --- /dev/null +++ b/src/main/java/com/taxes/core/messages/BroadcastMessage.java @@ -0,0 +1,22 @@ +package com.taxes.core.messages; + +import com.taxes.core.config.LanguageMessage; +import com.taxes.core.tag.TagValues; +import java.util.Iterator; +import org.bukkit.Bukkit; + +public class BroadcastMessage extends Message { + public BroadcastMessage(LanguageMessage langMessage, TagValues tagValues) { + super(langMessage, tagValues); + } + + public void sendMessage() { + Iterator var1 = this.messages.iterator(); + + while(var1.hasNext()) { + String message = (String)var1.next(); + Bukkit.broadcastMessage(message); + } + + } +} diff --git a/src/main/java/com/taxes/core/messages/CommandSenderMessage.java b/src/main/java/com/taxes/core/messages/CommandSenderMessage.java new file mode 100644 index 0000000..cd1618b --- /dev/null +++ b/src/main/java/com/taxes/core/messages/CommandSenderMessage.java @@ -0,0 +1,21 @@ +package com.taxes.core.messages; + +import com.taxes.core.config.LanguageMessage; +import com.taxes.core.tag.TagValues; +import org.bukkit.command.CommandSender; + +public class CommandSenderMessage extends Message { + protected CommandSender commandSender; + + public CommandSenderMessage(CommandSender commandSender, LanguageMessage langMessage, TagValues tagValues) { + super(langMessage, tagValues); + this.commandSender = commandSender; + } + + public void sendMessage() { + if (this.commandSender != null) { + this.commandSender.sendMessage((String[])this.messages.toArray(new String[0])); + } + + } +} diff --git a/src/main/java/com/taxes/core/messages/Message.java b/src/main/java/com/taxes/core/messages/Message.java new file mode 100644 index 0000000..9e96a0a --- /dev/null +++ b/src/main/java/com/taxes/core/messages/Message.java @@ -0,0 +1,39 @@ +package com.taxes.core.messages; + +import com.taxes.core.config.LanguageMessage; +import com.taxes.core.tag.Tag; +import com.taxes.core.tag.TagValues; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public abstract class Message { + private LanguageMessage langMessage; + protected List messages = new ArrayList(); + + public Message(LanguageMessage langMessage, TagValues tagValues) { + this.langMessage = langMessage; + this.addMessage(langMessage.getName(), tagValues); + } + + public void addMessage(String messageKey, TagValues tagValues) { + if (this.langMessage.isEnabled()) { + this.messages.addAll(this.replaceTags(this.langMessage.getMessage(messageKey), tagValues)); + } + + } + + private List replaceTags(List unFormattedMessages, TagValues tagValues) { + List formattedMessage = new ArrayList(); + Iterator var4 = unFormattedMessages.iterator(); + + while(var4.hasNext()) { + String unFormattedMessage = (String)var4.next(); + formattedMessage.add(Tag.replace(unFormattedMessage, tagValues)); + } + + return formattedMessage; + } + + public abstract void sendMessage(); +} diff --git a/src/main/java/com/taxes/core/messages/PlayerMessage.java b/src/main/java/com/taxes/core/messages/PlayerMessage.java new file mode 100644 index 0000000..ea78f1a --- /dev/null +++ b/src/main/java/com/taxes/core/messages/PlayerMessage.java @@ -0,0 +1,11 @@ +package com.taxes.core.messages; + +import com.taxes.core.config.LanguageMessage; +import com.taxes.core.tag.TagValues; +import org.bukkit.entity.Player; + +public class PlayerMessage extends CommandSenderMessage { + public PlayerMessage(Player player, LanguageMessage langMessage, TagValues tagValues) { + super(player, langMessage, tagValues); + } +} diff --git a/src/main/java/com/taxes/core/tag/EconTagValues.java b/src/main/java/com/taxes/core/tag/EconTagValues.java new file mode 100644 index 0000000..b7c03e4 --- /dev/null +++ b/src/main/java/com/taxes/core/tag/EconTagValues.java @@ -0,0 +1,14 @@ +package com.taxes.core.tag; + +import net.milkbowl.vault.economy.Economy; +import org.bukkit.entity.Player; + +public class EconTagValues extends PlayerTagValues { + public EconTagValues(Player player, Economy econ) { + super(player); + if (player != null && econ != null) { + this.addTagValuePair(Tag.PLAYER_BALANCE, new Value(econ.getBalance(player))); + } + + } +} diff --git a/src/main/java/com/taxes/core/tag/PlayerTagValues.java b/src/main/java/com/taxes/core/tag/PlayerTagValues.java new file mode 100644 index 0000000..9b34b2e --- /dev/null +++ b/src/main/java/com/taxes/core/tag/PlayerTagValues.java @@ -0,0 +1,15 @@ +package com.taxes.core.tag; + +import org.bukkit.entity.Player; + +public class PlayerTagValues extends TagValues { + public PlayerTagValues(Player player) { + if (player != null) { + this.addTagValuePair(Tag.PLAYER, new Value(player.getName())); + this.addTagValuePair(Tag.PLAYER_REAL_NAME, new Value(player.getName())); + this.addTagValuePair(Tag.PLAYER_DISPLAY_NAME, new Value(player.getDisplayName())); + this.addTagValuePair(Tag.PLAYER_UUID, new Value(player.getUniqueId().toString())); + } + + } +} diff --git a/src/main/java/com/taxes/core/tag/Tag.java b/src/main/java/com/taxes/core/tag/Tag.java new file mode 100644 index 0000000..6716c27 --- /dev/null +++ b/src/main/java/com/taxes/core/tag/Tag.java @@ -0,0 +1,52 @@ +package com.taxes.core.tag; + +import java.util.Iterator; +import java.util.Map.Entry; + +public enum Tag { + PLAYER, + PLAYER_REAL_NAME, + PLAYER_DISPLAY_NAME, + PLAYER_UUID, + PLAYER_BALANCE, + TAX_NAME, + TAX_ENABLED, + TAX_FREQUENCY, + TAX_DEPOSIT_ENABLED, + TAX_DEPOSIT_ACCOUNT, + PRE_TAX_BALANCE, + POST_TAX_BALANCE, + TAX_AMOUNT_TAXED, + TAX_COLLECTION_NAME, + TAX_BRACKET_GROUP_NAME, + TAX_BRACKET_GROUP_GROUPS, + TAX_BRACKET_NAME, + TAX_BRACKET_MIN, + TAX_BRACKET_MAX, + TAX_BRACKET_AMOUNT, + TAX_BRACKET_AMOUNT_TYPE, + TAX_NEXT_COLLECTION_TIME, + TAX_NAME_LIST, + MCMMO_SKILL, + MCMMO_LEVEL, + MCMMO_REWARD_NAME, + MCMMO_REWARD_TEXT; + + private String tagName = "{" + this.name() + "}"; + + public static String replace(String text, TagValues tagValues) { + String replacementText = text; + + Entry value; + for(Iterator var3 = tagValues.getTagsValuePairs().entrySet().iterator(); var3.hasNext(); replacementText = replacementText.replace(((Tag)value.getKey()).tagName, ((Value)value.getValue()).getTagValue())) { + value = (Entry)var3.next(); + } + + return replacementText; + } + + // $FF: synthetic method + private static Tag[] $values() { + return new Tag[]{PLAYER, PLAYER_REAL_NAME, PLAYER_DISPLAY_NAME, PLAYER_UUID, PLAYER_BALANCE, TAX_NAME, TAX_ENABLED, TAX_FREQUENCY, TAX_DEPOSIT_ENABLED, TAX_DEPOSIT_ACCOUNT, PRE_TAX_BALANCE, POST_TAX_BALANCE, TAX_AMOUNT_TAXED, TAX_COLLECTION_NAME, TAX_BRACKET_GROUP_NAME, TAX_BRACKET_GROUP_GROUPS, TAX_BRACKET_NAME, TAX_BRACKET_MIN, TAX_BRACKET_MAX, TAX_BRACKET_AMOUNT, TAX_BRACKET_AMOUNT_TYPE, TAX_NEXT_COLLECTION_TIME, TAX_NAME_LIST, MCMMO_SKILL, MCMMO_LEVEL, MCMMO_REWARD_NAME, MCMMO_REWARD_TEXT}; + } +} diff --git a/src/main/java/com/taxes/core/tag/TagValues.java b/src/main/java/com/taxes/core/tag/TagValues.java new file mode 100644 index 0000000..a129ada --- /dev/null +++ b/src/main/java/com/taxes/core/tag/TagValues.java @@ -0,0 +1,24 @@ +package com.taxes.core.tag; + +import java.util.HashMap; +import java.util.Map; + +public abstract class TagValues { + private final Map tagsValuePairs = new HashMap(); + + public void setTagValue(Tag tag, Value value) { + this.tagsValuePairs.put(tag, value); + } + + public void addTagValuePair(Tag tag, Value value) { + this.tagsValuePairs.put(tag, value); + } + + public Map getTagsValuePairs() { + return this.tagsValuePairs; + } + + public String toString() { + return "TagValues [tagsValuePairs=" + this.tagsValuePairs + "]"; + } +} diff --git a/src/main/java/com/taxes/core/tag/Value.java b/src/main/java/com/taxes/core/tag/Value.java new file mode 100644 index 0000000..5d4f972 --- /dev/null +++ b/src/main/java/com/taxes/core/tag/Value.java @@ -0,0 +1,53 @@ +package com.taxes.core.tag; + +import com.taxes.core.util.NumberFormat; +import java.util.List; + +public class Value { + private String value; + + public Value(String value) { + this.value = ""; + this.value = value; + } + + public Value(Double value) { + this(NumberFormat.formatNumber(value)); + } + + public Value(Float value) { + this(NumberFormat.formatNumber(value)); + } + + public Value(Integer value) { + this(NumberFormat.formatNumber(value)); + } + + public Value(Long value) { + this(NumberFormat.formatNumber(value)); + } + + public Value(Boolean value) { + this(value ? "Yes" : "No"); + } + + public Value(List groups) { + this(groups.toString()); + } + + public void addPrefix(String prefix) { + this.value = prefix + this.value; + } + + public void addSuffix(String suffix) { + this.value = this.value + suffix; + } + + public String getTagValue() { + return this.value; + } + + public String toString() { + return "Value [value=" + this.value + "]"; + } +} diff --git a/src/main/java/com/taxes/core/task/EnderTask.java b/src/main/java/com/taxes/core/task/EnderTask.java new file mode 100644 index 0000000..57eabb1 --- /dev/null +++ b/src/main/java/com/taxes/core/task/EnderTask.java @@ -0,0 +1,15 @@ +package com.taxes.core.task; + +import com.taxes.core.TaxesCore; + +public abstract class EnderTask implements Runnable { + private static TaxesCore plugin; + + public EnderTask(TaxesCore plugin) { + EnderTask.plugin = plugin; + } + + public TaxesCore getPlugin() { + return plugin; + } +} diff --git a/src/main/java/com/taxes/core/util/NumberFormat.java b/src/main/java/com/taxes/core/util/NumberFormat.java new file mode 100644 index 0000000..b2e07a6 --- /dev/null +++ b/src/main/java/com/taxes/core/util/NumberFormat.java @@ -0,0 +1,25 @@ +package com.taxes.core.util; + +import java.text.DecimalFormat; + +public class NumberFormat { + private static final String MAX_DISPLAY_VALUE = "(Infinity)"; + private static DecimalFormat decimalFormat = new DecimalFormat("#,###.##"); + private static DecimalFormat integerFormat = new DecimalFormat("#,###"); + + public static String formatNumber(Double number) { + return number == Double.MAX_VALUE ? "(Infinity)" : decimalFormat.format(number); + } + + public static String formatNumber(Float number) { + return number == Float.MAX_VALUE ? "(Infinity)" : decimalFormat.format(number); + } + + public static String formatNumber(Integer number) { + return number == Integer.MAX_VALUE ? "(Infinity)" : integerFormat.format(number); + } + + public static String formatNumber(Long number) { + return number == Long.MAX_VALUE ? "(Infinity)" : integerFormat.format(number); + } +} diff --git a/src/main/java/com/taxes/core/util/Time.java b/src/main/java/com/taxes/core/util/Time.java new file mode 100644 index 0000000..0580228 --- /dev/null +++ b/src/main/java/com/taxes/core/util/Time.java @@ -0,0 +1,48 @@ +package com.taxes.core.util; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class Time { + private static final long SECONDS_PER_DAY = 86400L; + private static final long SECONDS_PER_HOUR = 3600L; + private static final long SECONDS_PER_MINUTE = 60L; + private static final long SECONDS_PER_MONTH = 2419200L; + private static final long SECONDS_PER_WEEK = 604800L; + + public static long getCurrentTimeInTicks() { + return TimeUnit.SECONDS.convert((new Date()).getTime(), TimeUnit.MILLISECONDS) * 20L; + } + + public static String getFormatedDuration(long timeInSeconds) { + String formatedDuration = ""; + long months = timeInSeconds / 2419200L; + long timeLeft = timeInSeconds - months * 2419200L; + long weeks = timeLeft / 604800L; + timeLeft -= weeks * 604800L; + long days = timeLeft / 86400L; + timeLeft -= days * 86400L; + long hours = timeLeft / 3600L; + timeLeft -= hours * 3600L; + long minutes = timeLeft / 60L; + timeLeft -= minutes * 60L; + if (weeks > 0L) { + formatedDuration = formatedDuration + String.format("%d Weeks, ", days); + } + + if (weeks > 0L || days > 0L) { + formatedDuration = formatedDuration + String.format("%d Days, ", days); + } + + if (weeks > 0L || days > 0L || hours > 0L) { + formatedDuration = formatedDuration + String.format("%d Hours, ", hours); + } + + if (weeks > 0L || days > 0L || hours > 0L || minutes > 0L) { + formatedDuration = formatedDuration + String.format("%d Minutes, ", minutes); + } + + formatedDuration = formatedDuration + String.format("%d Seconds", timeLeft); + return formatedDuration; + } +} diff --git a/src/main/java/com/taxes/data/PermissionString.java b/src/main/java/com/taxes/data/PermissionString.java new file mode 100644 index 0000000..73216f2 --- /dev/null +++ b/src/main/java/com/taxes/data/PermissionString.java @@ -0,0 +1,20 @@ +package com.taxes.data; + +public enum PermissionString { + PLAYER_BALANCE_BYPASS_TAXES("PlayerBalanceTaxes.bypass.taxes"); + + private String permString; + + private PermissionString(String permString) { + this.permString = permString; + } + + public String getPermString() { + return this.permString; + } + + // $FF: synthetic method + private static PermissionString[] $values() { + return new PermissionString[]{PLAYER_BALANCE_BYPASS_TAXES}; + } +} diff --git a/src/main/java/com/taxes/tag/TaxTagValues.java b/src/main/java/com/taxes/tag/TaxTagValues.java new file mode 100644 index 0000000..b38e39d --- /dev/null +++ b/src/main/java/com/taxes/tag/TaxTagValues.java @@ -0,0 +1,61 @@ +package com.taxes.tag; + +import com.taxes.core.tag.EconTagValues; +import com.taxes.core.tag.Tag; +import com.taxes.core.tag.Value; +import com.taxes.TaxesPlugin; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.entity.Player; + +public class TaxTagValues extends EconTagValues { + public TaxTagValues() { + this((Player)null, (Economy)null, (Tax)null, (TaxBracketGroup)null, (TaxBracket)null, (Double)null, (Double)null); + } + + public TaxTagValues(Tax tax) { + this((Player)null, (Economy)null, tax, (TaxBracketGroup)null, (TaxBracket)null, (Double)null, (Double)null); + } + + public TaxTagValues(Player player, Economy econ, Tax tax, TaxBracketGroup taxBracketGroup, TaxBracket taxBracket, Double prevBalance, Double amountTaxed) { + super(player, econ); + if (prevBalance != null) { + this.addTagValuePair(Tag.PRE_TAX_BALANCE, new Value(prevBalance)); + } + + if (player != null && econ != null && tax != null && amountTaxed != null) { + this.addTagValuePair(Tag.POST_TAX_BALANCE, new Value(prevBalance - amountTaxed)); + } + + if (prevBalance != null && player != null && econ != null && tax != null && amountTaxed != null) { + this.addTagValuePair(Tag.TAX_AMOUNT_TAXED, new Value(amountTaxed)); + } + + if (taxBracket != null) { + this.addTagValuePair(Tag.TAX_BRACKET_AMOUNT, new Value(taxBracket.getTaxAmountString())); + this.addTagValuePair(Tag.TAX_BRACKET_AMOUNT_TYPE, new Value(taxBracket.getTaxAmountType().name())); + this.addTagValuePair(Tag.TAX_BRACKET_NAME, new Value(taxBracket.getName())); + this.addTagValuePair(Tag.TAX_BRACKET_MIN, new Value(taxBracket.getMinBalance())); + this.addTagValuePair(Tag.TAX_BRACKET_MAX, new Value(taxBracket.getMaxBalance())); + } + + if (tax != null) { + this.addTagValuePair(Tag.TAX_NEXT_COLLECTION_TIME, new Value(tax.getTimeTilNextTaxFormated())); + this.addTagValuePair(Tag.TAX_NAME, new Value(tax.getTaxData().getName().getName())); + this.addTagValuePair(Tag.TAX_ENABLED, new Value(tax.getTaxData().isEnabled())); + this.addTagValuePair(Tag.TAX_FREQUENCY, new Value(tax.getTaxData().getTaxFrequencyFormated())); + this.addTagValuePair(Tag.TAX_DEPOSIT_ENABLED, new Value(tax.getTaxData().isDepositAccountEnabled())); + this.addTagValuePair(Tag.TAX_DEPOSIT_ACCOUNT, new Value(tax.getTaxData().getDepositAccountName())); + this.addTagValuePair(Tag.TAX_COLLECTION_NAME, new Value(tax.getCollection().getName())); + } + + if (taxBracketGroup != null) { + this.addTagValuePair(Tag.TAX_BRACKET_GROUP_NAME, new Value(taxBracketGroup.getName())); + this.addTagValuePair(Tag.TAX_BRACKET_GROUP_GROUPS, new Value(taxBracketGroup.getGroups())); + } + + this.addTagValuePair(Tag.TAX_NAME_LIST, new Value(((TaxesPlugin)TaxesPlugin.getInstance()).getTaxNames())); + } +} diff --git a/src/main/java/com/taxes/tasks/PlayerBalanceTaxCollector.java b/src/main/java/com/taxes/tasks/PlayerBalanceTaxCollector.java new file mode 100644 index 0000000..b50db7b --- /dev/null +++ b/src/main/java/com/taxes/tasks/PlayerBalanceTaxCollector.java @@ -0,0 +1,228 @@ +package com.taxes.tasks; + +import com.taxes.TaxesPlugin; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scheduler.BukkitTask; + +public class PlayerBalanceTaxCollector extends TaxCollector { + public PlayerBalanceTaxCollector(TaxesPlugin plugin, Tax tax) { + super(plugin, tax); + } + + protected void collectTax() { + OfflinePlayer[] allPlayers = Bukkit.getOfflinePlayers(); + OfflinePlayer currentPlayer = null; + this.getPlugin().getLogger().info(String.format("Number of Players = %d", allPlayers.length)); + long count = 1L; + OfflinePlayer[] var5 = allPlayers; + int var6 = allPlayers.length; + + for(int var7 = 0; var7 < var6; ++var7) { + OfflinePlayer offlinePlayer = var5[var7]; + if (offlinePlayer != null) { + try { + currentPlayer = offlinePlayer; + count = this.checkForBatchDelay(count); + this.collectPlayerTax(offlinePlayer); + } catch (Throwable var10) { + this.getPlugin().getLogger().severe("Error Taxing Player " + currentPlayer.getName() + "\ne.toString() = " + var10.toString() + "\ne.getMessage() = " + var10.getMessage() + "\ne.getStackTrace() = " + var10.getStackTrace()); + } + } + } + + } + + private void collectPlayerTax(final OfflinePlayer player) throws Throwable { + this.getPlugin().getLogger().info("=== Starting tax collection for player: " + player.getName() + " ==="); + + try { + // Economy operations MUST run synchronously (Vault is not thread-safe) + if (!this.bypassTax(player)) { + String group = this.getPlayerPrimaryGroup(player); + this.getPlugin().getLogger().info("Player " + player.getName() + " is in group: " + group); + + TaxBracketGroup taxBracketGroup = this.findTaxBracketGroup(group); + if (taxBracketGroup != null) { + String withdrawSource = this.tax.getTaxData().getWithdrawSource().toString(); + Double balanceForTax = this.resolveBalanceForTax(player, withdrawSource); + if (balanceForTax == null) { + this.getPlugin().getLogger().warning("No balance available for tax calculation (source: " + withdrawSource + ") for player " + player.getName()); + return; + } + + double oldBalance = balanceForTax; + this.getPlugin().getLogger().info("Player " + player.getName() + " balance (source: " + withdrawSource + "): " + oldBalance); + + TaxBracket taxBracket = this.findTaxBracket(taxBracketGroup, oldBalance); + if (taxBracket != null) { + this.getPlugin().getLogger().info("Found tax bracket: " + taxBracket.getName() + " for player " + player.getName()); + + double playerTax = taxBracket.getAmountTaxed(oldBalance); + this.getPlugin().getLogger().info("Calculated tax amount: " + playerTax + " for player " + player.getName()); + + if (playerTax > 0.0D) { + double balanceBefore = oldBalance; + + boolean withdrawn = false; + this.getPlugin().getLogger().info("WithdrawSource: " + withdrawSource + " for player " + player.getName()); + + if ("BANK".equals(withdrawSource)) { + withdrawn = this.withdrawFromBank(player, playerTax); + } else if ("BANK_IF_AVAILABLE".equals(withdrawSource)) { + if (this.hasBankAccount(player)) { + withdrawn = this.withdrawFromBank(player, playerTax); + } else { + this.getPlugin().getLogger().info("Bank account not found for player " + player.getName() + ", falling back to player balance"); + withdrawn = this.withdrawFromPlayer(player, playerTax); + } + } else { + withdrawn = this.withdrawFromPlayer(player, playerTax); + } + + if (withdrawn) { + this.getPlugin().getLogger().info("Successfully collected " + playerTax + " from " + player.getName()); + this.depositTaxInAccount(playerTax); + this.sendPlayerMessage(player, taxBracketGroup, taxBracket, oldBalance, playerTax); + } else { + this.getPlugin().getLogger().warning("Tax withdrawal failed for player " + player.getName() + " - insufficient funds. Balance: " + balanceBefore + ", Tax: " + playerTax); + } + } else { + this.getPlugin().getLogger().info("Tax amount is 0.0 for player " + player.getName() + " - skipping"); + } + } else { + this.getPlugin().getLogger().warning("No tax bracket found for player " + player.getName() + " with balance " + oldBalance); + } + } else { + this.getPlugin().getLogger().warning("No tax bracket group found for group: " + group); + } + } else { + this.getPlugin().getLogger().info("Player " + player.getName() + " has bypass permission - skipping"); + } + } catch (Exception e) { + this.getPlugin().getLogger().severe("Exception during tax collection for player " + player.getName() + ": " + e.getMessage()); + e.printStackTrace(); + } + } + + private boolean withdrawFromPlayer(OfflinePlayer player, double amount) { + double balance = this.getPlugin().getEconomy().getBalance(player); + if (balance >= amount) { + double balanceBefore = balance; + this.getPlugin().getEconomy().withdrawPlayer(player, amount); + double balanceAfter = this.getPlugin().getEconomy().getBalance(player); + double actuallyWithdrawn = balanceBefore - balanceAfter; + return actuallyWithdrawn >= amount * 0.99; + } + return false; + } + + private boolean withdrawFromBank(OfflinePlayer player, double amount) { + try { + Object mebPlugin = this.getPlugin().getServer().getPluginManager().getPlugin("MysqlEconomyBank"); + if (mebPlugin == null) { + this.getPlugin().getLogger().warning("MysqlEconomyBank plugin not found!"); + return false; + } + + // Cast to Money class + Class moneyClass = Class.forName("net.craftersland.money.Money"); + Object moneyInstance = moneyClass.cast(mebPlugin); + + // Get AccountDatabaseInterface + Object accountInterface = moneyClass.getMethod("getMoneyDatabaseInterface").invoke(moneyInstance); + if (accountInterface == null) { + this.getPlugin().getLogger().warning("MoneyDatabaseInterface is null!"); + return false; + } + + // Get balance: getBalance(UUID) + Class accountInterfaceClass = Class.forName("net.craftersland.money.database.AccountDatabaseInterface"); + java.lang.reflect.Method getBalanceMethod = accountInterfaceClass.getMethod("getBalance", java.util.UUID.class); + Double bankBalance = (Double) getBalanceMethod.invoke(accountInterface, player.getUniqueId()); + + if (bankBalance == null || bankBalance < amount) { + this.getPlugin().getLogger().info("Insufficient bank balance for " + player.getName() + ": " + bankBalance + " < " + amount); + return false; + } + + // Withdraw by setting new balance: setBalance(UUID, Double) + double newBalance = bankBalance - amount; + java.lang.reflect.Method setBalanceMethod = accountInterfaceClass.getMethod("setBalance", java.util.UUID.class, Double.class); + Boolean success = (Boolean) setBalanceMethod.invoke(accountInterface, player.getUniqueId(), newBalance); + + if (success != null && success) { + this.getPlugin().getLogger().info("Successfully withdrew " + amount + " from bank account of " + player.getName() + " (old: " + bankBalance + ", new: " + newBalance + ")"); + return true; + } else { + this.getPlugin().getLogger().warning("setBalance returned false for " + player.getName()); + return false; + } + + } catch (Exception e) { + this.getPlugin().getLogger().warning("Error accessing MysqlEconomyBank: " + e.getMessage()); + e.printStackTrace(); + } + return false; + } + + private Double resolveBalanceForTax(OfflinePlayer player, String withdrawSource) { + if ("BANK".equals(withdrawSource)) { + Double bankBalance = this.getBankBalance(player); + if (bankBalance == null) { + this.getPlugin().getLogger().severe("Tax " + this.tax.getTaxData().getName().getConfigTag() + " configured to withdraw from BANK but bank account is not available!"); + } + return bankBalance; + } + + if ("BANK_IF_AVAILABLE".equals(withdrawSource)) { + Double bankBalance = this.getBankBalance(player); + if (bankBalance != null) { + return bankBalance; + } + } + + return this.getPlugin().getEconomy().getBalance(player); + } + + private boolean hasBankAccount(OfflinePlayer player) { + Double balance = this.getBankBalance(player); + return balance != null; + } + + private Double getBankBalance(OfflinePlayer player) { + try { + Object mebPlugin = this.getPlugin().getServer().getPluginManager().getPlugin("MysqlEconomyBank"); + if (mebPlugin == null) { + return null; + } + + // Cast to Money class + Class moneyClass = Class.forName("net.craftersland.money.Money"); + Object moneyInstance = moneyClass.cast(mebPlugin); + + // Get AccountDatabaseInterface + Object accountInterface = moneyClass.getMethod("getMoneyDatabaseInterface").invoke(moneyInstance); + if (accountInterface == null) { + return null; + } + + // Get balance: getBalance(UUID) + Class accountInterfaceClass = Class.forName("net.craftersland.money.database.AccountDatabaseInterface"); + java.lang.reflect.Method getBalanceMethod = accountInterfaceClass.getMethod("getBalance", java.util.UUID.class); + return (Double) getBalanceMethod.invoke(accountInterface, player.getUniqueId()); + + } catch (Exception e) { + this.getPlugin().getLogger().warning("Error accessing MysqlEconomyBank: " + e.getMessage()); + e.printStackTrace(); + return null; + } + } + + public String toString() { + return "PlayerBalanceTaxCollector [toString()=" + super.toString() + "]"; + } +} diff --git a/src/main/java/com/taxes/tasks/TaxCollector.java b/src/main/java/com/taxes/tasks/TaxCollector.java new file mode 100644 index 0000000..b06fc3b --- /dev/null +++ b/src/main/java/com/taxes/tasks/TaxCollector.java @@ -0,0 +1,146 @@ +package com.taxes.tasks; + +import com.taxes.core.messages.BroadcastMessage; +import com.taxes.core.messages.PlayerMessage; +import com.taxes.core.task.EnderTask; +import com.taxes.TaxesPlugin; +import com.taxes.config.BatchProcessing; +import com.taxes.tag.TaxTagValues; +import com.taxes.tax.Tax; +import com.taxes.tax.TaxBracket; +import com.taxes.tax.TaxBracketGroup; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +public abstract class TaxCollector extends EnderTask { + protected static final String BYPASS_PERMISSION_BASE = "taxes.bypass."; + protected Tax tax; + private OfflinePlayer depositAccount = null; + protected String bypassPerm; + + public TaxCollector(TaxesPlugin plugin, Tax tax) { + super(plugin); + this.tax = tax; + this.bypassPerm = "taxes.bypass." + tax.getTaxData().getName().getConfigTag().toLowerCase(); + if (tax.getTaxData().isDepositAccountEnabled()) { + this.depositAccount = this.getPlugin().getServer().getPlayer(tax.getTaxData().getDepositAccountName()); + } + + } + + public void run() { + this.broadcastStartMessage(); + this.collectTax(); + this.updateAndSaveLastTimeTaxed(); + this.broadcastCompleteMessage(); + } + + public long checkForBatchDelay(long count) { + BatchProcessing batch = this.tax.getTaxData().getBatchProcessing(); + this.getPlugin().getLogger().finest("Batch = " + batch); + this.getPlugin().getLogger().finest(String.format("Count = %d", count)); + if (batch.isEnabled() && count >= batch.getBatchSize()) { + try { + this.getPlugin().getLogger().finest("START DELAY"); + Thread.sleep((long)((double)batch.getBatchDelay() * 1000.0D / 20.0D)); + this.getPlugin().getLogger().finest("END DELAY"); + } catch (InterruptedException var5) { + var5.printStackTrace(); + } + + return 1L; + } else { + return count + 1L; + } + } + + private void broadcastStartMessage() { + TaxTagValues taxTagValues = new TaxTagValues(this.tax); + BroadcastMessage bm = new BroadcastMessage(this.getPlugin().getLanguageConfig().getMessage("BroadcastTaxCollectionStart"), taxTagValues); + bm.sendMessage(); + } + + private void broadcastCompleteMessage() { + TaxTagValues taxTagValues = new TaxTagValues(this.tax); + BroadcastMessage bm = new BroadcastMessage(this.getPlugin().getLanguageConfig().getMessage("BroadcastTaxCollectionComplete"), taxTagValues); + bm.sendMessage(); + } + + protected TaxBracketGroup findTaxBracketGroup(String group) { + TaxBracketGroup taxBracketGroup = this.tax.getCollection().getTaxBracketGroup(group); + if (taxBracketGroup == null) { + this.getPlugin().getLogger().warning(String.format("No tax bracket group found for Collection: %s, Primary Group: %s", this.tax.getCollection().getName(), group)); + } + + return taxBracketGroup; + } + + protected TaxBracket findTaxBracket(TaxBracketGroup taxBracketGroup, Double balance) { + TaxBracket taxBracket = null; + if (balance > 0.0D) { + taxBracket = taxBracketGroup.getTaxBracket(balance); + if (taxBracket == null) { + this.getPlugin().getLogger().warning(String.format("No tax bracket found for Collection: %s, Tax Bracket Group: %s, Balance: %f", this.tax.getCollection().getName(), taxBracketGroup.getName(), balance)); + } + } + + return taxBracket; + } + + protected void depositTaxInAccount(Double amount) { + this.getPlugin().getLogger().finest(String.format("Entered depositTaxInAccount with amount = %f", amount)); + this.getPlugin().getLogger().finest(String.format("tax.getTaxData().isDepositAccountEnabled() = %s", this.tax.getTaxData().isDepositAccountEnabled())); + if (this.tax.getTaxData().isDepositAccountEnabled()) { + this.getPlugin().getLogger().finest(String.format("deposit server account, amount = %f, bank account = %s", amount, this.tax.getTaxData().getDepositAccountName())); + this.getPlugin().getEconomy().depositPlayer(this.depositAccount, amount); + } + + } + + protected String getPlayerPrimaryGroup(OfflinePlayer player) { + String group = this.getPlugin().getPermission().getPrimaryGroup((String)null, player); + if (group == null) { + group = ""; + } + + return group; + } + + private void updateAndSaveLastTimeTaxed() { + this.getPlugin().getRuntimeData().saveLastTimeTaxed(this.tax.getTaxData().getName(), this.tax.updateLastTimeTaxed()); + } + + protected boolean bypassTax(OfflinePlayer player) { + if (player == null) { + return true; + } else if (player.getName() == null) { + return false; + } else if (this.getPlugin().getPermission().playerHas((String)null, player, this.bypassPerm)) { + return true; + } else if (this.tax.getTaxData().getDepositAccountName() == null) { + return false; + } else { + return player.getName().equalsIgnoreCase(this.tax.getTaxData().getDepositAccountName()); + } + } + + protected void sendPlayerMessage(OfflinePlayer offlineplayer, TaxBracketGroup taxBracketGroup, TaxBracket taxBracket, Double oldBalance, Double amountTaxed) { + if (offlineplayer.isOnline()) { + Player onlinePlayer = offlineplayer.getPlayer(); + TaxTagValues tagValues = new TaxTagValues(onlinePlayer, this.getPlugin().getEconomy(), this.tax, taxBracketGroup, taxBracket, oldBalance, amountTaxed); + PlayerMessage playerMessage = new PlayerMessage(onlinePlayer, this.getPlugin().getLanguageConfig().getMessage("PlayerTaxCollected"), tagValues); + playerMessage.sendMessage(); + } + + } + + public TaxesPlugin getPlugin() { + return (TaxesPlugin)super.getPlugin(); + } + + public String toString() { + return "TaxCollector [plugin=" + this.getPlugin() + ", tax=" + this.tax + "]"; + } + + protected abstract void collectTax(); +} diff --git a/src/main/java/com/taxes/tasks/TaxCollectorFactory.java b/src/main/java/com/taxes/tasks/TaxCollectorFactory.java new file mode 100644 index 0000000..cd700e5 --- /dev/null +++ b/src/main/java/com/taxes/tasks/TaxCollectorFactory.java @@ -0,0 +1,16 @@ +package com.taxes.tasks; + +import com.taxes.TaxesPlugin; +import com.taxes.tax.Tax; + +public class TaxCollectorFactory { + public static TaxCollector getTaxCollector(TaxesPlugin plugin, Tax tax) { + switch(tax.getTaxData().getName()) { + case PLAYER_BALANCE: + return new PlayerBalanceTaxCollector(plugin, tax); + default: + return null; + } + } +} + diff --git a/src/main/java/com/taxes/tax/Collection.java b/src/main/java/com/taxes/tax/Collection.java new file mode 100644 index 0000000..c29ddf0 --- /dev/null +++ b/src/main/java/com/taxes/tax/Collection.java @@ -0,0 +1,41 @@ +package com.taxes.tax; + +import java.util.Iterator; +import java.util.List; + +public class Collection { + private List taxBracketGroups; + private String name; + + public Collection(String name, List taxBracketGroups) { + this.name = name; + this.taxBracketGroups = taxBracketGroups; + } + + public TaxBracketGroup getTaxBracketGroup(String group) { + TaxBracketGroup retTaxBracketGroup = null; + Iterator var3 = this.taxBracketGroups.iterator(); + + while(var3.hasNext()) { + TaxBracketGroup taxBracketGroup = (TaxBracketGroup)var3.next(); + if (taxBracketGroup.containsGroup(group)) { + retTaxBracketGroup = taxBracketGroup; + break; + } + + if (taxBracketGroup.isApplicable(group)) { + retTaxBracketGroup = taxBracketGroup; + } + } + + return retTaxBracketGroup; + } + + public String getName() { + return this.name; + } + + public List getTaxBracketGroups() { + return this.taxBracketGroups; + } +} diff --git a/src/main/java/com/taxes/tax/PlayerBalanceTax.java b/src/main/java/com/taxes/tax/PlayerBalanceTax.java new file mode 100644 index 0000000..3675c41 --- /dev/null +++ b/src/main/java/com/taxes/tax/PlayerBalanceTax.java @@ -0,0 +1,24 @@ +package com.taxes.tax; + +import com.taxes.TaxesPlugin; +import com.taxes.config.TaxData; +import org.bukkit.OfflinePlayer; + +public class PlayerBalanceTax extends Tax { + public PlayerBalanceTax(TaxData taxData, long lastTimeTaxedTicks, Collection collection, TaxesPlugin plugin) { + super(taxData, lastTimeTaxedTicks, collection, plugin); + } + + public double getBalance(OfflinePlayer player) { + return this.plugin.getEconomy().getBalance(player); + } + + public String getGroup(OfflinePlayer player) { + try { + return this.plugin.getPermission().getPrimaryGroup((String)null, player); + } catch (UnsupportedOperationException e) { + // SuperPerms unterstützt keine Gruppen - verwende "default" als Fallback + return "default"; + } + } +} diff --git a/src/main/java/com/taxes/tax/Tax.java b/src/main/java/com/taxes/tax/Tax.java new file mode 100644 index 0000000..20b86c1 --- /dev/null +++ b/src/main/java/com/taxes/tax/Tax.java @@ -0,0 +1,68 @@ +package com.taxes.tax; + +import com.taxes.core.util.Time; +import com.taxes.TaxesPlugin; +import com.taxes.config.TaxData; +import org.bukkit.OfflinePlayer; + +public abstract class Tax { + private TaxData taxData; + private long lastTimeTaxedTicks; + private Collection collection; + protected TaxesPlugin plugin; + + public Tax(TaxData taxData, long lastTimeTaxedTicks, Collection collection, TaxesPlugin plugin) { + this.taxData = taxData; + this.lastTimeTaxedTicks = lastTimeTaxedTicks; + this.collection = collection; + this.plugin = plugin; + } + + public long getTimeTilNextTaxTicks() { + long time = this.taxData.getTaxFrequencyTicks() - (Time.getCurrentTimeInTicks() - this.lastTimeTaxedTicks); + if (time < 0L) { + time = 0L; + } + + return time; + } + + public String getTimeTilNextTaxFormated() { + return Time.getFormatedDuration(this.getTimeTilNextTaxTicks() / 20L); + } + + public long updateLastTimeTaxed() { + this.lastTimeTaxedTicks = Time.getCurrentTimeInTicks(); + return this.lastTimeTaxedTicks; + } + + public TaxData getTaxData() { + return this.taxData; + } + + public Collection getCollection() { + return this.collection; + } + + public TaxBracketGroup getTaxBracketGroup(OfflinePlayer player) { + return this.collection.getTaxBracketGroup(this.getGroup(player)); + } + + public TaxBracket getTaxBracket(OfflinePlayer player) { + TaxBracket taxBracket = null; + TaxBracketGroup taxBracketGroup = this.collection.getTaxBracketGroup(this.getGroup(player)); + if (taxBracketGroup != null) { + taxBracket = taxBracketGroup.getTaxBracket(this.getBalance(player)); + } + + return taxBracket; + } + + public abstract double getBalance(OfflinePlayer var1); + + public abstract String getGroup(OfflinePlayer var1); + + public String toString() { + return "Tax [taxData=" + this.taxData + ", lastTimeTaxedTicks=" + this.lastTimeTaxedTicks + ", collection=" + this.collection + ", plugin=" + this.plugin + "]"; + } +} diff --git a/src/main/java/com/taxes/tax/TaxBracket.java b/src/main/java/com/taxes/tax/TaxBracket.java new file mode 100644 index 0000000..215ebf5 --- /dev/null +++ b/src/main/java/com/taxes/tax/TaxBracket.java @@ -0,0 +1,91 @@ +package com.taxes.tax; + +import com.taxes.core.util.NumberFormat; + +public class TaxBracket { + private String name; + private double minBalance; + private double maxBalance; + private TaxBracket.TaxAmountType taxAmountType; + private double taxAmount; + + public TaxBracket(String name, double minBalance, double maxBalance, TaxBracket.TaxAmountType taxAmountType, double taxAmount) { + this.name = name; + this.minBalance = minBalance; + if (maxBalance < 0.0D) { + maxBalance = Double.MAX_VALUE; + } + + this.maxBalance = maxBalance; + this.taxAmountType = taxAmountType; + this.taxAmount = taxAmount; + } + + public Boolean isInBalRange(double balance) { + return balance > this.minBalance && balance <= this.maxBalance; + } + + public double applyTax(double balance) { + return balance - this.getAmountTaxed(balance); + } + + public double getAmountTaxed(double balance) { + double amountTaxed = 0.0D; + switch(this.taxAmountType) { + case FIXED: + amountTaxed = this.taxAmount; + break; + case PERCENT: + amountTaxed = balance * (this.taxAmount / 100.0D); + } + + return amountTaxed; + } + + public String getName() { + return this.name; + } + + public double getMinBalance() { + return this.minBalance; + } + + public double getMaxBalance() { + return this.maxBalance; + } + + public double getTaxAmount() { + return this.taxAmount; + } + + public String getTaxAmountString() { + String taxAmountString = NumberFormat.formatNumber(this.taxAmount); + switch(this.taxAmountType) { + case FIXED: + taxAmountString = "$" + taxAmountString; + break; + case PERCENT: + taxAmountString = taxAmountString + "%"; + } + + return taxAmountString; + } + + public TaxBracket.TaxAmountType getTaxAmountType() { + return this.taxAmountType; + } + + public String toString() { + return "TaxBracket [name=" + this.name + ", minBalance=" + this.minBalance + ", maxBalance=" + this.maxBalance + ", taxAmountType=" + this.taxAmountType + ", taxAmount=" + this.taxAmount + "]"; + } + + public static enum TaxAmountType { + PERCENT, + FIXED; + + // $FF: synthetic method + private static TaxBracket.TaxAmountType[] $values() { + return new TaxBracket.TaxAmountType[]{PERCENT, FIXED}; + } + } +} diff --git a/src/main/java/com/taxes/tax/TaxBracketGroup.java b/src/main/java/com/taxes/tax/TaxBracketGroup.java new file mode 100644 index 0000000..61d039b --- /dev/null +++ b/src/main/java/com/taxes/tax/TaxBracketGroup.java @@ -0,0 +1,55 @@ +package com.taxes.tax; + +import java.util.Iterator; +import java.util.List; + +public class TaxBracketGroup { + private String name = ""; + private List groups = null; + private List taxBrackets = null; + + public TaxBracketGroup(String name, List groups, List taxBrackets) { + this.name = name; + this.groups = groups; + this.taxBrackets = taxBrackets; + } + + public Boolean isApplicable(String group) { + return group == null || group.isEmpty() || this.groups == null || this.groups.isEmpty() || this.groups.contains(group); + } + + public Boolean containsGroup(String group) { + return group != null && !group.isEmpty() && this.groups != null && !this.groups.isEmpty() && this.groups.contains(group); + } + + public TaxBracket getTaxBracket(double balance) { + TaxBracket retTaxBracket = null; + Iterator var4 = this.taxBrackets.iterator(); + + while(var4.hasNext()) { + TaxBracket taxBracket = (TaxBracket)var4.next(); + if (taxBracket.isInBalRange(balance)) { + retTaxBracket = taxBracket; + break; + } + } + + return retTaxBracket; + } + + public String getName() { + return this.name; + } + + public List getGroups() { + return this.groups; + } + + public String toString() { + return "TaxBracketGroup [name=" + this.name + ", groups=" + this.groups + ", taxBrackets=" + this.taxBrackets + "]"; + } + + public List getTaxBrackets() { + return this.taxBrackets; + } +} diff --git a/src/main/java/com/taxes/tax/TaxFactory.java b/src/main/java/com/taxes/tax/TaxFactory.java new file mode 100644 index 0000000..add8144 --- /dev/null +++ b/src/main/java/com/taxes/tax/TaxFactory.java @@ -0,0 +1,17 @@ +package com.taxes.tax; + +import com.taxes.TaxesPlugin; +import com.taxes.config.TaxData; + +public class TaxFactory { + public static Tax getTax(TaxData taxData, long lastTimeTaxedTicks, Collection collection, TaxesPlugin plugin) { + Tax retTax = null; + switch(taxData.getName()) { + case PLAYER_BALANCE: + retTax = new PlayerBalanceTax(taxData, lastTimeTaxedTicks, collection, plugin); + break; + } + + return (Tax)retTax; + } +} diff --git a/src/main/java/com/taxes/tax/TaxNames.java b/src/main/java/com/taxes/tax/TaxNames.java new file mode 100644 index 0000000..7434297 --- /dev/null +++ b/src/main/java/com/taxes/tax/TaxNames.java @@ -0,0 +1,60 @@ +package com.taxes.tax; + +import java.util.ArrayList; +import java.util.List; + +public enum TaxNames { + PLAYER_BALANCE("PlayerBalanceTax", "PlayerBalanceTax"), + NATION("NationTax", "NationTax"), + TOWN("TownTax", "TownTax"); + + private String configTag; + private String name; + + private TaxNames(String configTag, String name) { + this.configTag = configTag; + this.name = name; + } + + public String getConfigTag() { + return this.configTag; + } + + public String getName() { + return this.name; + } + + public static TaxNames getValidTaxName(String testTaxName) { + TaxNames validTaxName = null; + TaxNames[] var2 = values(); + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + TaxNames taxName = var2[var4]; + if (taxName.configTag.equals(testTaxName)) { + validTaxName = taxName; + break; + } + } + + return validTaxName; + } + + public static String getTaxNameList() { + List nameList = new ArrayList(); + TaxNames[] var1 = values(); + int var2 = var1.length; + + for(int var3 = 0; var3 < var2; ++var3) { + TaxNames taxName = var1[var3]; + nameList.add(taxName.name); + } + + return nameList.toString(); + } + + // $FF: synthetic method + private static TaxNames[] $values() { + return new TaxNames[]{PLAYER_BALANCE, NATION, TOWN}; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..9870f15 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,130 @@ +# ================================================================================================== +# TAXES PLUGIN KONFIGURATION (v8.0) +# ================================================================================================== +# Diese Datei ermöglicht es dir zu konfigurieren, wie oft und wie viel Steuern von +# Spielerkonten eingezogen werden. +# +# DOKUMENTATION: +# - TaxFrequency: Zeitformat wie "1d" (1 Tag), "12h" (12 Stunden), "30m" (30 Minuten), "10s" (10 Sekunden) +# - WithdrawSource: PLAYER (vom Spielerkonto) | BANK (nur Bank) | BANK_IF_AVAILABLE (Bank wenn vorhanden, sonst Spieler) +# - TaxType: PERCENT (Prozentsatz) | FLAT (Festbetrag) +# ================================================================================================== + +# Debug-Modus: Aktiviere für ausführliche Logs (true/false) +Debug: false + +# STEUERN-KONFIGURATION +Taxes: + # SPIELERKONTO-STEUER + # Diese Steuer wird basierend auf dem Spielerkontostand eingezogen + PlayerBalanceTax: + # Ist diese Steuer aktiviert? (true/false) + Enabled: true + + # Wie oft werden Steuern eingezogen? + # Formate: 1s, 30m, 1h, 1d, 1w + # Beispiele: "30m" = alle 30 Minuten, "1d" = täglich + TaxFrequency: 1d + + # WICHTIG: Woher wird das Steuergeld genommen? + # PLAYER = Direkt vom Spielerkonto (Standard, immer verfügbar) + # BANK = Nur von MysqlEconomyBank-Konto (Server muss MysqlEconomyBank haben!) + # BANK_IF_AVAILABLE = Intelligent: Versucht Bank, fällt auf Spielerkonto zurück + WithdrawSource: PLAYER + + # OPTIONAL: Steuern auf ein Serverkonto deponieren? + TaxDepositAccount: + # Sollen Steuern auf ein bestimmtes Konto eingezahlt werden? (true/false) + Enabled: false + + # Name des Serverkontos (Spielername oder Bankkontoname) + # Beispiele: "Server", "town_vault", "kingdom_bank" + Name: server_account + + # Welche Steuergruppe wird verwendet? + # Muss mit einer Collection unten übereinstimmen (siehe TaxCollections) + TaxCollection: OnlyCollection + + # Batch-Processing: Optimierung für große Spielerzahlen + BatchProcessing: + # Steuern in Batches verarbeiten? (true/false) + # true = langsamer, aber weniger Server-Last + # false = schneller, aber mehr Last + Enabled: false + + # Wie viele Spieler pro Batch verarbeitet werden + Size: 500 + + # Verzögerung zwischen Batches in Ticks (20 Ticks = 1 Sekunde) + Delay: 20 + +# STEUERKOLLEKTIONEN +# Eine Kollektion = Eine Gruppe von Steuerstufen (Brackets) +# Du kannst mehrere Kollektionen erstellen und diese bei verschiedenen Steuern nutzen +TaxCollections: + # Name der Kollektion (wird bei TaxCollection referenziert) + OnlyCollection: + # Bracket-Gruppe: Festlegung welche Gruppen welche Steuersätze zahlen + AllPlayers: + # Welche Spielergruppen fallen unter diese Steuersätze? + # [] = Alle Spieler + # ["VIP", "Premium"] = Nur diese Gruppen (setzt Permission-Plugin voraus) + Groups: [] + + # Steuerstufen (nach Kontostand sortieren!) + # Jede Stufe definiert: "Ab welchem Kontostand zahlt man wie viel Steuern?" + TaxBrackets: + # STUFE 1: "Arm" (0 - 100.000 Gold) + Arm: + # Obergrenze dieses Brackets in Gold + MaxBalance: 100000.00 + + # Steuertyp: PERCENT = Prozentsatz, FLAT = Festbetrag + TaxType: PERCENT + + # Steuersatz (Prozent oder Betrag je nach TaxType) + # Beispiel: 5.0 mit PERCENT = 5% Steuern + TaxAmount: 0.0 + + # STUFE 2: "Mittelschicht" (100.000 - 500.000 Gold) + Mittelschicht: + MaxBalance: 500000.00 + TaxType: PERCENT + # 10% Steuern für diese Gruppe + TaxAmount: 10.0 + + # STUFE 3: "Reich" (ab 500.000 Gold) + # MaxBalance: -1 bedeutet "unbegrenzt" (höchste Stufe) + Reich: + MaxBalance: -1 + TaxType: PERCENT + # 20% Steuern für sehr reiche Spieler + TaxAmount: 20.0 + +# ================================================================================================== +# KONFIGURATIONSBEISPIELE +# ================================================================================================== +# +# BEISPIEL 1: Unterschiedliche Steuersätze nach Kontostand +# Arm: 0%, Mittel: 5%, Reich: 15% +# +# BEISPIEL 2: Festbetrag-Steuern mit FLAT +# TaxType: FLAT +# TaxAmount: 100.0 (100 Gold pro Tag, egal wie reich) +# +# BEISPIEL 3: MysqlEconomyBank aktivieren +# WithdrawSource: BANK_IF_AVAILABLE # Nutzt Bank wenn vorhanden +# (Sicherstelle dass MysqlEconomyBank auf dem Server lädt!) +# +# BEISPIEL 4: Mehrere Steuerkollektionen +# TaxCollections: +# RichierTaxes: +# VIPPlayers: +# Groups: [VIP, Premium] +# TaxBrackets: {...} +# NormalTaxes: +# RegularPlayers: +# Groups: [] +# TaxBrackets: {...} +# +# ================================================================================================== diff --git a/src/main/resources/data.yml b/src/main/resources/data.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml new file mode 100644 index 0000000..70f22ca --- /dev/null +++ b/src/main/resources/language.yml @@ -0,0 +1,213 @@ +# ================================================================================================== +# +# Place Holders (Tax Collection Messages Only): +# ---------------------------------------------------- +# {PRE_TAX_BALANCE} - The balance before taxes were collected. +# {POST_TAX_BALANCE} - The balance after taxes were collected. +# {TAX_AMOUNT_TAXED} - The amount collected for a tax. +# +# +# Player Place Holders: +# --------------------- +# {PLAYER_REAL_NAME} - The player's real name. +# {PLAYER_DISPLAY_NAME} - The player's nickname if they have one. Otherwise real name is used. +# {PLAYER_BALANCE} - The player's current balance. +# +# +# Tax Place Holders: +# ------------------ +# {TAX_NAME} - Name of the tax in the config.yml file. +# {TAX_ENABLED} - Evaluates to Yes if tax is enabled, No otherwise. +# {TAX_FREQUENCY} - How often tax is collected. Example: 1 day +# {TAX_DEPOSIT_ENABLED} - Evaluates to Yes if Tax Deposit Account is enabled, No otherwise. +# {TAX_DEPOSIT_ACCOUNT} - Name of the Tax Deposit Account where taxes are deposited. +# {TAX_COLLECTION_NAME} - Name of the tax collection. +# {TAX_NEXT_COLLECTION_TIME} - Date and Time the tax will be collected again. +# {TAX_NAME_LIST} - Comma seperated list of valid tax names. +# +# +# Tax Collections, Bracket Groups, and Brackets Place Holders: +# ------------------------------------------------------------ +# {TAX_COLLECTION_NAME} - Name of the tax collection. +# {TAX_BRACKET_GROUP_NAME} - Name of the tax bracket group. +# {TAX_BRACKET_GROUP_GROUPS} - The list of groups for a tax bracket group. +# {TAX_BRACKET_NAME} - Name of the tax bracket +# {TAX_BRACKET_MIN} - Minimum balance for the tax bracket. +# {TAX_BRACKET_MAX} - Maximum balance for the tax bracket. +# {TAX_BRACKET_AMOUNT} - The amount of tax to collect. Either a $ or % amount. +# {TAX_BRACKET_AMOUNT_TYPE} - The type of tax collected. Either PERCENT or FIXED. +# +# NOTE: If a place holder is not replaced in a message, the chances are that that +# place holder is a valid place holder for that message. +# +# Messages: +# --------- +# Messages can be multiline or single line. Messages support the place holders listed +# above and color codes. Each message can be disabled by setting Enabled to fale. +# +# Multiline example: +# Message: +# Enabled: true +# Contents: +# - 'Line 1' +# - 'Line 2' +# - 'Line 3' +# +# Singleline example: +# Message: +# Enabled: true +# Contents: +# - 'Entire Message' +# +# +# Some messages are complicated and need to be broken up into multiple sub-messages. Any +# message sub-message that starts with the word 'Each' means that it can be used multiple +# times in the message like in a list. These sub-messages can be single or multiple lines. +# Sub-messages can be disabled by setting them to []. To disable the entire message, it is +# best to set Enabled to false. +# +# Example: +# Message: +# Enabled: true +# Contents: +# Header: +# - 'Line 1' +# EachLine: +# - 'Line 1' +# - 'Line 2' +# - 'Line 3' +# Footer: +# - 'Line 1' +# +# Disable sub-message example (disable footer sub-message): +# Message: +# Enabled: true +# Contents: +# Header: +# - 'Line 1' +# EachLine: +# - 'Line 1' +# - 'Line 2' +# - 'Line 3' +# Footer: [] +# +# Defined Messages: +# ----------------- +# PlayerTaxCollected - Message that is displayed to the player when a tax is collected. +# This same message is used for all taxes. +# +# BroadcastTaxCollectionStart - Broadcast message that is displayed to all players when a tax +# collection is about to start. +# +# BroadcastTaxCollectionComplete - Broadcast message that is displayed to all players when a +# tax collection has completed. +# +# PlayerTaxList - Message that is displayed when the /taxes-list command is executed. +# Header - Header/title for the message. It is only displayed once. +# EachTax - This message is displayed once for each tax that is applicable for the +# command that was executed. +# Footer - This is the footer of the message. It is only displayed once. +# +# +# PlayerTaxListAll - Message that is displayed when the /taxes-listall command is executed. +# Header - Header/title for the message. It is only displayed once. +# EachTax - This message is displayed once for each tax that is applicable for the +# command that was executed. +# Footer - This is the footer of the message. It is only displayed once. +# +# +# PlayerTaxInfo - Message for the /taxes-info command. Displays the details of the +# tax specified by for the player that executed the command in-game. +# This message only displays the Tax Bracket info that is applicable to the +# to the player at the moment the /taxes-info command was executed. +# +# PlayerTaxInfoAll - Message for the /taxes-infoall command. Displays the complete +# config details of the tax specified by . +# This message displays all of the Tax Bracket Groups and all of the +# Tax Brackets that are configured for the specified tax. +# TaxInfo - Display the tax level info. This is only displayed once. +# EachTaxBracketGroup - This is the Tax Bracket Group info. It is displayed for +# each Tax Bracket Group in the specified tax. +# EachTaxBracket - This is the Tax Bracket info. It is displayed for each Tax Bracket +# of each Tax Bracket Group. +# Footer - This is the footer of the message. It is only displayed once. +# +# PlayerInvalidTaxName - Displayed when the player runs a command that requires a tax name +# and the tax name is not valid. +# +# ================================================================================================== + +Messages: + PlayerTaxCollected: + Enabled: true + Contents: + - '&5{TAX_NAME} &6Steuern wurden eingezogen.' + - '&6Altes Guthaben: &5${PRE_TAX_BALANCE}' + - '&6Neues Guthaben: &5${POST_TAX_BALANCE}' + - '&6Steuerbetrag: &5${TAX_AMOUNT_TAXED}' + - '&6Besteuert mit: &5{TAX_BRACKET_AMOUNT} &6(&5{TAX_BRACKET_AMOUNT_TYPE}&6)' + PlayerTaxList: + Enabled: true + Contents: + Header: + - '&7&l&m---------------------------------------------' + - '&5{PLAYER_REAL_NAME}s &6anwendbare Steuern:' + - '&7&l&m---------------------------------------------' + EachTax: + - '&6Steuername: &5{TAX_NAME}&6, Aktuelle Steuer: &5{TAX_BRACKET_AMOUNT}' + Footer: + - '&7&l&m---------------------------------------------' + PlayerTaxListAll: + Enabled: true + Contents: + Header: + - '&7&l&m---------------------------------------------' + - '&6Vollständige Liste aller Steuern:' + - '&7&l&m---------------------------------------------' + EachTax: + - '&6Steuername: &5{TAX_NAME}&6, Aktiviert: &5{TAX_ENABLED}' + Footer: + - '&7&l&m---------------------------------------------' + PlayerTaxInfo: + Enabled: true + Contents: + - '&6Aktuelle Steuerinfo von &5{PLAYER_REAL_NAME} &6für &5{TAX_NAME}&6:' + - '&6Steuerhäufigkeit: &5{TAX_FREQUENCY}' + - '&6Nächste Steuererhebung: &5{TAX_NEXT_COLLECTION_TIME}' + - '&6Steuererhebungsname: &5{TAX_COLLECTION_NAME}' + - '&6 Steuerklassen-Gruppenname: &5{TAX_BRACKET_GROUP_NAME}' + - '&6 Steuerklassenname: &5{TAX_BRACKET_NAME}' + - '&6 Guthabenbereich: &5${TAX_BRACKET_MIN} &6- &5${TAX_BRACKET_MAX}' + - '&6 Aktuelle Steuer: &5{TAX_BRACKET_AMOUNT}' + PlayerTaxInfoAll: + Enabled: true + Contents: + TaxInfo: + - '&7&l&m---------------------------------------------' + - '&6Alle Steuerinformationen für &5{TAX_NAME}&6:' + - '&7&l&m---------------------------------------------' + - '&6Steuerhäufigkeit: &5{TAX_FREQUENCY}' + - '&6Nächste Steuererhebung: &5{TAX_NEXT_COLLECTION_TIME}' + - '&6Steuererhebungsname: &5{TAX_COLLECTION_NAME}' + EachTaxBracketGroup: + - '&6 Steuerklassen-Gruppenname: &5{TAX_BRACKET_GROUP_NAME}' + - '&6 Steuerklassen-Gruppen: &5{TAX_BRACKET_GROUP_GROUPS}' + EachTaxBracket: + - '&6 Steuerklassenname: &5{TAX_BRACKET_NAME}' + - '&6 Guthabenbereich: &5${TAX_BRACKET_MIN} &6- &5${TAX_BRACKET_MAX}' + - '&6 Aktuelle Steuer: &5{TAX_BRACKET_AMOUNT}' + Footer: + - '&7&l&m---------------------------------------------' + BroadcastTaxCollectionStart: + Enabled: true + Contents: + - '&5{TAX_NAME} &6wird eingezogen.' + BroadcastTaxCollectionComplete: + Enabled: true + Contents: + - '&5{TAX_NAME} &6Einzug abgeschlossen.' + PlayerInvalidTaxName: + Enabled: true + Contents: + - '&6Das ist kein gültiger Steuername. Gültige Steuernamen sind: &5{TAX_NAME_LIST}.' + \ 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..0e5cb09 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,128 @@ +name: Taxes +main: com.taxes.TaxesPlugin +version: 8.0 +api-version: 1.21 +description: Collects taxes based on balances like player, towny, etc. +author: M_Viper +prefix: Taxes +depend: [Vault] +softdepend: [CMI, EssentialsX, PlaceholderAPI, MysqlEconomyBank] + +commands: + taxes: + description: Zeigt die Befehlshilfe für das Taxes Plugin an. + aliases: [tax, taxes-help, tax-help] + permission: taxes.player.help + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-collect: + description: Sammelt Steuern für die angegebene Steuer ein. Dieser Befehl ignoriert, ob die Steuer aktiviert ist oder nicht. Steuernamen erhältst du mit /tax-listall. + aliases: [tax-collect] + permission: taxes.admin.collect + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-collectall: + description: Sammelt alle Steuern ein. Dieser Befehl ignoriert, ob die Steuern aktiviert sind oder nicht. + aliases: [tax-collectall] + permission: taxes.admin.collectall + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-list: + description: Listet alle anwendbaren Steuern nach Namen für den Spieler auf. + aliases: [tax-list] + permission: taxes.player.list + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-listall: + description: Listet alle Steuern in der Config nach Namen auf. Dies ist für Admins gedacht. + aliases: [tax-listall] + permission: taxes.admin.listall + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-info: + description: Zeigt detaillierte Informationen für den angegebenen Steuernamen für den Spieler an. Steuernamen erhältst du mit /tax-list. + aliases: [tax-info] + permission: taxes.player.info + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-infoall: + description: Zeigt alle detaillierten Informationen für den angegebenen Steuernamen an. Dies ist für Admins, um Config-Einstellungen im Spiel zu sehen. Steuernamen erhältst du mit /tax-listall. + aliases: [tax-infoall] + permission: taxes.admin.infoall + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + taxes-reload: + description: Lädt die Taxes Konfigurationsdaten neu. + aliases: [tax-reload] + permission: taxes.admin.reload + permission-message: §6Du benötigst die Berechtigung §5 §6um diesen Befehl auszuführen. + usage: §6Befehlsfehler! Korrekte Verwendung ist §5/ + +permissions: + taxes.*: + description: Gibt alle Berechtigungen für dieses Plugin. + default: op + children: + taxes.admin: true + taxes.player: true + + taxes.player: + description: Gibt Zugriff auf alle Spieler-Berechtigungen. + default: op + children: + taxes.player.help: true + taxes.player.list: true + taxes.player.info: true + + taxes.admin: + description: Gibt Zugriff auf alle Admin-Berechtigungen. + default: op + children: + taxes.admin.reload: true + taxes.admin.collect: true + taxes.admin.collectall: true + taxes.admin.listall: true + taxes.admin.infoall: true + + taxes.bypass.*: + description: Gibt Zugriff auf alle Umgehungs-Berechtigungen. + default: false + children: + taxes.bypass.playerbalancetax: true + + taxes.player.help: + description: Gibt Zugriff auf den /taxes Befehl. + default: op + + taxes.player.list: + description: Gibt Zugriff auf den /taxes-list Befehl. + default: op + + taxes.player.info: + description: Gibt Zugriff auf den /taxes-info Befehl. + default: op + + taxes.admin.reload: + description: Gibt Zugriff auf den /taxes-reload Befehl. + default: op + + taxes.admin.collect: + description: Gibt Zugriff auf den /taxes-collect Befehl. + default: op + + taxes.admin.collectall: + description: Gibt Zugriff auf den /taxes-collectall Befehl. + default: op + + taxes.admin.listall: + description: Gibt Zugriff auf den /taxes-listall Befehl. + default: op + + taxes.admin.infoall: + description: Gibt Zugriff auf den /taxes-infoall Befehl. + default: op + + taxes.bypass.playerbalancetax: + description: Spieler-Kontostand-Steuer wird nicht von Spielern mit dieser Berechtigung eingezogen. + default: false +