Compare commits

...
47 Commits
Author SHA1 Message Date
BenCodez b8acfe20ec Update version number to 6.19 2025-08-24 15:48:12 -06:00
BenCodez 110aaf096e Refactor player name retrieval to match casing from UUID cache 2025-08-24 13:30:53 -06:00
Ben 171975c3d3 Merge pull request #1457 from BenCodez/dependabot/maven/VotingPlugin/org.apache.maven.plugins-maven-javadoc-plugin-3.11.3
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3 in /VotingPlugin
2025-08-18 18:47:52 -06:00
dependabot[bot] ac96d277c5 Bump org.apache.maven.plugins:maven-javadoc-plugin in /VotingPlugin
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.2 to 3.11.3.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.2...maven-javadoc-plugin-3.11.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-version: 3.11.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 09:18:02 +00:00
BenCodez b1ad952950 Add debug message for DiscordSRV leaderboard updates 2025-08-17 13:37:18 -06:00
BenCodez ca30bcb183 Fix clearing discord message id with command 2025-08-15 16:56:13 -06:00
BenCodez eecd975731 Add debug logging and minor changes for discord top voters 2025-08-13 15:52:53 -06:00
BenCodez aa55b10e50 Implement delay handling for global message sending on PLUGINMESSAGING
Added to handle cases where too many pluginmessages causes messages to
be skipped, subject to change
2025-08-10 14:16:08 -06:00
BenCodez 64f59f8195 Update WaitForUserOnline setting to true for consistent reward behavior 2025-08-10 13:09:43 -06:00
BenCodez a51e041430 Add command to clear Discord message ID for top voter
This will force a new discord message to be sent
2025-08-10 12:19:42 -06:00
BenCodez b39f768a46 Add support for multiple top voter types in DiscordSRV integration 2025-08-06 19:33:44 -06:00
BenCodez e98bc49add Parse placeholders on discord message reward 2025-08-05 17:00:00 -06:00
BenCodez 8b2209aa59 Attempt fixing player name casing in offline while player is offline 2025-08-03 15:02:21 -06:00
BenCodez 58a0e85d00 Prevent redundant updates to last vote time for a specific vote site 2025-08-03 13:31:53 -06:00
BenCodez 3febfa4056 Update vote times in all possible cases 2025-08-03 13:31:28 -06:00
BenCodez e5668c862a Fix player name casing in offline mode Bungee and Velocity proxies
Will attempt to correct while player is online
2025-08-01 16:26:54 -06:00
BenCodez fd4c6a3954 Restore bungeeVoteParty data on all methods on startup 2025-08-01 16:16:14 -06:00
BenCodez 9e9472680a Remove unused command aliases from plugin configuration 2025-07-31 16:55:56 -06:00
Ben cbecd7be30 Merge pull request #1452 from BenCodez/dependabot/maven/VotingPlugin/com.discordsrv-discordsrv-1.30.0
Bump com.discordsrv:discordsrv from 1.29.0 to 1.30.0 in /VotingPlugin
2025-07-28 16:26:03 -06:00
dependabot[bot] fcb1af77cf Bump com.discordsrv:discordsrv from 1.29.0 to 1.30.0 in /VotingPlugin
Bumps com.discordsrv:discordsrv from 1.29.0 to 1.30.0.

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-version: 1.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 08:27:53 +00:00
BenCodez 5d9b5b7b6c Add configurable titles and rank display for DiscordSRV top voters 2025-07-26 20:26:04 -06:00
BenCodez d26d61a6f0 Fix formatting of vote count display in Discord embed 2025-07-24 15:55:15 -06:00
BenCodez 3f885aa358 Check DiscordSRV status on initialization 2025-07-22 18:45:19 -06:00
Ben d088f2e91a Merge pull request #1449 from BenCodez/dependabot/maven/VotingPlugin/com.discordsrv-discordsrv-1.29.0
Bump com.discordsrv:discordsrv from 1.26.0 to 1.29.0 in /VotingPlugin
2025-07-21 17:27:56 -06:00
dependabot[bot] a536c53dd9 Bump com.discordsrv:discordsrv from 1.26.0 to 1.29.0 in /VotingPlugin
Bumps com.discordsrv:discordsrv from 1.26.0 to 1.29.0.

---
updated-dependencies:
- dependency-name: com.discordsrv:discordsrv
  dependency-version: 1.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-21 08:06:43 +00:00
Ben 5d2d6f0763 Merge pull request #1440 from BenCodez/dependabot/maven/VotingPlugin/net.md-5-bungeecord-api-1.21-R0.3
Bump net.md-5:bungeecord-api from 1.21-R0.2 to 1.21-R0.3 in /VotingPlugin
2025-07-20 20:26:50 -06:00
BenCodez 0848ed83c2 Add DiscordSRV integration for top voter updates and injected reward 2025-07-20 16:08:08 -06:00
ben 1771fe0889 Update to 1.21.8 2025-07-19 21:23:35 -06:00
ben ce5b197e8b Don't always close inventory on VoteURL 2025-07-19 15:16:43 -06:00
ben 15489d9c64 Modify how slots are set in VoteURL GUI 2025-07-18 19:37:42 -06:00
ben 758632b5a5 Fix redis messages showing up in logs without debug enabled 2025-07-17 16:05:52 -06:00
ben 3dc45b6a63 Add extra items to VoteURL first 2025-07-15 19:02:55 -06:00
ben 26c9ad98bc Change MYSQL method to use MYSQL to communicate between servers
Works like PLUGINMESSAGING, SOCKETS, REDIS, or MQTT
2025-07-13 20:28:59 -06:00
BenCodez ee2531af1e Modify shutdown order 2025-07-06 16:16:16 -06:00
BenCodez 461e5f8413 Cancel more timers on velocity shutdown 2025-07-05 20:38:34 -06:00
BenCodez 1c5acbd1a1 Improve resource cleanup in VotingPluginProxy shutdown method
- Added socketHandler connection closure
- Added redisHandler resource cleanup
- Shutdown globalDataHandler if initialized
- Ensured proper cleanup of all handlers
- Maintained existing bungeeTimeChecker shutdown logic
- Set `enabled` to false after cleanup
2025-07-05 14:48:17 -06:00
BenCodez e855c01854 Stop timer on velocity shutdown 2025-07-05 08:57:30 -06:00
BenCodez aeec7d9d17 Shutdown bungeeTimeChecker during proxy disable process.
- Added `bungeeTimeChecker.shutdown()` in `VotingPluginProxy`.
- Ensures proper cleanup of `bungeeTimeChecker`.
- Prevents potential resource leaks during proxy shutdown.
- Maintains consistency in shutdown logic.
- Improves reliability of proxy disable functionality.
- Minor code enhancement for better resource management.
2025-07-04 15:46:30 -06:00
BenCodez 4861c041e4 Add ResetMilestonesMonthly to proxy 2025-07-01 08:58:23 -06:00
BenCodez d1c6752240 Update version number to 6.18.8-SNAPSHOT 2025-06-30 18:48:11 -06:00
BenCodez caa7058363 Update version number to 6.18.7 2025-06-30 18:41:45 -06:00
BenCodez b67f6a509c Fix waituntilvotedelay on proxy with better handling 2025-06-30 16:53:00 -06:00
BenCodez 0edc09dc80 Update to 1.21.7 2025-06-30 16:14:27 -06:00
BenCodez 19e597e094 Remove version check on startup 2025-06-30 15:53:54 -06:00
BenCodez bfc838bfaa Add wait until vote delay feature on proxy
- Implemented vote delay checks in `VotingPluginProxy`.
- Added methods to handle vote delay logic in `Config` classes.
- Updated `VotingPluginProxyConfig` with new vote delay methods.
- Extended `bungeeconfig.yml` with `WaitUntilVoteDelay` settings.
- Improved vote handling to skip votes if delay conditions are unmet.
- Enhanced logging for skipped votes due to delay.
2025-06-29 15:57:32 -06:00
BenCodez 9cda17e89e Update version number to 6.18.7-SNAPSHOT 2025-06-22 15:50:59 -06:00
dependabot[bot] 71ccf6a7b0 Bump net.md-5:bungeecord-api in /VotingPlugin
Bumps [net.md-5:bungeecord-api](https://github.com/SpigotMC/BungeeCord) from 1.21-R0.2 to 1.21-R0.3.
- [Commits](https://github.com/SpigotMC/BungeeCord/commits)

---
updated-dependencies:
- dependency-name: net.md-5:bungeecord-api
  dependency-version: 1.21-R0.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-16 06:57:36 +00:00
24 changed files with 935 additions and 166 deletions

No files matched your search

+17 -12
View File
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.bencodez</groupId>
<artifactId>votingplugin</artifactId>
<version>6.18.6</version>
<version>6.19</version>
<packaging>jar</packaging>
<name>VotingPlugin</name>
<properties>
@@ -129,11 +129,6 @@
<shadedPattern>
${project.groupId}.votingplugin.mysqlapi</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.HikariCP</pattern>
<shadedPattern>
${project.groupId}.votingplugin.HikariCP</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>
@@ -214,12 +209,16 @@
<url>
https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>scarsz</id>
<url>https://nexus.scarsz.me/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.21.6-R0.1-SNAPSHOT</version>
<version>1.21.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -231,7 +230,7 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.21-R0.2</version>
<version>1.21-R0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -267,7 +266,7 @@
<dependency>
<groupId>com.bencodez</groupId>
<artifactId>advancedcore</artifactId>
<version>3.7.17</version>
<version>3.7.18</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -282,6 +281,12 @@
<version>5.15.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.30.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<profile>
@@ -364,7 +369,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<version>3.11.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -439,7 +444,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<version>3.11.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -581,7 +586,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<version>3.11.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -1,6 +1,7 @@
package com.bencodez.votingplugin;
import java.io.File;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
@@ -9,6 +10,7 @@ import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -23,11 +25,13 @@ import com.bencodez.advancedcore.bungeeapi.globaldata.GlobalDataHandler;
import com.bencodez.advancedcore.bungeeapi.globaldata.GlobalMySQL;
import com.bencodez.simpleapi.array.ArrayUtils;
import com.bencodez.simpleapi.encryption.EncryptionHandler;
import com.bencodez.simpleapi.messages.MessageAPI;
import com.bencodez.simpleapi.servercomm.global.GlobalMessageHandler;
import com.bencodez.simpleapi.servercomm.global.GlobalMessageListener;
import com.bencodez.simpleapi.servercomm.mqtt.MqttHandler;
import com.bencodez.simpleapi.servercomm.mqtt.MqttServerComm;
import com.bencodez.simpleapi.servercomm.mqtt.MqttHandler.MessageHandler;
import com.bencodez.simpleapi.servercomm.mqtt.MqttServerComm;
import com.bencodez.simpleapi.servercomm.mysql.BackendMessenger;
import com.bencodez.simpleapi.servercomm.pluginmessage.PluginMessageHandler;
import com.bencodez.simpleapi.servercomm.redis.RedisHandler;
import com.bencodez.simpleapi.servercomm.redis.RedisListener;
@@ -78,6 +82,9 @@ public class BungeeHandler implements Listener {
private Thread redisThread;
@Getter
private BackendMessenger backendMysqlMessenger;
public BungeeHandler(VotingPluginMain plugin) {
this.plugin = plugin;
}
@@ -165,6 +172,10 @@ public class BungeeHandler implements Listener {
}
public void close() {
if (backendMysqlMessenger != null) {
backendMysqlMessenger.shutdown();
}
if (socketHandler != null) {
socketHandler.closeConnection();
}
@@ -192,7 +203,14 @@ public class BungeeHandler implements Listener {
@Override
public void sendMessage(String subChannel, String... messageData) {
if (method.equals(BungeeMethod.MYSQL)) {
plugin.getPluginMessaging().sendPluginMessage(subChannel, messageData);
// plugin.getPluginMessaging().sendPluginMessage(subChannel, messageData);
try {
backendMysqlMessenger.sendToProxy(subChannel + "%l%" + String.join("%l%", messageData));
} catch (SQLException e) {
e.printStackTrace();
}
} else if (method.equals(BungeeMethod.PLUGINMESSAGING)) {
plugin.getPluginMessaging().sendPluginMessage(subChannel, messageData);
} else if (method.equals(BungeeMethod.SOCKETS)) {
@@ -414,11 +432,6 @@ public class BungeeHandler implements Listener {
user.offVote();
if (args.size() > 3 && plugin.getBungeeSettings().isPerServerMilestones()) {
BungeeMessageData text = new BungeeMessageData(args.get(3));
plugin.getSpecialRewards().checkMilestone(user, text, true);
}
if (args.size() > 2) {
bungeeVotePartyCurrent = Integer.parseInt(args.get(1));
bungeeVotePartyRequired = Integer.parseInt(args.get(2));
@@ -426,6 +439,26 @@ public class BungeeHandler implements Listener {
plugin.getServerData().setBungeeVotePartyRequired(bungeeVotePartyRequired);
}
if (args.size() > 3 && plugin.getBungeeSettings().isPerServerMilestones()) {
BungeeMessageData text = new BungeeMessageData(args.get(3));
plugin.getSpecialRewards().checkMilestone(user, text, true);
}
if (args.size() > 5) {
String service = args.get(4);
String data = args.get(5);
if (MessageAPI.isLong(data)) {
long time = Long.valueOf(data);
if (time > 0) {
user.setTime(plugin.getVoteSite(service, true), time);
} else {
if (plugin.getBungeeSettings().isBungeeDebug()) {
plugin.debug("Invalid last vote time received from bungee: " + time);
}
}
}
}
plugin.setUpdate(true);
}
});
@@ -517,6 +550,27 @@ public class BungeeHandler implements Listener {
if (method.equals(BungeeMethod.MYSQL)) {
plugin.registerBungeeChannels(plugin.getBungeeSettings().getPluginMessagingChannel());
try {
backendMysqlMessenger = new BackendMessenger("VotingPlugin",
plugin.getMysql().getMysql().getConnectionManager().getDataSource(),
plugin.getOptions().getServer(), msg -> {
plugin.debug("Proxy sent: " + msg.payload);
String[] message = msg.payload.split(Pattern.quote("%l%"));
if (message.length > 0) {
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i < message.length; i++) {
list.add(message[i]);
}
globalMessageHandler.onMessage(message[0], list);
}
});
} catch (SQLException e) {
e.printStackTrace();
}
} else if (method.equals(BungeeMethod.REDIS)) {
redisHandler = new RedisHandler(plugin.getBungeeSettings().getRedisHost(),
plugin.getBungeeSettings().getRedisPort(), plugin.getBungeeSettings().getRedisUsername(),
@@ -531,7 +585,9 @@ public class BungeeHandler implements Listener {
@Override
protected void onMessage(String channel, String[] message) {
plugin.getLogger().info(channel + ArrayUtils.makeStringList(ArrayUtils.convert(message)));
if (plugin.getBungeeSettings().isBungeeDebug()) {
plugin.debug(channel + " " + ArrayUtils.makeStringList(ArrayUtils.convert(message)));
}
if (message.length > 0) {
ArrayList<String> list = new ArrayList<>();
for (int i = 1; i < message.length; i++) {
@@ -563,9 +619,6 @@ public class BungeeHandler implements Listener {
plugin.getPluginMessaging().setEncryptionHandler(encryptionHandler);
}
bungeeVotePartyCurrent = plugin.getServerData().getBungeeVotePartyCurrent();
bungeeVotePartyRequired = plugin.getServerData().getBungeeVotePartyRequired();
plugin.getPluginMessaging().setDebug(plugin.getBungeeSettings().isBungeeDebug());
plugin.getPluginMessaging().add(new PluginMessageHandler() {
@@ -632,6 +685,9 @@ public class BungeeHandler implements Listener {
}
}
bungeeVotePartyCurrent = plugin.getServerData().getBungeeVotePartyCurrent();
bungeeVotePartyRequired = plugin.getServerData().getBungeeVotePartyRequired();
if (plugin.getOptions().getServer().equalsIgnoreCase("pleaseset")) {
plugin.getLogger().warning("Server name for bungee voting is not set, please set it");
}
@@ -57,7 +57,6 @@ import com.bencodez.advancedcore.api.rewards.injectedrequirement.RequirementInje
import com.bencodez.advancedcore.api.user.AdvancedCoreUser;
import com.bencodez.advancedcore.logger.Logger;
import com.bencodez.simpleapi.file.YMLConfig;
import com.bencodez.simpleapi.nms.NMSManager;
import com.bencodez.simpleapi.skull.SkullCache;
import com.bencodez.simpleapi.sql.Column;
import com.bencodez.simpleapi.updater.Updater;
@@ -76,6 +75,7 @@ import com.bencodez.votingplugin.config.ShopFile;
import com.bencodez.votingplugin.config.SpecialRewardsConfig;
import com.bencodez.votingplugin.cooldown.CoolDownCheck;
import com.bencodez.votingplugin.data.ServerData;
import com.bencodez.votingplugin.discord.DiscordHandler;
import com.bencodez.votingplugin.listeners.BlockBreak;
import com.bencodez.votingplugin.listeners.PlayerInteract;
import com.bencodez.votingplugin.listeners.PlayerJoinEvent;
@@ -247,6 +247,9 @@ public class VotingPluginMain extends AdvancedCorePlugin {
private boolean firstTimeLoaded = false;
@Getter
private DiscordHandler discordHandler;
public void addDirectlyDefinedRewards(DirectlyDefinedReward directlyDefinedReward) {
getRewardHandler().addDirectlyDefined(directlyDefinedReward);
}
@@ -1199,6 +1202,12 @@ public class VotingPluginMain extends AdvancedCorePlugin {
mvdwPlaceholders.loadMVdWPlaceholders();
}
if (Bukkit.getPluginManager().isPluginEnabled("DiscordSRV") && configFile.isDiscordSRVEnabled()) {
discordHandler = new DiscordHandler(this);
discordHandler.load();
debug("DiscordSRV enabled, loading DiscordSRV handler");
}
// Add rewards
getRewardHandler().addInjectedReward(new RewardInjectInt("Points", 0) {
@@ -1385,18 +1394,6 @@ public class VotingPluginMain extends AdvancedCorePlugin {
public void onPreLoad() {
plugin = this;
// disable plugin for older versions below 1.12
if (NMSManager.getInstance().isVersion("1.7", "1.8", "1.9", "1.10", "1.11")) {
plugin.getLogger().severe("Detected running " + Bukkit.getVersion()
+ ", this version is not supported on this build, read the plugin page. Disabling...");
if (!configFile.isOverrideVersionDisable()) {
Bukkit.getPluginManager().disablePlugin(this);
return;
}
plugin.getLogger().warning("Overriding version disable, beware of using this! This may cause issues!");
}
setupFiles();
loadVoteSites();
@@ -1713,6 +1710,11 @@ public class VotingPluginMain extends AdvancedCorePlugin {
checkFirstTimeLoaded();
if (discordHandler != null) {
plugin.extraDebug("Attempting to update DiscordSRV leaderboard");
discordHandler.updateDiscordLeaderboard();
}
plugin.getUserManager().getDataManager().clearNonNeededCachedUsers();
plugin.extraDebug("Current cached users: "
+ plugin.getUserManager().getDataManager().getUserDataCache().keySet().size());
@@ -1842,6 +1842,21 @@ public class CommandLoader {
}
});
plugin.getAdminVoteCommand()
.add(new CommandHandler(plugin, new String[] { "ClearDiscordMessageID", "(topvoter)" },
"VotingPlugin.Commands.AdminVote.ClearDiscordMessageID",
"Clear discord message ID for top voter", true, true) {
@Override
public void execute(CommandSender sender, String[] args) {
String topVoter = args[1];
TopVoter top = TopVoter.getTopVoter(topVoter);
plugin.getServerData().setTopVoterMessageId(top, 0);
plugin.getDiscordHandler().getTopVoterMessageIds().put(top, 0L);
sendMessage(sender, "&cCleared discord message ID for " + top.toString());
}
});
plugin.getAdminVoteCommand().add(new CommandHandler(plugin, new String[] {},
"VotingPlugin.Commands.AdminVote|" + adminPerm, "Base command") {
@@ -186,8 +186,26 @@ public class VoteURL extends GUIHandler {
@Override
public void onChest(Player player) {
// normal GUI
BInventory inv = new BInventory(plugin.getGui().getChestVoteURLName());
if (!plugin.getConfigFile().isAlwaysCloseInventory()) {
inv.dontClose();
}
for (final String str : plugin.getGui().getChestVoteURLExtraItems()) {
inv.addButton(new BInventoryButton(new ItemBuilder(plugin.getGui().getChestVoteURLExtraItemsItem(str))) {
@Override
public void onClick(ClickEvent clickEvent) {
new RewardBuilder(plugin.getGui().getData(),
"CHEST.VoteURL.ExtraItems." + str + "." + clickEvent.getButton().getLastRewardsPath(player))
.setGiveOffline(false).send(clickEvent.getPlayer());
}
});
}
if (plugin.getGui().isChestVoteURLViewAllUrlsButtonEnabled()) {
ItemBuilder builderAll = getItemAll();
@@ -195,6 +213,7 @@ public class VoteURL extends GUIHandler {
@Override
public void onClick(ClickEvent event) {
event.closeInventory();
VotingPluginUser user = plugin.getVotingPluginUserManager().getVotingPluginUser(event.getPlayer());
json = true;
if (event.getClick().equals(ClickType.SHIFT_LEFT)
@@ -218,6 +237,15 @@ public class VoteURL extends GUIHandler {
if (voteSite.getPermissionToView().isEmpty() || player.hasPermission(voteSite.getPermissionToView())) {
ItemBuilder builder = getItemVoteSite(voteSite);
if (startSlot >= 0) {
if (inv.isSlotTaken(startSlot)) {
boolean found = false;
while (!found) {
startSlot++;
if (!inv.isSlotTaken(startSlot)) {
found = true;
}
}
}
builder.setSlot(startSlot);
startSlot++;
}
@@ -226,6 +254,7 @@ public class VoteURL extends GUIHandler {
@Override
public void onClick(ClickEvent event) {
event.closeInventory();
Player player = event.getPlayer();
if (player != null) {
VotingPluginUser user = plugin.getVotingPluginUserManager().getVotingPluginUser(player);
@@ -252,21 +281,6 @@ public class VoteURL extends GUIHandler {
}
}
for (
final String str : plugin.getGui().getChestVoteURLExtraItems()) {
inv.addButton(new BInventoryButton(new ItemBuilder(plugin.getGui().getChestVoteURLExtraItemsItem(str))) {
@Override
public void onClick(ClickEvent clickEvent) {
new RewardBuilder(plugin.getGui().getData(),
"CHEST.VoteURL.ExtraItems." + str + "." + clickEvent.getButton().getLastRewardsPath(player))
.setGiveOffline(false).send(clickEvent.getPlayer());
}
});
}
if (plugin.getGui().isChestVoteURLBackButton()) {
inv.addButton(plugin.getCommandLoader().getBackButton(user));
}
@@ -14,6 +14,7 @@ import com.bencodez.simpleapi.file.annotation.ConfigDataBoolean;
import com.bencodez.simpleapi.file.annotation.ConfigDataInt;
import com.bencodez.simpleapi.file.annotation.ConfigDataKeys;
import com.bencodez.simpleapi.file.annotation.ConfigDataListString;
import com.bencodez.simpleapi.file.annotation.ConfigDataLong;
import com.bencodez.simpleapi.file.annotation.ConfigDataString;
import com.bencodez.votingplugin.VotingPluginMain;
import com.bencodez.votingplugin.placeholders.PlaceholderCacheLevel;
@@ -67,6 +68,134 @@ public class Config extends YMLFile {
@Getter
private boolean preloadSkulls = false;
@ConfigDataBoolean(path = "DiscordSRV.Enabled")
@Getter
private boolean discordSRVEnabled = false;
@ConfigDataBoolean(path = "DiscordSRV.TopVoter.AllTime.Enabled")
@Getter
private boolean discordSRVTopVoterAllTimeEnabled = false;
@ConfigDataLong(path = "DiscordSRV.TopVoter.AllTime.Channel")
@Getter
private long discordSRVTopVoterAllTimeChannel = 0;
@ConfigDataString(path = "DiscordSRV.TopVoter.AllTime.Title")
@Getter
private String discordSRVTopVoterAllTimeTitle = "All Time Top Voters";
@ConfigDataString(path = "DiscordSRV.TopVoter.AllTime.RankDisplay")
@Getter
private String discordSRVTopVoterAllTimeRankDisplay = "%rank%: &6%player% - %votes% Votes";
@ConfigDataBoolean(path = "DiscordSRV.TopVoter.Monthly.Enabled")
@Getter
private boolean discordSRVTopVoterMonthlyEnabled = false;
@ConfigDataLong(path = "DiscordSRV.TopVoter.Monthly.Channel")
@Getter
private long discordSRVTopVoterMonthlyChannel = 0;
@ConfigDataString(path = "DiscordSRV.TopVoter.Monthly.Title")
@Getter
private String discordSRVTopVoterMonthlyTitle = "Top Voters of the Month";
@ConfigDataString(path = "DiscordSRV.TopVoter.Monthly.RankDisplay")
@Getter
private String discordSRVTopVoterMonthlyRankDisplay = "%rank%: &6%player% - %votes% Votes";
@ConfigDataBoolean(path = "DiscordSRV.TopVoter.Weekly.Enabled")
@Getter
private boolean discordSRVTopVoterWeeklyEnabled = false;
@ConfigDataLong(path = "DiscordSRV.TopVoter.Weekly.Channel")
@Getter
private long discordSRVTopVoterWeeklyChannel = 0;
@ConfigDataString(path = "DiscordSRV.TopVoter.Weekly.Title")
@Getter
private String discordSRVTopVoterWeeklyTitle = "Top Voters of the Week";
@ConfigDataString(path = "DiscordSRV.TopVoter.Weekly.RankDisplay")
@Getter
private String discordSRVTopVoterWeeklyRankDisplay = "%rank%: &6%player% - %votes% Votes";
@ConfigDataBoolean(path = "DiscordSRV.TopVoter.Daily.Enabled")
@Getter
private boolean discordSRVTopVoterDailyEnabled = false;
@ConfigDataLong(path = "DiscordSRV.TopVoter.Daily.Channel")
@Getter
private long discordSRVTopVoterDailyChannel = 0;
@ConfigDataString(path = "DiscordSRV.TopVoter.Daily.Title")
@Getter
private String discordSRVTopVoterDailyTitle = "Top Voters of the Day";
@ConfigDataString(path = "DiscordSRV.TopVoter.Daily.RankDisplay")
@Getter
private String discordSRVTopVoterDailyRankDisplay = "%rank%: &6%player% - %votes% Votes";
public boolean isDiscordSRVTopVoterEnabled(TopVoter topVoter) {
switch (topVoter) {
case AllTime:
return isDiscordSRVTopVoterAllTimeEnabled();
case Monthly:
return isDiscordSRVTopVoterMonthlyEnabled();
case Weekly:
return isDiscordSRVTopVoterWeeklyEnabled();
case Daily:
return isDiscordSRVTopVoterDailyEnabled();
default:
return false;
}
}
public long getDiscordSRVTopVoterChannel(TopVoter topVoter) {
switch (topVoter) {
case AllTime:
return getDiscordSRVTopVoterAllTimeChannel();
case Monthly:
return getDiscordSRVTopVoterMonthlyChannel();
case Weekly:
return getDiscordSRVTopVoterWeeklyChannel();
case Daily:
return getDiscordSRVTopVoterDailyChannel();
default:
return 0;
}
}
public String getDiscordSRVTopVoterTitle(TopVoter topVoter) {
switch (topVoter) {
case AllTime:
return getDiscordSRVTopVoterAllTimeTitle();
case Monthly:
return getDiscordSRVTopVoterMonthlyTitle();
case Weekly:
return getDiscordSRVTopVoterWeeklyTitle();
case Daily:
return getDiscordSRVTopVoterDailyTitle();
default:
return "";
}
}
public String getDiscordSRVTopVoterRankDisplay(TopVoter topVoter) {
switch (topVoter) {
case AllTime:
return getDiscordSRVTopVoterAllTimeRankDisplay();
case Monthly:
return getDiscordSRVTopVoterMonthlyRankDisplay();
case Weekly:
return getDiscordSRVTopVoterWeeklyRankDisplay();
case Daily:
return getDiscordSRVTopVoterDailyRankDisplay();
default:
return "";
}
}
@ConfigDataBoolean(path = "AllowUnJoinedCheckServer")
@Getter
private boolean allowUnJoinedCheckServer = true;
@@ -16,6 +16,7 @@ import com.bencodez.simpleapi.array.ArrayUtils;
import com.bencodez.votingplugin.VotingPluginMain;
import com.bencodez.votingplugin.signs.SignHandler;
import com.bencodez.votingplugin.timequeue.VoteTimeQueue;
import com.bencodez.votingplugin.topvoter.TopVoter;
// TODO: Auto-generated Javadoc
/**
@@ -244,6 +245,15 @@ public class ServerData {
plugin.getServerDataFile().reloadData();
}
public long getTopVoterMessageId(TopVoter top) {
return getData().getLong("DiscordSRV.TopVoterMessageId." + top.toString(), 0);
}
public void setTopVoterMessageId(TopVoter top, long messageId) {
getData().set("DiscordSRV.TopVoterMessageId." + top.toString(), messageId);
saveData();
}
/**
* Removes the sign.
*
@@ -0,0 +1,146 @@
package com.bencodez.votingplugin.discord;
import java.awt.Color;
import java.time.Instant;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bukkit.configuration.ConfigurationSection;
import com.bencodez.advancedcore.api.messages.PlaceholderUtils;
import com.bencodez.advancedcore.api.rewards.Reward;
import com.bencodez.advancedcore.api.rewards.injected.RewardInjectConfigurationSection;
import com.bencodez.votingplugin.VotingPluginMain;
import com.bencodez.votingplugin.topvoter.TopVoter;
import com.bencodez.votingplugin.topvoter.TopVoterPlayer;
import github.scarsz.discordsrv.DiscordSRV;
import github.scarsz.discordsrv.api.Subscribe;
import github.scarsz.discordsrv.api.events.DiscordReadyEvent;
import github.scarsz.discordsrv.dependencies.jda.api.EmbedBuilder;
import github.scarsz.discordsrv.dependencies.jda.api.JDA;
import github.scarsz.discordsrv.dependencies.jda.api.entities.TextChannel;
import github.scarsz.discordsrv.util.DiscordUtil;
import lombok.Getter;
public class DiscordHandler {
private final VotingPluginMain plugin;
@Getter
private final HashMap<TopVoter, Long> topVoterMessageIds = new HashMap<TopVoter, Long>();
private final AtomicBoolean discordReady = new AtomicBoolean(false);
public DiscordHandler(VotingPluginMain plugin) {
this.plugin = plugin;
for (TopVoter top : TopVoter.values()) {
long savedId = plugin.getServerData().getTopVoterMessageId(top);
topVoterMessageIds.put(top, savedId);
}
}
/** Call this early, e.g. from onEnable() in main plugin class */
public void load() {
DiscordSRV.api.subscribe(this);
plugin.getLogger().info("DiscordHandler loaded; awaiting Discord readiness.");
// if DiscordSRV is already up and running, mark it ready now
if (DiscordUtil.getJda().getStatus() == JDA.Status.CONNECTED) {
discordReady.set(true);
plugin.getLogger().info("DiscordSRV was already ready; manual update now available.");
}
plugin.getRewardHandler().addInjectedReward(new RewardInjectConfigurationSection("DiscordSRV") {
@Override
public String onRewardRequested(Reward arg0, com.bencodez.advancedcore.api.user.AdvancedCoreUser user,
ConfigurationSection section, HashMap<String, String> placeholders) {
if (section.getBoolean("Enabled")) {
String msg = PlaceholderUtils
.replacePlaceHolder(section.getString("Message", "Please set a message"), placeholders);
msg = PlaceholderUtils.replacePlaceHolders(user.getOfflinePlayer(), msg);
sendRewardMessage(msg, section.getString("ChannelID", "0"));
}
return null;
}
});
}
/** Fired once JDA is fully initialized */
@Subscribe
public void onDiscordReady(DiscordReadyEvent event) {
discordReady.set(true);
plugin.getLogger().info("DiscordSRV is ready; manual update now available.");
}
/**
* Public method to update the Top Voter message on demand. Checks Discord
* readiness internally.
*/
public void updateDiscordLeaderboard() {
if (!discordReady.get()) {
plugin.getLogger().warning("DiscordSRV not ready yet; cannot update Top Voters.");
return;
}
for (TopVoter top : TopVoter.values()) {
if (plugin.getConfigFile().isDiscordSRVTopVoterEnabled(top)) {
plugin.debug("Updating Discord Top Voter: " + top.toString());
updateTopVoterMessageId(top);
}
}
}
public void updateTopVoterMessageId(TopVoter top) {
long channelId = plugin.getConfigFile().getDiscordSRVTopVoterChannel(top);
LinkedHashMap<TopVoterPlayer, Integer> topVoters = plugin.getTopVoter(top);
String title = plugin.getConfigFile().getDiscordSRVTopVoterTitle(top);
String rankDisplay = plugin.getConfigFile().getDiscordSRVTopVoterRankDisplay(top);
EmbedBuilder eb = new EmbedBuilder().setTitle(title).setColor(Color.CYAN).setTimestamp(Instant.now());
int rank = 1;
for (Entry<TopVoterPlayer, Integer> entry : topVoters.entrySet()) {
if (rank > 10)
break;
String line = rankDisplay.replace("%rank%", String.valueOf(rank))
.replace("%player%", entry.getKey().getPlayerName())
.replace("%votes%", String.valueOf(entry.getValue()));
eb.addField("", line, false);
rank++;
}
TextChannel channel = DiscordUtil.getJda().getTextChannelById(channelId);
if (channel == null) {
plugin.getLogger().warning("Discord channel ID " + channelId + " not found: " + top.toString());
return;
}
if (topVoterMessageIds.get(top) <= 0) {
channel.sendMessageEmbeds(eb.build()).queue(msg -> {
long newId = msg.getIdLong();
topVoterMessageIds.put(top, newId);
plugin.getServerData().setTopVoterMessageId(top, newId);
plugin.getLogger().info("Posted new Top Voters " + top.toString() + " (ID: " + newId + ")");
}, err -> plugin.getLogger()
.warning("Error sending Top Voters " + top.toString() + ": " + err.getMessage()));
} else {
channel.editMessageEmbedsById(topVoterMessageIds.get(top), eb.build())
.queue(m -> plugin.getLogger()
.info("Edited Top Voters " + top.toString() + " (ID: " + topVoterMessageIds.get(top) + ")"),
err -> plugin.getLogger()
.warning("Error editing Top Voters" + top.toString() + ": " + err.getMessage()));
}
}
public void sendRewardMessage(String message, String channelId) {
TextChannel channel = DiscordUtil.getJda().getTextChannelById(channelId);
if (channel != null) {
channel.sendMessage(message).queue();
} else {
plugin.getLogger().warning("Discord channel ID " + channelId + " not found for reward message.");
}
}
}
@@ -3,6 +3,7 @@ package com.bencodez.votingplugin.listeners;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -16,7 +17,6 @@ import com.bencodez.votingplugin.VotingPluginMain;
import com.bencodez.votingplugin.events.PlayerPostVoteEvent;
import com.bencodez.votingplugin.events.PlayerVoteEvent;
import com.bencodez.votingplugin.objects.VoteSite;
import com.bencodez.votingplugin.proxy.BungeeMethod;
import com.bencodez.votingplugin.topvoter.TopVoter;
import com.bencodez.votingplugin.user.VotingPluginUser;
@@ -127,6 +127,15 @@ public class PlayerVoteListener implements Listener {
// player online
user = plugin.getVotingPluginUserManager().getVotingPluginUser(p);
} else {
// attempt to get exact name from cache matching casing
if (!plugin.getOptions().isOnlineMode()) {
for (Entry<String, String> entry : plugin.getUuidNameCache().entrySet()) {
if (entry.getValue().equalsIgnoreCase(playerName)) {
playerName = entry.getValue();
break;
}
}
}
user = plugin.getVotingPluginUserManager().getVotingPluginUser(playerName);
}
}
@@ -258,21 +267,6 @@ public class PlayerVoteListener implements Listener {
plugin.getSpecialRewards().checkMilestone(user, event.getBungeeTextTotals(), event.isForceBungee());
plugin.getCoolDownCheck().vote(user, voteSite);
if (plugin.getBungeeSettings().isUseBungeecoord()) {
if (plugin.getBungeeHandler().getMethod().equals(BungeeMethod.MYSQL)) {
plugin.getBukkitScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
@Override
public void run() {
if (Bukkit.getOnlinePlayers().size() > 0) {
plugin.getBungeeHandler().getGlobalMessageHandler().sendMessage("VoteUpdate", uuid);
}
}
}, 2);
}
}
PlayerPostVoteEvent postVoteEvent = new PlayerPostVoteEvent(voteSite, user, event.isRealVote(),
event.isForceBungee(), voteTime);
plugin.getServer().getPluginManager().callEvent(postVoteEvent);
@@ -16,7 +16,6 @@ import com.bencodez.advancedcore.api.rewards.RewardBuilder;
import com.bencodez.simpleapi.array.ArrayUtils;
import com.bencodez.simpleapi.messages.MessageAPI;
import com.bencodez.votingplugin.VotingPluginMain;
import com.bencodez.votingplugin.proxy.BungeeMethod;
import com.bencodez.votingplugin.user.VotingPluginUser;
import lombok.Getter;
@@ -118,17 +117,9 @@ public class VoteSite {
}
if (checkBungee && plugin.getBungeeSettings().isBungeeBroadcast()
&& plugin.getBungeeSettings().isUseBungeecoord()) {
if (plugin.getBungeeHandler().getMethod().equals(BungeeMethod.SOCKETS)) {
plugin.getBungeeHandler().sendData("Broadcast", getServiceSite(), user.getPlayerName());
} else if (plugin.getBungeeHandler().getMethod().equals(BungeeMethod.MYSQL)
|| plugin.getBungeeHandler().getMethod().equals(BungeeMethod.PLUGINMESSAGING)) {
String uuid = user.getUUID();
String service = getServiceSite();
if (Bukkit.getOnlinePlayers().size() > 0) {
plugin.getPluginMessaging().sendPluginMessage("VoteBroadcast", uuid, service);
}
}
String uuid = user.getUUID();
String service = getServiceSite();
plugin.getBungeeHandler().getGlobalMessageHandler().sendMessage("VoteBroadcast", uuid, service);
} else {
String bc = MessageAPI.colorize(plugin.getConfigFile().getFormatBroadCastMsg());
@@ -4,7 +4,7 @@ public enum BungeeMethod {
MYSQL, PLUGINMESSAGING, SOCKETS, REDIS, MQTT;
public boolean requiresPlayerOnline() {
return this == MYSQL || this == PLUGINMESSAGING;
return this == PLUGINMESSAGING;
}
public static BungeeMethod getByName(String str) {
@@ -1,6 +1,7 @@
package com.bencodez.votingplugin.proxy;
import lombok.Getter;
import lombok.Setter;
public class OfflineBungeeVote {
@@ -11,6 +12,7 @@ public class OfflineBungeeVote {
@Getter
private String service;
@Getter
@Setter
private String text;
@Getter
private long time;
@@ -9,6 +9,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
@@ -23,6 +25,9 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import org.eclipse.paho.client.mqttv3.MqttException;
@@ -37,6 +42,7 @@ import com.bencodez.simpleapi.servercomm.global.GlobalMessageProxyHandler;
import com.bencodez.simpleapi.servercomm.mqtt.MqttHandler;
import com.bencodez.simpleapi.servercomm.mqtt.MqttHandler.MessageHandler;
import com.bencodez.simpleapi.servercomm.mqtt.MqttServerComm;
import com.bencodez.simpleapi.servercomm.mysql.ProxyMessenger;
import com.bencodez.simpleapi.servercomm.redis.RedisHandler;
import com.bencodez.simpleapi.servercomm.redis.RedisListener;
import com.bencodez.simpleapi.servercomm.sockets.ClientHandler;
@@ -121,6 +127,35 @@ public abstract class VotingPluginProxy {
@Getter
private GlobalMessageProxyHandler globalMessageProxyHandler;
@Getter
private ProxyMessenger proxyMysqlMessenger;
public void resetMilestoneCountInVotes() {
// Iterate through cached online votes
for (Map.Entry<String, ArrayList<OfflineBungeeVote>> entry : cachedOnlineVotes.entrySet()) {
ArrayList<OfflineBungeeVote> votes = entry.getValue();
for (OfflineBungeeVote vote : votes) {
String updatedText = updateMilestoneCount(vote.getText());
vote.setText(updatedText);
}
}
// Iterate through cached votes
for (Map.Entry<String, ArrayList<OfflineBungeeVote>> entry : cachedVotes.entrySet()) {
ArrayList<OfflineBungeeVote> votes = entry.getValue();
for (OfflineBungeeVote vote : votes) {
String updatedText = updateMilestoneCount(vote.getText());
vote.setText(updatedText);
}
}
}
private String updateMilestoneCount(String text) {
BungeeMessageData data = new BungeeMessageData(text);
data.setMilestoneCount(0); // Reset milestone count to 0
return data.toString();
}
public VotingPluginProxy() {
enabled = true;
@@ -193,6 +228,11 @@ public abstract class VotingPluginProxy {
@Override
public void timeChanged(TimeType type, boolean fake, boolean pre, boolean post) {
if (type.equals(TimeType.MONTH) && getConfig().getResetMilestonesMonthly()) {
debug("Resetting milestones for month change");
resetMilestoneCountInVotes();
}
if (getConfig().getVoteCacheTime() > 0) {
checkVoteCacheTime();
}
@@ -200,6 +240,7 @@ public abstract class VotingPluginProxy {
warn("Global data not enabled, ignoring time change event");
return;
}
int delay = 1;
for (String s : getAllAvailableServers()) {
if (getGlobalDataHandler().getGlobalMysql().containsKey(s)) {
String lastOnlineStr = getGlobalDataHandler().getString(s, "LastOnline");
@@ -219,11 +260,8 @@ public abstract class VotingPluginProxy {
dataToSet.put("FinishedProcessing", new DataValueBoolean(false));
dataToSet.put(type.toString(), new DataValueBoolean(true));
getGlobalDataHandler().setData(s, dataToSet);
if (method.equals(BungeeMethod.PLUGINMESSAGING)) {
sendPluginMessageServer(s, "BungeeTimeChange", "");
} else if (method.equals(BungeeMethod.SOCKETS)) {
sendServerMessage(s, "BungeeTimeChange");
}
globalMessageProxyHandler.sendMessage(s, delay, "BungeeTimeChange", "");
delay++;
} else {
warn("Server " + s + " hasn't been online recently");
}
@@ -262,6 +300,7 @@ public abstract class VotingPluginProxy {
public abstract void broadcast(String message);
public synchronized void checkCachedVotes(String server) {
int delay = 1;
if (isServerValid(server)) {
if (isSomeoneOnlineServer(server)) {
if (cachedVotes.containsKey(server) && !getConfig().getBlockedServers().contains(server)) {
@@ -282,12 +321,13 @@ public abstract class VotingPluginProxy {
}
if (toSend) {
globalMessageProxyHandler.sendMessage(server, "Vote", cache.getPlayerName(),
globalMessageProxyHandler.sendMessage(server, delay, "Vote", cache.getPlayerName(),
cache.getUuid(), cache.getService(), "" + cache.getTime(),
Boolean.FALSE.toString(), "" + cache.isRealVote(), cache.getText(),
"" + getConfig().getBungeeManageTotals(),
"" + BungeeVersion.getPluginMessageVersion(), "" + getConfig().getBroadcast(),
"" + num, "" + numberOfVotes);
delay++;
num++;
} else {
debug("Not sending vote because user isn't on server " + server + ": "
@@ -304,6 +344,7 @@ public abstract class VotingPluginProxy {
}
public synchronized void checkOnlineVotes(String player, String uuid, String server) {
int delay = 1;
if (isPlayerOnline(player) && cachedOnlineVotes.containsKey(uuid)) {
ArrayList<OfflineBungeeVote> c = cachedOnlineVotes.get(uuid);
if (!c.isEmpty()) {
@@ -314,11 +355,12 @@ public abstract class VotingPluginProxy {
int num = 1;
int numberOfVotes = c.size();
for (OfflineBungeeVote cache : c) {
globalMessageProxyHandler.sendMessage(server, "VoteOnline", cache.getPlayerName(),
globalMessageProxyHandler.sendMessage(server, delay, "VoteOnline", cache.getPlayerName(),
cache.getUuid(), cache.getService(), "" + cache.getTime(), Boolean.FALSE.toString(),
"" + cache.isRealVote(), cache.getText(), "" + getConfig().getBungeeManageTotals(),
"" + BungeeVersion.getPluginMessageVersion(), "" + getConfig().getBroadcast(), "" + num,
"" + numberOfVotes);
delay++;
num++;
}
cachedOnlineVotes.put(uuid, new ArrayList<>());
@@ -492,7 +534,22 @@ public abstract class VotingPluginProxy {
method = BungeeMethod.PLUGINMESSAGING;
}
if (method.equals(BungeeMethod.PLUGINMESSAGING)) {
if (method.equals(BungeeMethod.MYSQL)) {
try {
proxyMysqlMessenger = new ProxyMessenger("VotingPlugin",
getProxyMySQL().getMysql().getConnectionManager().getDataSource(), msg -> {
debug("Got from " + msg.sourceServerId + ": " + msg.payload);
String[] data = msg.payload.split(Pattern.quote("%l%"));
globalMessageProxyHandler.onMessage(data[0], ArrayUtils.convertAndRemoveFirst(data));
});
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (method.equals(BungeeMethod.PLUGINMESSAGING)) {
if (getConfig().getPluginMessageEncryption()) {
encryptionHandler = new EncryptionHandler("VotingPlugin",
new File(getDataFolderPlugin(), "secretkey.key"));
@@ -592,23 +649,31 @@ public abstract class VotingPluginProxy {
}
}
currentVotePartyVotesRequired = getConfig().getVotePartyVotesRequired()
+ getVoteCacheVotePartyIncreaseVotesRequired();
currentVotePartyVotesRequired =
getConfig().getVotePartyVotesRequired() + getVoteCacheVotePartyIncreaseVotesRequired();
votePartyVotes = getVoteCacheCurrentVotePartyVotes();
globalMessageProxyHandler = new GlobalMessageProxyHandler() {
@Override
public void sendMessage(String server, String channel, String... messageData) {
public void sendMessage(String server, int delay, String channel, String... messageData) {
switch (method) {
case MQTT:
sendMqttMessageServer(server, channel, messageData);
break;
case MYSQL:
sendPluginMessageServer(server, channel, messageData);
// sendPluginMessageServer(server, channel, messageData);
try {
proxyMysqlMessenger.sendToBackend(server, channel + "%l%" + String.join("%l%", messageData));
} catch (SQLException e) {
e.printStackTrace();
}
break;
case PLUGINMESSAGING:
sendPluginMessageServer(server, channel, messageData);
sendPluginMessageServer(server, delay, channel, messageData);
break;
case REDIS:
sendRedisMessageServer(server, channel, messageData);
@@ -659,8 +724,10 @@ public abstract class VotingPluginProxy {
@Override
public void onReceive(ArrayList<String> message) {
int delay = 1;
for (String send : getAllAvailableServers()) {
globalMessageProxyHandler.sendMessage(send, "VoteUpdate", ArrayUtils.convert(message));
globalMessageProxyHandler.sendMessage(send, delay, "VoteUpdate", ArrayUtils.convert(message));
delay++;
}
}
});
@@ -831,6 +898,10 @@ public abstract class VotingPluginProxy {
public void onDisable() {
if (getProxyMysqlMessenger() != null) {
getProxyMysqlMessenger().shutdown();
}
if (getProxyMySQL() != null) {
getProxyMySQL().shutdown();
}
@@ -838,6 +909,20 @@ public abstract class VotingPluginProxy {
multiProxyHandler.close();
}
if (socketHandler != null) {
socketHandler.closeConnection();
}
if (redisHandler != null) {
redisHandler.close();
}
bungeeTimeChecker.shutdown();
if (getGlobalDataHandler() != null) {
getGlobalDataHandler().shutdown();
}
enabled = false;
}
@@ -934,36 +1019,43 @@ public abstract class VotingPluginProxy {
public abstract void sendPluginMessageData(String server, String channel, byte[] data, boolean queue);
public void sendPluginMessageServer(String server, String channel, String... messageData) {
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(byteOutStream);
try {
if (getConfig().getPluginMessageEncryption() && encryptionHandler != null) {
out.writeUTF(encryptionHandler.encrypt(channel));
} else {
out.writeUTF(channel);
}
out.writeInt(messageData.length);
public void sendPluginMessageServer(String server, int delay, String channel, String... messageData) {
getScheduler().schedule(new Runnable() {
String data = "";
for (String message : messageData) {
data += message + "/a/";
@Override
public void run() {
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(byteOutStream);
try {
if (getConfig().getPluginMessageEncryption() && encryptionHandler != null) {
out.writeUTF(encryptionHandler.encrypt(channel));
} else {
out.writeUTF(channel);
}
out.writeInt(messageData.length);
String data = "";
for (String message : messageData) {
data += message + "/a/";
}
if (getConfig().getPluginMessageEncryption() && encryptionHandler != null) {
out.writeUTF(encryptionHandler.encrypt(data));
} else {
out.writeUTF(data);
}
if (isSomeoneOnlineServer(server)) {
sendPluginMessageData(server, getConfig().getPluginMessageChannel().toLowerCase(),
byteOutStream.toByteArray(), false);
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
debug("Sending plugin message " + server + " " + channel + " "
+ ArrayUtils.makeStringList(ArrayUtils.convert(messageData)));
}
if (getConfig().getPluginMessageEncryption() && encryptionHandler != null) {
out.writeUTF(encryptionHandler.encrypt(data));
} else {
out.writeUTF(data);
}
if (isSomeoneOnlineServer(server)) {
sendPluginMessageData(server, getConfig().getPluginMessageChannel().toLowerCase(),
byteOutStream.toByteArray(), false);
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
debug("Sending plugin message " + server + " " + channel + " "
+ ArrayUtils.makeStringList(ArrayUtils.convert(messageData)));
}, delay * 5, TimeUnit.MILLISECONDS);
}
public void sendRedisMessageServer(String server, String channel, String... messageData) {
@@ -1000,7 +1092,7 @@ public abstract class VotingPluginProxy {
public void sendServerNameMessage() {
if (method.equals(BungeeMethod.PLUGINMESSAGING)) {
for (String s : getAllAvailableServers()) {
sendPluginMessageServer(s, "ServerName", s);
sendPluginMessageServer(s, 1, "ServerName", s);
}
}
@@ -1008,7 +1100,7 @@ public abstract class VotingPluginProxy {
public void sendVoteParty(String server) {
if (isSomeoneOnlineServer(server)) {
globalMessageProxyHandler.sendMessage(server, "VotePartyBungee", "");
globalMessageProxyHandler.sendMessage(server, 1, "VotePartyBungee", "");
}
}
@@ -1039,11 +1131,113 @@ public abstract class VotingPluginProxy {
} else {
// send
log("Sending request for status message on " + s);
globalMessageProxyHandler.sendMessage(s, "Status", s);
globalMessageProxyHandler.sendMessage(s, 1, "Status", s);
}
}
}
public String getWaitUntilDelaySiteFromService(String service) {
for (String site : getConfig().getWaitUntilVoteDelaySites()) {
if (getConfig().getWaitUntilVoteDelayService(site).equalsIgnoreCase(service)) {
return site;
}
}
return "";
}
private long getLastVotesTime(String uuid, ArrayList<Column> cols, String site, String service) {
long mostRecentTime = 0;
// Check cached online votes
if (cachedOnlineVotes.containsKey(uuid)) {
ArrayList<OfflineBungeeVote> onlineVotes = cachedOnlineVotes.get(uuid);
for (OfflineBungeeVote vote : onlineVotes) {
if (vote.getService().equalsIgnoreCase(service)) {
mostRecentTime = Math.max(mostRecentTime, vote.getTime());
}
}
}
// Check cached votes
for (ArrayList<OfflineBungeeVote> votes : cachedVotes.values()) {
for (OfflineBungeeVote vote : votes) {
if (vote.getUuid().equals(uuid) && vote.getService().equalsIgnoreCase(service)) {
mostRecentTime = Math.max(mostRecentTime, vote.getTime());
}
}
}
for (Column d : cols) {
if (d.getName().equalsIgnoreCase("LastVotes")) {
DataValue value = d.getValue();
String[] list = value.getString().split("%line%");
for (String str : list) {
String[] data = str.split("//");
if (data[0].equalsIgnoreCase(site)) {
mostRecentTime = Math.max(mostRecentTime, Long.valueOf(data[1]));
}
}
}
}
return mostRecentTime;
}
public boolean checkVoteDelay(String uuid, String service, ArrayList<Column> data) {
String site = getWaitUntilDelaySiteFromService(service);
if (site.isEmpty()) {
debug("No service site set for " + service + ", skipping vote delay check");
return true;
}
int voteDelay = getConfig().getWaitUntilVoteDelayVoteDelay(site);
int voteDelayMin = getConfig().getWaitUntilVoteDelayVoteDelayMin(site);
long lastVote = getLastVotesTime(uuid, data, site, service);
if (lastVote == 0) {
debug("No last vote time found for " + uuid + "/" + service + ", skipping vote delay check");
return true;
}
try {
LocalDateTime now = getBungeeTimeChecker().getTime();
LocalDateTime lastVoteTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastVote), ZoneId.systemDefault())
.plusHours(getConfig().getTimeHourOffSet());
if (!getConfig().getWaitUntilVoteDelayVoteDelayDaily(site)) {
if (voteDelay == 0 && voteDelayMin == 0) {
debug("Vote delay is 0 for " + site + ", skipping vote delay check");
return true;
}
LocalDateTime nextvote = lastVoteTime.plusHours((long) voteDelay).plusMinutes((long) voteDelayMin);
return now.isAfter(nextvote);
}
LocalDateTime resetTime = lastVoteTime.withHour(getConfig().getWaitUntilVoteDelayVoteDelayHour(site))
.withMinute(0).withSecond(0);
LocalDateTime resetTimeTomorrow = resetTime.plusHours(24);
if (lastVoteTime.isBefore(resetTime)) {
if (now.isAfter(resetTime)) {
debug("Vote delay is met for " + uuid + "/" + service + ", vote can be processed");
return true;
}
} else {
if (now.isAfter(resetTimeTomorrow)) {
debug("Vote delay is met for " + uuid + "/" + service + ", vote can be processed");
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
debug("Vote delay is not met for " + uuid + "/" + service + ", skipping vote");
return false;
}
public synchronized void vote(String player, String service, boolean realVote, boolean timeQueue, long queueTime,
BungeeMessageData text, String uuid) {
try {
@@ -1127,6 +1321,11 @@ public abstract class VotingPluginProxy {
ArrayList<Column> data = getProxyMySQL()
.getExactQuery(new Column("uuid", new DataValueString(uuid)));
if (!checkVoteDelay(uuid, service, data)) {
log("Vote delay is not met for " + player + "/" + service + ", skipping vote");
return;
}
int allTimeTotal = getValue(data, "AllTimeTotal", 1);
int monthTotal = getValue(data, "MonthTotal", 1);
int dateMonthTotal = -1;
@@ -1188,8 +1387,7 @@ public abstract class VotingPluginProxy {
debug("Forcing vote to cache");
}
if (getConfig().getBroadcast()) {
globalMessageProxyHandler.sendMessage(s, "VoteBroadcast", uuid, player, service);
globalMessageProxyHandler.sendMessage(s, 1, "VoteBroadcast", uuid, player, service);
}
if ((!isSomeoneOnlineServer(s) && method.requiresPlayerOnline()) || forceCache) {
// cache
@@ -1204,7 +1402,7 @@ public abstract class VotingPluginProxy {
} else {
// send
globalMessageProxyHandler.sendMessage(s, "Vote", player, uuid, service, "" + time,
globalMessageProxyHandler.sendMessage(s, 2, "Vote", player, uuid, service, "" + time,
Boolean.TRUE.toString(), "" + realVote, text.toString(),
"" + getConfig().getBungeeManageTotals(), "" + BungeeVersion.getPluginMessageVersion(),
"" + getConfig().getBroadcast(), "1", "1");
@@ -1213,7 +1411,7 @@ public abstract class VotingPluginProxy {
}
} else {
if (isPlayerOnline(player) && getAllAvailableServers().contains(getCurrentPlayerServer(player))) {
globalMessageProxyHandler.sendMessage(getCurrentPlayerServer(player), "VoteOnline", player, uuid,
globalMessageProxyHandler.sendMessage(getCurrentPlayerServer(player), 1, "VoteOnline", player, uuid,
service, "" + time, Boolean.TRUE.toString(), "" + realVote, text.toString(),
"" + getConfig().getBungeeManageTotals(), "" + BungeeVersion.getPluginMessageVersion(),
"" + getConfig().getBroadcast(), "1", "1");
@@ -1232,12 +1430,14 @@ public abstract class VotingPluginProxy {
cachedOnlineVotes.put(uuid, list);
debug("Caching online vote for " + player + " on " + service);
}
int delay = 2;
for (String s : getAllAvailableServers()) {
if (getConfig().getBroadcast()) {
globalMessageProxyHandler.sendMessage(s, "VoteBroadcast", uuid, player, service);
globalMessageProxyHandler.sendMessage(s, delay, "VoteBroadcast", uuid, player, service);
}
globalMessageProxyHandler.sendMessage(s, "VoteUpdate", uuid, "" + votePartyVotes,
"" + currentVotePartyVotesRequired, text.toString());
globalMessageProxyHandler.sendMessage(s, delay + 1, "VoteUpdate", uuid, "" + votePartyVotes,
"" + currentVotePartyVotesRequired, text.toString(), service, "" + time);
delay += 2;
}
}
@@ -1268,4 +1468,6 @@ public abstract class VotingPluginProxy {
}
public abstract void warn(String message);
public abstract ScheduledExecutorService getScheduler();
}
@@ -70,6 +70,7 @@ public class VotingPluginProxyCommand {
return "&aChecking status via sockets. Check console for details.";
case PLUGINMESSAGING:
case MYSQL:
case REDIS:
plugin.status();
plugin.sendServerNameMessage();
@@ -130,6 +130,20 @@ public interface VotingPluginProxyConfig {
public List<String> getWhiteListedServers();
public Collection<String> getWaitUntilVoteDelaySites();
public String getWaitUntilVoteDelayService(String site);
public int getWaitUntilVoteDelayVoteDelay(String site);
public int getWaitUntilVoteDelayVoteDelayMin(String site);
public boolean getResetMilestonesMonthly();
public int getWaitUntilVoteDelayVoteDelayHour(String site);
public boolean getWaitUntilVoteDelayVoteDelayDaily(String site);
public void load();
public void save();
@@ -300,7 +300,7 @@ public class Config implements VotingPluginProxyConfig {
@Override
public boolean getWaitForUserOnline() {
return getData().getBoolean("WaitForUserOnline", false);
return getData().getBoolean("WaitForUserOnline", true);
}
@Override
@@ -374,4 +374,39 @@ public class Config implements VotingPluginProxyConfig {
return getData().getBoolean("PluginMessageEncryption", false);
}
@Override
public Collection<String> getWaitUntilVoteDelaySites() {
return getData().getSection("WaitUntilVoteDelay").getKeys();
}
@Override
public String getWaitUntilVoteDelayService(String site) {
return getData().getString("WaitUntilVoteDelay." + site + ".ServiceSite", "");
}
@Override
public int getWaitUntilVoteDelayVoteDelay(String site) {
return getData().getInt("WaitUntilVoteDelay." + site + ".VoteDelay", 24);
}
@Override
public boolean getWaitUntilVoteDelayVoteDelayDaily(String site) {
return getData().getBoolean("WaitUntilVoteDelay." + site + ".VoteDelayDaily", false);
}
@Override
public int getWaitUntilVoteDelayVoteDelayHour(String site) {
return getData().getInt("WaitUntilVoteDelay." + site + ".VoteDelayDailyHour", 0);
}
@Override
public int getWaitUntilVoteDelayVoteDelayMin(String site) {
return getData().getInt("WaitUntilVoteDelay." + site + ".VoteDelayMin", 0);
}
@Override
public boolean getResetMilestonesMonthly() {
return getData().getBoolean("ResetMilestonesMonthly", false);
}
}
@@ -15,6 +15,8 @@ import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -63,6 +65,9 @@ public class VotingPluginBungee extends Plugin implements Listener {
@Getter
private VotingPluginProxy votingPluginProxy;
@Getter
private ScheduledExecutorService timer;
public void debug(String msg) {
if (config.getDebug()) {
getLogger().info("Debug: " + msg);
@@ -224,11 +229,8 @@ public class VotingPluginBungee extends Plugin implements Listener {
}
for (String s : getAvailableAllServers()) {
getVotingPluginProxy().getGlobalDataHandler().setBoolean(s, "ForceUpdate", true);
if (getVotingPluginProxy().getMethod().equals(BungeeMethod.PLUGINMESSAGING)) {
getVotingPluginProxy().sendPluginMessageServer(s, "BungeeTimeChange", "");
} else if (getVotingPluginProxy().getMethod().equals(BungeeMethod.SOCKETS)) {
getVotingPluginProxy().sendServerMessage(s, "BungeeTimeChange");
}
getVotingPluginProxy().getGlobalMessageProxyHandler().sendMessage(s, 1, "BungeeTimeChange",
"");
}
getVotingPluginProxy().processQueue();
@@ -292,11 +294,8 @@ public class VotingPluginBungee extends Plugin implements Listener {
}
for (String s : getAvailableAllServers()) {
getVotingPluginProxy().getGlobalDataHandler().setBoolean(s, "ForceUpdate", true);
if (getVotingPluginProxy().getMethod().equals(BungeeMethod.PLUGINMESSAGING)) {
getVotingPluginProxy().sendPluginMessageServer(s, "BungeeTimeChange", "");
} else if (getVotingPluginProxy().getMethod().equals(BungeeMethod.SOCKETS)) {
getVotingPluginProxy().sendServerMessage(s, "BungeeTimeChange");
}
getVotingPluginProxy().getGlobalMessageProxyHandler().sendMessage(s, 1,
"BungeeTimeChange", "");
}
getVotingPluginProxy().processQueue();
@@ -413,6 +412,8 @@ public class VotingPluginBungee extends Plugin implements Listener {
voteCacheFile.save();
nonVotedPlayersCache.save();
timer.shutdownNow();
getLogger().info("VotingPlugin disabled");
}
@@ -420,6 +421,8 @@ public class VotingPluginBungee extends Plugin implements Listener {
@Override
public void onEnable() {
timer = Executors.newScheduledThreadPool(1);
getProxy().getPluginManager().registerListener(this, this);
config = new Config(this);
@@ -473,6 +476,11 @@ public class VotingPluginBungee extends Plugin implements Listener {
public String getUUID(String playerName) {
if (!config.getOnlineMode()) {
// correct casing
ProxiedPlayer p = getProxy().getPlayer(playerName);
if (p != null && p.isConnected()) {
playerName = p.getName();
}
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + playerName).getBytes(StandardCharsets.UTF_8))
.toString();
}
@@ -638,6 +646,11 @@ public class VotingPluginBungee extends Plugin implements Listener {
reloadPlugin(mysql);
}
@Override
public ScheduledExecutorService getScheduler() {
return timer;
}
};
try {
Class.forName("com.vexsoftware.votifier.bungee.events.VotifierEvent");
@@ -2,6 +2,7 @@ package com.bencodez.votingplugin.proxy.velocity;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -330,7 +331,7 @@ public class Config extends VelocityYMLFile implements VotingPluginProxyConfig {
@Override
public boolean getWaitForUserOnline() {
return getBoolean(getNode("WaitForUserOnline"), false);
return getBoolean(getNode("WaitForUserOnline"), true);
}
@Override
@@ -364,4 +365,39 @@ public class Config extends VelocityYMLFile implements VotingPluginProxyConfig {
return getBoolean(getNode("PluginMessageEncryption"), false);
}
@Override
public Collection<String> getWaitUntilVoteDelaySites() {
return getChildrenAsList(getNode("WaitUntilVoteDelay"));
}
@Override
public String getWaitUntilVoteDelayService(String site) {
return getString(getNode("WaitUntilVoteDelay", site, "ServiceSite"), "");
}
@Override
public int getWaitUntilVoteDelayVoteDelay(String site) {
return getInt(getNode("WaitUntilVoteDelay", site, "VoteDelay"), 24);
}
@Override
public boolean getWaitUntilVoteDelayVoteDelayDaily(String site) {
return getBoolean(getNode("WaitUntilVoteDelay", site, "VoteDelayDaily"), false);
}
@Override
public int getWaitUntilVoteDelayVoteDelayHour(String site) {
return getInt(getNode("WaitUntilVoteDelay", site, "VoteDelayDailyHour"), 0);
}
@Override
public int getWaitUntilVoteDelayVoteDelayMin(String site) {
return getInt(getNode("WaitUntilVoteDelay", site, "VoteDelayMin"), 0);
}
@Override
public boolean getResetMilestonesMonthly() {
return getBoolean(getNode("ResetMilestonesMonthly"), false);
}
}
@@ -59,6 +59,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.scheduler.ScheduledTask;
import lombok.Getter;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@@ -276,11 +277,8 @@ public class VotingPluginVelocity {
}
for (String s : getAvailableAllServers()) {
getVotingPluginProxy().getGlobalDataHandler().setBoolean(s, "ForceUpdate", true);
if (getVotingPluginProxy().getMethod().equals(BungeeMethod.PLUGINMESSAGING)) {
getVotingPluginProxy().sendPluginMessageServer(s, "BungeeTimeChange", "");
} else if (getVotingPluginProxy().getMethod().equals(BungeeMethod.SOCKETS)) {
getVotingPluginProxy().sendServerMessage(s, "BungeeTimeChange");
}
getVotingPluginProxy().getGlobalMessageProxyHandler().sendMessage(s, 1, "BungeeTimeChange",
"");
}
getVotingPluginProxy().processQueue();
@@ -339,11 +337,8 @@ public class VotingPluginVelocity {
}
for (String s : getAvailableAllServers()) {
getVotingPluginProxy().getGlobalDataHandler().setBoolean(s, "ForceUpdate", true);
if (getVotingPluginProxy().getMethod().equals(BungeeMethod.PLUGINMESSAGING)) {
getVotingPluginProxy().sendPluginMessageServer(s, "BungeeTimeChange", "");
} else if (getVotingPluginProxy().getMethod().equals(BungeeMethod.SOCKETS)) {
getVotingPluginProxy().sendServerMessage(s, "BungeeTimeChange");
}
getVotingPluginProxy().getGlobalMessageProxyHandler().sendMessage(s, 1, "BungeeTimeChange",
"");
}
getVotingPluginProxy().processQueue();
@@ -451,17 +446,27 @@ public class VotingPluginVelocity {
num++;
}
}
getVotingPluginProxy().onDisable();
voteCacheFile.save();
nonVotedPlayersCache.save();
getVotingPluginProxy().onDisable();
if (voteCheckTask != null)
voteCheckTask.cancel();
if (cacheSaveTask != null)
cacheSaveTask.cancel();
timer.shutdownNow();
logger.info("VotingPlugin disabled");
}
@Getter
public VotingPluginProxy votingPluginProxy;
private ScheduledTask voteCheckTask;
private ScheduledTask cacheSaveTask;
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
File configFile = new File(dataDirectory.toFile(), "bungeeconfig.yml");
@@ -551,6 +556,18 @@ public class VotingPluginVelocity {
public String getUUID(String playerName) {
if (!config.getOnlineMode()) {
// correct case
if (server.getPlayer(playerName).isPresent()) {
Player p = server.getPlayer(playerName).get();
if (p != null && p.isActive()) {
playerName = p.getUsername();
}
}
for (Entry<UUID, String> entry : getVotingPluginProxy().getUuidPlayerNameCache().entrySet()) {
if (entry.getValue().equalsIgnoreCase(playerName)) {
playerName = entry.getValue();
}
}
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + playerName).getBytes(StandardCharsets.UTF_8))
.toString();
}
@@ -727,6 +744,11 @@ public class VotingPluginVelocity {
reloadPlugin(mysql);
}
@Override
public ScheduledExecutorService getScheduler() {
return timer;
}
};
try {
@@ -834,7 +856,7 @@ public class VotingPluginVelocity {
voteCacheFile.clearData();
server.getScheduler().buildTask(this, () -> {
voteCheckTask = server.getScheduler().buildTask(this, () -> {
if (getVotingPluginProxy().getGlobalDataHandler() == null
|| !getVotingPluginProxy().getGlobalDataHandler().isTimeChangedHappened()) {
for (String server : getVotingPluginProxy().getCachedVotes().keySet()) {
@@ -850,7 +872,7 @@ public class VotingPluginVelocity {
}
}).delay(120, TimeUnit.SECONDS).repeat(60, TimeUnit.SECONDS).schedule();
server.getScheduler().buildTask(this, () -> {
cacheSaveTask = server.getScheduler().buildTask(this, () -> {
if (nonVotedPlayersCache != null) {
debug("Checking nonvotedplayerscache.yml...");
nonVotedPlayersCache.check();
@@ -1826,6 +1826,12 @@ public class VotingPluginUser extends com.bencodez.advancedcore.api.user.Advance
*/
public void setTime(VoteSite voteSite, Long time) {
HashMap<VoteSite, Long> lastVotes = getLastVotes();
if (lastVotes != null && lastVotes.containsKey(voteSite)) {
if (lastVotes.get(voteSite).longValue() == time.longValue()) {
plugin.debug("Not setting last vote time for " + voteSite.getKey() + ", already set to " + time);
return;
}
}
lastVotes.put(voteSite, time);
setLastVotes(lastVotes);
}
@@ -614,6 +614,63 @@ StoreMonthTotalsWithDate: false
# This setting may be very buggy as it's in early stages
UseMonthDateTotalsAsPrimaryTotal: false
###########################################
# DiscordSRV settings
###########################################
DiscordSRV:
# Enable DiscordSRV support
# Also enables using rewards in discord
Enabled: false
# Show live top voter counts in discord
TopVoter:
AllTime:
# If true, will send top voter messages to discord
# Will send a message show top 10 voters
Enabled: false
# DiscordSRV channel to send messages to
Channel: 1234565 # Replace with your channel ID
Title: 'All Time Top Voters'
RankDisplay: '%rank%: &6%player% - %votes% Votes'
Monthly:
# If true, will send top voter messages to discord
# Will send a message show top 10 voters
Enabled: false
# DiscordSRV channel to send messages to
Channel: 1234565 # Replace with your channel ID
Title: 'Top Voters of the Month'
RankDisplay: '%rank%: &6%player% - %votes% Votes'
Weekly:
# If true, will send top voter messages to discord
# Will send a message show top 10 voters
Enabled: false
# DiscordSRV channel to send messages to
Channel: 1234565 # Replace with your channel ID
Title: 'Top Voters of the Week'
RankDisplay: '%rank%: &6%player% - %votes% Votes'
Daily:
# If true, will send top voter messages to discord
# Will send a message show top 10 voters
Enabled: false
# DiscordSRV channel to send messages to
Channel: 1234565 # Replace with your channel ID
Title: 'Top Voters of the Day'
RankDisplay: '%rank%: &6%player% - %votes% Votes'
###########################################
# Skull settings
###########################################
@@ -121,6 +121,7 @@ Redis:
# SOCKETS Settings
###########################################
# Settings hidden to avoid confusion, highly recommend other methods first
# Settings available here https://github.com/BenCodez/VotingPlugin/wiki/Bungee-Setup-SOCKETS
###########################################
@@ -139,8 +140,9 @@ MQTT:
######################################################################################
# Votes will be forwarded when specific player is online
# If set to false, rewards should still reward when player logs in (by default)
WaitForUserOnline: false
# If set to false, rewards should still reward when player logs in even when false
# but it can fail to reward, this setting has no effect if sendtoallservers is false
WaitForUserOnline: true
# If false, votes will be checked if user is a valid player that has joined to server
# Works for PLUGINMESSAGING and SOCKETS methods only
@@ -158,7 +160,7 @@ BungeeManageTotals: true
# Tell servers to broadcast
# Set DisableBroadcast to true on spigot servers (BungeeSettings.yml) as well
Broadcast: true
Broadcast: false
# Geyser/bedrock player settings
# https://github.com/BenCodez/VotingPlugin/wiki/Bedrock-Player-Support
@@ -208,6 +210,21 @@ OnlineMode: true
# If true plugin will atempt to lookup uuids if none exist
UUIDLookup: true
# Should be enabled if enabled on backend servers
ResetMilestonesMonthly: false
# If you use this plugin will ignore votes from these service sites for said amount of time
WaitUntilVoteDelay:
# sitename must match what's in VoteSites.yml on backend servers
SITENAME:
# Set service site here and vote delay
ServiceSite: SERVICESITE
VoteDelay: 24
VoteDelayMin: 0
# If true it resets based on the day isntead
VoteDelayDaily: false
VoteDelayDailyHour: 0
###########################################
# Month Date Totals
# Experimental feature
+1 -5
View File
@@ -18,6 +18,7 @@ softdepend:
- PremiumVanish
- LuckPerms
- nLogin
- DiscordSRV
loadbefore:
- MCPerks
api-version: 1.13
@@ -86,9 +87,6 @@ commands:
votechoices:
description: A command
alaises: vchoices
votegivepoints:
description: A command
alaises: vgivepoints
adminvotehelp:
description: Open adminvote help
aliases: avhelp
@@ -171,8 +169,6 @@ commands:
adminvoteresyncmilestonesalreadygiven:
description: Command Alias
aliases: avresyncmilestonesalreadygiven
votesetprimaryaccount:
description: Command Alias
adminvoteclearofflinevotes:
description: Command Alias
aliases: avclearofflinevotes
@@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import org.mockito.Mockito;
@@ -199,4 +200,9 @@ public class VotingPluginProxyTestImpl extends VotingPluginProxy {
// TODO Auto-generated method stub
}
@Override
public ScheduledExecutorService getScheduler() {
return null;
}
}