From 2d61dffaeae2c702cf8f9aeb98ff59323893ece1 Mon Sep 17 00:00:00 2001 From: AlexTheCoder Date: Tue, 11 Apr 2017 19:57:10 -0400 Subject: [PATCH] Implement an easter egg hunt of epic proportions --- .../src/mineplex/core/common/util/F.java | 5 + .../src/mineplex/hub/HubManager.java | 26 +- .../mineplex/hub/commands/EggAddCommand.java | 27 ++ .../mineplex/hub/modules/EasterEggHunt.java | 347 ++++++++++++++++++ 4 files changed, 397 insertions(+), 8 deletions(-) create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/commands/EggAddCommand.java create mode 100644 Plugins/Mineplex.Hub/src/mineplex/hub/modules/EasterEggHunt.java diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java index 49da7d9cf..4240b9a9b 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/F.java @@ -57,6 +57,11 @@ public class F { return C.mElem + elem + C.mBody; } + + public static String count(int elem) + { + return count(String.valueOf(elem)); + } public static String count(String elem) { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java index c01ec5d2b..1e7dfd060 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubManager.java @@ -4,13 +4,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.UUID; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.HoverEvent.Action; -import net.md_5.bungee.api.chat.TextComponent; -import net.minecraft.server.v1_8_R3.EntityInsentient; -import net.minecraft.server.v1_8_R3.EntityPlayer; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -48,7 +41,6 @@ import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.achievement.AchievementManager; import mineplex.core.antispam.AntiSpamManager; -import mineplex.core.aprilfools.AprilFoolsManager; import mineplex.core.benefit.BenefitManager; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.bonuses.BonusManager; @@ -121,6 +113,7 @@ import mineplex.hub.commands.ForcefieldRadius; import mineplex.hub.commands.GadgetToggle; import mineplex.hub.commands.GameModeCommand; import mineplex.hub.commands.NewsCommand; +import mineplex.hub.modules.EasterEggHunt; import mineplex.hub.modules.ForcefieldManager; import mineplex.hub.modules.HubVisibilityManager; import mineplex.hub.modules.JumpManager; @@ -138,6 +131,12 @@ import mineplex.minecraft.game.classcombat.item.event.ItemTriggerEvent; import mineplex.minecraft.game.core.combat.DeathMessageType; import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; import mineplex.minecraft.game.core.condition.ConditionManager; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.HoverEvent.Action; +import net.md_5.bungee.api.chat.TextComponent; +import net.minecraft.server.v1_8_R3.EntityInsentient; +import net.minecraft.server.v1_8_R3.EntityPlayer; public class HubManager extends MiniClientPlugin implements IChatMessageFormatter { @@ -177,6 +176,8 @@ public class HubManager extends MiniClientPlugin implements IChatMess // private TrickOrTreatManager _trickOrTreatManager; private MavericksManager _mavericksManager; private final TwoFactorAuth _twofactor = Managers.require(TwoFactorAuth.class); + + private HologramManager _hologramManager; private Location _spawn; @@ -283,6 +284,10 @@ public class HubManager extends MiniClientPlugin implements IChatMess new SalesAnnouncementManager(plugin); new CommunityManager(plugin, _clientManager); + + _hologramManager = hologramManager; + + new EasterEggHunt(plugin, _clientManager); ScoreboardManager scoreboardManager = new ScoreboardManager(plugin) { @@ -781,6 +786,11 @@ public class HubManager extends MiniClientPlugin implements IChatMess { return _disguiseManager; } + + public HologramManager getHologram() + { + return _hologramManager; + } public GadgetManager GetGadget() { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/EggAddCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/EggAddCommand.java new file mode 100644 index 000000000..df33b562b --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/EggAddCommand.java @@ -0,0 +1,27 @@ +package mineplex.hub.commands; + +import org.bukkit.entity.Player; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.hub.modules.EasterEggHunt; + +public class EggAddCommand extends CommandBase +{ + public EggAddCommand(EasterEggHunt plugin) + { + super(plugin, Rank.ADMIN, "addegg"); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (args.length < 1) + { + UtilPlayer.message(caller, F.main(Plugin.getName(), "Usage: /addegg ")); + } + Plugin.addEgg(caller, args[0]); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/EasterEggHunt.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/EasterEggHunt.java new file mode 100644 index 000000000..bc92b49cf --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/EasterEggHunt.java @@ -0,0 +1,347 @@ +package mineplex.hub.modules; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +import mineplex.core.Managers; +import mineplex.core.MiniDbClientPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.currency.GlobalCurrency; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.donation.DonationManager; +import mineplex.core.hologram.Hologram; +import mineplex.core.inventory.InventoryManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.HubManager; +import mineplex.hub.commands.EggAddCommand; +import mineplex.hub.modules.EasterEggHunt.EasterEggHunter; +import mineplex.serverdata.database.DBPool; + +public class EasterEggHunt extends MiniDbClientPlugin +{ + private static final int SHARD_REWARD = 500; + private static final String ITEM_REWARD = "Omega Chest"; + private static final int EGGS_PER_DAY = 30; + + private final DonationManager _donationManager; + private final InventoryManager _inventoryManager; + private final List _possibleEggs; + + public EasterEggHunt(JavaPlugin plugin, CoreClientManager clientManager) + { + super("Egg Hunt", plugin, clientManager); + + _donationManager = Managers.get(DonationManager.class); + _inventoryManager = Managers.get(InventoryManager.class); + + _possibleEggs = new ArrayList<>(); + runAsync(() -> + { + final List fetch = new ArrayList<>(); + loadEggs(fetch); + runSync(() -> + { + fetch.stream().peek(EasterEgg::setup).forEach(_possibleEggs::add); + }); + }); + + addCommand(new EggAddCommand(this)); + } + + private String vecToStr(Vector vec) + { + return vec.getX() + "," + vec.getY() + "," + vec.getZ(); + } + + private Vector strToVec(String str) + { + String[] coords = str.split(","); + double x = Double.parseDouble(coords[0]); + double y = Double.parseDouble(coords[0]); + double z = Double.parseDouble(coords[0]); + + return new Vector(x, y, z); + } + + private void loadEggs(List eggs) + { + try (Connection c = DBPool.getAccount().getConnection()) + { + ResultSet rs = c.prepareStatement("SELECT * FROM easterEggs;").executeQuery(); + while (rs.next()) + { + EasterEgg egg = new EasterEgg(rs.getInt("id"), strToVec(rs.getString("eggLocation")), rs.getDate("eggDate")); + eggs.add(egg); + } + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + + private void addEggToInventory(int accountId, int eggId) + { + runAsync(() -> + { + try (Connection c = DBPool.getAccount().getConnection()) + { + PreparedStatement ps = c.prepareStatement("INSERT INTO accountEggs (accountId, eggId) VALUES (?, ?);"); + ps.setInt(1, accountId); + ps.setInt(2, eggId); + ps.execute(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + @EventHandler + public void interactBlock(PlayerInteractAtEntityEvent event) + { + if (event.getRightClicked() == null) + { + return; + } + + Player player = event.getPlayer(); + + for (EasterEgg egg : _possibleEggs) + { + if (egg.isMe(event.getRightClicked())) + { + findEgg(player, egg.getId()); + break; + } + } + } + + @EventHandler + public void refreshEggs(UpdateEvent event) + { + if (event.getType() == UpdateType.SEC) + { + LocalDate currentDate = LocalDate.now(ZoneId.of("UTC")); + + _possibleEggs.stream().filter(EasterEgg::isSpawned).filter(egg -> + { + LocalDate eggDate = egg.getDate().toLocalDate(); + + return eggDate.getDayOfYear() != currentDate.getDayOfYear(); + }).forEach(egg -> + { + egg.despawn(); + GetValues().forEach(hunter -> hunter.getEggs().remove(egg.getId())); + }); + _possibleEggs.stream().filter(egg -> !egg.isSpawned()).filter(egg -> + { + LocalDate eggDate = egg.getDate().toLocalDate(); + + return eggDate.getDayOfYear() == currentDate.getDayOfYear(); + }).forEach(EasterEgg::spawn); + } + } + + public void addEgg(Player player, String date) + { + final Date parsed = Date.valueOf(date); + final Vector loc = player.getLocation().toVector(); + runAsync(() -> + { + try (Connection c = DBPool.getAccount().getConnection()) + { + PreparedStatement ps = c.prepareStatement("INSERT INTO easterEggs (eggLocation, eggDate) VALUES (?, ?);"); + ps.setString(1, vecToStr(loc)); + ps.setDate(2, parsed); + ps.execute(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + private void findEgg(Player player, Integer eggId) + { + if (Get(player).getEggs().contains(eggId)) + { + UtilPlayer.message(player, F.main(getName(), "You have already found this egg!")); + return; + } + player.playSound(player.getLocation(), Sound.CAT_MEOW, 1, 0.7F); + Get(player).findEgg(eggId); + UtilPlayer.message(player, F.main(getName(), "Found " + F.count(Get(player).getEggs().size()) + "/" + F.count(EGGS_PER_DAY) + " Easter Eggs +" + F.currency(GlobalCurrency.TREASURE_SHARD, SHARD_REWARD) + ".")); + _donationManager.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, player, "", SHARD_REWARD); + addEggToInventory(ClientManager.getAccountId(player), eggId); + + if (Get(player).getEggs().size() == 1) + { + UtilPlayer.message(player, F.main(getName(), "There are " + F.count(EGGS_PER_DAY) + " hidden " + F.elem("Easter Eggs") + " to find through the lobby each day.")); + UtilPlayer.message(player, F.main(getName(), "Each one is worth " + F.currency(GlobalCurrency.TREASURE_SHARD, SHARD_REWARD) + ".")); + UtilPlayer.message(player, F.main(getName(), "If you find all " + F.count(EGGS_PER_DAY) + " you will receive an " + C.cAqua + "Omega Chest for that day!")); + } + else if (Get(player).getEggs().size() == EGGS_PER_DAY) + { + UtilPlayer.message(player, F.main(getName(), "You have found all the eggs available today!")); + + _inventoryManager.addItemToInventory(success -> + { + if (success) + { + UtilPlayer.message(player, F.main(getName(), "+1 " + C.cAqua + ITEM_REWARD + C.mBody + "!")); + } + else + { + UtilPlayer.message(player, F.main(getName(), "Oh no! An error occurred while trying to give you your chest! Go find a staff member ASAP!")); + } + }, player, ITEM_REWARD, 1); + } + } + + public static class EasterEggHunter + { + private List _found; + + public EasterEggHunter() + { + this(new ArrayList<>()); + } + + public EasterEggHunter(List foundEggs) + { + _found = foundEggs; + } + + public List getEggs() + { + return _found; + } + + public void findEgg(Integer id) + { + _found.add(id); + } + } + + public static class EasterEgg + { + private final Integer _id; + private final Vector _loc; + private final Date _date; + private Location _spawn; + private ArmorStand _stand; + private Hologram _holo; + + public EasterEgg(Integer id, Vector loc, Date date) + { + _id = id; + _loc = loc; + _date = date; + } + + public Integer getId() + { + return _id; + } + + public Date getDate() + { + return _date; + } + + public boolean isSpawned() + { + return _stand != null; + } + + public boolean isMe(Entity e) + { + return isSpawned() && e.getEntityId() == _stand.getEntityId(); + } + + public void setup() + { + _spawn = _loc.toLocation(Managers.get(HubManager.class).GetSpawn().getWorld()); + _stand = null; + _holo = new Hologram(Managers.get(HubManager.class).getHologram(), _spawn.clone().add(0, 1.5, 0), C.cDPurple + C.Scramble + "ABC " + C.cPurpleB + "Easter Egg Hunt" + C.cDPurple + C.Scramble + " ABC"); + _holo.stop(); + } + + public void spawn() + { + if (isSpawned()) + { + return; + } + _stand = (ArmorStand)_spawn.getWorld().spawnEntity(_spawn, EntityType.ARMOR_STAND); + _stand.setItemInHand(new ItemStack(Material.EGG)); + _stand.setVisible(false); + _stand.setBasePlate(false); + _holo.start(); + } + + public void despawn() + { + if (isSpawned()) + { + _stand.remove(); + _stand = null; + _holo.stop(); + } + } + } + + @Override + public String getQuery(int accountId, String uuid, String name) + { + return "SELECT ae.eggId, ee.eggDate FROM accountEggs AS ae INNER JOIN easterEggs AS ee ON ae.eggId=ee.id WHERE ae.accountId=" + accountId + ";"; + } + + @Override + public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException + { + List found = new ArrayList<>(); + while (resultSet.next()) + { + if (resultSet.getDate("eggDate").toLocalDate().getDayOfYear() == LocalDate.now(ZoneId.of("UTC")).getDayOfYear()) + { + found.add(resultSet.getInt("eggId")); + } + } + + Set(uuid, new EasterEggHunter(found)); + } + + @Override + protected EasterEggHunter addPlayer(UUID uuid) + { + return new EasterEggHunter(); + } +} \ No newline at end of file