All source projects

MrUltimateLibrary Source

Standalone source project / 68 files

MrUltimateLibrary is the backbone of all my plugins; it offers features that facilitate plugin creation, maintenance, and updates.

java

MrUltimateLibrary/src/main/java/eu/mrneznamy/mrultimatelibrary/economy/MrLibEconomy.java

JAVA · Read-only source

package eu.mrneznamy.mrultimatelibrary.economy;

import eu.mrneznamy.mrultimatelibrary.utils.MrLibConsoleSayer;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.Plugin;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;

/**
 * Unified multi-economy manager for MrLib plugins.
 * Supports Vault, CoinsEngine, BeastTokens, PlayerPoints, GemsEconomy, MrUltimateEconomy, and VotingPlugin.
 */
public class MrLibEconomy {

    public enum EconomyType {
        VAULT,
        COINS_ENGINE,
        BEAST_TOKENS,
        PLAYER_POINTS,
        GEMS_ECONOMY,
        MR_ULTIMATE_ECONOMY,
        VOTING_PLUGIN,
        MR_VOTE_TRAIN
    }

    /**
     * Checks if the specified economy type is currently available on the server.
     */
    public static boolean isEnabled(EconomyType type) {
        if (type == null) return false;
        switch (type) {
            case VAULT:
                return MrLibVaultManager.getInstance().isEnabled();
            case COINS_ENGINE:
                return isPluginEnabled("CoinsEngine");
            case BEAST_TOKENS:
                return isPluginEnabled("BeastTokens");
            case PLAYER_POINTS:
                return isPluginEnabled("PlayerPoints");
            case GEMS_ECONOMY:
                return isPluginEnabled("GemsEconomy");
            case MR_ULTIMATE_ECONOMY:
                return isPluginEnabled("MrUltimateEconomy");
            case VOTING_PLUGIN:
                return isPluginEnabled("VotingPlugin");
            case MR_VOTE_TRAIN:
                return isPluginEnabled("MrVoteTrain");
            default:
                return false;
        }
    }

    private static boolean isPluginEnabled(String pluginName) {
        Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
        return plugin != null && plugin.isEnabled();
    }

    /**
     * Gets the balance of a player.
     *
     * @param player   The player to check.
     * @param type     The economy type to use.
     * @param currency Optional currency name/identifier (used for multi-currency economies like CoinsEngine, GemsEconomy, MrUltimateEconomy).
     * @return The player's balance, or 0.0 if failed/not supported.
     */
    public static double getBalance(OfflinePlayer player, EconomyType type, String currency) {
        if (!isEnabled(type) || player == null) return 0.0;

        try {
            switch (type) {
                case VAULT:
                    if (player.isOnline()) {
                        return MrLibVaultManager.getInstance().getBalance(player.getPlayer());
                    }
                    
                    Object vaultProvider = MrLibVaultManager.getInstance().getEconomy();
                    if (vaultProvider != null) {
                        Method getBal = vaultProvider.getClass().getMethod("getBalance", OfflinePlayer.class);
                        return (double) getBal.invoke(vaultProvider, player);
                    }
                    return 0.0;

                case COINS_ENGINE:
                    return getCoinsEngineBalance(player, currency);

                case BEAST_TOKENS:
                    return getBeastTokensBalance(player);

                case PLAYER_POINTS:
                    return getPlayerPointsBalance(player);

                case GEMS_ECONOMY:
                    return getGemsEconomyBalance(player, currency);

                case MR_ULTIMATE_ECONOMY:
                    return getMrUltimateEconomyBalance(player, currency);

                case VOTING_PLUGIN:
                    return getVotingPluginBalance(player);

                case MR_VOTE_TRAIN:
                    return getMrVoteTrainBalance(player);
            }
        } catch (Exception e) {
            MrLibConsoleSayer.MrSay_Warning("Failed to get balance using " + type + ": " + e.getMessage());
        }
        return 0.0;
    }

    /**
     * Checks if a player has at least a specific amount of currency.
     */
    public static boolean has(OfflinePlayer player, EconomyType type, String currency, double amount) {
        return getBalance(player, type, currency) >= amount;
    }

    /**
     * Withdraws currency from a player.
     */
    public static boolean withdraw(OfflinePlayer player, EconomyType type, String currency, double amount) {
        if (!isEnabled(type) || player == null || amount <= 0) return false;

        try {
            switch (type) {
                case VAULT:
                    return MrLibVaultManager.getInstance().withdraw(player, amount);

                case COINS_ENGINE:
                    return modifyCoinsEngineBalance(player, currency, amount, false);

                case BEAST_TOKENS:
                    return modifyBeastTokensBalance(player, amount, false);

                case PLAYER_POINTS:
                    return modifyPlayerPointsBalance(player, (int) amount, false);

                case GEMS_ECONOMY:
                    return modifyGemsEconomyBalance(player, currency, amount, false);

                case MR_ULTIMATE_ECONOMY:
                    return modifyMrUltimateEconomyBalance(player, currency, amount, false);

                case VOTING_PLUGIN:
                    return modifyVotingPluginBalance(player, (int) amount, false);

                case MR_VOTE_TRAIN:
                    return modifyMrVoteTrainBalance(player, (int) amount, false);
            }
        } catch (Exception e) {
            MrLibConsoleSayer.MrSay_Warning("Failed to withdraw using " + type + ": " + e.getMessage());
        }
        return false;
    }

    /**
     * Deposits currency to a player.
     */
    public static boolean deposit(OfflinePlayer player, EconomyType type, String currency, double amount) {
        if (!isEnabled(type) || player == null || amount <= 0) return false;

        try {
            switch (type) {
                case VAULT:
                    return MrLibVaultManager.getInstance().deposit(player, amount);

                case COINS_ENGINE:
                    return modifyCoinsEngineBalance(player, currency, amount, true);

                case BEAST_TOKENS:
                    return modifyBeastTokensBalance(player, amount, true);

                case PLAYER_POINTS:
                    return modifyPlayerPointsBalance(player, (int) amount, true);

                case GEMS_ECONOMY:
                    return modifyGemsEconomyBalance(player, currency, amount, true);

                case MR_ULTIMATE_ECONOMY:
                    return modifyMrUltimateEconomyBalance(player, currency, amount, true);

                case VOTING_PLUGIN:
                    return modifyVotingPluginBalance(player, (int) amount, true);

                case MR_VOTE_TRAIN:
                    return modifyMrVoteTrainBalance(player, (int) amount, true);
            }
        } catch (Exception e) {
            MrLibConsoleSayer.MrSay_Warning("Failed to deposit using " + type + ": " + e.getMessage());
        }
        return false;
    }

    

    private static double getCoinsEngineBalance(OfflinePlayer player, String currencyId) throws Exception {
        if (currencyId == null || currencyId.isEmpty()) currencyId = "coins";
        Object currencyObj = getCoinsEngineCurrency(currencyId);
        if (currencyObj == null) return 0.0;

        Method getBal = findMethod(currencyObj.getClass(), "getBalance", OfflinePlayer.class);
        if (getBal == null) getBal = findMethod(currencyObj.getClass(), "getBalance", org.bukkit.entity.Player.class);
        
        if (getBal != null) {
            Object result = getBal.invoke(currencyObj, player.isOnline() ? player.getPlayer() : player);
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyCoinsEngineBalance(OfflinePlayer player, String currencyId, double amount, boolean give) throws Exception {
        if (currencyId == null || currencyId.isEmpty()) currencyId = "coins";
        Object currencyObj = getCoinsEngineCurrency(currencyId);
        if (currencyObj == null) return false;

        String methodName = give ? "addBalance" : "takeBalance";
        Method modifyMethod = findMethod(currencyObj.getClass(), methodName, OfflinePlayer.class, double.class);
        if (modifyMethod == null) modifyMethod = findMethod(currencyObj.getClass(), methodName, org.bukkit.entity.Player.class, double.class);

        if (modifyMethod != null) {
            modifyMethod.invoke(currencyObj, player.isOnline() ? player.getPlayer() : player, amount);
            return true;
        }
        return false;
    }

    private static Object getCoinsEngineCurrency(String id) {
        try {
            Class<?> apiClass = null;
            try {
                apiClass = Class.forName("su.nightexpress.coinsengine.api.CoinsEngineAPI");
            } catch (ClassNotFoundException e) {
                apiClass = Class.forName("su.nex.coinsengine.api.CoinsEngineAPI");
            }

            if (apiClass != null) {
                Method getCurrencyMethod = apiClass.getMethod("getCurrency", String.class);
                return getCurrencyMethod.invoke(null, id);
            }
        } catch (Exception ignored) {}
        return null;
    }

    

    private static double getBeastTokensBalance(OfflinePlayer player) throws Exception {
        Class<?> apiClass = Class.forName("me.mraxet.beasttokens.api.BeastTokensAPI");
        Method getTokens = findMethod(apiClass, "getTokens", OfflinePlayer.class);
        if (getTokens == null) getTokens = findMethod(apiClass, "getTokens", UUID.class);

        if (getTokens != null) {
            Object param = getTokens.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player;
            Object result = getTokens.invoke(null, param);
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyBeastTokensBalance(OfflinePlayer player, double amount, boolean give) throws Exception {
        Class<?> apiClass = Class.forName("me.mraxet.beasttokens.api.BeastTokensAPI");
        String methodName = give ? "addTokens" : "removeTokens";
        
        Method modifyMethod = findMethod(apiClass, methodName, OfflinePlayer.class, double.class);
        if (modifyMethod == null) modifyMethod = findMethod(apiClass, methodName, UUID.class, double.class);

        if (modifyMethod != null) {
            Object param = modifyMethod.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player;
            modifyMethod.invoke(null, param, amount);
            return true;
        }
        return false;
    }

    

    private static double getPlayerPointsBalance(OfflinePlayer player) throws Exception {
        Object api = getPlayerPointsAPI();
        if (api == null) return 0.0;

        Method look = findMethod(api.getClass(), "look", UUID.class);
        if (look == null) look = findMethod(api.getClass(), "look", String.class);

        if (look != null) {
            Object param = look.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player.getName();
            Object result = look.invoke(api, param);
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyPlayerPointsBalance(OfflinePlayer player, int amount, boolean give) throws Exception {
        Object api = getPlayerPointsAPI();
        if (api == null) return false;

        String methodName = give ? "give" : "take";
        Method modifyMethod = findMethod(api.getClass(), methodName, UUID.class, int.class);
        if (modifyMethod == null) modifyMethod = findMethod(api.getClass(), methodName, String.class, int.class);

        if (modifyMethod != null) {
            Object param = modifyMethod.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player.getName();
            Object result = modifyMethod.invoke(api, param, amount);
            return result instanceof Boolean ? (Boolean) result : true;
        }
        return false;
    }

    private static Object getPlayerPointsAPI() {
        try {
            Plugin pp = Bukkit.getPluginManager().getPlugin("PlayerPoints");
            if (pp != null) {
                Method getApiMethod = pp.getClass().getMethod("getAPI");
                return getApiMethod.invoke(pp);
            }
        } catch (Exception ignored) {}
        return null;
    }

    

    private static double getGemsEconomyBalance(OfflinePlayer player, String currencyName) throws Exception {
        Class<?> apiClass = Class.forName("me.xanium.gemseconomy.api.GemsEconomyAPI");
        Constructor<?> constructor = apiClass.getConstructor();
        Object apiInstance = constructor.newInstance();

        Method getBal = findMethod(apiClass, "getBalance", UUID.class);
        if (getBal == null) getBal = findMethod(apiClass, "getBalance", OfflinePlayer.class);

        if (getBal != null) {
            Object param = getBal.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player;
            Object result = getBal.invoke(apiInstance, param);
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyGemsEconomyBalance(OfflinePlayer player, String currencyName, double amount, boolean give) throws Exception {
        Class<?> apiClass = Class.forName("me.xanium.gemseconomy.api.GemsEconomyAPI");
        Constructor<?> constructor = apiClass.getConstructor();
        Object apiInstance = constructor.newInstance();

        String methodName = give ? "deposit" : "withdraw";
        Method modifyMethod = findMethod(apiClass, methodName, UUID.class, double.class);
        if (modifyMethod == null) modifyMethod = findMethod(apiClass, methodName, OfflinePlayer.class, double.class);

        if (modifyMethod != null) {
            Object param = modifyMethod.getParameterTypes()[0].equals(UUID.class) ? player.getUniqueId() : player;
            modifyMethod.invoke(apiInstance, param, amount);
            return true;
        }
        return false;
    }

    

    private static double getMrUltimateEconomyBalance(OfflinePlayer player, String currencyName) throws Exception {
        if (currencyName == null || currencyName.isEmpty()) currencyName = "dollar";
        Class<?> apiClass = Class.forName("eu.mrneznamy.mrultimateeconomy.api.MrUltimateEconomyAPI");
        Method getInstance = apiClass.getMethod("getInstance");
        Object apiInstance = getInstance.invoke(null);

        if (apiInstance != null) {
            Method getBal = apiClass.getMethod("getBalance", OfflinePlayer.class, String.class);
            return (double) getBal.invoke(apiInstance, player, currencyName);
        }
        return 0.0;
    }

    private static boolean modifyMrUltimateEconomyBalance(OfflinePlayer player, String currencyName, double amount, boolean give) throws Exception {
        if (currencyName == null || currencyName.isEmpty()) currencyName = "dollar";
        Class<?> apiClass = Class.forName("eu.mrneznamy.mrultimateeconomy.api.MrUltimateEconomyAPI");
        Method getInstance = apiClass.getMethod("getInstance");
        Object apiInstance = getInstance.invoke(null);

        if (apiInstance != null) {
            String methodName = give ? "give" : "take";
            Method modifyMethod = apiClass.getMethod(methodName, OfflinePlayer.class, String.class, double.class);
            modifyMethod.invoke(apiInstance, player, currencyName, amount);
            return true;
        }
        return false;
    }

    

    private static double getVotingPluginBalance(OfflinePlayer player) throws Exception {
        Object user = getVotingPluginUser(player);
        if (user == null) return 0.0;

        Method getPoints = findMethod(user.getClass(), "getPoints");
        if (getPoints != null) {
            Object result = getPoints.invoke(user);
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyVotingPluginBalance(OfflinePlayer player, int amount, boolean give) throws Exception {
        Object user = getVotingPluginUser(player);
        if (user == null) return false;

        String methodName = give ? "addPoints" : "removePoints";
        Method modifyMethod = findMethod(user.getClass(), methodName, int.class);

        if (modifyMethod != null) {
            modifyMethod.invoke(user, amount);
            return true;
        }
        return false;
    }

    private static Object getVotingPluginUser(OfflinePlayer player) {
        try {
            Class<?> mainClass = Class.forName("com.bencodez.votingplugin.VotingPluginMain");
            Method getPlugin = mainClass.getMethod("getPlugin");
            Object pluginInstance = getPlugin.invoke(null);

            if (pluginInstance != null) {
                Method getUserManager = pluginInstance.getClass().getMethod("getVotingPluginUserManager");
                Object userManager = getUserManager.invoke(pluginInstance);

                if (userManager != null) {
                    Method getUser = userManager.getClass().getMethod("getVotingPluginUser", OfflinePlayer.class);
                    return getUser.invoke(userManager, player);
                }
            }
        } catch (Exception ignored) {}
        return null;
    }

    

    private static double getMrVoteTrainBalance(OfflinePlayer player) throws Exception {
        Object dbManager = getMrVoteTrainDatabaseManager();
        if (dbManager == null) return 0.0;

        Method getPoints = findMethod(dbManager.getClass(), "getPlayerPoints", UUID.class);
        if (getPoints != null) {
            Object result = getPoints.invoke(dbManager, player.getUniqueId());
            return result instanceof Number ? ((Number) result).doubleValue() : 0.0;
        }
        return 0.0;
    }

    private static boolean modifyMrVoteTrainBalance(OfflinePlayer player, int amount, boolean give) throws Exception {
        Object dbManager = getMrVoteTrainDatabaseManager();
        if (dbManager == null) return false;

        int currentPoints = (int) getMrVoteTrainBalance(player);
        int newPoints = give ? currentPoints + amount : currentPoints - amount;
        if (newPoints < 0 && !give) return false;

        Method setPoints = findMethod(dbManager.getClass(), "setPlayerPoints", UUID.class, int.class);
        if (setPoints != null) {
            setPoints.invoke(dbManager, player.getUniqueId(), newPoints);
            return true;
        }
        return false;
    }

    private static Object getMrVoteTrainDatabaseManager() {
        try {
            Plugin plugin = Bukkit.getPluginManager().getPlugin("MrVoteTrain");
            if (plugin != null) {
                Method getDb = plugin.getClass().getMethod("getDatabaseManager");
                return getDb.invoke(plugin);
            }
        } catch (Exception ignored) {}
        return null;
    }

    /**
     * Gets a list of available currency names for the given economy type.
     */
    public static java.util.List<String> getCurrencies(EconomyType type) {
        java.util.List<String> list = new java.util.ArrayList<>();
        if (!isEnabled(type)) return list;

        try {
            switch (type) {
                case VAULT:
                    list.add("default");
                    break;
                case COINS_ENGINE:
                    Class<?> ceApiClass = null;
                    try {
                        ceApiClass = Class.forName("su.nightexpress.coinsengine.api.CoinsEngineAPI");
                    } catch (ClassNotFoundException e2) {
                        ceApiClass = Class.forName("su.nex.coinsengine.api.CoinsEngineAPI");
                    }
                    if (ceApiClass != null) {
                        Method getMgr = ceApiClass.getMethod("getCurrencyManager");
                        Object mgr = getMgr.invoke(null);
                        if (mgr != null) {
                            Method getCurs = mgr.getClass().getMethod("getCurrencies");
                            java.util.Collection<?> curs = (java.util.Collection<?>) getCurs.invoke(mgr);
                            if (curs != null) {
                                for (Object cur : curs) {
                                    Method getId = cur.getClass().getMethod("getId");
                                    list.add(String.valueOf(getId.invoke(cur)));
                                }
                            }
                        }
                    }
                    break;
                case GEMS_ECONOMY:
                    Class<?> geApiClass = Class.forName("me.xanium.gemseconomy.api.GemsEconomyAPI");
                    java.lang.reflect.Constructor<?> constr = geApiClass.getConstructor();
                    Object geApi = constr.newInstance();
                    Method getCurs = geApiClass.getMethod("getCurrencies");
                    java.util.Collection<?> curs = (java.util.Collection<?>) getCurs.invoke(geApi);
                    if (curs != null) {
                        for (Object cur : curs) {
                            Method getName = cur.getClass().getMethod("getName");
                            list.add(String.valueOf(getName.invoke(cur)));
                        }
                    }
                    break;
                case MR_ULTIMATE_ECONOMY:
                    Class<?> mueApiClass = Class.forName("eu.mrneznamy.mrultimateeconomy.api.MrUltimateEconomyAPI");
                    Method getInstance = mueApiClass.getMethod("getInstance");
                    Object mueApi = getInstance.invoke(null);
                    if (mueApi != null) {
                        Method getCurs2 = mueApiClass.getMethod("getCurrencies");
                        java.util.List<?> curs2 = (java.util.List<?>) getCurs2.invoke(mueApi);
                        if (curs2 != null) {
                            for (Object cur : curs2) {
                                list.add(String.valueOf(cur));
                            }
                        }
                    }
                    break;
                default:
                    list.add("default");
                    break;
            }
        } catch (Exception ignored) {}

        return list;
    }

    

    private static Method findMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
        try {
            return clazz.getMethod(name, parameterTypes);
        } catch (NoSuchMethodException e) {
            
            for (Method method : clazz.getMethods()) {
                if (method.getName().equals(name) && method.getParameterCount() == parameterTypes.length) {
                    boolean match = true;
                    Class<?>[] types = method.getParameterTypes();
                    for (int i = 0; i < types.length; i++) {
                        if (!types[i].isAssignableFrom(parameterTypes[i]) && 
                            !wrap(types[i]).isAssignableFrom(wrap(parameterTypes[i]))) {
                            match = false;
                            break;
                        }
                    }
                    if (match) return method;
                }
            }
        }
        return null;
    }

    private static Class<?> wrap(Class<?> type) {
        if (!type.isPrimitive()) return type;
        if (type == int.class) return Integer.class;
        if (type == double.class) return Double.class;
        if (type == boolean.class) return Boolean.class;
        if (type == long.class) return Long.class;
        if (type == float.class) return Float.class;
        if (type == byte.class) return Byte.class;
        if (type == char.class) return Character.class;
        if (type == short.class) return Short.class;
        return type;
    }
}
581 linesGNU GENERAL PUBLIC LICENSE · Version 3, 29 June 2007 · UTF-8 · Read only