# VersionResolver
Maps Minecraft version strings to protocol numbers and evaluates lists of comma-separated `VersionExpression` strings (AND within an entry, OR across entries).
The bundled `version_protocols.yml` resource ships protocol numbers from 1.21 through 26.1.2 at the time of release. Plugin config can extend or override this table under `version_protocols:`.
---
## Source
```java
package gg.lode.paintingapi.api.version;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
public final class VersionResolver {
private final Map<String, Integer> versionToProtocol = new LinkedHashMap<>();
public VersionResolver() {
loadBundled();
}
private void loadBundled() {
try (InputStream in = VersionResolver.class.getClassLoader()
.getResourceAsStream("version_protocols.yml")) {
if (in == null) return;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
String trimmed = line.trim();
if (trimmed.isEmpty() || trimmed.startsWith("#")) continue;
int colon = trimmed.indexOf(':');
if (colon < 0) continue;
String key = trimmed.substring(0, colon).trim().replace("\"", "").replace("'", "");
String value = trimmed.substring(colon + 1).trim();
try {
versionToProtocol.put(key, Integer.parseInt(value));
} catch (NumberFormatException ignored) {}
}
}
} catch (IOException ignored) {}
}
public void override(@NotNull String version, int protocol) {
versionToProtocol.put(version, protocol);
}
public void overrideAll(@NotNull Map<String, Integer> overrides) {
versionToProtocol.putAll(overrides);
}
public @Nullable Integer protocolFor(@NotNull String version) {
return versionToProtocol.get(version);
}
public @NotNull Map<String, Integer> table() {
return new LinkedHashMap<>(versionToProtocol);
}
public boolean evaluateExpressions(@NotNull Collection<String> expressions, int playerProtocol) {
if (expressions.isEmpty()) return false;
for (String raw : expressions) {
if (evaluateAndExpression(raw, playerProtocol)) return true;
}
return false;
}
private boolean evaluateAndExpression(@NotNull String raw, int playerProtocol) {
String[] parts = raw.split(",");
for (String part : parts) {
VersionExpression expr = VersionExpression.parse(part);
Integer ref = versionToProtocol.get(expr.version());
if (ref == null) {
throw new IllegalArgumentException(
"Unknown Minecraft version '" + expr.version() + "' in expression '" + raw
+ "'. Add it via version_protocols override in config.");
}
if (!expr.evaluate(playerProtocol, ref)) return false;
}
return true;
}
}
```
---
## Related Pages
- [[Painting/API/VersionExpression]] — single-expression parser used here
- [[Painting/Server Owners/Configuration]] — `version_protocols:` config form