This commit is contained in:
LCastr0 2016-10-01 00:46:36 -03:00
commit 76fc4d6ac4
7 changed files with 323 additions and 155 deletions

View File

@ -5,11 +5,13 @@ import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.powerplayclub.PowerPlayData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.time.LocalDate;
import java.time.YearMonth;
public class PowerPlayCommand extends CommandBase<BonusManager>
{
@ -37,7 +39,8 @@ public class PowerPlayCommand extends CommandBase<BonusManager>
return;
}
_bonusManager.getPowerPlayClubRepository().Get(player).setSubscribed(true);
PowerPlayData cached = _bonusManager.getPowerPlayClubRepository().getCachedData(player);
cached.getUnclaimedMonths().add(YearMonth.now());
_bonusManager.getPowerPlayClubRepository().addSubscription(_bonusManager.getClientManager().Get(player).getAccountId(), LocalDate.now(), "month");
caller.sendMessage(ChatColor.GREEN + "Gave a month's subscription to " + player.getName());

View File

@ -1,6 +1,11 @@
package mineplex.core.bonuses.gui.buttons;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import mineplex.core.bonuses.BonusManager;
import mineplex.core.common.util.C;
@ -11,6 +16,7 @@ import mineplex.core.gui.GuiItem;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.powerplayclub.PowerPlayClubRewards;
import mineplex.core.powerplayclub.PowerPlayData;
import mineplex.core.shop.item.ShopItem;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -52,7 +58,7 @@ public class PowerPlayClubButton implements GuiItem
@Override
public void click(ClickType clickType)
{
if (isAvailable() && !_bonusManager.getPowerPlayClubRepository().alreadyClaimed(_player))
if (isAvailable())
{
_player.closeInventory();
_player.playSound(_player.getLocation(), Sound.NOTE_PLING, 1, 1.6f);
@ -61,9 +67,9 @@ public class PowerPlayClubButton implements GuiItem
else
{
_player.playSound(_player.getLocation(), Sound.ITEM_BREAK, 1, 10);
if (_powerPlayClubRepository.alreadyClaimed(_player))
if (_powerPlayClubRepository.getCachedData(_player).isSubscribed())
{
UtilPlayer.message(_player, F.main("Power Play Club", "Already claimed!"));
UtilPlayer.message(_player, F.main("Power Play Club", "Already claimed! Come back next month!"));
}
else
{
@ -80,58 +86,75 @@ public class PowerPlayClubButton implements GuiItem
private void setItem()
{
ArrayList<String> lore = new ArrayList<>();
Material material;
byte data = 0;
String itemName;
final Material material;
final String itemName;
final List<String> lore;
if (isAvailable())
PowerPlayData cached = _powerPlayClubRepository.getCachedData(_player);
List<YearMonth> unclaimed = cached.getUnclaimedMonths();
if (!unclaimed.isEmpty())
{
// Player has unclaimed rewards, even if s/he's not currently subscribed
material = Material.GOLD_INGOT;
itemName = C.cGreenB + "Power Play Club";
lore.add("");
lore.add(C.Reset + "Click to claim!");
}
else
lore = buildLore(unclaimed);
lore.add(" ");
lore.add(C.cGold + "Click to claim!");
} else if (cached.isSubscribed())
{
// Player is subscribed and has claimed all of his/her rewards
material = Material.REDSTONE_BLOCK;
itemName = C.cRedB + "Power Play Club";
}
lore.add(C.cYellow + "Rewards");
lore.add(" " + C.cWhite + "2 Game Amplifiers");
lore.add(" " + C.cWhite + "1 Omega Chest");
for (PowerPlayClubRewards.PowerPlayClubItem prize : PowerPlayClubRewards.septemberItems())
{
lore.add(" " + C.cWhite + prize.getAmount() + " " + prize.getPrize());
}
//lore.add(" ");
//lore.add(C.cYellow + "Months left: " + C.cWhite + getMonthsLeft(true)); //TODO: figure this out
if (!isAvailable())
lore = new ArrayList<>();
lore.add(C.cRed + "Already claimed!");
// TODO: 'come back later!'
} else
{
// Player isn't subscribed; show them the rewards for this current month and tell them to subscribe
material = Material.REDSTONE_BLOCK;
itemName = C.cRedB + "Power Play Club";
lore = buildLore(Collections.singletonList(YearMonth.now()));
lore.add(" ");
if (_powerPlayClubRepository.alreadyClaimed(_player))
{
lore.add(C.cRed + "Already claimed!");
}
else
{
lore.add(C.cRed + "Get Power Play Club months at");
lore.add(C.cAqua + "mineplex.com/shop");
}
lore.add(C.cGreen + "First-time Bonus:");
lore.add(" " + C.cWhite + "Metal Man Morph");
lore.add(" ");
lore.add(C.cRed + "Get Power Play Club months at");
lore.add(C.cAqua + "mineplex.com/shop");
}
_item = new ShopItem(material, data, itemName, lore.toArray(new String[0]), 1, false, false);
_item = new ShopItem(material, (byte)0, itemName, lore.toArray(new String[lore.size()]), 1, false, false);
}
private List<String> buildLore(List<YearMonth> unclaimed)
{
List<String> lore = new ArrayList<>();
lore.add(C.cYellow + "Rewards");
lore.add(" " + C.cWhite + (PowerPlayClubRewards.AMPLIFIERS_PER_MONTH * unclaimed.size()) + " Game Amplifier");
lore.add(" " + C.cWhite + (PowerPlayClubRewards.CHESTS_PER_MONTH * unclaimed.size()) + " Omega Chest");
PowerPlayClubRewards.rewardsForMonths(unclaimed).forEach(prize ->
{
lore.add(" " + C.cWhite + prize.getPrize());
});
return lore;
}
private boolean isAvailable()
{
return _powerPlayClubRepository.canClaim(_player);
return !_powerPlayClubRepository.getCachedData(_player).getUnclaimedMonths().isEmpty();
}
public static boolean isAvailable(Player player, PowerPlayClubRepository repo)
{
return repo.canClaim(player);
return !repo.getCachedData(player).getUnclaimedMonths().isEmpty();
}
}

View File

@ -344,7 +344,6 @@ public class GadgetManager extends MiniPlugin
addGadget(new MorphUncleSam(this));
addGadget(new MorphSquid(this));
addGadget(new MorphWitch(this));
// Not being added in this update!
addGadget(new MorphMetalMan(this));
// Particles

View File

@ -1,26 +0,0 @@
package mineplex.core.powerplayclub;
public class PPCPlayerData {
private boolean _subscribed;
private boolean _claimed;
public void setSubscribed(boolean subscribed)
{
_subscribed = subscribed;
}
public void setClaimed(boolean claimed)
{
_claimed = claimed;
}
public boolean hasClaimed()
{
return _claimed;
}
public boolean hasSubscribed()
{
return _subscribed;
}
}

View File

@ -1,26 +1,39 @@
package mineplex.core.powerplayclub;
import mineplex.core.MiniClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.account.ILoginProcessor;
import mineplex.serverdata.database.DBPool;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.*;
import java.sql.Date;
import java.time.LocalDate;
import java.util.UUID;
import java.time.YearMonth;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
public class PowerPlayClubRepository extends MiniClientPlugin<PPCPlayerData> {
public class PowerPlayClubRepository implements Listener {
// Data loaded by the first ILoginProcessor, waiting for the second
private final Map<UUID, List<YearMonth>> _stageOneDataClaims = new HashMap<>();
// Cached data produced by combining the first and second ILoginProcessors.
// This data is not guaranteed to be fresh, and should be recalculated before
// giving a player his/her rewards.
private final Map<UUID, PowerPlayData> _cachedPlayerData = new HashMap<>();
private final CoreClientManager _clientManager;
public PowerPlayClubRepository(JavaPlugin plugin, CoreClientManager clientManager) {
super("PowerPlayClubRepository", plugin);
_clientManager = clientManager;
Bukkit.getPluginManager().registerEvents(this, plugin);
clientManager.addStoredProcedureLoginProcessor(new ILoginProcessor() {
@Override
public String getName() {
@ -29,7 +42,12 @@ public class PowerPlayClubRepository extends MiniClientPlugin<PPCPlayerData> {
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException {
PowerPlayClubRepository.this.Get(uuid).setClaimed(resultSet.next());
List<YearMonth> claims = new ArrayList<>();
while (resultSet.next())
{
claims.add(YearMonth.of(resultSet.getInt("claimYear"), resultSet.getInt("claimMonth")));
}
_stageOneDataClaims.put(uuid, claims);
}
@Override
@ -46,7 +64,16 @@ public class PowerPlayClubRepository extends MiniClientPlugin<PPCPlayerData> {
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException {
PowerPlayClubRepository.this.Get(uuid).setSubscribed(resultSet.next());
List<PowerPlayData.Subscription> subscriptions = new ArrayList<>();
while (resultSet.next())
{
LocalDate date = resultSet.getDate("startDate").toLocalDate();
PowerPlayData.SubscriptionDuration duration = PowerPlayData.SubscriptionDuration.valueOf(resultSet.getString("duration").toUpperCase());
subscriptions.add(new PowerPlayData.Subscription(date, duration));
}
// Now that we have the claims from the first processor and subscriptions from this one, combine them
_cachedPlayerData.put(uuid, PowerPlayData.fromSubsAndClaims(subscriptions, _stageOneDataClaims.remove(uuid)));
}
@Override
@ -56,6 +83,13 @@ public class PowerPlayClubRepository extends MiniClientPlugin<PPCPlayerData> {
});
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
_stageOneDataClaims.remove(event.getPlayer().getUniqueId()); // Just in case.
_cachedPlayerData.remove(event.getPlayer().getUniqueId());
}
public CompletableFuture<Void> addSubscription(int accountId, LocalDate date, String duration)
{
return CompletableFuture.supplyAsync(() ->
@ -101,18 +135,75 @@ public class PowerPlayClubRepository extends MiniClientPlugin<PPCPlayerData> {
});
}
public boolean alreadyClaimed(Player player)
public CompletableFuture<PowerPlayData> loadData(Player player)
{
return Get(player).hasClaimed();
return loadSubscriptions(player).thenCombine(loadClaimMonths(player), PowerPlayData::fromSubsAndClaims);
}
public boolean canClaim(Player player)
public CompletableFuture<List<YearMonth>> loadClaimMonths(Player player)
{
return Get(player).hasSubscribed() && !Get(player).hasClaimed();
int accountId = _clientManager.Get(player).getAccountId();
return CompletableFuture.supplyAsync(() ->
{
try (Connection connection = DBPool.getAccount().getConnection())
{
PreparedStatement statement = connection.prepareStatement("SELECT * FROM powerPlayClaims WHERE accountId = ?");
statement.setInt(1, accountId);
ResultSet resultSet = statement.executeQuery();
List<YearMonth> claims = new ArrayList<>();
while (resultSet.next())
{
claims.add(YearMonth.of(resultSet.getInt("claimYear"), resultSet.getInt("claimMonth")));
}
return claims;
} catch (SQLException e)
{
throw new CompletionException(e);
}
});
}
@Override
protected PPCPlayerData addPlayer(UUID uuid) {
return new PPCPlayerData();
public CompletableFuture<List<PowerPlayData.Subscription>> loadSubscriptions(Player player)
{
int accountId = _clientManager.Get(player).getAccountId();
return CompletableFuture.supplyAsync(() ->
{
try (Connection connection = DBPool.getAccount().getConnection())
{
PreparedStatement statement = connection.prepareStatement("SELECT * FROM powerPlaySubs WHERE accountId = ?");
statement.setInt(1, accountId);
ResultSet resultSet = statement.executeQuery();
List<PowerPlayData.Subscription> subscriptions = new ArrayList<>();
while (resultSet.next())
{
LocalDate date = resultSet.getDate("startDate").toLocalDate();
PowerPlayData.SubscriptionDuration duration = PowerPlayData.SubscriptionDuration.valueOf(resultSet.getString("duration").toUpperCase());
subscriptions.add(new PowerPlayData.Subscription(date, duration));
}
return subscriptions;
} catch (SQLException e)
{
throw new CompletionException(e);
}
});
}
public PowerPlayData getCachedData(Player player)
{
return _cachedPlayerData.get(player.getUniqueId());
}
public void putCachedData(Player player, PowerPlayData data)
{
if (player.isOnline())
{
_cachedPlayerData.put(player.getUniqueId(), data);
}
}
}

View File

@ -1,9 +1,12 @@
package mineplex.core.powerplayclub;
import java.time.Month;
import java.time.Year;
import java.time.YearMonth;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableMap;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.skin.SkinData;
import mineplex.core.common.util.BukkitFuture;
@ -18,65 +21,22 @@ import org.bukkit.inventory.ItemStack;
public class PowerPlayClubRewards
{
private static final Map<RewardMonth, List<PowerPlayClubItem>> rewards = new HashMap<>();
public static final int AMPLIFIERS_PER_MONTH = 2;
public static final int CHESTS_PER_MONTH = 1;
static
{
setRewards(2016, Month.SEPTEMBER, new PowerPlayClubItem("Squid Morph", 1, new ItemStack(Material.INK_SACK)));
setRewards(2016, Month.OCTOBER, new PowerPlayClubItem("Witch Morph", 1, SkinData.WITCH.getSkull()));
}
public static List<PowerPlayClubItem> septemberItems() // TODO: figure this out
{
return rewards.values().iterator().next();
}
private static void setRewards(int year, Month month, PowerPlayClubItem... items)
{
rewards.put(new RewardMonth(Year.of(year), month), Arrays.asList(items));
}
private static class RewardMonth
{
private final Year year;
private final Month month;
static RewardMonth of(Year year, Month month)
{
return new RewardMonth(year, month);
}
RewardMonth(Year year, Month month)
{
this.year = year;
this.month = month;
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) return false;
RewardMonth that = (RewardMonth) obj;
return Objects.equals(this.year, that.year) && Objects.equals(this.month, that.month);
}
@Override
public int hashCode() {
return Objects.hash(year, month);
}
}
private static final Map<YearMonth, PowerPlayClubItem> rewards = ImmutableMap.<YearMonth, PowerPlayClubItem>builder()
.put(YearMonth.of(2016, Month.SEPTEMBER), new PowerPlayClubItem("Squid Morph", new ItemStack(Material.INK_SACK)))
.put(YearMonth.of(2016, Month.OCTOBER), new PowerPlayClubItem("Witch Morph", SkinData.WITCH.getSkull()))
.build();
public static class PowerPlayClubItem
{
private final String _prize;
private final int _amount;
private final ItemStack _display;
public PowerPlayClubItem(String prize, int amount, ItemStack display)
PowerPlayClubItem(String prize, ItemStack display)
{
_prize = prize;
_amount = amount;
_display = display;
}
@ -85,51 +45,50 @@ public class PowerPlayClubRewards
return _prize;
}
public int getAmount()
{
return _amount;
}
public ItemStack getDisplay()
{
return _display;
}
}
public static List<PowerPlayClubItem> rewardsForMonths(List<YearMonth> months)
{
return months.stream().map(rewards::get).collect(Collectors.toList());
}
public static void giveAllItems(Player player, DonationManager donationManager, InventoryManager inventoryManager, PowerPlayClubRepository repo)
{
UtilPlayer.message(player, F.main("Power Play Club", "Verifying subscription.."));
repo.attemptClaim(player).thenCompose(BukkitFuture.accept(success ->
repo.attemptClaim(player).thenCompose(success ->
{
if (!success)
{
UtilPlayer.message(player, F.main("Power Play Club", "An unexpected error happened!"));
return;
return CompletableFuture.completedFuture(null);
}
repo.Get(player).setClaimed(true);
PowerPlayData cached = repo.getCachedData(player);
List<PowerPlayClubItem> items = rewardsForMonths(cached.getUnclaimedMonths());
for (PowerPlayClubItem item : septemberItems()) // TODO: figure this out
// Give Metal Man morph for signing up
donationManager.PurchaseUnknownSalesPackage(null, player.getName(),
donationManager.getClientManager().Get(player).getAccountId(), "Metal Man Morph",
GlobalCurrency.TREASURE_SHARD, 0, true);
// Give normal power play items
items.forEach(item ->
{
/*Item fItem = manager.getItem(item.getPrize());
if (fItem == null)
{
UtilPlayer.message(player, F.main("Power Play Club", "An unexpected error happened!"));
}
else
{
manager.addItemToInventory(player, fItem.Name, 1);
UtilPlayer.message(player, F.main("Power Play Club", "You received " + item.getAmount() + "x " + F.elem(item.getPrize()) + "."));
}*/
donationManager.PurchaseUnknownSalesPackage(null, player.getName(),
donationManager.getClientManager().Get(player).getAccountId(), item.getPrize(),
GlobalCurrency.TREASURE_SHARD, 0, true);
UtilPlayer.message(player, F.main("Power Play Club", "You received " + item.getAmount() + "x " +
UtilPlayer.message(player, F.main("Power Play Club", "You received the " +
F.elem(item.getPrize()) + "."));
}
});
// Give amplifiers and chests
Item gameAmplifier = inventoryManager.getItem("Game Booster");
if (gameAmplifier == null)
{
@ -137,8 +96,8 @@ public class PowerPlayClubRewards
}
else
{
inventoryManager.addItemToInventory(player, gameAmplifier.Name, 2);
UtilPlayer.message(player, F.main("Power Play Club", "You received 2x " + F.elem("Game Boosters") + "."));
inventoryManager.addItemToInventory(player, gameAmplifier.Name, AMPLIFIERS_PER_MONTH * items.size());
UtilPlayer.message(player, F.main("Power Play Club", "You received " + (AMPLIFIERS_PER_MONTH * items.size()) + "x " + F.elem("Game Amplifier") + "."));
}
Item omegaChest = inventoryManager.getItem("Omega Chest");
if (omegaChest == null)
@ -147,10 +106,13 @@ public class PowerPlayClubRewards
}
else
{
inventoryManager.addItemToInventory(player, omegaChest.Name, 1);
UtilPlayer.message(player, F.main("Power Play Club", "You received 1x " + F.elem("Omega Chest") + "."));
inventoryManager.addItemToInventory(player, omegaChest.Name, CHESTS_PER_MONTH * items.size());
UtilPlayer.message(player, F.main("Power Play Club", "You received " + (CHESTS_PER_MONTH * items.size()) + "x " + F.elem("Omega Chest") + "."));
}
}));
// Refresh Power Play data on the server
return repo.loadData(player).thenCompose(BukkitFuture.accept(data -> repo.putCachedData(player, data)));
});
}
}

View File

@ -0,0 +1,116 @@
package mineplex.core.powerplayclub;
import com.google.common.base.Objects;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;
import java.util.stream.Collectors;
public class PowerPlayData
{
private final boolean _subscribed;
private final List<YearMonth> _unclaimedMonths;
static PowerPlayData fromSubsAndClaims(List<Subscription> subscriptions, List<YearMonth> claimedMonths)
{
if (subscriptions.isEmpty())
{
return new PowerPlayData(false, Collections.emptyList());
}
// Build the list of potential claim dates from subscriptions
List<LocalDate> claimDates = subscriptions.stream()
.flatMap(sub -> buildMonths(sub).stream())
.sorted()
.collect(Collectors.toCollection(LinkedList::new));
// Determine if player is subscribed
LocalDate latestSub = claimDates.get(claimDates.size() - 1);
final boolean subscribed = latestSub.plusMonths(1).isAfter(LocalDate.now());
// Remove already-claimed months
Optional<YearMonth> latestClaimed = claimedMonths.stream().collect(Collectors.maxBy(YearMonth::compareTo));
latestClaimed.ifPresent(latest ->
{
while (!claimDates.isEmpty())
{
LocalDate claimDate = claimDates.get(0);
YearMonth claimMonth = YearMonth.from(claimDate);
if (latest.equals(claimMonth) || latest.isAfter(claimMonth))
{
claimDates.remove(0);
} else
{
break;
}
}
});
List<YearMonth> unclaimedMonths = claimDates.stream()
.filter(date -> date.isBefore(LocalDate.now()) || date.equals(LocalDate.now())) // Filter dates yet to come
.map(YearMonth::from)
.distinct()
.collect(Collectors.toList());
return new PowerPlayData(subscribed, unclaimedMonths);
}
private static List<LocalDate> buildMonths(Subscription subscription)
{
switch (subscription._duration)
{
case MONTH:
return Collections.singletonList(subscription._startDate);
case YEAR:
List<LocalDate> months = new ArrayList<>();
for (int i = 0; i < 12; i++)
{
months.add(subscription._startDate.plusMonths(i));
}
return months;
default:
throw new IllegalStateException("Invalid duration");
}
}
static class Subscription {
private final LocalDate _startDate;
private final SubscriptionDuration _duration;
Subscription(LocalDate startDate, SubscriptionDuration duration)
{
_startDate = startDate;
_duration = duration;
}
}
enum SubscriptionDuration {
MONTH, YEAR
}
private PowerPlayData(boolean subscribed, List<YearMonth> unclaimedMonths)
{
_subscribed = subscribed;
_unclaimedMonths = unclaimedMonths;
}
public List<YearMonth> getUnclaimedMonths()
{
return _unclaimedMonths;
}
public boolean isSubscribed()
{
return _subscribed;
}
@Override
public String toString()
{
return Objects.toStringHelper(this).add("subscribed", _subscribed).add("unclaimed", _unclaimedMonths).toString();
}
}