Fix voting rewards
This commit is contained in:
1 parent
12b77c50ce
commit
d38e70e012
9 files changed
+238
-46
No files matched your search
@@ -81,7 +81,9 @@ import com.bencodez.votingplugin.listeners.PlayerInteract;
|
||||
import com.bencodez.votingplugin.listeners.PlayerJoinEvent;
|
||||
import com.bencodez.votingplugin.listeners.PlayerVoteListener;
|
||||
import com.bencodez.votingplugin.listeners.SignChange;
|
||||
import com.bencodez.votingplugin.listeners.SurvivalRewardGate;
|
||||
import com.bencodez.votingplugin.listeners.VotiferEvent;
|
||||
import com.bencodez.votingplugin.listeners.WeekStreakExpBonus;
|
||||
import com.bencodez.votingplugin.listeners.VotingPluginUpdateEvent;
|
||||
import com.bencodez.votingplugin.objects.VoteSite;
|
||||
import com.bencodez.votingplugin.placeholders.MVdWPlaceholders;
|
||||
@@ -1490,6 +1492,8 @@ public class VotingPluginMain extends AdvancedCorePlugin {
|
||||
pm.registerEvents(new VotiferEvent(this), this);
|
||||
}
|
||||
pm.registerEvents(new PlayerVoteListener(this), this);
|
||||
pm.registerEvents(new SurvivalRewardGate(this), this);
|
||||
pm.registerEvents(new WeekStreakExpBonus(this), this);
|
||||
pm.registerEvents(new SignChange(this), this);
|
||||
pm.registerEvents(new BlockBreak(this), this);
|
||||
if (!plugin.getConfigFile().isDisableInteractEvent()) {
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -78,6 +77,9 @@ import com.bencodez.votingplugin.objects.VoteSite;
|
||||
import com.bencodez.votingplugin.topvoter.TopVoter;
|
||||
import com.bencodez.votingplugin.user.VotingPluginUser;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
/**
|
||||
* The Class CommandLoader.
|
||||
@@ -818,8 +820,10 @@ public class CommandLoader {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
sender.sendMessage(ChatColor.GREEN + "UUID of player " + ChatColor.DARK_GREEN + args[1]
|
||||
+ ChatColor.GREEN + " is: " + PlayerManager.getInstance().getUUID(args[1]));
|
||||
sender.sendMessage(Component.text("UUID of player ", NamedTextColor.GREEN)
|
||||
.append(Component.text(args[1], NamedTextColor.DARK_GREEN))
|
||||
.append(Component.text(" is: " + PlayerManager.getInstance().getUUID(args[1]),
|
||||
NamedTextColor.GREEN)));
|
||||
|
||||
}
|
||||
});
|
||||
@@ -830,11 +834,11 @@ public class CommandLoader {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
try {
|
||||
sender.sendMessage(ChatColor.GREEN + "PlayerName of player " + ChatColor.DARK_GREEN + args[1]
|
||||
+ ChatColor.GREEN + " is: "
|
||||
+ PlayerManager.getInstance().getPlayerName(
|
||||
sender.sendMessage(Component.text("PlayerName of player ", NamedTextColor.GREEN)
|
||||
.append(Component.text(args[1], NamedTextColor.DARK_GREEN))
|
||||
.append(Component.text(" is: " + PlayerManager.getInstance().getPlayerName(
|
||||
plugin.getVotingPluginUserManager().getVotingPluginUser(UUID.fromString(args[1])),
|
||||
args[1]));
|
||||
args[1]), NamedTextColor.GREEN)));
|
||||
} catch (IllegalArgumentException e) {
|
||||
sendMessage(sender, "&cInvalid uuid");
|
||||
}
|
||||
|
||||
+6
-4
@@ -23,7 +23,8 @@ import com.bencodez.votingplugin.VotingPluginMain;
|
||||
import com.bencodez.votingplugin.topvoter.TopVoterPlayer;
|
||||
import com.bencodez.votingplugin.user.VotingPluginUser;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
public class VoteTopVoterPreviousMonths extends GUIHandler {
|
||||
|
||||
@@ -68,18 +69,19 @@ public class VoteTopVoterPreviousMonths extends GUIHandler {
|
||||
if (!yearMonthList.isEmpty()) {
|
||||
yearMonth = yearMonthList.get(0);
|
||||
}
|
||||
player.sendMessage(ChatColor.RED + "Can't open previous months, no data");
|
||||
player.sendMessage(Component.text("Can't open previous months, no data", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
if (yearMonthList.size() <= index) {
|
||||
player.sendMessage(ChatColor.RED + "Can't open previous months, no data for requested index");
|
||||
player.sendMessage(
|
||||
Component.text("Can't open previous months, no data for requested index", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
yearMonth = yearMonthList.get(index);
|
||||
|
||||
Set<Entry<TopVoterPlayer, Integer>> users = null;
|
||||
if (!plugin.getPreviousMonthsTopVoters().containsKey(yearMonth)) {
|
||||
player.sendMessage(ChatColor.RED + "Can't open previous months, no data");
|
||||
player.sendMessage(Component.text("Can't open previous months, no data", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
users = plugin.getPreviousMonthsTopVoters().get(yearMonth).entrySet();
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -213,7 +212,7 @@ public class ConfigVoteSites extends YMLFile {
|
||||
try {
|
||||
data.save(dFile);
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe(ChatColor.RED + "Could not create VoteSites/" + siteName + ".yml!");
|
||||
plugin.getLogger().severe("Could not create VoteSites/" + siteName + ".yml!");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.bencodez.votingplugin.listeners;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
|
||||
import com.bencodez.advancedcore.api.user.AdvancedCoreUser;
|
||||
import com.bencodez.advancedcore.listeners.PlayerRewardEvent;
|
||||
import com.bencodez.votingplugin.VotingPluginMain;
|
||||
import com.bencodez.votingplugin.user.VotingPluginUser;
|
||||
|
||||
// Rewards given outside survival in the main worlds get wiped by
|
||||
// GameModeInventories' per-gamemode XP/inventory swap or land in the wrong
|
||||
// context, so bank them until the player is eligible again.
|
||||
public class SurvivalRewardGate implements Listener {
|
||||
|
||||
private static final Set<String> REWARD_WORLDS = Set.of("world", "world_nether", "world_the_end");
|
||||
private static final long NOTICE_THROTTLE_MILLIS = 30000L;
|
||||
|
||||
static boolean eligibleForRewards(Player player) {
|
||||
return player.getGameMode() == GameMode.SURVIVAL && REWARD_WORLDS.contains(player.getWorld().getName());
|
||||
}
|
||||
|
||||
private final VotingPluginMain plugin;
|
||||
private final ConcurrentHashMap<UUID, Long> lastBankNotice = new ConcurrentHashMap<>();
|
||||
|
||||
public SurvivalRewardGate(VotingPluginMain plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// Fires on an async thread; PlayerRewardEvent does not implement Cancellable
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerReward(PlayerRewardEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
AdvancedCoreUser user = event.getPlayer();
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) {
|
||||
// truly offline: stock offline handling applies
|
||||
return;
|
||||
}
|
||||
if (eligibleForRewards(player)) {
|
||||
return;
|
||||
}
|
||||
event.setCancelled(true);
|
||||
user.addOfflineRewards(event.getReward(), event.getRewardOptions().getPlaceholders());
|
||||
plugin.debug("Banked reward " + event.getReward().getRewardName() + " for " + user.getPlayerName()
|
||||
+ " until survival in a main world");
|
||||
notifyBanked(player);
|
||||
}
|
||||
|
||||
private void notifyBanked(Player player) {
|
||||
long now = System.currentTimeMillis();
|
||||
Long last = lastBankNotice.put(player.getUniqueId(), now);
|
||||
if (last != null && now - last < NOTICE_THROTTLE_MILLIS) {
|
||||
return;
|
||||
}
|
||||
plugin.getLogger().info(player.getName() + " has vote rewards banked until survival in a main world");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onGameModeChange(PlayerGameModeChangeEvent event) {
|
||||
if (event.getNewGameMode() != GameMode.SURVIVAL) {
|
||||
return;
|
||||
}
|
||||
scheduleReplay(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onWorldChange(PlayerChangedWorldEvent event) {
|
||||
scheduleReplay(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
private void scheduleReplay(UUID uuid) {
|
||||
// 1 tick later the change is applied and GameModeInventories' restore has settled
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null || !player.isOnline() || !eligibleForRewards(player)) {
|
||||
return;
|
||||
}
|
||||
// reward replay fires the async PlayerRewardEvent, so hop off the main thread
|
||||
plugin.getLoginTimer().execute(() -> {
|
||||
VotingPluginUser user = plugin.getVotingPluginUserManager().getVotingPluginUser(player);
|
||||
user.offVote();
|
||||
user.checkOfflineRewards();
|
||||
});
|
||||
}, 1L);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.bencodez.votingplugin.listeners;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.bencodez.advancedcore.api.rewards.Reward;
|
||||
import com.bencodez.advancedcore.api.user.AdvancedCoreUser;
|
||||
import com.bencodez.advancedcore.listeners.PlayerRewardEvent;
|
||||
import com.bencodez.votingplugin.VotingPluginMain;
|
||||
import com.bencodez.votingplugin.user.VotingPluginUser;
|
||||
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
||||
// Each full week of voting every day adds a bonus level on top of the per-site
|
||||
// EXPLevels reward, capping the streak credit at MAX_WEEKS; missing a day
|
||||
// resets the day streak and with it the bonus.
|
||||
public class WeekStreakExpBonus implements Listener {
|
||||
|
||||
private static final String SITE_REWARD_PREFIX = "VoteSites.";
|
||||
private static final String SITE_REWARD_SUFFIX = ".Rewards";
|
||||
private static final int BASE_LEVELS = 15;
|
||||
private static final int MAX_WEEKS = 52;
|
||||
private static final int DAYS_PER_WEEK = 7;
|
||||
|
||||
private final VotingPluginMain plugin;
|
||||
|
||||
public WeekStreakExpBonus(VotingPluginMain plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// Runs after SurvivalRewardGate (HIGHEST); a banked reward arrives cancelled
|
||||
// here and earns its bonus when the replay passes the gate
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerReward(PlayerRewardEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Reward reward = event.getReward();
|
||||
if (reward == null || reward.getRewardName() == null) {
|
||||
return;
|
||||
}
|
||||
String name = reward.getRewardName();
|
||||
if (!name.startsWith(SITE_REWARD_PREFIX) || !name.endsWith(SITE_REWARD_SUFFIX)) {
|
||||
return;
|
||||
}
|
||||
AdvancedCoreUser acUser = event.getPlayer();
|
||||
if (acUser == null) {
|
||||
return;
|
||||
}
|
||||
Player player = acUser.getPlayer();
|
||||
if (player == null || !SurvivalRewardGate.eligibleForRewards(player)) {
|
||||
return;
|
||||
}
|
||||
final UUID uuid = player.getUniqueId();
|
||||
// async event; XP must change on the main thread
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
Player target = Bukkit.getPlayer(uuid);
|
||||
if (target == null || !target.isOnline() || !SurvivalRewardGate.eligibleForRewards(target)) {
|
||||
return;
|
||||
}
|
||||
VotingPluginUser user = plugin.getVotingPluginUserManager().getVotingPluginUser(target);
|
||||
int dayStreak = user.getDayVoteStreak();
|
||||
int weeks = dayStreak / DAYS_PER_WEEK;
|
||||
int bonus = Math.min(weeks, MAX_WEEKS);
|
||||
if (bonus > 0) {
|
||||
target.giveExpLevels(bonus);
|
||||
plugin.debug("Week streak bonus: +" + bonus + " levels for " + target.getName());
|
||||
}
|
||||
target.sendMessage(MiniMessage.miniMessage().deserialize(buildMessage(dayStreak, weeks, bonus)));
|
||||
});
|
||||
}
|
||||
|
||||
private String buildMessage(int dayStreak, int weeks, int bonus) {
|
||||
int total = BASE_LEVELS + bonus;
|
||||
if (bonus > 0) {
|
||||
return "<green>+" + total + " XP levels <gray>(" + weeks
|
||||
+ " week streak <dark_gray>-</dark_gray> vote every day to keep it)";
|
||||
}
|
||||
if (dayStreak > 0) {
|
||||
return "<green>+" + total + " XP levels <gray>(" + dayStreak + "/" + DAYS_PER_WEEK
|
||||
+ " days to your first bonus level)";
|
||||
}
|
||||
return "<green>+" + total + " XP levels <gray>(vote every day for a week to earn bonus XP)";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -18,6 +17,9 @@ import com.bencodez.simpleapi.messages.MessageAPI;
|
||||
import com.bencodez.votingplugin.VotingPluginMain;
|
||||
import com.bencodez.votingplugin.user.VotingPluginUser;
|
||||
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -178,8 +180,8 @@ public class VoteSite {
|
||||
}
|
||||
|
||||
public String getVoteURLJsonStrip() {
|
||||
String url = ChatColor
|
||||
.stripColor(MessageAPI.colorize(PlaceholderUtils.parseJson(getVoteURL(false)).toPlainText()));
|
||||
String url = PlainTextComponentSerializer.plainText().serialize(LegacyComponentSerializer.legacySection()
|
||||
.deserialize(MessageAPI.colorize(PlaceholderUtils.parseJson(getVoteURL(false)).toPlainText())));
|
||||
if (!url.startsWith("http")) {
|
||||
if (!url.startsWith("www.")) {
|
||||
url = "https://www." + url;
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
# Rewards will be given if there is a reward to give, otherwise they will be ignored
|
||||
|
||||
# First vote rewards
|
||||
FirstVote:
|
||||
Messages:
|
||||
Player: '&aYou voted for your first time!'
|
||||
FirstVote: {}
|
||||
|
||||
# First vote of the day reward
|
||||
FirstVoteToday: {}
|
||||
@@ -15,9 +13,7 @@ FirstVoteToday: {}
|
||||
# All vote rewards
|
||||
# One time reward for voting on all sites in one day
|
||||
# Enable ExtraAllSitesCheck if you get double rewards
|
||||
AllSites:
|
||||
Messages:
|
||||
Player: '&aYou voted on all sites in 1 day!'
|
||||
AllSites: {}
|
||||
|
||||
# Give a reward for voting on all sites minus 1
|
||||
# Similar to allsites
|
||||
@@ -60,7 +56,7 @@ Cumulative:
|
||||
|
||||
# Vote party configuration
|
||||
VoteParty:
|
||||
Enabled: true
|
||||
Enabled: false
|
||||
VotesRequired: 50
|
||||
GiveAllPlayers: false
|
||||
GiveOnlinePlayersOnly: true
|
||||
@@ -79,38 +75,34 @@ VoteParty:
|
||||
VoteReminderAtVotes: []
|
||||
GlobalCommands: []
|
||||
GlobalRandomCommand: []
|
||||
Rewards:
|
||||
Commands:
|
||||
- 'xp give %player% 50L'
|
||||
Rewards:
|
||||
EXPLevels: 50
|
||||
|
||||
ResetMilestonesMonthly: false
|
||||
|
||||
MileStones:
|
||||
'100':
|
||||
Enabled: true
|
||||
Enabled: false
|
||||
Rewards:
|
||||
Messages:
|
||||
Player: '&aYou reached the 100 votes milestone!'
|
||||
Commands:
|
||||
- 'xp give %player% 100L'
|
||||
EXPLevels: 100
|
||||
|
||||
VoteStreak:
|
||||
Day:
|
||||
'7':
|
||||
Enabled: true
|
||||
Enabled: false
|
||||
Rewards:
|
||||
Messages:
|
||||
Player: "&aYou voted for 7 Days in a row!"
|
||||
Commands:
|
||||
- 'xp give %player% 50L'
|
||||
EXPLevels: 50
|
||||
Week:
|
||||
'4':
|
||||
Enabled: true
|
||||
Enabled: false
|
||||
Rewards:
|
||||
Messages:
|
||||
Player: "&aYou voted for 4 Weeks in a row!"
|
||||
Commands:
|
||||
- 'xp give %player% 200L'
|
||||
EXPLevels: 200
|
||||
Month:
|
||||
'2':
|
||||
Enabled: false
|
||||
@@ -147,7 +139,7 @@ LoginRewards: {}
|
||||
# Will queue until player logs in unless forceoffline is enabled
|
||||
LogoutRewards: {}
|
||||
|
||||
EnableMonthlyAwards: true
|
||||
EnableMonthlyAwards: false
|
||||
|
||||
MonthlyAwards:
|
||||
1:
|
||||
@@ -158,8 +150,7 @@ MonthlyAwards:
|
||||
DIAMOND_BLOCK:
|
||||
Material: 'DIAMOND_BLOCK'
|
||||
Amount: 5
|
||||
Commands:
|
||||
- 'xp give %player% 500L'
|
||||
EXPLevels: 500
|
||||
2:
|
||||
Rewards:
|
||||
Messages:
|
||||
@@ -168,8 +159,7 @@ MonthlyAwards:
|
||||
DIAMOND_BLOCK:
|
||||
Material: 'DIAMOND_BLOCK'
|
||||
Amount: 3
|
||||
Commands:
|
||||
- 'xp give %player% 300L'
|
||||
EXPLevels: 300
|
||||
3:
|
||||
Rewards:
|
||||
Messages:
|
||||
@@ -178,8 +168,7 @@ MonthlyAwards:
|
||||
DIAMOND_BLOCK:
|
||||
Material: 'DIAMOND_BLOCK'
|
||||
Amount: 1
|
||||
Commands:
|
||||
- 'xp give %player% 100L'
|
||||
EXPLevels: 100
|
||||
|
||||
EnableWeeklyAwards: false
|
||||
# Rewards to give on weekly top voter
|
||||
|
||||
@@ -14,8 +14,7 @@ VoteSites:
|
||||
Material: 'DIAMOND'
|
||||
Amount: 1
|
||||
Rewards:
|
||||
Commands:
|
||||
- 'xp give %player% 15L'
|
||||
EXPLevels: 15
|
||||
Messages:
|
||||
Player: '&aThank you for voting on MinecraftServerList!'
|
||||
|
||||
@@ -34,8 +33,7 @@ VoteSites:
|
||||
Material: 'EMERALD'
|
||||
Amount: 1
|
||||
Rewards:
|
||||
Commands:
|
||||
- 'xp give %player% 15L'
|
||||
EXPLevels: 15
|
||||
Messages:
|
||||
Player: '&aThank you for voting on MinecraftServersGG!'
|
||||
|
||||
|
||||
Reference in new issue
Block a user