From 9ba486bab43adf46398098c3b25d6ca63f1734a9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 16 Dec 2023 17:59:06 +0100 Subject: [PATCH] Initial commit --- .gitignore | 113 ++++++++++++ .../knarcraft/timeismoney/TimeIsMoney.java | 171 ++++++++++++++++++ .../timeismoney/command/ReloadCommand.java | 33 ++++ .../command/SetGroupPaymentCommand.java | 5 + .../command/SetPlayerPaymentCommand.java | 5 + .../timeismoney/config/Configuration.java | 131 ++++++++++++++ .../listener/PlayerJoinListener.java | 18 ++ .../timeismoney/manager/EconomyManager.java | 55 ++++++ .../manager/PermissionManager.java | 46 +++++ .../timeismoney/manager/PlayerTracker.java | 42 +++++ src/main/resources/config.yml | 16 ++ src/main/resources/plugin.yml | 21 +++ 12 files changed, 656 insertions(+) create mode 100644 .gitignore create mode 100644 src/main/java/net/knarcraft/timeismoney/TimeIsMoney.java create mode 100644 src/main/java/net/knarcraft/timeismoney/command/ReloadCommand.java create mode 100644 src/main/java/net/knarcraft/timeismoney/command/SetGroupPaymentCommand.java create mode 100644 src/main/java/net/knarcraft/timeismoney/command/SetPlayerPaymentCommand.java create mode 100644 src/main/java/net/knarcraft/timeismoney/config/Configuration.java create mode 100644 src/main/java/net/knarcraft/timeismoney/listener/PlayerJoinListener.java create mode 100644 src/main/java/net/knarcraft/timeismoney/manager/EconomyManager.java create mode 100644 src/main/java/net/knarcraft/timeismoney/manager/PermissionManager.java create mode 100644 src/main/java/net/knarcraft/timeismoney/manager/PlayerTracker.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/src/main/java/net/knarcraft/timeismoney/TimeIsMoney.java b/src/main/java/net/knarcraft/timeismoney/TimeIsMoney.java new file mode 100644 index 0000000..5636645 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/TimeIsMoney.java @@ -0,0 +1,171 @@ +package net.knarcraft.timeismoney; + +import com.earth2me.essentials.IEssentials; +import net.knarcraft.timeismoney.command.ReloadCommand; +import net.knarcraft.timeismoney.config.Configuration; +import net.knarcraft.timeismoney.listener.PlayerJoinListener; +import net.knarcraft.timeismoney.manager.EconomyManager; +import net.knarcraft.timeismoney.manager.PermissionManager; +import net.knarcraft.timeismoney.manager.PlayerTracker; +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; +import org.bukkit.Statistic; +import org.bukkit.command.PluginCommand; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Level; + +/** + * Time is money's main class + */ +public final class TimeIsMoney extends JavaPlugin { + + private Configuration configuration; + private IEssentials essentials = null; + private static TimeIsMoney timeIsMoney; + + @Override + public void onEnable() { + timeIsMoney = this; + this.saveDefaultConfig(); + FileConfiguration fileConfiguration = this.getConfig(); + fileConfiguration.options().copyDefaults(true); + this.saveConfig(); + this.reloadConfig(); + this.configuration = new Configuration(fileConfiguration); + + // Plugin startup logic + if (Bukkit.getPluginManager().getPlugin("Vault") != null) { + setupVault(); + } else { + this.getLogger().log(Level.SEVERE, "Could not find Vault. Plugin disabled."); + this.setEnabled(false); + return; + } + + if (Bukkit.getPluginManager().isPluginEnabled("Essentials")) { + essentials = (com.earth2me.essentials.IEssentials) + Bukkit.getServer().getPluginManager().getPlugin("Essentials"); + } else { + this.getLogger().log(Level.WARNING, "Could not find Essentials. AFK tracking is disabled."); + } + + ReloadCommand reloadCommand = new ReloadCommand(); + PluginCommand command = getCommand("reload"); + if (command != null) { + command.setExecutor(reloadCommand); + command.setTabCompleter(reloadCommand); + } + + Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), this); + + Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this::payPlayers, 20, 20); + } + + @Override + public void onDisable() { + // Plugin shutdown logic + } + + /** + * Reloads the configuration from disk + */ + public static void reload() { + timeIsMoney.reloadConfig(); + timeIsMoney.saveConfig(); + timeIsMoney.configuration = new Configuration(timeIsMoney.getConfig()); + } + + /** + * Pay all players that have been on the server long enough + */ + private void payPlayers() { + if (!EconomyManager.isInitialized()) { + return; + } + + // Deposit money to all players + for (Player player : Bukkit.getOnlinePlayers()) { + Long lastPaid = PlayerTracker.getPaymentTime(player); + if (lastPaid == null) { + continue; + } + if ((System.currentTimeMillis() - lastPaid) / 60000 < configuration.getPaymentDelay()) { + continue; + } + + // Don't pay, or just pay a percentage to AFK players + double afkPercentage = configuration.getAfkPercentage(); + boolean isAFK = essentials != null && essentials.getUser(player).isAfk(); + if (isAFK && afkPercentage <= 0) { + continue; + } + double payment = configuration.getBasePay(player) * getPayoutMultiplier(player); + if (isAFK) { + payment *= afkPercentage; + } + EconomyManager.deposit(player, payment); + if (configuration.displayPaymentMessage()) { + player.sendMessage(this.getDescription().getPrefix() + "You got a paycheck of " + + EconomyManager.format(payment)); + } + PlayerTracker.trackPlayer(player); + } + } + + /** + * Gets a payout multiplier based on how many hours the player has played on the server + * + * @param player

The player to check

+ * @return

The player's payout multiplier

+ */ + private double getPayoutMultiplier(Player player) { + if (configuration.getHoursUntilBonus() < 0) { + return 1; + } + double playtimeHours = getPlayTimeHours(player); + if (playtimeHours < configuration.getHoursUntilBonus()) { + return 1; + } else { + return Math.max((playtimeHours / configuration.getHoursUntilBonus()) * configuration.getBonusMultiplier(), 1); + } + } + + /** + * Gets the number of hours a player has played + * + * @param player

The player to check playtime for

+ * @return

The player's playtime

+ */ + private double getPlayTimeHours(@NotNull Player player) { + return player.getStatistic(Statistic.PLAY_ONE_MINUTE) / 20.0 / 3600.0; + } + + /** + * Sets up Vault by getting plugins from their providers + */ + private void setupVault() { + ServicesManager servicesManager = this.getServer().getServicesManager(); + RegisteredServiceProvider permissionProvider = servicesManager.getRegistration(Permission.class); + RegisteredServiceProvider economyProvider = servicesManager.getRegistration(Economy.class); + + if (permissionProvider != null) { + PermissionManager.initialize(permissionProvider.getProvider()); + } else { + getLogger().log(Level.WARNING, "No Vault permission provider found. Permission rewards are unavailable."); + } + + if (economyProvider != null) { + EconomyManager.initialize(economyProvider.getProvider()); + } else { + getLogger().log(Level.WARNING, "No Vault economy provider found. Economy rewards are unavailable."); + } + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/command/ReloadCommand.java b/src/main/java/net/knarcraft/timeismoney/command/ReloadCommand.java new file mode 100644 index 0000000..6c49288 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/command/ReloadCommand.java @@ -0,0 +1,33 @@ +package net.knarcraft.timeismoney.command; + +import net.knarcraft.timeismoney.TimeIsMoney; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * The command for reloading this plugin's configuration + */ +public class ReloadCommand implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + TimeIsMoney.reload(); + sender.sendMessage("Plugin reloaded!"); + return true; + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, + @NotNull String[] args) { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/command/SetGroupPaymentCommand.java b/src/main/java/net/knarcraft/timeismoney/command/SetGroupPaymentCommand.java new file mode 100644 index 0000000..f6c6709 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/command/SetGroupPaymentCommand.java @@ -0,0 +1,5 @@ +package net.knarcraft.timeismoney.command; + +public class SetGroupPaymentCommand { + // TODO: Implement this +} diff --git a/src/main/java/net/knarcraft/timeismoney/command/SetPlayerPaymentCommand.java b/src/main/java/net/knarcraft/timeismoney/command/SetPlayerPaymentCommand.java new file mode 100644 index 0000000..44260c3 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/command/SetPlayerPaymentCommand.java @@ -0,0 +1,5 @@ +package net.knarcraft.timeismoney.command; + +public class SetPlayerPaymentCommand { + //TODO: Implement this +} diff --git a/src/main/java/net/knarcraft/timeismoney/config/Configuration.java b/src/main/java/net/knarcraft/timeismoney/config/Configuration.java new file mode 100644 index 0000000..b510d36 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/config/Configuration.java @@ -0,0 +1,131 @@ +package net.knarcraft.timeismoney.config; + +import net.knarcraft.timeismoney.manager.PermissionManager; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * This plugin's configuration + */ +public class Configuration { + + private final Map groupPayouts; + private final Map playerPayouts; + private final double defaultPayout; + private final int hoursUntilBonus; + private final double bonusMultiplier; + private final int paymentDelay; + private final double afkPercentage; + private final boolean displayPaymentMessage; + + /** + * Instantiates a new configuration + * + * @param fileConfiguration

The file configuration to read values from

+ */ + public Configuration(FileConfiguration fileConfiguration) { + groupPayouts = new HashMap<>(); + playerPayouts = new HashMap<>(); + ConfigurationSection groupPayoutsSection = fileConfiguration.getConfigurationSection("groupPayouts"); + if (groupPayoutsSection != null) { + for (String key : groupPayoutsSection.getKeys(false)) { + groupPayouts.put(key, groupPayoutsSection.getDouble(key)); + } + } + ConfigurationSection playerPayoutsSection = fileConfiguration.getConfigurationSection("playerPayouts"); + if (playerPayoutsSection != null) { + for (String key : playerPayoutsSection.getKeys(false)) { + playerPayouts.put(UUID.fromString(key), playerPayoutsSection.getDouble(key)); + } + } + this.defaultPayout = fileConfiguration.getDouble("defaultPayout", 10); + this.hoursUntilBonus = fileConfiguration.getInt("hoursUntilBonus", 100); + this.bonusMultiplier = fileConfiguration.getDouble("bonusMultiplier", 1); + this.paymentDelay = fileConfiguration.getInt("paymentDelay", 60); + this.afkPercentage = fileConfiguration.getDouble("afkPercentage", 0); + this.displayPaymentMessage = fileConfiguration.getBoolean("displayPaymentMessage", true); + } + + /** + * Gets the number of hours a player must have played to receive a payment bonus + * + * @return

The min. amount of hours required to get a bonus

+ */ + public int getHoursUntilBonus() { + return hoursUntilBonus; + } + + /** + * A multiplier to apply to the bonus + * + *

By default, the bonus is total playtime / hours until bonus. This multiplier allows adjusting how high or low + * the bonus becomes. For example, a bonus multiplier of 0.5 would halve the paid bonus, while a bonus multiplier + * of 2 would double the paid bonus.

+ * + * @return

The bonus multiplier

+ */ + public double getBonusMultiplier() { + return bonusMultiplier; + } + + /** + * Gets the base payout to pay the given player + * + * @param player

The player to get the base payout for

+ * @return

The player's base pay

+ */ + public double getBasePay(@NotNull Player player) { + if (playerPayouts.get(player.getUniqueId()) != null) { + return playerPayouts.get(player.getUniqueId()); + } + + double maxPay = -1; + if (PermissionManager.isInitialized()) { + for (String group : PermissionManager.getPlayerGroups(player)) { + if (groupPayouts.containsKey(group)) { + maxPay = Math.max(maxPay, groupPayouts.get(group)); + } + } + } + + if (maxPay == -1) { + return defaultPayout; + } else { + return maxPay; + } + } + + /** + * The delay between each time a player is paid + * + * @return

The delay between payments

+ */ + public int getPaymentDelay() { + return paymentDelay; + } + + /** + * The percentage of the payment to pay AFK players + * + * @return

AFK players' payment percentage

+ */ + public double getAfkPercentage() { + return afkPercentage; + } + + /** + * Whether to display a message to players when they're paid + * + * @return

True if a payment message should be displayed

+ */ + public boolean displayPaymentMessage() { + return displayPaymentMessage; + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/listener/PlayerJoinListener.java b/src/main/java/net/knarcraft/timeismoney/listener/PlayerJoinListener.java new file mode 100644 index 0000000..11e5227 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/listener/PlayerJoinListener.java @@ -0,0 +1,18 @@ +package net.knarcraft.timeismoney.listener; + +import net.knarcraft.timeismoney.manager.PlayerTracker; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +/** + * A listener that starts tracking player time once players join + */ +public class PlayerJoinListener implements Listener { + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + PlayerTracker.trackPlayer(event.getPlayer()); + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/manager/EconomyManager.java b/src/main/java/net/knarcraft/timeismoney/manager/EconomyManager.java new file mode 100644 index 0000000..8674f27 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/manager/EconomyManager.java @@ -0,0 +1,55 @@ +package net.knarcraft.timeismoney.manager; + +import net.milkbowl.vault.economy.Economy; +import org.bukkit.OfflinePlayer; + +/** + * A manager that performs all Economy tasks + */ +public final class EconomyManager { + + private static Economy economy; + + private EconomyManager() { + + } + + /** + * Initializes the economy manager + * + * @param economy

The economy object to use for everything economy-related

+ */ + public static void initialize(Economy economy) { + EconomyManager.economy = economy; + } + + /** + * Checks whether the economy manager has been initialized + * + * @return

True if the economy manager has been initialized

+ */ + public static boolean isInitialized() { + return EconomyManager.economy != null; + } + + /** + * Formats the given amount of currency according to the economy plugin's format + * + * @param amount

The amount of currency to format

+ * @return

The formatted string

+ */ + public static String format(double amount) { + return economy.format(amount); + } + + /** + * Deposits a given sum into the given player's account + * + * @param player

The player to deposit money to

+ * @param sum

The amount of money to deposit

+ */ + public static void deposit(OfflinePlayer player, double sum) { + economy.depositPlayer(player, sum); + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/manager/PermissionManager.java b/src/main/java/net/knarcraft/timeismoney/manager/PermissionManager.java new file mode 100644 index 0000000..94bb8c5 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/manager/PermissionManager.java @@ -0,0 +1,46 @@ +package net.knarcraft.timeismoney.manager; + +import net.milkbowl.vault.permission.Permission; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +/** + * A manager that performs all Permission tasks + */ +public final class PermissionManager { + + private static Permission permission; + + private PermissionManager() { + + } + + /** + * Initializes the permission manager + * + * @param permission

The permission object to use for everything permission-related

+ */ + public static void initialize(Permission permission) { + PermissionManager.permission = permission; + } + + /** + * Checks whether the permission manager has been initialized + * + * @return

True if the permission manager has been initialized

+ */ + public static boolean isInitialized() { + return PermissionManager.permission != null; + } + + /** + * Gets all groups of a player + * + * @param player

The player to get the groups for

+ * @return

The player's groups

+ */ + public static String[] getPlayerGroups(@NotNull Player player) { + return permission.getPlayerGroups(player); + } + +} diff --git a/src/main/java/net/knarcraft/timeismoney/manager/PlayerTracker.java b/src/main/java/net/knarcraft/timeismoney/manager/PlayerTracker.java new file mode 100644 index 0000000..847c816 --- /dev/null +++ b/src/main/java/net/knarcraft/timeismoney/manager/PlayerTracker.java @@ -0,0 +1,42 @@ +package net.knarcraft.timeismoney.manager; + +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +/** + * A tracker keeping track of players' payment times + */ +public final class PlayerTracker { + + private static final Map playerLastPaid = new HashMap<>(); + + private PlayerTracker() { + + } + + /** + * Track's a player's last payment time + * + *

Call this when the player joins to set the 0 time.

+ * + * @param player

The player to track

+ */ + public static void trackPlayer(Player player) { + playerLastPaid.put(player, System.currentTimeMillis()); + } + + /** + * Gets the last time the given player was paid + * + *

The return time is in the format of 'System.currentTimeMillis()'

+ * + * @param player

The player to check player time for

+ * @return

The last time the player was paid

+ */ + public static Long getPaymentTime(Player player) { + return playerLastPaid.get(player); + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..c617326 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,16 @@ +# The default payout if the player has no overrides +defaultPayout: 10 +# The amount of minutes to wait between each payment +paymentDelay: 60 +# Whether to announce to a player that they've just been paid +displayPaymentMessage: true +# The amount of hours until a bonus is given. Set to -1 to disable. +hoursUntilBonus: 100 +# A multiplier used to increase or decrease the time bonus +bonusMultiplier: 1 +# The percentage of the payment to pay AFK players +afkPercentage: 0 +# Overrides for specific groups +groupPayouts: [ ] +# Overrides for specific players +playerPayouts: [ ] \ 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..38ee0c1 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,21 @@ +name: "TimeIsMoney" +version: '${project.version}' +main: net.knarcraft.timeismoney.TimeIsMoney +api-version: '1.20' +prefix: 'TimeIsMoney' +author: EpicKnarvik97 +depend: + - Vault +softdepend: + - Essentials + +commands: + reload: + permission: timeismoney.reload + description: Reloads the plugin + usage: / + +permissions: + timeismoney.reload: + description: Allows usage of the /reload command + default: false \ No newline at end of file