Skip to content

Commit 933404f

Browse files
authored
Merge pull request #53 from LNDF/enhancements
Some enhancements
2 parents 85c9b37 + e37b084 commit 933404f

7 files changed

Lines changed: 186 additions & 56 deletions

File tree

src/main/java/lol/hyper/velocityblockversion/VelocityBlockVersion.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public class VelocityBlockVersion {
6262
@Inject
6363
private Injector injector;
6464

65+
/**
66+
* Called by Velocity when the proxy is being initialized
67+
* @param event The event context
68+
*/
6569
@Subscribe
6670
public void onProxyInitialization(final ProxyInitializeEvent event) {
6771
final ConfigHandler configHandler = injector.getInstance(ConfigHandler.class);
@@ -81,6 +85,9 @@ public void onProxyInitialization(final ProxyInitializeEvent event) {
8185
commandManager.register(meta, commandReload);
8286
}
8387

88+
/**
89+
* Checks for available updates and informs the user by logging it to console.
90+
*/
8491
public void checkForUpdates() {
8592
GitHubReleaseAPI api;
8693
try {

src/main/java/lol/hyper/velocityblockversion/commands/CommandReload.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public final class CommandReload implements SimpleCommand {
2828
@Inject
2929
private ConfigHandler configHandler;
3030

31+
/**
32+
* Called by Brigadier when the command is executed.
33+
*/
3134
@Override
3235
public void execute(final Invocation invocation) {
3336
final CommandSource source = invocation.source();
@@ -36,6 +39,9 @@ public void execute(final Invocation invocation) {
3639
}
3740
}
3841

42+
/**
43+
* Returns whether an invoacion has permission to execute this command.
44+
*/
3945
@Override
4046
public boolean hasPermission(final Invocation invocation) {
4147
return invocation.source().hasPermission("velocityblockversion.reload");

src/main/java/lol/hyper/velocityblockversion/events/JoinEvent.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,45 +23,33 @@
2323
import com.velocitypowered.api.event.connection.PreLoginEvent;
2424
import com.velocitypowered.api.network.ProtocolVersion;
2525
import lol.hyper.velocityblockversion.tools.ConfigHandler;
26-
import lol.hyper.velocityblockversion.tools.VersionToStrings;
27-
import net.kyori.adventure.text.Component;
28-
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
2926
import org.slf4j.Logger;
3027

31-
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
32-
3328
public final class JoinEvent {
3429
@Inject
3530
private Logger logger;
3631
@Inject
3732
private ConfigHandler configHandler;
3833

34+
/**
35+
* Called by Velocity when a player joins.
36+
* @param event The context of the event.
37+
*/
3938
@Subscribe(order = PostOrder.FIRST)
4039
public void onPlayerLogin(final PreLoginEvent event) {
4140
final int version = event.getConnection().getProtocolVersion().getProtocol();
4241
if (configHandler.getConfig().getBoolean("log_connection_versions", false)) {
4342
logger.info("Player is connecting with protocol version: {}", version);
4443
}
4544

46-
if (!configHandler.getBlockVersions().contains(version)) {
45+
boolean isBlacklist = configHandler.getOperationMode().equals(ConfigHandler.OperationMode.BLACKLIST);
46+
if (configHandler.getVersionsSet().contains(version) ^ isBlacklist) {
4747
return;
4848
}
4949

50-
String allowedVersions = VersionToStrings.allowedVersions(configHandler.getBlockVersions());
51-
String blockedMessage = configHandler.getConfig().getString("disconnect_message");
52-
53-
if (allowedVersions == null) {
54-
blockedMessage = "<red>All versions are currently blocked from playing.";
55-
allowedVersions = "";
56-
}
57-
58-
final Component message = miniMessage().deserialize(
59-
blockedMessage,
60-
Placeholder.unparsed("versions", allowedVersions)
61-
);
62-
event.setResult(PreLoginEvent.PreLoginComponentResult.denied(message));
50+
event.setResult(PreLoginEvent.PreLoginComponentResult.denied(configHandler.getDeniedMessage()));
6351
logger.info(
64-
"Blocking player {} because they are playing on version {} which is blocked!",
52+
"Blocking player {} because they are playing on version {} which is not allowed!",
6553
event.getUsername(),
6654
ProtocolVersion.getProtocolVersion(version).getMostRecentSupportedVersion()
6755
);

src/main/java/lol/hyper/velocityblockversion/tools/ConfigHandler.java

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@
1717

1818
package lol.hyper.velocityblockversion.tools;
1919

20+
import com.google.common.collect.ImmutableSet;
2021
import com.google.inject.Inject;
2122
import com.google.inject.Singleton;
2223
import com.moandjiezana.toml.Toml;
2324
import com.velocitypowered.api.network.ProtocolVersion;
2425
import com.velocitypowered.api.plugin.annotation.DataDirectory;
26+
27+
import net.kyori.adventure.text.Component;
28+
import net.kyori.adventure.text.minimessage.MiniMessage;
29+
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
30+
2531
import org.slf4j.Logger;
2632

2733
import java.io.IOException;
@@ -30,23 +36,45 @@
3036
import java.nio.file.Path;
3137
import java.util.ArrayList;
3238
import java.util.List;
39+
import java.util.Set;
3340
import java.util.stream.Collectors;
3441

3542
@Singleton
3643
public final class ConfigHandler {
44+
public enum OperationMode {
45+
BLACKLIST, WHITELIST;
46+
47+
public static OperationMode fromString(String mode) {
48+
switch (mode) {
49+
case "blacklist":
50+
return BLACKLIST;
51+
case "whitelist":
52+
return WHITELIST;
53+
default:
54+
return null;
55+
}
56+
}
57+
};
58+
3759
@Inject
3860
private Logger logger;
3961
@Inject
4062
@DataDirectory
4163
private Path folderPath;
4264

4365
private Toml config;
44-
private final List<Integer> blockVersions = new ArrayList<>();
45-
public final long CONFIG_VERSION = 5;
66+
private OperationMode operationMode = OperationMode.BLACKLIST;
67+
private Set<Integer> versionsSet = ImmutableSet.of();
68+
private Component deniedMessage = MiniMessage.miniMessage().deserialize("");
69+
public final long CONFIG_VERSION = 6;
4670

4771
@Inject
4872
public ConfigHandler() {}
4973

74+
/**
75+
* Load the plugin settings from the configuration file.
76+
* @return True if the configuration was loaded, false if there was an error.
77+
*/
5078
public boolean loadConfig() {
5179
if (Files.notExists(folderPath)) {
5280
try {
@@ -83,41 +111,76 @@ public boolean loadConfig() {
83111
logger.warn(
84112
"To fix this, delete your current config and let the server remake it.");
85113
}
86-
blockVersions.clear();
87114

115+
operationMode = OperationMode.fromString(config.getString("mode", "blacklist"));
116+
if (operationMode == null) {
117+
logger.error("Unexpected mode option found. Using default value.");
118+
operationMode = OperationMode.BLACKLIST;
119+
}
120+
logger.info("Operation mode: {}", operationMode.toString());
121+
122+
List<Integer> versionsList = new ArrayList<>();
88123
// for some reason, the config loads the versions as longs
89124
// we have to convert them this ugly way
90125
for (Object obj : config.getList("versions", List.of())) {
91126
if (obj instanceof Number) {
92127
int t = ((Number) obj).intValue();
93-
blockVersions.add(t);
128+
versionsList.add(t);
94129
} else {
95130
logger.error("Unexpected versions configuration input {}", obj);
96131
}
97132
}
98133

99-
if (blockVersions.isEmpty()) {
134+
if (versionsList.isEmpty()) {
100135
logger.warn("There are no versions listed in the config!");
101136
} else {
102-
blockVersions.removeIf(protocol -> {
103-
if (ProtocolVersion.ID_TO_PROTOCOL_CONSTANT.containsKey(protocol)) {
104-
return false;
105-
} else {
106-
logger.warn("Version {} is NOT a valid version number! Ignoring this version.", protocol);
107-
return true;
108-
}
109-
});
110-
logger.info("Loaded {} versions!", blockVersions.size());
137+
versionsList.sort((a, b) -> a.compareTo(b));
138+
versionsList = versionsList.stream().filter(elm -> ProtocolVersion.ID_TO_PROTOCOL_CONSTANT.containsKey(elm))
139+
.distinct().sorted().toList();
140+
logger.info("Loaded {} versions!", versionsList.size());
111141
}
112-
logger.info("Loaded versions: {}", blockVersions.stream().map(String::valueOf).collect(Collectors.joining(", ")));
142+
logger.info("Loaded versions: {}", versionsList.stream().map(String::valueOf).collect(Collectors.joining(", ")));
113143

144+
String versionString = VersionToStrings.versionRange(versionsList);
145+
String disconnectMessage = config.getString("disconnect_message");
146+
147+
deniedMessage = MiniMessage.miniMessage().deserialize(
148+
disconnectMessage,
149+
Placeholder.unparsed("versions", versionString)
150+
);
151+
152+
versionsSet = ImmutableSet.copyOf(versionsList);
114153
return true;
115154
}
116155

117-
public List<Integer> getBlockVersions() {
118-
return blockVersions;
156+
/**
157+
* Get the set of version protocol included in the configuration by the user
158+
* @return The version set
159+
*/
160+
public Set<Integer> getVersionsSet() {
161+
return versionsSet;
162+
}
163+
164+
/**
165+
* Get the mode on which the plugin operates.
166+
* @return A value from the enum describing the mode.
167+
*/
168+
public OperationMode getOperationMode() {
169+
return operationMode;
170+
}
171+
172+
/**
173+
* Get the computed message sent to players that are denied access.
174+
* @return miniMessage Component containing the message.
175+
*/
176+
public Component getDeniedMessage() {
177+
return deniedMessage;
119178
}
120179

180+
/**
181+
* Get the config parse instance.
182+
* @return The Toml parser instance.
183+
*/
121184
public Toml getConfig() {
122185
return config;
123186
}

src/main/java/lol/hyper/velocityblockversion/tools/VersionToStrings.java

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,61 @@
2222
import java.util.*;
2323

2424
public final class VersionToStrings {
25+
private static class VersionRange {
26+
int start;
27+
int end;
28+
29+
VersionRange(int start, int end) {
30+
this.start = start;
31+
this.end = end;
32+
}
33+
34+
/**
35+
* Get the string representation of this version range
36+
* @return A string representing the minimum and maximum version of this range.
37+
*/
38+
@Override
39+
public String toString() {
40+
String firstVersion = ProtocolVersion.ID_TO_PROTOCOL_CONSTANT.get(start).getVersionIntroducedIn();
41+
String lastVersion = ProtocolVersion.ID_TO_PROTOCOL_CONSTANT.get(end).getMostRecentSupportedVersion();
42+
return firstVersion.equals(lastVersion) ? firstVersion : firstVersion + " - " + lastVersion;
43+
}
44+
}
45+
2546
private VersionToStrings() {}
2647

2748
/**
2849
* Builds a string that will show what versions the server supports. Example: 1.8 to 1.14.4
29-
* @param deniedVersions Versions to deny.
30-
* @return Returns the string of versions. Returns nulls if there are no versions that are allowed.
50+
* @param versionList The list of versions
51+
* @return Returns the string of versions. Returns "{null}" if the input list is empty.
3152
*/
32-
public static String allowedVersions(final List<Integer> deniedVersions) {
33-
final Map<Integer, ProtocolVersion> versionMap = new HashMap<>(ProtocolVersion.ID_TO_PROTOCOL_CONSTANT);
34-
versionMap.remove(-1);
35-
versionMap.remove(-2);
36-
final List<Integer> allVersions = new ArrayList<>(versionMap.keySet());
37-
allVersions.removeAll(deniedVersions);
38-
if (allVersions.isEmpty()) {
39-
return null;
53+
public static String versionRange(final List<Integer> versionList) {
54+
if (versionList.isEmpty()) {
55+
return "{null}";
4056
}
4157

42-
final int minVersion = Collections.min(allVersions);
43-
final int maxVersion = Collections.max(allVersions);
58+
List<VersionRange> ranges = new ArrayList<>();
59+
List<Integer> supported = new ArrayList<>(ProtocolVersion.SUPPORTED_VERSIONS
60+
.stream().map(ProtocolVersion::getProtocol).toList());
61+
62+
int start = supported.indexOf(versionList.get(0));
63+
int prev = start;
64+
65+
Iterator<Integer> it = versionList.iterator();
66+
it.next();
67+
68+
while (it.hasNext()) {
69+
int version = it.next();
70+
if (version == supported.get(prev + 1)) {
71+
prev += 1;
72+
} else {
73+
ranges.add(new VersionRange(supported.get(start), supported.get(prev)));
74+
start = supported.indexOf(version);
75+
prev = start;
76+
}
77+
}
78+
ranges.add(new VersionRange(supported.get(start), supported.get(prev)));
4479

45-
return versionMap.get(minVersion).toString() + " to " + versionMap.get(maxVersion).toString();
80+
return String.join(", ", ranges.stream().map(VersionRange::toString).toList());
4681
}
4782
}

src/main/resources/config.toml

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
# These versions will NOT be allowed to connect.
1+
# Set the mode for the plugin. This can either be "blacklist" or "whitelist".
2+
# blacklist: Versions listed below will not be allowed to connect.
3+
# whitelist: Only versions listed below will be allowed to connect.
4+
mode = "blacklist"
5+
26
# These versions MUST be the version number. You can check the numbers here: https://wiki.vg/Protocol_version_numbers
3-
# By default, all versions are listed here.
7+
# By default, all versions from 1.7.2 to 1.21.10 are listed here.
48
# Everything here must have a comma after it!
59
versions = [
10+
4,
11+
5,
612
47,
713
107,
814
108,
@@ -37,16 +43,29 @@ versions = [
3743
759,
3844
760,
3945
761,
46+
762,
47+
763,
48+
764,
49+
765,
50+
766,
51+
767,
52+
768,
53+
769,
54+
770,
55+
771,
56+
772,
57+
773,
4058
]
4159

42-
# Send this message if someone connects with a blocked version.
43-
# Use <versions> to show what versions your server uses. It will display like "1.8 to 1.16.3" or whatever.
60+
# Send this message when someone is denied access to the server.
61+
# Use <versions> to show what versions your server uses. It will display like "1.8 - 1.16.3" or whatever.
4462
# If you don't want to use <versions>, just remove it.
45-
disconnect_message = "<red>You cannot connect with this version! We only allow version(s) <versions>."
63+
# You may need to change the default value if you use whitelist mode.
64+
disconnect_message = "<red>The following version(s) are not allowed to join this server: <versions>."
4665

4766
# This will say "Player is connecting with protocol version" when someone joins.
4867
# This is off by default to not spam your console, but you can enable it for debug reasons.
4968
log_connection_versions = false
5069

5170
# No touch please :)
52-
config_version = 5
71+
config_version = 6
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"id": "velocityblockversion",
3+
"name": "VelocityBlockVersion",
4+
"version": "1.0.9",
5+
"description": "Block certain Minecraft versions from connecting to your network.",
6+
"url": "https://github.com/hyperdefined/VelocityBlockVersion",
7+
"authors": [
8+
"hyperdefined"
9+
],
10+
"dependencies": [],
11+
"main": "lol.hyper.velocityblockversion.VelocityBlockVersion"
12+
}

0 commit comments

Comments
 (0)