diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java index a7ceb4e48..310452f04 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusAmount.java @@ -2,18 +2,16 @@ package mineplex.core.bonuses; import java.util.List; -import org.bukkit.ChatColor; - import mineplex.core.common.util.C; public class BonusAmount { private int _gems; - private int _coins; - private int _gold; + private int _shards; + private GoldAmount _gold = new GoldAmount(); private int _bonusGems; - private int _bonusCoins; - private int _bonusGold; + private int _bonusShards; + private GoldAmount _bonusGold = new GoldAmount(); private int _experience; private int _bonusExperience; private int _tickets; @@ -38,24 +36,24 @@ public class BonusAmount _gems = gems; } - public int getCoins() + public int getShards() { - return _coins; + return _shards; } - public void setCoins(int coins) + public void setShards(int shards) { - _coins = coins; + _shards = shards; } - public int getGold() + public GoldAmount getGold() { return _gold; } - public void setGold(int gold) + public void setGold(Integer serverId, Integer gold) { - _gold = gold; + _gold.setGoldFor(serverId, gold); } public int getBonusGems() @@ -68,24 +66,24 @@ public class BonusAmount _bonusGems = bonusGems; } - public int getBonusCoins() + public int getBonusShards() { - return _bonusCoins; + return _bonusShards; } - public void setBonusCoins(int bonusCoins) + public void setBonusShards(int bonusShards) { - _bonusCoins = bonusCoins; + _bonusShards = bonusShards; } - public int getBonusGold() + public GoldAmount getBonusGold() { return _bonusGold; } - public void setBonusGold(int bonusGold) + public void setBonusGold(Integer serverId, Integer bonusGold) { - _bonusGold = bonusGold; + _bonusGold.setGoldFor(serverId, bonusGold); } public int getTotalGems() @@ -93,14 +91,14 @@ public class BonusAmount return getGems() + getBonusGems(); } - public int getTotalCoins() + public int getTotalShards() { - return getCoins() + getBonusCoins(); + return getShards() + getBonusShards(); } public int getTotalGold() { - return getGold() + getBonusGold(); + return getGold().getTotalGold() + getBonusGold().getTotalGold(); } public int getExperience() @@ -190,16 +188,16 @@ public class BonusAmount public boolean isGreaterThanZero() { - return _bonusCoins > 0 || _coins > 0 || _bonusGems > 0 || _gems > 0 || _gold > 0 || _bonusGold > 0 || _oldChests > 0 || _ancientChests > 0 || _mythicalChests > 0; + return _bonusShards > 0 || _shards > 0 || _bonusGems > 0 || _gems > 0 || _gold.getTotalGold() > 0 || _bonusGold.getTotalGold() > 0 || _oldChests > 0 || _ancientChests > 0 || _mythicalChests > 0; } public void addLore(List lore) { lore.add(C.cYellow + "Rewards"); addLore(lore, getTickets(), 0, "Carl Spin Ticket" + (getTickets() > 1 ? "s" : "")); - addLore(lore, getCoins(), getBonusCoins(), "Treasure Shards"); + addLore(lore, getShards(), getBonusShards(), "Treasure Shards"); addLore(lore, getGems(), getBonusGems(), "Gems"); - addLore(lore, getGold(), getBonusGold(), "Gold"); + addLore(lore, getGold().getTotalGold(), getBonusGold().getTotalGold(), "Gold"); addLore(lore, getExperience(), getBonusExperience(), "Experience"); addLore(lore, getOldChests(), 0, "Old Chest", "Old Chests"); addLore(lore, getAncientChests(), 0, "Ancient Chest", "Ancient Chests"); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index 13f355f0a..1eae0d658 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -10,10 +10,6 @@ import java.util.HashMap; import java.util.TimeZone; import java.util.UUID; -import net.minecraft.server.v1_8_R3.DataWatcher; -import net.minecraft.server.v1_8_R3.EntityCreeper; -import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; - import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Sound; @@ -44,6 +40,8 @@ import mineplex.core.bonuses.event.CarlSpinnerEvent; import mineplex.core.bonuses.gui.BonusGui; import mineplex.core.bonuses.gui.SpinGui; import mineplex.core.bonuses.gui.buttons.PowerPlayClubButton; +import mineplex.core.bonuses.redis.VoteHandler; +import mineplex.core.bonuses.redis.VotifierCommand; import mineplex.core.common.Rank; import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.util.C; @@ -76,7 +74,12 @@ import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.core.youtube.YoutubeManager; import mineplex.database.Tables; +import mineplex.database.tables.records.BonusRecord; +import mineplex.serverdata.commands.ServerCommandManager; import mineplex.serverdata.database.DBPool; +import net.minecraft.server.v1_8_R3.DataWatcher; +import net.minecraft.server.v1_8_R3.EntityCreeper; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityMetadata; public class BonusManager extends MiniClientPlugin implements ILoginProcessor { @@ -89,6 +92,7 @@ public class BonusManager extends MiniClientPlugin implements I private ArrayList _pendingExplosionsPlayers = new ArrayList<>(); private HashMap _showCarl = new HashMap<>(); private long _explode; + private boolean _canVote; private boolean _animationRunning; public static long getSqlTime() @@ -135,6 +139,32 @@ public class BonusManager extends MiniClientPlugin implements I private Location _carlLocation; private AnimationCarl _animation; private int _visualTick; + + private ArrayList _voteList; + + /** + * THIS SHOULD ONLY BE USED FOR VOTIFIER! + */ + public BonusManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager) + { + super("Bonus", plugin); + _enabled = false; + + _repository = new BonusRepository(plugin, this, donationManager); + _clientManager = clientManager; + _donationManager = donationManager; + _powerPlayClubRepository = new PowerPlayClubRepository(plugin, clientManager, donationManager); + + System.out.print("VOTIFIER: "); + System.out.print("DONATION MANAGER - > " + _donationManager.toString()); + + _voteList = new ArrayList<>(); + _voteList.add("http://vote1.mineplex.com"); + _voteList.add("http://vote2.mineplex.com"); + _voteList.add("http://vote3.mineplex.com"); + + updateOffSet(); + } public BonusManager(JavaPlugin plugin, Location carlLocation, PlayWireManager playWireManager, CoreClientManager clientManager, DonationManager donationManager, PollManager pollManager, NpcManager npcManager, HologramManager hologramManager, StatsManager statsManager, InventoryManager inventoryManager, PetManager petManager, FacebookManager facebookManager, YoutubeManager youtubeManager, GadgetManager gadgetManager, ThankManager thankManager) { @@ -162,6 +192,12 @@ public class BonusManager extends MiniClientPlugin implements I _playWireManager = playWireManager; _powerPlayClubRepository = new PowerPlayClubRepository(plugin, _clientManager, _donationManager); + + _voteList = new ArrayList<>(); + _voteList.add("http://vote1.mineplex.com"); + _voteList.add("http://vote2.mineplex.com"); + _voteList.add("http://vote3.mineplex.com"); + _canVote = true; if (npcManager != null) { @@ -187,7 +223,9 @@ public class BonusManager extends MiniClientPlugin implements I } clientManager.addStoredProcedureLoginProcessor(this); - + + ServerCommandManager.getInstance().registerCommandType("VotifierCommand", VotifierCommand.class, new VoteHandler(this)); + updateOffSet(); } @@ -210,6 +248,26 @@ public class BonusManager extends MiniClientPlugin implements I updateOffSet(); } + public void handleVote(final Player player, final int gemsReceived) + { + final int accountId = _clientManager.getAccountId(player); + + runAsync(() -> _repository.getClientData(accountId, data -> runSync(() -> + { + BonusClientData oldData = Get(player); + if (oldData != null) + { + data.setHologram(oldData.getHologram()); + } + Set(player, data); + + _statsManager.incrementStat(player, "Global.DailyVote", 1); + addPendingExplosion(player, player.getName()); + UtilPlayer.message(player, F.main("Carl", "Thanks for voting for Mineplex!")); + UtilPlayer.message(player, F.main("Carl", "You received " + F.elem(gemsReceived + " Gems") + " and " + F.elem("1 Carl Spinner Ticket") + "!")); + }))); + } + @EventHandler public void fireCreeper(UpdateEvent event) { @@ -222,12 +280,16 @@ public class BonusManager extends MiniClientPlugin implements I if (_animationRunning) return; + if (!_canVote) + return; + if (!_enabled) return; _animationRunning = true; _explode = System.currentTimeMillis(); _animation.setTicks(0); + _canVote = false; } @EventHandler @@ -236,6 +298,9 @@ public class BonusManager extends MiniClientPlugin implements I if (event.getType() != UpdateType.TICK) return; + if (_canVote) + return; + if (!_enabled) return; @@ -275,6 +340,7 @@ public class BonusManager extends MiniClientPlugin implements I DecreaseSize(creeper); _pendingExplosions.remove(0); _pendingExplosionsPlayers.remove(0); + _canVote = true; } @EventHandler @@ -312,7 +378,7 @@ public class BonusManager extends MiniClientPlugin implements I public static final long TIME_BETWEEN_BONUSES = 1000 * 60 * 60 * 20; public static final long DAILY_STREAK_RESET_TIME = 1000 * 60 * 60 * 12; - + public static final long VOTE_STREAK_RESET_TIME = 1000 * 60 * 60 * 24; public void attemptDailyBonus(final Player player, final BonusAmount amount, final Callback result) { @@ -434,6 +500,20 @@ public class BonusManager extends MiniClientPlugin implements I } } } + + public void updateVoteStreak(BonusRecord client) + { + if (client.getVoteStreak() > 0 && client.getVotetime() != null) + { + long lastBonus = getLocalTime(client.getVotetime().getTime()); + long timeLeft = getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); + + if (timeLeft < 0) + { + client.setVoteStreak(0); + } + } + } public void incrementDailyStreak(Player player) { @@ -444,6 +524,16 @@ public class BonusManager extends MiniClientPlugin implements I if (data.getDailyStreak() > data.getMaxDailyStreak()) data.setMaxDailyStreak(data.getDailyStreak()); } + + public void incrementVoteStreak(BonusRecord client) + { + client.setVoteStreak(client.getVoteStreak() + 1); + + if (client.getVoteStreak() > client.getMaxVoteStreak()) + { + client.setMaxVoteStreak(client.getVoteStreak()); + } + } public boolean continueStreak(long localLastBonus, long extendTime) { @@ -484,25 +574,52 @@ public class BonusManager extends MiniClientPlugin implements I if (streak >= 40) multiplier += (1 * (streak - 40)); return multiplier; } + + public int getVoteMultiplier(int streak) + { + int multiplier = Math.min(100, 5 * streak); + if (streak >= 20) + { + multiplier += (1 * (streak - 40)); + } + return multiplier; + } public BonusAmount getDailyBonusAmount(Player player) { double mult = getDailyMultiplier(player) / 100.0; BonusAmount amount = new BonusAmount(); - int coins = 100; + int shards = 100; int gems = 100; int experience = 250; - amount.setCoins(coins); + amount.setShards(shards); amount.setGems(gems); amount.setExperience(experience); - amount.setBonusCoins((int) (mult * coins)); + amount.setBonusShards((int) (mult * shards)); amount.setBonusGems((int) (mult * gems)); amount.setBonusExperience((int) (mult * experience)); return amount; } + + public BonusAmount getVoteBonusAmount(Player player) + { + return getVoteBonusAmount(Get(player).getVoteStreak()); + } + + public BonusAmount getVoteBonusAmount(int voteStreak) + { + double mult = getVoteMultiplier(voteStreak) / 100.0; + + BonusAmount amount = new BonusAmount(); + amount.setTickets(1); + amount.setGems(400); + amount.setBonusGems((int) (mult * 400)); + + return amount; + } public BonusAmount getRankBonusAmount(Player player) { @@ -535,6 +652,26 @@ public class BonusManager extends MiniClientPlugin implements I return data; } + + + //VOTE + public long timeTillVoteBonus(Player player) + { + return nextVoteTime(player) - getLocalTime(); + } + + // This calculates the the next vote bonus, IT HAS TO MATCH THE MYSQL STORED FUNCTION. + public long nextVoteTime(Player player) + { + Date date = Get(player).getVoteTime(); + if (date == null) + { + return 0; + } + long lastBonus = date.getTime(); + + return getNextVoteTime(getLocalTime(lastBonus)); + } public void awardBonus(final Player player, BonusAmount amount) { @@ -543,7 +680,7 @@ public class BonusManager extends MiniClientPlugin implements I final int gems = amount.getTotalGems(); final int gold = amount.getTotalGold(); - final int coins = amount.getTotalCoins(); + final int coins = amount.getTotalShards(); final int tickets = amount.getTickets(); int experience = amount.getTotalExperience(); int oldChests = amount.getOldChests(); @@ -625,6 +762,27 @@ public class BonusManager extends MiniClientPlugin implements I UtilPlayer.message(player, F.main("Carl", "Rewarded " + F.elem(experience + " Experience"))); } } + + public static long getNextVoteTime(long time) + { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(TIMEZONE); + calendar.setTimeInMillis(time); + + calendar.add(Calendar.DAY_OF_YEAR, 1); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTimeInMillis(); + } + + public boolean canVote(Player player) + { + long nextVoteTime = nextVoteTime(player); + return System.currentTimeMillis() >= nextVoteTime; + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void openGui(PlayerInteractAtEntityEvent event) @@ -688,6 +846,7 @@ public class BonusManager extends MiniClientPlugin implements I int availableRewards = 0; + if (canVote(player)) availableRewards++; if (_playWireManager.Get(player) != null && _playWireManager.Get(player).getAccountId() != -1 && _playWireManager.canRedeemTickets(_playWireManager.Get(player))) availableRewards++; if (_youtubeManager.canYoutube(player)) availableRewards++; if (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA) && isPastAugust()) availableRewards++; @@ -849,7 +1008,7 @@ public class BonusManager extends MiniClientPlugin implements I { if (Recharge.Instance.use(player, "Carl Inform", 240000, false, false)) { - if (_pollManager.hasPoll(player) || (_playWireManager.Get(player) != null && _playWireManager.Get(player).getAccountId() != -1 && _playWireManager.canRedeemTickets(_playWireManager.Get(player))) || (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA) && isPastAugust()) || canDaily(player) || PowerPlayClubButton.isAvailable(player, _powerPlayClubRepository)) + if (_pollManager.hasPoll(player) || canVote(player) || (_playWireManager.Get(player) != null && _playWireManager.Get(player).getAccountId() != -1 && _playWireManager.canRedeemTickets(_playWireManager.Get(player))) || (canRank(player) && _clientManager.hasRank(player, Rank.ULTRA) && isPastAugust()) || canDaily(player) || PowerPlayClubButton.isAvailable(player, _powerPlayClubRepository)) { if (_showCarl.containsKey(player.getName())) { @@ -860,6 +1019,16 @@ public class BonusManager extends MiniClientPlugin implements I } } } + + public String getVoteLink() + { + long sqlTime = getSqlTime(); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(sqlTime); + int date = calendar.get(Calendar.DAY_OF_YEAR); + int index = date % _voteList.size(); + return _voteList.get(index); + } /** * Used for disabling rank rewards during first month of release @@ -923,4 +1092,4 @@ public class BonusManager extends MiniClientPlugin implements I { _carlLocation = carlLocation; } -} \ No newline at end of file +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java index 241544a1d..5af1890e0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusRepository.java @@ -173,10 +173,10 @@ public class BonusRepository extends RepositoryBase public void attemptDailyBonus(final Player player, final Callback result) { final int accountId = _manager.getClientManager().Get(player).getAccountId(); - final int coins = 0; + final int shards = 0; final int gems = 0; /* - * if (coins == 0 && gems == 0) { result.accept(false); return; } + * if (shards == 0 && gems == 0) { result.accept(false); return; } */ final JavaPlugin plug = _manager.getPlugin(); @@ -189,7 +189,7 @@ public class BonusRepository extends RepositoryBase CallableStatement callableStatement = connection.prepareCall("{call check_daily(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); - callableStatement.setInt(2, coins); + callableStatement.setInt(2, shards); callableStatement.setInt(3, gems); callableStatement.registerOutParameter(4, java.sql.Types.BOOLEAN); callableStatement.registerOutParameter(5, java.sql.Types.TIMESTAMP); @@ -285,7 +285,7 @@ public class BonusRepository extends RepositoryBase CallableStatement callableStatement = connection.prepareCall("{call rankBonus(?, ?, ?, ?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); - callableStatement.setInt(2, bonusAmount.getCoins()); + callableStatement.setInt(2, bonusAmount.getShards()); callableStatement.setInt(3, bonusAmount.getGems()); callableStatement.setInt(4, bonusAmount.getMythicalChests()); callableStatement.setInt(5, bonusAmount.getOmegaChests()); @@ -331,7 +331,7 @@ public class BonusRepository extends RepositoryBase public void attemptVoteBonus(final int accountId, final Callback> result) { - final int coins = 0; + final int shards = 0; final int gems = 0; final JavaPlugin plug = _manager.getPlugin(); @@ -345,7 +345,7 @@ public class BonusRepository extends RepositoryBase try (Connection connection = getConnection(); CallableStatement callableStatement = connection.prepareCall("{call check_vote(?, ?, ?, ?, ?)}")) { callableStatement.setInt(1, accountId); - callableStatement.setInt(2, coins); + callableStatement.setInt(2, shards); callableStatement.setInt(3, gems); callableStatement.registerOutParameter(4, Types.BOOLEAN); callableStatement.registerOutParameter(5, Types.DATE); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GoldAmount.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GoldAmount.java new file mode 100644 index 000000000..36ed82194 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/GoldAmount.java @@ -0,0 +1,51 @@ +package mineplex.core.bonuses; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class GoldAmount +{ + private Map _goldAmounts; + + public GoldAmount() + { + _goldAmounts = new HashMap<>(); + } + + public Collection getServerIds() + { + return _goldAmounts.keySet(); + } + + public Integer getGoldFor(Integer serverId) + { + return _goldAmounts.getOrDefault(serverId, 0); + } + + public Integer getTotalGold() + { + Integer gold = 0; + for (Integer g : _goldAmounts.values()) + { + gold += g; + } + + return gold; + } + + public void setGoldFor(Integer serverId, Integer gold) + { + _goldAmounts.put(serverId, gold); + } + + public void addGold(Integer serverId, Integer gold) + { + _goldAmounts.put(serverId, getGoldFor(serverId) + gold); + } + + public void clearGoldFor(Integer serverId) + { + _goldAmounts.remove(serverId); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index 99faaa17a..8263222e4 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -14,14 +14,14 @@ import org.bukkit.plugin.Plugin; public class BonusGui extends SimpleGui { - //private final int VOTE_SLOT = 10; + private final int VOTE_SLOT = 22; private final int RANK_BONUS_SLOT = 11; private final int DAILY_BONUS_SLOT = 13; private final int POLL_SLOT = 15; - private final int FACEBOOK_SLOT = 19; - private final int CLAIM_TIPS_SLOT = 25; - private final int POWER_PLAY_SLOT = 21; - private final int CARL_SPINNER_SLOT = 23; + private final int FACEBOOK_SLOT = 18; + private final int CLAIM_TIPS_SLOT = 26; + private final int POWER_PLAY_SLOT = 20; + private final int CARL_SPINNER_SLOT = 24; private final int YOUTUBE_SLOT = 29; private final int TWITTER_SLOT = 33; private final int PLAY_WIRE_SLOT = 31; @@ -32,7 +32,7 @@ public class BonusGui extends SimpleGui { super(plugin, player, player.getName() + "'s Bonuses", INV_SIZE); - //setItem(VOTE_SLOT, new VoteButton(plugin, player, this, manager)); + setItem(VOTE_SLOT, new VoteButton(plugin, player, this, manager)); setItem(RANK_BONUS_SLOT, new RankBonusButton(getPlugin(), player, this, manager)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java index 29054f2a6..6e8c16e17 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PollButton.java @@ -97,7 +97,7 @@ public class PollButton extends SimpleGui implements GuiItem { } lore.add(""); BonusAmount amount = new BonusAmount(); - amount.setCoins(_poll.getCoinReward()); + amount.setShards(_poll.getCoinReward()); amount.setGems(_poll.getCoinReward()); amount.addLore(lore); // lore.add(C.cYellow + "Reward:" + C.cWhite + " 500 Gems"); @@ -142,7 +142,7 @@ public class PollButton extends SimpleGui implements GuiItem { } lore.add(""); BonusAmount amount = new BonusAmount(); - amount.setCoins(_poll.getCoinReward()); + amount.setShards(_poll.getCoinReward()); amount.setGems(_poll.getCoinReward()); amount.addLore(lore); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java new file mode 100644 index 000000000..b04e4e16f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/VoteButton.java @@ -0,0 +1,185 @@ +package mineplex.core.bonuses.gui.buttons; + +import java.util.ArrayList; + +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusClientData; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.common.jsonchat.ClickEvent; +import mineplex.core.common.jsonchat.JsonMessage; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.gui.GuiItem; +import mineplex.core.gui.ItemRefresher; +import mineplex.core.shop.item.ShopItem; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +public class VoteButton implements GuiItem, Listener +{ + private ItemStack _item; + + private String _url; + + private Player _player; + private Plugin _plugin; + private ItemRefresher _gui; + + private BonusManager _bonusManager; + + public VoteButton(Plugin plugin, Player player, ItemRefresher gui, BonusManager bonusManager) + { + this._bonusManager = bonusManager; + this._player = player; + this._plugin = plugin; + this._gui = gui; + } + + @Override + public void setup() + { + //TODO get url from db + _url = _bonusManager.getVoteLink(); + + setItem(); + Bukkit.getPluginManager().registerEvents(this, getPlugin()); + } + + @Override + public void close() + { + HandlerList.unregisterAll(this); + } + + @Override + public void click(ClickType clickType) + { + if (isAvailable()) + { + getPlayer().closeInventory(); + + getPlayer().playSound(getPlayer().getLocation(), Sound.NOTE_PLING, 1, 1.6f); + + UtilPlayer.message(getPlayer(), C.cGold + C.Bold + C.Strike + "============================================="); + UtilPlayer.message(getPlayer(), ""); + + new JsonMessage(" " + C.Bold + "Click to Open in Web Browser").click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + new JsonMessage( " " + C.cGreen + C.Line + _url).click(ClickEvent.OPEN_URL, _url).sendToPlayer(getPlayer()); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), " Please be patient. Votes may take a few minutes to register."); + UtilPlayer.message(getPlayer(), ""); + UtilPlayer.message(getPlayer(), C.cGold + C.Bold + C.Strike + "============================================="); + + getPlayer().closeInventory(); + + } + else + { + getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_BREAK, 1, 10); + } + } + + @Override + public ItemStack getObject() + { + return _item; + } + + private void setItem() + { + ArrayList lore = new ArrayList(); + Material material; + String itemName; + byte data = 0; + + if (isAvailable()) + { + material = Material.JUKEBOX; + itemName = C.cGreen + C.Bold + "Vote for Mineplex"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Click to Vote!"); + } + else + { + material = Material.REDSTONE_BLOCK; + itemName = C.cRed + C.Bold + "Vote for Mineplex"; + + lore.add(" "); + lore.add(ChatColor.RESET + "Next vote in " + UtilTime.convertString(timeLeft(), 0, TimeUnit.FIT) + "!"); + } + + lore.add(" "); + + BonusClientData client = _bonusManager.Get(_player); + + BonusAmount bonusAmount = _bonusManager.getVoteBonusAmount(_player); + bonusAmount.addLore(lore); + lore.add(" "); + + lore.add(C.cYellow + "Current Streak: " + C.cWhite + client.getVoteStreak()); + lore.add(C.cYellow + "Streak Bonus: " + C.cWhite + "+" + _bonusManager.getVoteMultiplier(client.getVoteStreak()) + "%"); + if (client.getVoteTime() != null) + { + long lastBonus = _bonusManager.getLocalTime(client.getVoteTime().getTime()); + long timeLeft = _bonusManager.getStreakTimeRemaining(lastBonus, BonusManager.VOTE_STREAK_RESET_TIME); + + if (timeLeft > 0) + { + lore.add(C.cYellow + "Streak Reset: " + C.cWhite + UtilTime.convertString(timeLeft, 1, TimeUnit.FIT)); + } + } + + lore.add(" "); + lore.add(C.cYellow + "Highest Streak: " + C.cWhite + client.getMaxVoteStreak()); + +// StreakRecord streakRecord = _bonusManager.getVoteStreak(); +// if (streakRecord != null) +// { +// lore.add(" "); +// lore.add(C.cYellow + "Record: " + C.cWhite + streakRecord.getPlayerName()); +// lore.add(C.cYellow + "Streak: " + C.cWhite + streakRecord.getStreak()); +// } + + _item = new ShopItem(material, itemName, lore.toArray(new String[0]), 1, false, false); + } + + public long timeLeft() + { + return _bonusManager.nextVoteTime(getPlayer()) - System.currentTimeMillis(); + } + + public boolean isAvailable() + { + if (_url == null) + return false; + + return (timeLeft() <= 0); + } + + public Plugin getPlugin() + { + return _plugin; + } + + public Player getPlayer() + { + return _player; + } + + public ItemRefresher getGui() + { + return _gui; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java new file mode 100644 index 000000000..3559ee6da --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VoteHandler.java @@ -0,0 +1,31 @@ +package mineplex.core.bonuses.redis; + +import org.bukkit.entity.Player; + +import mineplex.core.bonuses.BonusManager; +import mineplex.core.common.util.UtilPlayer; +import mineplex.serverdata.commands.CommandCallback; +import mineplex.serverdata.commands.ServerCommand; + +public class VoteHandler implements CommandCallback +{ + private BonusManager _bonusManager; + + public VoteHandler(BonusManager bonusManager) + { + _bonusManager = bonusManager; + } + + @Override + public void run(ServerCommand command) + { + VotifierCommand v = ((VotifierCommand) command); + + Player player = UtilPlayer.searchExact(v.getPlayerName()); + + if (player != null) + { + _bonusManager.handleVote(player, v.getGemsReceived()); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java new file mode 100644 index 000000000..d9e4792b4 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/redis/VotifierCommand.java @@ -0,0 +1,27 @@ +package mineplex.core.bonuses.redis; + +import mineplex.serverdata.commands.ServerCommand; + +public class VotifierCommand extends ServerCommand +{ + private String _playerName; + private int _gemsReceived; + + public VotifierCommand(String playerName, int gemsReceived, String... targetServer) + { + super(targetServer); + + _playerName = playerName; + _gemsReceived = gemsReceived; + } + + public String getPlayerName() + { + return _playerName; + } + + public int getGemsReceived() + { + return _gemsReceived; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java b/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java index 4c0e206a0..5bec0e084 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/donation/DonationManager.java @@ -251,6 +251,20 @@ public class DonationManager extends MiniClientPlugin { rewardCurrency(currency, client.getName(), client.getUniqueId(), reason, amount, updateTotal, callback); } + + /** + * Rewards a player a specific amount of a currency type - used by Votifier ONLY due to volatile playerName and playerUUID + * @param currency The type of currency to reward + * @param playerName The name of the player being rewarded + * @param playerUUID The UUID of the player being rewarded + * @param reason The reason for the currency being awarded + * @param amount The amount of currency being rewarded + * @param callback A callback to retrieve the success of the award + */ + public void rewardCurrency(GlobalCurrency currency, String playerName, UUID playerUUID, String reason, int amount, Consumer callback) + { + rewardCurrency(currency, playerName, playerUUID, reason, amount, true, callback); + } // Private because volatile with playerName and playerUUID private void rewardCurrency(GlobalCurrency currency, String playerName, UUID playerUUID, String reason, int amount, boolean updateTotal, Consumer callback) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java index 8475fb95f..8ea5aa1bf 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardManager.java @@ -148,7 +148,9 @@ import mineplex.core.pet.PetType; import mineplex.core.powerplayclub.PowerPlayData.SubscriptionDuration; import mineplex.core.reward.RewardPool.Type; import mineplex.core.reward.rewards.ChestReward; +import mineplex.core.reward.rewards.ExperienceReward; import mineplex.core.reward.rewards.GameAmplifierReward; +import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.PetReward; import mineplex.core.reward.rewards.PowerPlayReward; @@ -217,7 +219,8 @@ public class RewardManager { RewardRarity rarity = RewardRarity.COMMON; - addReward(Type.CARL_SPINNER, new TreasureShardReward(_clientManager, _donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 25, rarity)); + addReward(Type.CARL_SPINNER, new GemReward(_donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 25, 0, rarity)); + addReward(Type.CARL_SPINNER, new ExperienceReward(_statsManager, getAmmoMin(rarity)*5, getAmmoMax(rarity)*5, 25, 0, rarity)); //Normal Gadgets addInventoryReward(Type.NORMAL, getGadget(ItemBatGun.class), rarity, 10, getShards(rarity), 4, 10); @@ -246,7 +249,8 @@ public class RewardManager { RewardRarity rarity = RewardRarity.UNCOMMON; - addReward(Type.CARL_SPINNER, new TreasureShardReward(_clientManager, _donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 1200, rarity)); + addReward(Type.CARL_SPINNER, new GemReward(_donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 1200, 0, rarity)); + addReward(Type.CARL_SPINNER, new ExperienceReward(_statsManager, getAmmoMin(rarity)*5, getAmmoMax(rarity)*5, 1200, 0, rarity)); //Gadgets addInventoryReward(Type.NORMAL, getGadget(ItemBatGun.class), rarity, 250, 0, 20, 40); @@ -330,7 +334,8 @@ public class RewardManager { RewardRarity rarity = RewardRarity.RARE; - addReward(Type.CARL_SPINNER, new TreasureShardReward(_clientManager, _donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 150, rarity)); + addReward(Type.CARL_SPINNER, new GemReward(_donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 150, 0, rarity)); + addReward(Type.CARL_SPINNER, new ExperienceReward(_statsManager, getAmmoMin(rarity)*5, getAmmoMax(rarity)*5, 150, 0, rarity)); //Morphs addGadget(Type.NORMAL, getGadget(MorphVillager.class), rarity, 83); @@ -551,7 +556,8 @@ public class RewardManager { RewardRarity rarity = RewardRarity.LEGENDARY; - addReward(Type.CARL_SPINNER, new TreasureShardReward(_clientManager, _donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 10, rarity)); + addReward(Type.CARL_SPINNER, new GemReward(_donationManager, getAmmoMin(rarity), getAmmoMax(rarity), 10, 0, rarity)); + addReward(Type.CARL_SPINNER, new ExperienceReward(_statsManager, getAmmoMin(rarity)*5, getAmmoMax(rarity)*5, 10, 0, rarity)); //REGULAR diff --git a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardPool.java b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardPool.java index c8a1fc4fc..dc9f2cd9f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardPool.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/reward/RewardPool.java @@ -6,7 +6,6 @@ import java.util.List; import org.bukkit.entity.Player; -import mineplex.core.reward.rewards.GemReward; import mineplex.core.reward.rewards.InventoryReward; import mineplex.core.reward.rewards.TreasureShardReward; import mineplex.core.reward.rewards.UnknownPackageReward; @@ -115,13 +114,6 @@ public class RewardPool } } } - if (this == Type.CARL_SPINNER) - { - if (reward instanceof GemReward) - { - return false; - } - } return true; } diff --git a/Plugins/Mineplex.Votifier/plugin.yml b/Plugins/Mineplex.Votifier/plugin.yml new file mode 100644 index 000000000..75a40f893 --- /dev/null +++ b/Plugins/Mineplex.Votifier/plugin.yml @@ -0,0 +1,3 @@ +name: MineplexVotifier +main: mineplex.votifier.Votifier +version: 0.1 \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/pom.xml b/Plugins/Mineplex.Votifier/pom.xml new file mode 100644 index 000000000..23f4e3d0e --- /dev/null +++ b/Plugins/Mineplex.Votifier/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + + + com.mineplex + mineplex-plugin + dev-SNAPSHOT + ../plugin.xml + + + MineplexVotifier + mineplex-votifier + + + + ${project.groupId} + mineplex-core + ${project.version} + + + com.vexsoftware + votifier + + + \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java new file mode 100644 index 000000000..e0474d0f5 --- /dev/null +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/Votifier.java @@ -0,0 +1,31 @@ +package mineplex.votifier; + +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.Managers; +import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.command.CommandCenter; +import mineplex.core.donation.DonationManager; + +public class Votifier extends JavaPlugin +{ + private String WEB_CONFIG = "webServer"; + + @Override + public void onEnable() + { + getConfig().addDefault(WEB_CONFIG, "http://accounts.mineplex.com/"); + getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG)); + saveConfig(); + + String webServerAddress = getConfig().getString(WEB_CONFIG); + + CommandCenter.Initialize(this); + CoreClientManager clientManager = new CoreClientManager(this); + DonationManager donationManager = Managers.require(DonationManager.class); + BonusManager bonusManager = new BonusManager(this, clientManager, donationManager); + + VotifierManager vote = new VotifierManager(this, clientManager, donationManager, bonusManager); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java new file mode 100644 index 000000000..d603b9a5e --- /dev/null +++ b/Plugins/Mineplex.Votifier/src/mineplex/votifier/VotifierManager.java @@ -0,0 +1,257 @@ +package mineplex.votifier; + +import java.sql.Date; +import java.util.UUID; + +import org.bukkit.event.EventHandler; +import org.bukkit.plugin.java.JavaPlugin; +import org.jooq.DSLContext; +import org.jooq.Record1; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; + +import com.vexsoftware.votifier.model.Vote; +import com.vexsoftware.votifier.model.VotifierEvent; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.bonuses.BonusAmount; +import mineplex.core.bonuses.BonusManager; +import mineplex.core.bonuses.redis.VotifierCommand; +import mineplex.core.common.Pair; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.Callback; +import mineplex.core.common.util.UUIDFetcher; +import mineplex.core.donation.DonationManager; +import mineplex.database.Tables; +import mineplex.database.tables.records.BonusRecord; +import mineplex.serverdata.Region; +import mineplex.serverdata.Utility; +import mineplex.serverdata.commands.ServerCommand; +import mineplex.serverdata.data.PlayerStatus; +import mineplex.serverdata.database.DBPool; +import mineplex.serverdata.redis.RedisConfig; +import mineplex.serverdata.redis.RedisDataRepository; +import mineplex.serverdata.servers.ServerManager; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +public class VotifierManager extends MiniPlugin +{ + private CoreClientManager _clientManager; + private DonationManager _donationManager; + private BonusManager _bonusManager; + + private RedisConfig _usConfig; + private RedisConfig _euConfig; + private RedisDataRepository _usPlayerRepo; + private RedisDataRepository _euPlayerRepo; + private JedisPool _usWritePool; + private JedisPool _euWritePool; + + public VotifierManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, BonusManager bonusManager) + { + super("Votifier", plugin); + + _clientManager = clientManager; + _donationManager = donationManager; + _bonusManager = bonusManager; + + _usConfig = ServerManager.loadConfig("us-redis.dat"); + _euConfig = ServerManager.loadConfig("eu-redis.dat"); + + _usPlayerRepo = new RedisDataRepository(_usConfig.getConnection(true, "DefaultConnection"), + _usConfig.getConnection(false, "DefaultConnection"), Region.US, PlayerStatus.class, "playerStatus"); + _euPlayerRepo = new RedisDataRepository(_euConfig.getConnection(true, "DefaultConnection"), + _euConfig.getConnection(false, "DefaultConnection"), Region.EU, PlayerStatus.class, "playerStatus"); + + _usWritePool = Utility.generatePool(_usConfig.getConnection(true, "DefaultConnection")); + _euWritePool = Utility.generatePool(_euConfig.getConnection(true, "DefaultConnection")); + } + + @EventHandler + public void handleVote(VotifierEvent event) + { + final Vote vote = event.getVote(); + final String playerName = vote.getUsername(); + + System.out.println("New Vote: " + playerName); + + runAsync(new Runnable() + { + @Override + public void run() + { + UUID uuid = UUIDFetcher.getUUIDOf(playerName); + if (uuid == null) + { + System.out.println("Failed to load UUID of " + playerName + " from UUIDFetcher. Trying with database"); + uuid = _clientManager.loadUUIDFromDB(playerName); + + if (uuid == null) + { + System.out.println("Failed to load UUID from database. Giving up on " + playerName); + } + } + + String lowerPlayerName = playerName.toLowerCase(); + final PlayerStatus usStatus = _usPlayerRepo.getElement(lowerPlayerName); + final PlayerStatus euStatus = _euPlayerRepo.getElement(lowerPlayerName); + + System.out.println("Loaded " + playerName + " with uuid " + uuid); + System.out.println("Attempting to award bonus"); + final UUID finalUuid = uuid; + awardBonus(playerName, finalUuid, new Callback() + { + @Override + public void run(final Integer gems) + { + runSync(new Runnable() + { + @Override + public void run() + { + if (usStatus != null) + { + System.out.println("Found " + playerName + " on US " + usStatus.getServer()); + notifyServer(playerName, gems, Region.US, usStatus.getServer()); + } + + if (euStatus != null) + { + System.out.println("Found " + playerName + " on EU " + euStatus.getServer()); + notifyServer(playerName, gems, Region.EU, euStatus.getServer()); + } + } + }); + } + }); + } + }); + System.out.println(); + System.out.println(); + +// UUID uuid = _clientManager.loadUUIDFromDB(playerName); +// if (uuid != null) +// { +// System.out.println("Found UUID:" + uuid.toString()); +// if (playerName.equalsIgnoreCase("Phinary")) +// { +// System.out.println("award bonus"); +// awardBonus(uuid); +// } +// } +// else +// { +// System.out.println("Failed to load UUID for player: " + playerName); +// } + +// PlayerStatus usStatus = _usPlayerRepo.getElement(playerName); +// if (usStatus != null) +// { +// System.out.println("Found on US Server: " + usStatus.getServer()); +// writePool = _usWritePool; +// serverName = usStatus.getServer(); +// } +// +// PlayerStatus euStatus = _euPlayerRepo.getElement(playerName); +// if (euStatus != null) +// { +// System.out.println("Found on EU Server: " + euStatus.getServer()); +// writePool = _euWritePool; +// serverName = euStatus.getServer(); +// } + + // Currently we just notify all servers, and the server with the player on it can deal with it +// notifyServer(playerName, true); + } + + private void notifyServer(String playerName, int gems, Region region, String targetServer) + { + JedisPool writePool = region == Region.EU ? _euWritePool : _usWritePool; + + VotifierCommand command = new VotifierCommand(playerName, gems, targetServer); + publishCommand(command, writePool); + } + + private void awardBonus(final String playerName, final UUID uuid, final Callback onComplete) + { + DSLContext create = DSL.using(DBPool.getAccount(), SQLDialect.MYSQL); + + Record1 idRecord = create.select(Tables.accounts.id).from(Tables.accounts).where(Tables.accounts.uuid.eq(uuid.toString())).fetchOne(); + if (idRecord != null) + { + final int accountId = idRecord.value1(); + final BonusRecord client = _bonusManager.getRepository().loadRecord(playerName, accountId); + + final BonusAmount amount = _bonusManager.getVoteBonusAmount(client.getVoteStreak()); + + _bonusManager.getRepository().attemptVoteBonus(accountId, new Callback>() + { + @Override + public void run(Pair pair) + { + if (pair.getLeft()) + { + // Reward Amount + if (amount.getTickets() > 0) + client.setTickets(client.getTickets() + amount.getTickets()); + + if (amount.getTotalGems() > 0) + { + _donationManager.rewardCurrency(GlobalCurrency.GEM, playerName, uuid, "Votifier", amount.getTotalGems(), data -> + { + if (data) + System.out.println("Gave " + amount.getGems() + " gems to " + playerName); + else + System.out.println("Failed to give " + amount.getTotalGems() + " gems to " + playerName); + }); + } + + if (amount.getTotalShards() > 0) + { + _donationManager.rewardCurrency(GlobalCurrency.TREASURE_SHARD, playerName, uuid, "Votifier", amount.getTotalShards(), data -> + { + if (data) + System.out.println("Gave " + amount.getGems() + " shards to " + playerName); + else + System.out.println("Failed to give " + amount.getTotalShards() + " shards to " + playerName); + }); + } + + // Check if we need to reset vote streak + _bonusManager.updateVoteStreak(client); + client.setVotetime(pair.getRight()); + + // Update Streak + _bonusManager.incrementVoteStreak(client); + + client.store(); + System.out.println("Awarded carl ticket to " + playerName); + onComplete.run(amount.getTotalGems()); + } + else + { + System.out.println(playerName + " attempted to vote, vote bonus returned false!"); + } + } + }); + } + } + + private void publishCommand(final ServerCommand serverCommand, final JedisPool writePool) + { + new Thread(new Runnable() + { + public void run() + { + try (Jedis jedis = writePool.getResource()) + { + String commandType = serverCommand.getClass().getSimpleName(); + String serializedCommand = Utility.serialize(serverCommand); + jedis.publish("commands.server" + ":" + commandType, serializedCommand); + } + } + }).start(); + } +} \ No newline at end of file diff --git a/Plugins/pom.xml b/Plugins/pom.xml index 0eb37a3d5..46ff3c9e3 100644 --- a/Plugins/pom.xml +++ b/Plugins/pom.xml @@ -36,6 +36,7 @@ Mineplex.ServerData Mineplex.ServerMonitor Mineplex.StaffServer + Mineplex.Votifier Nautilus.Game.Arcade Nautilus.Game.Arcade.UHC.WorldGen @@ -65,6 +66,12 @@ 2.2.1 compile + + com.vexsoftware + votifier + 1.9 + provided + javax.mail mail