Skip to content

Commit

Permalink
add negation to registry filter rule
Browse files Browse the repository at this point in the history
(cherry picked from commit 5945016)
  • Loading branch information
deirn committed Mar 24, 2024
1 parent bddfdf9 commit 2318a62
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 35 deletions.
45 changes: 41 additions & 4 deletions src/api/java/mcp/mobius/waila/api/IRegistryFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,25 @@
* Filters registry object based on set of string rules.
* <p>
* <b> Rule Operators:</b><ul>
* <li>{@code @namespace} - Filter objects based on their namespace location.</li>
* <li>{@code #tag} - Filter objects based on data pack tags.</li>
* <li>{@code /regex/} - Filter objects based on regular expression.</li>
* <li>{@code default} - Filter objects with specific ID.</li>
* <li>{@code @namespace} - include objects based on their namespace location.</li>
* <li>{@code #tag} - include objects based on data pack tags.</li>
* <li>{@code /regex/} - include objects based on regular expression.</li>
* <li>{@code default} - include objects with specific ID.</li>
* </ul>
* <p>
* An exclamation mark (!) prefix can be added which negates the pattern.
* Any entries matching previous rules will be removed from it.
* Can be combined with other rule to exclude what matches the rule.
* <p>
* <b>Note:</b> Instances of {@link IRegistryFilter} should only be obtained once, unless the ruleset is changed.
* <p>
* <b>Example</b><ul>
* <li>{@code @aether} - include all block from the aether namespace</li>
* <li>{@code #minecraft:planks} - include all blocks in the planks tag</li>
* <li>{@code /.*_ore/} - include all blocks that ends with {@code _ore}</li>
* <li>{@code minecraft:iron_block} - include only the iron block</li>
* <li>{@code !/.*:oak_.*$/} - exclude all blocks that its path start with {@code oak_}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
Expand All @@ -27,6 +39,31 @@ static <T> Builder<T> of(ResourceKey<? extends Registry<T>> registryKey) {
return IApiService.INSTANCE.createRegistryFilterBuilder(registryKey);
}

/**
* Comment to be used with as a file header.
* <p>
* Not a constant so it won't be inlined as it can change.
*/
static String getHeader() {
return """
Operators:
@namespace - include objects based on their namespace location
#tag - include objects based on data pack tags
/regex/ - include objects based on regular expression
default - include objects with specific ID
An exclamation mark (!) prefix can be added which negates the pattern.
Any entries matching previous rules will be removed from it.
Can be combined with other rule to exclude what matches the rule.
Example:
@aether - include all block from the aether namespace
#minecraft:planks - include all blocks in the planks tag
/.*_ore/ - include all blocks that ends with "_ore"
minecraft:iron_block - include only the iron block
!/.*:oak_.*$/ - exclude all blocks that its path start with "oak_\"""";
}

/**
* Returns whether the filter matches the object.
* <p>
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/mcp/mobius/waila/config/BlacklistConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,10 @@ public JsonElement serialize(BlacklistConfig src, Type typeOfSrc, JsonSerializat
Run /waila reload to apply changes server-wide.
Run /wailac reload to apply changes to only your client.
Rule Operators:
@namespace - Filter objects based on their namespace location
#tag - Filter objects based on data pack tags
/regex/ - Filter objects based on regular expression
default - Filter objects with specific ID
%s
The %s tag rule can not be removed"""
.formatted(BLACKLIST_TAG)
.formatted(IRegistryFilter.getHeader(), BLACKLIST_TAG)
.split("\n");

var commentArray = new JsonArray();
Expand Down
48 changes: 31 additions & 17 deletions src/main/java/mcp/mobius/waila/registry/RegistryFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.regex.Pattern;

import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -70,7 +72,13 @@ private void load() {
var entries = new HashSet<T>(this.entries.get().size());

rules.forEach(rule -> registry.holders().forEach(holder -> {
if (rule.matches(holder)) entries.add(holder.value());
if (rule.predicate.test(holder)) {
if (rule.negate) {
entries.remove(holder.value());
} else {
entries.add(holder.value());
}
}
}));

this.entries.set(Collections.unmodifiableSet(entries));
Expand Down Expand Up @@ -98,9 +106,9 @@ public boolean matches(T object) {
return entries.get().contains(object);
}

private interface Rule<T> {

boolean matches(Holder.Reference<T> holder);
private record Rule<T>(
boolean negate,
Predicate<Holder.Reference<T>> predicate) {

}

Expand All @@ -120,38 +128,44 @@ public Builder(ResourceKey<? extends Registry<T>> registryKey) {
}

this.registryKey = registryKey;
this.rules = new HashSet<>();
this.rules = new LinkedHashSet<>();
}

@Override
public IRegistryFilter.Builder<T> parse(String rule) {
var prefix = rule.charAt(0);
if (rule.charAt(0) == '!') {
parse0(rule.substring(1), true);
} else {
parse0(rule, false);
}

switch (prefix) {
return this;
}

private void parse0(String rule, boolean negate) {
switch (rule.charAt(0)) {
case '@' -> {
LOG.debug("\tNamespace: {}", rule);
LOG.debug("\tNegate: {}, Namespace: {}", negate, rule);
var namespace = rule.substring(1);
rules.add(it -> it.key().location().getNamespace().equals(namespace));
rules.add(new Rule<>(negate, it -> it.key().location().getNamespace().equals(namespace)));
}
case '#' -> {
LOG.debug("\tTag : {}", rule);
LOG.debug("\tNegate: {}, Tag : {}", negate, rule);
var tagId = new ResourceLocation(rule.substring(1));
var tag = TagKey.create(registryKey, tagId);
rules.add(it -> it.is(tag));
rules.add(new Rule<>(negate, it -> it.is(tag)));
}
case '/' -> {
LOG.debug("\tRegex : {}", rule);
LOG.debug("\tNegate: {}, Regex : {}", negate, rule);
Preconditions.checkArgument(rule.endsWith("/"), "Regex filter must also ends with /");
var pattern = Pattern.compile(rule.substring(1, rule.length() - 1));
rules.add(it -> pattern.matcher(it.key().location().toString()).matches());
rules.add(new Rule<>(negate, it -> pattern.matcher(it.key().location().toString()).matches()));
}
default -> {
LOG.debug("\tID : {}", rule);
rules.add(it -> it.is(new ResourceLocation(rule)));
LOG.debug("\tNegate: {}, ID : {}", negate, rule);
rules.add(new Rule<>(negate, it -> it.is(new ResourceLocation(rule))));
}
}

return this;
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/mcp/mobius/waila/util/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}

public void debug(String msg) {
logger.debug(PREFIX + msg);
}

public void debug(String msg, Object arg) {
logger.debug(PREFIX + msg, arg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class NetworkConstants {

public static final int NETWORK_VERSION = 8;
public static final int NETWORK_VERSION = 9;

public static final byte CONFIG_BOOL = 0;
public static final byte CONFIG_INT = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,10 @@ public JsonElement serialize(ExtraBlacklistConfig src, Type typeOfSrc, JsonSeria
var comments = """
The game needs to be restarted for the changes to apply.
Operators:
@namespace - Filter objects based on their namespace location
#tag - Filter objects based on data pack tags
/regex/ - Filter objects based on regular expression
default - Filter objects with specific ID
%s
The %s tag rule can not be removed"""
.formatted(tagRule)
.formatted(IRegistryFilter.getHeader(), tagRule)
.split("\n");

var commentArray = new JsonArray();
Expand Down

0 comments on commit 2318a62

Please sign in to comment.