Skip to content

Commit

Permalink
Variant improvements in pools & map command (#1250)
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Herrera <[email protected]>
  • Loading branch information
Pablete1234 authored Oct 9, 2023
1 parent b366be5 commit 24cf489
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 43 deletions.
21 changes: 19 additions & 2 deletions core/src/main/java/tc/oc/pgm/api/map/MapInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.Nullable;
Expand All @@ -24,8 +25,14 @@ public interface MapInfo extends Comparable<MapInfo>, Cloneable {
*
* @return A variant for the map, if any.
*/
@Nullable
String getVariant();
String getVariantId();

/**
* Get all the variants available for the map
*
* @return a map of variants by their variant id
*/
Map<String, VariantInfo> getVariants();

/** @return the subfolder in which the world is in, or null for the parent folder */
@Nullable
Expand Down Expand Up @@ -187,4 +194,14 @@ default String getStyledNameLegacy(MapNameStyle style, @Nullable CommandSender s
default int compareTo(MapInfo o) {
return getId().compareTo(o.getId());
}

interface VariantInfo {
String getVariantId();

String getMapId();

String getMapName();

String getWorld();
}
}
7 changes: 3 additions & 4 deletions core/src/main/java/tc/oc/pgm/api/map/MapSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import org.jetbrains.annotations.Nullable;
import tc.oc.pgm.api.map.exception.MapMissingException;
import tc.oc.pgm.api.map.includes.MapInclude;
import tc.oc.pgm.map.source.MapRoot;

/** A source where {@link MapInfo} documents and files are downloaded. */
public interface MapSource {
Path FILE = Paths.get("map.xml");
String DEFAULT_VARIANT = "default";

/**
* Get a unique identifier for the source, should be human-readable.
Expand All @@ -24,10 +24,9 @@ public interface MapSource {
/**
* The variant of the map this is for
*
* @return the variant the source, null for the parent source
* @return the variant the source, DEFAULT_VARIANT for the parent source
*/
@Nullable
String getVariant();
String getVariantId();

/**
* A copy of the map source, tailored to a specific variant
Expand Down
34 changes: 33 additions & 1 deletion core/src/main/java/tc/oc/pgm/command/MapCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.stream.Stream;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TextComponent.Builder;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
Expand Down Expand Up @@ -277,6 +278,10 @@ public void map(
}
}

if (map.getVariants().size() > 1) {
audience.sendMessage(formatVariants(map));
}

if (!map.getSource().getRoot().isPrivate() || sender.hasPermission(Permissions.DEBUG)) {
audience.sendMessage(formatMapSource(sender, map));
}
Expand Down Expand Up @@ -356,10 +361,37 @@ private Component formatContribution(Contributor contributor) {
private Component mapInfoLabel(String key) {
return text()
.append(translatable(key, NamedTextColor.DARK_PURPLE, TextDecoration.BOLD))
.append(text(": "))
.append(text(": ", NamedTextColor.WHITE))
.build();
}

private ComponentLike formatVariants(MapInfo map) {
TextComponent.Builder text =
text().append(mapInfoLabel("map.info.variants")).color(NamedTextColor.GOLD);

for (MapInfo.VariantInfo variant : map.getVariants().values()) {
TextComponent variantComp;
if (map.getVariantId().equals(variant.getVariantId())) {
variantComp =
text(variant.getVariantId(), null, TextDecoration.UNDERLINED)
.hoverEvent(
showText(translatable("map.info.variants.current", NamedTextColor.GRAY)));
} else {
variantComp =
text(variant.getVariantId())
.hoverEvent(
showText(
translatable(
"command.maps.hover",
NamedTextColor.GRAY,
text(variant.getMapName(), NamedTextColor.GOLD))))
.clickEvent(runCommand("/map " + variant.getMapName()));
}
text.append(variantComp).append(text(" "));
}
return text;
}

@NotNull
private ComponentLike formatMapSource(CommandSender sender, MapInfo map) {
MapSource source = map.getSource();
Expand Down
22 changes: 19 additions & 3 deletions core/src/main/java/tc/oc/pgm/map/MapFilePreprocessor.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package tc.oc.pgm.map;

import static tc.oc.pgm.api.map.MapSource.DEFAULT_VARIANT;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jdom2.Attribute;
Expand Down Expand Up @@ -45,6 +49,7 @@ public class MapFilePreprocessor {
private final List<MapInclude> includes;

private final Map<String, String> constants;
private final Set<String> variantIds;

public static Document getDocument(MapSource source, MapIncludeProcessor includes)
throws MapMissingException, IOException, JDOMException, InvalidXMLException {
Expand All @@ -54,9 +59,10 @@ public static Document getDocument(MapSource source, MapIncludeProcessor include
private MapFilePreprocessor(MapSource source, MapIncludeProcessor includeProcessor) {
this.source = source;
this.includeProcessor = includeProcessor;
this.variant = source.getVariant() == null ? "default" : source.getVariant();
this.variant = source.getVariantId();
this.includes = new ArrayList<>();
this.constants = new HashMap<>();
this.variantIds = new HashSet<>();
}

public Document getDocument()
Expand All @@ -67,6 +73,11 @@ public Document getDocument()
document.setBaseURI(source.getId());
}

variantIds.add(DEFAULT_VARIANT);
for (Element variant : document.getRootElement().getChildren("variant")) {
variantIds.add(XMLUtils.parseRequiredId(variant));
}

document.runWithoutVisitation(
() -> {
MapInclude global = includeProcessor.getGlobalInclude();
Expand Down Expand Up @@ -133,9 +144,14 @@ private List<Content> processIncludeElement(Element element) throws InvalidXMLEx

private List<Content> processConditional(Element el, boolean shouldContain)
throws InvalidXMLException {

Node node = Node.fromRequiredAttr(el, "variant", "has-variant");
List<String> filter = Arrays.asList(node.getValue().split("[\\s,]+"));

boolean contains =
Arrays.asList(Node.fromRequiredAttr(el, "variant").getValue().split("[\\s,]+"))
.contains(variant);
"variant".equals(node.getName())
? filter.contains(this.variant)
: filter.stream().anyMatch(variantIds::contains);

return contains == shouldContain ? el.cloneContent() : Collections.emptyList();
}
Expand Down
106 changes: 81 additions & 25 deletions core/src/main/java/tc/oc/pgm/map/MapInfoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.Component.translatable;
import static tc.oc.pgm.api.map.MapSource.DEFAULT_VARIANT;
import static tc.oc.pgm.util.Assert.assertNotNull;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import java.lang.ref.SoftReference;
Expand Down Expand Up @@ -50,7 +52,9 @@ public class MapInfoImpl implements MapInfo {
private final MapSource source;

private final String id;
private final String variant;
private final String variantId;
private final Map<String, VariantInfo> variants;

private final String worldFolder;
private final Version proto;
private final Version version;
Expand All @@ -77,31 +81,18 @@ public class MapInfoImpl implements MapInfo {

public MapInfoImpl(MapSource source, Element root) throws InvalidXMLException {
this.source = source;
this.variant = source.getVariant();

String tmpName = assertNotNull(Node.fromRequiredChildOrAttr(root, "name").getValueNormalize());
String tmpWorld = null;
if (variant != null) {
Element variantEl =
root.getChildren("variant").stream()
.filter(el -> Objects.equals(variant, el.getAttributeValue("id")))
.findFirst()
.orElseThrow(
() -> new InvalidXMLException("Could not find variant definition", root));

boolean override = XMLUtils.parseBoolean(Node.fromAttr(variantEl, "override"), false);
tmpName = (override ? "" : tmpName + ": ") + variantEl.getTextNormalize();
tmpWorld = variantEl.getAttributeValue("world");
}
this.worldFolder = tmpWorld;
this.variantId = source.getVariantId();
this.variants = createVariantMap(root);

this.name = tmpName;
this.normalizedName = StringUtils.normalize(name);
VariantInfo variant = variants.get(variantId);
if (variant == null) throw new InvalidXMLException("Could not find variant definition", root);

String slug = assertNotNull(root).getChildTextNormalize("slug");
if (slug != null && variant != null) slug += "_" + variant;
this.worldFolder = variant.getWorld();

this.id = assertNotNull(StringUtils.slugify(slug != null ? slug : name));
this.name = variant.getMapName();
this.normalizedName = StringUtils.normalize(name);

this.id = assertNotNull(variant.getMapId());

this.proto = assertNotNull(XMLUtils.parseSemanticVersion(Node.fromRequiredAttr(root, "proto")));
this.version =
Expand All @@ -127,14 +118,31 @@ public MapInfoImpl(MapSource source, Element root) throws InvalidXMLException {
Node.fromLastChildOrAttr(root, "friendlyfire", "friendly-fire"), false);
}

@NotNull
private static Map<String, VariantInfo> createVariantMap(Element root)
throws InvalidXMLException {
ImmutableMap.Builder<String, VariantInfo> variants = ImmutableMap.builder();
variants.put(DEFAULT_VARIANT, new VariantData(root, null));
for (Element el : root.getChildren("variant")) {
VariantData vd = new VariantData(root, el);
variants.put(vd.variantId, vd);
}
return variants.build();
}

@Override
public String getId() {
return id;
}

@Override
public String getVariant() {
return variant;
public String getVariantId() {
return variantId;
}

@Override
public Map<String, VariantInfo> getVariants() {
return variants;
}

@Override
Expand Down Expand Up @@ -353,4 +361,52 @@ protected void setContext(MapContextImpl context) {
}
this.context = new SoftReference<>(context);
}

private static class VariantData implements VariantInfo {
private final String variantId;
private final String mapName;
private final String mapId;
private final String world;

public VariantData(Element root, @Nullable Element variantEl) throws InvalidXMLException {
String name = assertNotNull(Node.fromRequiredChildOrAttr(root, "name").getValueNormalize());
String slug = assertNotNull(root).getChildTextNormalize("slug");

if (variantEl == null) {
this.variantId = DEFAULT_VARIANT;
this.mapName = name;
this.world = null;
} else {
this.variantId = Node.fromRequiredAttr(variantEl, "id").getValue();
if (DEFAULT_VARIANT.equals(variantId)) {
throw new InvalidXMLException("Default variant is not allowed", variantEl);
}
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;
}
this.mapId = assertNotNull(StringUtils.slugify(slug != null ? slug : mapName));
}

@Override
public String getVariantId() {
return variantId;
}

@Override
public String getMapId() {
return mapId;
}

@Override
public String getMapName() {
return mapName;
}

@Override
public String getWorld() {
return world;
}
}
}
3 changes: 2 additions & 1 deletion core/src/main/java/tc/oc/pgm/map/MapLibraryImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tc.oc.pgm.map;

import static tc.oc.pgm.api.map.MapSource.DEFAULT_VARIANT;
import static tc.oc.pgm.util.Assert.assertNotNull;

import java.util.Collections;
Expand Down Expand Up @@ -202,7 +203,7 @@ private MapContext loadMap(MapSource source, @Nullable String mapId) throws MapE
context = factory.load();

// We're not loading a specific map id, and we're not on a variant, load variants
if (mapId == null && source.getVariant() == null) {
if (mapId == null && DEFAULT_VARIANT.equals(source.getVariantId())) {
for (String variant : factory.getVariants()) {
loadMapSafe(source.asVariant(variant), null);
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/tc/oc/pgm/map/source/SystemMapSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ public boolean checkForUpdates() throws MapMissingException {
}

@Override
public String getVariant() {
return variant;
public String getVariantId() {
return variant == null ? DEFAULT_VARIANT : variant;
}

@Override
Expand Down
Loading

0 comments on commit 24cf489

Please sign in to comment.