Skip to content

Commit

Permalink
Add support for version-gated maps & variants
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Herrera <[email protected]>
  • Loading branch information
Pablete1234 committed Jul 6, 2024
1 parent 6bedcf1 commit 77caa04
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 4 deletions.
11 changes: 11 additions & 0 deletions core/src/main/java/tc/oc/pgm/api/map/MapInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;

import com.google.common.collect.Range;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -34,6 +36,13 @@ public interface MapInfo extends Comparable<MapInfo>, Cloneable {
*/
Map<String, VariantInfo> getVariants();

/**
* Get what servers versions should load this map, servers outside the range should ignore the map.
*
* @return range of the server versions that can load this map
*/
Range<Version> getServerVersion();

/** @return the subfolder in which the world is in, or null for the parent folder */
@Nullable
String getWorldFolder();
Expand Down Expand Up @@ -203,5 +212,7 @@ interface VariantInfo {
String getMapName();

String getWorld();

Range<Version> getServerVersions();
}
}
8 changes: 8 additions & 0 deletions core/src/main/java/tc/oc/pgm/map/MapFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -35,6 +36,7 @@
import tc.oc.pgm.regions.RegionParser;
import tc.oc.pgm.util.ClassLogger;
import tc.oc.pgm.util.Version;
import tc.oc.pgm.util.platform.Platform;
import tc.oc.pgm.util.xml.DocumentWrapper;
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.Node;
Expand Down Expand Up @@ -75,6 +77,12 @@ public MapContext load() throws MapException {
document = MapFilePreprocessor.getDocument(source, includes);

info = new MapInfoImpl(source, document.getRootElement());

// We're not loading this map, return a dummy map context to allow variants to load, if needed
if (!info.getServerVersion().contains(Platform.MINECRAFT_VERSION)) {
return new MapContextImpl(info, List.of());
}

try {
loadAll();
} catch (ModuleLoadException e) {
Expand Down
31 changes: 30 additions & 1 deletion core/src/main/java/tc/oc/pgm/map/MapInfoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import com.google.common.collect.Range;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
Expand Down Expand Up @@ -56,6 +58,7 @@ public class MapInfoImpl implements MapInfo {
private final Map<String, VariantInfo> variants;

private final String worldFolder;
private final Range<Version> serverVersion;
private final Version proto;
private final Version version;
private final Phase phase;
Expand Down Expand Up @@ -88,6 +91,7 @@ public MapInfoImpl(MapSource source, Element root) throws InvalidXMLException {
if (variant == null) throw new InvalidXMLException("Could not find variant definition", root);

this.worldFolder = variant.getWorld();
this.serverVersion = variant.getServerVersions();

this.name = variant.getMapName();
this.normalizedName = StringUtils.normalize(name);
Expand Down Expand Up @@ -145,6 +149,11 @@ public Map<String, VariantInfo> getVariants() {
return variants;
}

@Override
public Range<Version> getServerVersion() {
return serverVersion;
}

@Override
public String getWorldFolder() {
return worldFolder;
Expand Down Expand Up @@ -367,10 +376,13 @@ private static class VariantData implements VariantInfo {
private final String mapName;
private final String mapId;
private final String world;
private final Range<Version> serverVersions;

public VariantData(Element root, @Nullable Element variantEl) throws InvalidXMLException {
String name = assertNotNull(Node.fromRequiredChildOrAttr(root, "name").getValueNormalize());
String slug = assertNotNull(root).getChildTextNormalize("slug");
Node minVer = Node.fromAttr(root, "min-server-version");
Node maxVer = Node.fromAttr(root, "max-server-version");

if (variantEl == null) {
this.variantId = DEFAULT_VARIANT;
Expand All @@ -384,9 +396,21 @@ public VariantData(Element root, @Nullable Element variantEl) throws InvalidXMLE
boolean override = XMLUtils.parseBoolean(Node.fromAttr(variantEl, "override"), false);
this.mapName = (override ? "" : name + ": ") + variantEl.getTextNormalize();
this.world = variantEl.getAttributeValue("world");
if (slug != null) slug += "_" + variantId;

String variantSlug = variantEl.getAttributeValue("slug");
if (variantSlug != null) slug = variantSlug;
else if (slug != null) slug += "_" + variantId;

Node minVerVariant = Node.fromAttr(variantEl, "min-server-version");
if (minVerVariant != null) minVer = minVerVariant;

Node maxVerVariant = Node.fromAttr(variantEl, "max-server-version");
if (maxVerVariant != null) minVer = minVerVariant;
}
this.mapId = assertNotNull(slug != null ? slug : StringUtils.slugify(mapName));

this.serverVersions = XMLUtils.parseClosedRange(minVer,
XMLUtils.parseSemanticVersion(minVer), XMLUtils.parseSemanticVersion(maxVer));
}

@Override
Expand All @@ -408,5 +432,10 @@ public String getMapName() {
public String getWorld() {
return world;
}

@Override
public Range<Version> getServerVersions() {
return serverVersions;
}
}
}
7 changes: 5 additions & 2 deletions core/src/main/java/tc/oc/pgm/map/MapLibraryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import tc.oc.pgm.api.map.includes.MapIncludeProcessor;
import tc.oc.pgm.util.LiquidMetal;
import tc.oc.pgm.util.StringUtils;
import tc.oc.pgm.util.platform.Platform;
import tc.oc.pgm.util.usernames.UsernameResolvers;

public class MapLibraryImpl implements MapLibrary {
Expand Down Expand Up @@ -226,8 +227,10 @@ private MapContext loadMap(MapSource source, @Nullable String mapId) throws MapE
}

MapInfo info = context.getInfo();
maps.merge(
info.getId(), info, (m1, m2) -> m2.getVersion().isOlderThan(m1.getVersion()) ? m1 : m2);
// Only if from a supported version, add it to our library
if (info.getServerVersion().contains(Platform.MINECRAFT_VERSION)) {
maps.merge(info.getId(), info, (m1, m2) -> m2.getVersion().isOlderThan(m1.getVersion()) ? m1 : m2);
}
failed.remove(source);

return context;
Expand Down
11 changes: 10 additions & 1 deletion util/src/main/java/tc/oc/pgm/util/xml/XMLUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,16 @@ public static <T extends Number & Comparable<T>> Range<T> parseNumericRange(
lowStr == null || lowStr.equals("-oo") ? null : parseNumber(node, lowStr, type, false);
T upper = uppStr == null || uppStr.equals("oo") ? null : parseNumber(node, uppStr, type, false);

return parseRange(node, lower, lowerBound, upper, upperBound);
}

public static <T extends Comparable<T>> Range<T> parseClosedRange(Node node, @Nullable T lower, @Nullable T upper) throws InvalidXMLException {
return parseRange(node, lower, BoundType.CLOSED, upper, BoundType.CLOSED);
}

public static <T extends Comparable<T>> Range<T> parseRange(Node node,
@Nullable T lower, BoundType lowerBound,
@Nullable T upper, BoundType upperBound) throws InvalidXMLException {
if (lower != null && upper != null) {
if (lower.compareTo(upper) > 0) {
throw new InvalidXMLException(
Expand All @@ -476,7 +486,6 @@ public static <T extends Number & Comparable<T>> Range<T> parseNumericRange(
}

return Range.range(lower, lowerBound, upper, upperBound);

} else if (lower != null) {
return Range.downTo(lower, lowerBound);
} else if (upper != null) {
Expand Down

0 comments on commit 77caa04

Please sign in to comment.