diff --git a/src/main/java/tc/oc/pgm/PGMImpl.java b/src/main/java/tc/oc/pgm/PGMImpl.java index fd6d9a64a6..df1e0e2209 100644 --- a/src/main/java/tc/oc/pgm/PGMImpl.java +++ b/src/main/java/tc/oc/pgm/PGMImpl.java @@ -90,6 +90,7 @@ import tc.oc.pgm.map.MapNotFoundException; import tc.oc.pgm.map.PGMMap; import tc.oc.pgm.map.ProtoVersions; +import tc.oc.pgm.maptag.StandardMapTags; import tc.oc.pgm.match.MatchManagerImpl; import tc.oc.pgm.modes.ObjectiveModesModule; import tc.oc.pgm.module.ModuleRegistry; @@ -265,6 +266,8 @@ public void onEnable() { MapLoader mapLoader = new MapLoader(this, logger, registry); mapLibrary = new MapLibrary(logger); + StandardMapTags.registerDefaults(logger); + try { matchManager = new MatchManagerImpl(server, mapLibrary, mapLoader); diff --git a/src/main/java/tc/oc/pgm/api/registry/IRegistry.java b/src/main/java/tc/oc/pgm/api/registry/IRegistry.java new file mode 100644 index 0000000000..c348478ad9 --- /dev/null +++ b/src/main/java/tc/oc/pgm/api/registry/IRegistry.java @@ -0,0 +1,85 @@ +package tc.oc.pgm.api.registry; + +import java.util.Collection; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; + +/** + * A container that collects T by its ID as {@link String}. + * + * @param type of objects to collect + */ +// TODO should be extended to NamespacedKeys +public interface IRegistry { + /** + * Does this registry contain the given ID? + * + * @param id ID of the object + * @return {@code true} whether this registry contains ID, otherwise {@link false} + */ + boolean contains(String id); + + /** + * Get T object from the given ID. + * + * @param id ID of the object + * @return Object from this ID, never {@code null} + * @throws NoSuchElementException When this registry does not contain the given ID + */ + T get(String id) throws NoSuchElementException; + + /** + * Get optional T object from the given ID. + * + * @param id ID of the object + * @return Object from this ID, or {@link Optional#empty()} when this registry does not contain + * the given ID + */ + Optional getMaybe(String id); + + /** + * Get all keys registered in this registry. + * + * @return {@link Set} of all keys + */ + Set getKeys(); + + /** + * Get all T objects registered in this registry. + * + * @return {@link Collection} of all objects + */ + Collection getAll(); + + /** + * Convert this registry into a {@link Set} of entries. + * + * @return {@link Set} of all entries + */ + Set> entrySet(); + + /** + * Convert this registry into a {@link Map} where keys are string IDs. + * + * @return {@link Map} of all entries + */ + Map asKeyMap(); + + /** + * Register the given T object in this registry. + * + * @param id ID of the object + * @param object Object itself, may not be {@code null} + */ + void register(String id, T object); + + /** + * Unregister object from this registry. + * + * @param id ID of the object + * @return {@code true} whether this registry contained this ID, otherwise {@code false} + */ + boolean unregister(String id); +} diff --git a/src/main/java/tc/oc/pgm/api/registry/Registry.java b/src/main/java/tc/oc/pgm/api/registry/Registry.java new file mode 100644 index 0000000000..ac9ba93af9 --- /dev/null +++ b/src/main/java/tc/oc/pgm/api/registry/Registry.java @@ -0,0 +1,65 @@ +package tc.oc.pgm.api.registry; + +import static com.google.common.base.Preconditions.*; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; + +public class Registry implements IRegistry { + private final Map map; + + public Registry(Map map) { + this.map = checkNotNull(map); + } + + @Override + public boolean contains(String id) { + return map.containsKey(checkNotNull(id)); + } + + @Override + public T get(String id) throws NoSuchElementException { + return getMaybe(checkNotNull(id)).orElseThrow(NoSuchElementException::new); + } + + @Override + public Optional getMaybe(String id) { + return Optional.ofNullable(map.get(checkNotNull(id))); + } + + @Override + public Set getKeys() { + return map.keySet(); + } + + @Override + public Collection getAll() { + return map.values(); + } + + @Override + public Set> entrySet() { + return map.entrySet(); + } + + @Override + public Map asKeyMap() { + return Collections.unmodifiableMap(map); + } + + @Override + public void register(String id, T object) { + checkNotNull(id); + checkNotNull(object); + map.put(id, object); + } + + @Override + public boolean unregister(String id) { + return map.remove(checkNotNull(id)) != null; + } +} diff --git a/src/main/java/tc/oc/pgm/maptag/StandardMapTags.java b/src/main/java/tc/oc/pgm/maptag/StandardMapTags.java index e97a847f3f..a5f9eb7754 100644 --- a/src/main/java/tc/oc/pgm/maptag/StandardMapTags.java +++ b/src/main/java/tc/oc/pgm/maptag/StandardMapTags.java @@ -6,10 +6,16 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; + +import tc.oc.pgm.api.registry.IRegistry; +import tc.oc.pgm.api.registry.Registry; import tc.oc.pgm.blitz.BlitzModule; import tc.oc.pgm.classes.ClassModule; import tc.oc.pgm.controlpoint.ControlPointModule; @@ -34,6 +40,8 @@ import tc.oc.pgm.worldborder.WorldBorderModule; public interface StandardMapTags { + IRegistry REGISTRY = new Registry<>(new LinkedHashMap<>()); + StandardMapTag _4TEAMS = create("4teams", TeamModule.class, team -> team.getTeams().size() == 4); StandardMapTag AUTOTNT = create("autotnt", TNTModule.class, tnt -> tnt.getProperties().instantIgnite); @@ -94,7 +102,20 @@ static StandardMapTag create( .orElse(false)); } + static void registerDefaults(Logger logger) { + checkNotNull(logger); + + try { + collect(StandardMapTags.class) + .forEach(standardMapTag -> REGISTRY.register(standardMapTag.getName(), standardMapTag)); + } catch (IllegalAccessException e) { + logger.log(Level.SEVERE, "Could not register standard map tags.", e); + } + } + static Set collect(Class clazz) throws IllegalAccessException { + checkNotNull(clazz); + SortedSet sorted = new TreeSet<>(Comparator.naturalOrder()); for (Field field : clazz.getFields()) { int modifiers = field.getModifiers();