Initial commit

This commit is contained in:
Kristian Knarvik 2023-12-16 17:59:06 +01:00
commit 9ba486bab4
12 changed files with 656 additions and 0 deletions

113
.gitignore vendored Normal file
View File

@ -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/

View File

@ -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 <p>The player to check</p>
* @return <p>The player's payout multiplier</p>
*/
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 <p>The player to check playtime for</p>
* @return <p>The player's playtime</p>
*/
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<Permission> permissionProvider = servicesManager.getRegistration(Permission.class);
RegisteredServiceProvider<Economy> 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.");
}
}
}

View File

@ -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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
return new ArrayList<>();
}
}

View File

@ -0,0 +1,5 @@
package net.knarcraft.timeismoney.command;
public class SetGroupPaymentCommand {
// TODO: Implement this
}

View File

@ -0,0 +1,5 @@
package net.knarcraft.timeismoney.command;
public class SetPlayerPaymentCommand {
//TODO: Implement this
}

View File

@ -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<String, Double> groupPayouts;
private final Map<UUID, Double> 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 <p>The file configuration to read values from</p>
*/
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 <p>The min. amount of hours required to get a bonus</p>
*/
public int getHoursUntilBonus() {
return hoursUntilBonus;
}
/**
* A multiplier to apply to the bonus
*
* <p>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.</p>
*
* @return <p>The bonus multiplier</p>
*/
public double getBonusMultiplier() {
return bonusMultiplier;
}
/**
* Gets the base payout to pay the given player
*
* @param player <p>The player to get the base payout for</p>
* @return <p>The player's base pay</p>
*/
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 <p>The delay between payments</p>
*/
public int getPaymentDelay() {
return paymentDelay;
}
/**
* The percentage of the payment to pay AFK players
*
* @return <p>AFK players' payment percentage</p>
*/
public double getAfkPercentage() {
return afkPercentage;
}
/**
* Whether to display a message to players when they're paid
*
* @return <p>True if a payment message should be displayed</p>
*/
public boolean displayPaymentMessage() {
return displayPaymentMessage;
}
}

View File

@ -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());
}
}

View File

@ -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 <p>The economy object to use for everything economy-related</p>
*/
public static void initialize(Economy economy) {
EconomyManager.economy = economy;
}
/**
* Checks whether the economy manager has been initialized
*
* @return <p>True if the economy manager has been initialized</p>
*/
public static boolean isInitialized() {
return EconomyManager.economy != null;
}
/**
* Formats the given amount of currency according to the economy plugin's format
*
* @param amount <p>The amount of currency to format</p>
* @return <p>The formatted string</p>
*/
public static String format(double amount) {
return economy.format(amount);
}
/**
* Deposits a given sum into the given player's account
*
* @param player <p>The player to deposit money to</p>
* @param sum <p>The amount of money to deposit</p>
*/
public static void deposit(OfflinePlayer player, double sum) {
economy.depositPlayer(player, sum);
}
}

View File

@ -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 <p>The permission object to use for everything permission-related</p>
*/
public static void initialize(Permission permission) {
PermissionManager.permission = permission;
}
/**
* Checks whether the permission manager has been initialized
*
* @return <p>True if the permission manager has been initialized</p>
*/
public static boolean isInitialized() {
return PermissionManager.permission != null;
}
/**
* Gets all groups of a player
*
* @param player <p>The player to get the groups for</p>
* @return <p>The player's groups</p>
*/
public static String[] getPlayerGroups(@NotNull Player player) {
return permission.getPlayerGroups(player);
}
}

View File

@ -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<Player, Long> playerLastPaid = new HashMap<>();
private PlayerTracker() {
}
/**
* Track's a player's last payment time
*
* <p>Call this when the player joins to set the 0 time.</p>
*
* @param player <p>The player to track</p>
*/
public static void trackPlayer(Player player) {
playerLastPaid.put(player, System.currentTimeMillis());
}
/**
* Gets the last time the given player was paid
*
* <p>The return time is in the format of 'System.currentTimeMillis()'</p>
*
* @param player <p>The player to check player time for</p>
* @return <p>The last time the player was paid</p>
*/
public static Long getPaymentTime(Player player) {
return playerLastPaid.get(player);
}
}

View File

@ -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: [ ]

View File

@ -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: /<command>
permissions:
timeismoney.reload:
description: Allows usage of the /reload command
default: false