Skip to content

Commit dce31f1

Browse files
committed
Add configurable VoteReward source
1 parent c594150 commit dce31f1

File tree

2 files changed

+164
-16
lines changed

2 files changed

+164
-16
lines changed

src/main/java/nl/hauntedmc/serverfeatures/features/votereward/VoteReward.java

Lines changed: 102 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
import org.bukkit.Bukkit;
1515

1616
import java.util.List;
17+
import java.util.Locale;
1718

1819
public class VoteReward extends BukkitBaseFeature<Meta> {
1920

21+
private static final String VOTIFIER_FEATURE_NAME = "Votifier";
22+
2023
private CacheDirectory playerCacheDir;
2124
private VoteHandler voteHandler;
2225

@@ -28,6 +31,7 @@ public VoteReward(ServerFeatures plugin) {
2831
public ConfigMap getDefaultConfig() {
2932
ConfigMap defaults = new ConfigMap();
3033
defaults.put("enabled", false);
34+
defaults.put("vote_source", VoteSource.NATIVE.configValue());
3135
defaults.put("vote_whitelist", List.of("SERVERPACTTEST", "TopMinecraftServers", "SERVERPACT.NL", "minecraftkrant.nl", "Minecraft-MP.com"));
3236
defaults.put("rewards", List.of("eco give {player} 10"));
3337
defaults.put("join_message_delay", 100);
@@ -56,34 +60,56 @@ public void initialize() {
5660

5761
this.voteHandler = new VoteHandler(this);
5862

59-
boolean nativeVotifierAvailable = detectVotifierOnce();
60-
61-
if (nativeVotifierAvailable) {
62-
getLifecycleManager().getListenerManager().registerListener(new VotifierVoteListener(this));
63-
} else {
64-
getLifecycleManager().getListenerManager().registerListener(new NativeVoteListener(this));
65-
getLogger().info("Votifier not available or incompatible; using native vote events.");
63+
String configuredVoteSource = getConfigHandler().get("vote_source", String.class, VoteSource.NATIVE.configValue());
64+
ResolvedVoteSource voteSource = resolveVoteSource(configuredVoteSource);
65+
if (voteSource.invalidConfiguredValue()) {
66+
getLogger().warning("Unknown VoteReward vote_source \"" + voteSource.configuredValue()
67+
+ "\"; defaulting to \"" + VoteSource.NATIVE.configValue()
68+
+ "\". Allowed values: " + VoteSource.allowedValues() + ".");
6669
}
6770

71+
registerVoteListener(voteSource.source());
72+
6873
getLifecycleManager().getListenerManager().registerListener(
6974
new VoteJoinListener(this)
7075
);
7176
}
7277

73-
private boolean detectVotifierOnce() {
74-
if (!Bukkit.getPluginManager().isPluginEnabled("Votifier")) {
75-
return false;
78+
private void registerVoteListener(VoteSource voteSource) {
79+
switch (voteSource) {
80+
case VOTIFIER -> registerVotifierVoteListener();
81+
case NATIVE -> registerNativeVoteListener();
7682
}
83+
}
84+
85+
private void registerNativeVoteListener() {
86+
getLifecycleManager().getListenerManager().registerListener(new NativeVoteListener(this));
87+
getLogger().info("VoteReward listening for native vote events from ServerFeatures Votifier.");
88+
89+
String warning = unavailableSourceWarning(VoteSource.NATIVE, isNativeVoteFeatureEnabled(), isExternalVotifierPluginEnabled());
90+
if (warning != null) {
91+
getLogger().warning(warning);
92+
}
93+
}
94+
95+
private void registerVotifierVoteListener() {
96+
getLifecycleManager().getListenerManager().registerListener(new VotifierVoteListener(this));
97+
getLogger().info("VoteReward listening for Votifier plugin vote events.");
7798

78-
try {
79-
Class.forName("com.vexsoftware.votifier.model.Vote", false, getClass().getClassLoader());
80-
Class.forName("com.vexsoftware.votifier.model.VotifierEvent", false, getClass().getClassLoader());
81-
return true;
82-
} catch (Throwable t) {
83-
return false;
99+
String warning = unavailableSourceWarning(VoteSource.VOTIFIER, isNativeVoteFeatureEnabled(), isExternalVotifierPluginEnabled());
100+
if (warning != null) {
101+
getLogger().warning(warning);
84102
}
85103
}
86104

105+
private boolean isNativeVoteFeatureEnabled() {
106+
return getPlugin().getConfigHandler().isFeatureEnabled(VOTIFIER_FEATURE_NAME);
107+
}
108+
109+
private boolean isExternalVotifierPluginEnabled() {
110+
return Bukkit.getPluginManager().isPluginEnabled(VOTIFIER_FEATURE_NAME);
111+
}
112+
87113
@Override
88114
public void disable() {
89115
}
@@ -98,4 +124,64 @@ public CacheDirectory getPlayerCacheDir() {
98124
public VoteHandler getVoteHandler() {
99125
return voteHandler;
100126
}
127+
128+
static ResolvedVoteSource resolveVoteSource(String configuredSource) {
129+
if (configuredSource == null) {
130+
return new ResolvedVoteSource(VoteSource.NATIVE, false, null);
131+
}
132+
133+
String normalized = configuredSource.trim().toLowerCase(Locale.ROOT);
134+
if (normalized.isEmpty()) {
135+
return new ResolvedVoteSource(VoteSource.NATIVE, false, "");
136+
}
137+
138+
for (VoteSource source : VoteSource.values()) {
139+
if (source.configValue().equals(normalized)) {
140+
return new ResolvedVoteSource(source, false, normalized);
141+
}
142+
}
143+
144+
return new ResolvedVoteSource(VoteSource.NATIVE, true, normalized);
145+
}
146+
147+
static String unavailableSourceWarning(
148+
VoteSource voteSource,
149+
boolean nativeVoteFeatureEnabled,
150+
boolean externalVotifierPluginEnabled
151+
) {
152+
return switch (voteSource) {
153+
case NATIVE -> nativeVoteFeatureEnabled
154+
? null
155+
: "VoteReward vote_source is \"" + VoteSource.NATIVE.configValue()
156+
+ "\", but the ServerFeatures Votifier feature is not enabled. "
157+
+ "VoteReward will not receive native vote events until that feature is enabled.";
158+
case VOTIFIER -> externalVotifierPluginEnabled
159+
? null
160+
: "VoteReward vote_source is \"" + VoteSource.VOTIFIER.configValue()
161+
+ "\", but the Votifier plugin is not enabled. "
162+
+ "VoteReward will not receive Votifier events until that plugin is enabled.";
163+
};
164+
}
165+
166+
enum VoteSource {
167+
NATIVE("native"),
168+
VOTIFIER("votifier");
169+
170+
private final String configValue;
171+
172+
VoteSource(String configValue) {
173+
this.configValue = configValue;
174+
}
175+
176+
String configValue() {
177+
return configValue;
178+
}
179+
180+
static String allowedValues() {
181+
return NATIVE.configValue + ", " + VOTIFIER.configValue;
182+
}
183+
}
184+
185+
record ResolvedVoteSource(VoteSource source, boolean invalidConfiguredValue, String configuredValue) {
186+
}
101187
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package nl.hauntedmc.serverfeatures.features.votereward;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
import static org.junit.jupiter.api.Assertions.assertFalse;
7+
import static org.junit.jupiter.api.Assertions.assertNull;
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
9+
10+
class VoteRewardTest {
11+
12+
@Test
13+
void resolveVoteSourceDefaultsToNativeWhenMissing() {
14+
VoteReward.ResolvedVoteSource fromNull = VoteReward.resolveVoteSource(null);
15+
VoteReward.ResolvedVoteSource fromBlank = VoteReward.resolveVoteSource(" ");
16+
17+
assertEquals(VoteReward.VoteSource.NATIVE, fromNull.source());
18+
assertFalse(fromNull.invalidConfiguredValue());
19+
assertEquals(VoteReward.VoteSource.NATIVE, fromBlank.source());
20+
assertFalse(fromBlank.invalidConfiguredValue());
21+
}
22+
23+
@Test
24+
void resolveVoteSourceSupportsConfiguredValuesCaseInsensitively() {
25+
VoteReward.ResolvedVoteSource resolved = VoteReward.resolveVoteSource(" VoTiFiEr ");
26+
27+
assertEquals(VoteReward.VoteSource.VOTIFIER, resolved.source());
28+
assertFalse(resolved.invalidConfiguredValue());
29+
assertEquals("votifier", resolved.configuredValue());
30+
}
31+
32+
@Test
33+
void resolveVoteSourceFallsBackToNativeForInvalidValues() {
34+
VoteReward.ResolvedVoteSource resolved = VoteReward.resolveVoteSource("redis");
35+
36+
assertEquals(VoteReward.VoteSource.NATIVE, resolved.source());
37+
assertTrue(resolved.invalidConfiguredValue());
38+
assertEquals("redis", resolved.configuredValue());
39+
}
40+
41+
@Test
42+
void unavailableSourceWarningReturnsNullWhenSelectedSourceIsAvailable() {
43+
assertNull(VoteReward.unavailableSourceWarning(VoteReward.VoteSource.NATIVE, true, false));
44+
assertNull(VoteReward.unavailableSourceWarning(VoteReward.VoteSource.VOTIFIER, false, true));
45+
}
46+
47+
@Test
48+
void unavailableSourceWarningExplainsMissingNativeSourceProducer() {
49+
String warning = VoteReward.unavailableSourceWarning(VoteReward.VoteSource.NATIVE, false, true);
50+
51+
assertTrue(warning.contains("ServerFeatures Votifier feature is not enabled"));
52+
assertTrue(warning.contains("\"native\""));
53+
}
54+
55+
@Test
56+
void unavailableSourceWarningExplainsMissingVotifierPlugin() {
57+
String warning = VoteReward.unavailableSourceWarning(VoteReward.VoteSource.VOTIFIER, true, false);
58+
59+
assertTrue(warning.contains("Votifier plugin is not enabled"));
60+
assertTrue(warning.contains("\"votifier\""));
61+
}
62+
}

0 commit comments

Comments
 (0)