Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for search aliases #3703

Merged
merged 8 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ public interface IIngredientFilterConfig {

boolean getSearchModAliases();

boolean getSearchIngredientAliases();

boolean getSearchShortModNames();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class IngredientFilterConfig implements IIngredientFilterConfig {
public final Supplier<Boolean> searchModIds;
public final Supplier<Boolean> searchModAliases;
public final Supplier<Boolean> searchShortModNames;
public final Supplier<Boolean> searchIngredientAliases;

public IngredientFilterConfig(IConfigSchemaBuilder builder) {
IConfigCategoryBuilder search = builder.addCategory("search");
Expand Down Expand Up @@ -57,13 +58,18 @@ public IngredientFilterConfig(IConfigSchemaBuilder builder) {
searchModAliases = search.addBoolean(
"SearchModAliases",
true,
"Search mod aliases in addition to mod names"
"Search mod aliases (alternative names) that are added by plugins, in addition to mod names"
);
searchShortModNames = search.addBoolean(
"SearchShortModNames",
true,
"Search by the shorthand first letters of a mod's name"
);
searchIngredientAliases = search.addBoolean(
"SearchIngredientAliases",
true,
"Search ingredient aliases (alternative names) that are added by plugins, in addition to ingredient names"
);
}

@Override
Expand Down Expand Up @@ -106,6 +112,11 @@ public boolean getSearchModAliases() {
return searchModAliases.get();
}

@Override
public boolean getSearchIngredientAliases() {
return searchIngredientAliases.get();
}

@Override
public boolean getSearchShortModNames() {
return searchShortModNames.get();
Expand Down
5 changes: 4 additions & 1 deletion Common/src/main/resources/assets/jei/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"jei.tooltip.transfer": "Move Items",
"jei.tooltip.recipe.tag": "Accepts tag: %s",
"jei.tooltip.item.colors": "Colors: %s",
"jei.tooltip.item.search.aliases": "Search Aliases:",
"jei.tooltip.shapeless.recipe": "Shapeless Recipe",
"jei.tooltip.cheat.mode.button.enabled": "Cheat Mode enabled",
"jei.tooltip.cheat.mode.how.to.disable.hotkey": "Press \"%s\" to toggle it.",
Expand Down Expand Up @@ -201,5 +202,7 @@
"description.jei.wooden.door.3": "Wooden Doors can be opened/closed via redstone circuits.",
"description.jei.debug.formatting.1": "Testing %s formatting replacements.",
"description.jei.debug.formatting.2": "Testing %s %s formatting replacements.",
"description.jei.debug.formatting.3": "%s nested"
"description.jei.debug.formatting.3": "%s nested",
"jei.alias.panda.spawn.egg": "endangered",
"jei.alias.villager.spawn.egg": "HMMM"
}
12 changes: 12 additions & 0 deletions CommonApi/src/main/java/mezz/jei/api/IModPlugin.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mezz.jei.api;

import mezz.jei.api.helpers.IPlatformFluidHelper;
import mezz.jei.api.registration.IIngredientAliasRegistration;
import mezz.jei.api.registration.IModInfoRegistration;
import mezz.jei.api.registration.IRuntimeRegistration;
import mezz.jei.api.runtime.config.IJeiConfigManager;
Expand Down Expand Up @@ -53,6 +54,17 @@ default void registerIngredients(IModIngredientRegistration registration) {

}

/**
* Register search aliases for ingredients.
*
* @implNote If the player has disabled search aliases in the config, this will not be called.
*
* @since 19.10.0
*/
default void registerIngredientAliases(IIngredientAliasRegistration registration) {

}

/**
* Register extra info about a mod, such as aliases for the mod that users can search for.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package mezz.jei.api.registration;

import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient;

import java.util.Collection;
import java.util.List;

/**
* Allows registration of search aliases for ingredients.
* Search aliases allow mods to add alternative names for ingredients, to help players find them more easily.
*
* @since 19.10.0
*/
public interface IIngredientAliasRegistration {
/**
* Register a search alias for an ingredient.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAlias(IIngredientType<I> type, I ingredient, String alias);

/**
* Register a search alias for an ingredient.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAlias(ITypedIngredient<I> typedIngredient, String alias);

/**
* Register multiple search aliases for an ingredient.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(IIngredientType<I> type, I ingredient, Collection<String> aliases);

/**
* Register multiple search aliases for an ingredient.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(ITypedIngredient<I> typedIngredient, Collection<String> aliases);

/**
* Register a search aliases for multiple ingredients.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(IIngredientType<I> type, Collection<I> ingredients, String alias);

/**
* Register a search aliases for multiple ingredients.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(Collection<ITypedIngredient<I>> typedIngredients, String alias);

/**
* Register multiple search aliases for multiple ingredients.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(IIngredientType<I> type, Collection<I> ingredients, Collection<String> aliases);

/**
* Register multiple search aliases for multiple ingredients.
* An alias may be a translation key.
*
* @since 19.10.0
*/
<I> void addAliases(Collection<ITypedIngredient<I>> typedIngredients, Collection<String> aliases);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import mezz.jei.api.ingredients.IIngredientTypeWithSubtypes;
import mezz.jei.api.ingredients.ITypedIngredient;
import mezz.jei.api.ingredients.subtypes.UidContext;
import mezz.jei.api.registration.IIngredientAliasRegistration;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Unmodifiable;

Expand Down Expand Up @@ -176,6 +177,16 @@ default <V> Optional<ITypedIngredient<V>> createTypedIngredient(V ingredient) {
@Deprecated(since = "19.9.0", forRemoval = true)
<V> Optional<ITypedIngredient<V>> getTypedIngredientByUid(IIngredientType<V> ingredientType, String ingredientUuid);

/**
* Get localized search aliases for ingredients.
* Registered by mods with {@link IIngredientAliasRegistration#addAlias}.
*
* If search aliases are disabled by the player in the configs, this will return an empty collection.
*
* @since 19.10.0
*/
Collection<String> getIngredientAliases(ITypedIngredient<?> ingredient);

/**
* Add a listener to receive updates when ingredients are added or removed from the ingredient manager.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

public interface IListElementInfo<V> {

String getName();
List<String> getNames();

String getModNameForSorting();

Expand All @@ -39,5 +39,4 @@ public interface IListElementInfo<V> {
void setSortedIndex(int sortIndex);

int getSortedIndex();

}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private static Comparator<IListElementInfo<?>> getCreativeMenuComparator() {
}

private static Comparator<IListElementInfo<?>> getAlphabeticalComparator() {
return Comparator.comparing(IListElementInfo::getName);
return Comparator.comparing(i -> i.getNames().getFirst());
}

private Comparator<IListElementInfo<?>> getModNameComparator() {
Expand Down
39 changes: 26 additions & 13 deletions Gui/src/main/java/mezz/jei/gui/ingredients/ListElementInfo.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package mezz.jei.gui.ingredients;

import com.google.common.collect.ImmutableSet;
import mezz.jei.api.helpers.IModIdHelper;
import mezz.jei.api.ingredients.IIngredientHelper;
import mezz.jei.api.ingredients.IIngredientRenderer;
import mezz.jei.api.ingredients.ITypedIngredient;
import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.common.config.IIngredientFilterConfig;
import mezz.jei.common.util.SafeIngredientUtil;
import mezz.jei.common.util.Translator;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.TooltipFlag;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
Expand All @@ -25,7 +26,7 @@ public class ListElementInfo<V> implements IListElementInfo<V> {
private static final Logger LOGGER = LogManager.getLogger();

private final IListElement<V> element;
private final String displayNameLowercase;
private final List<String> names;
private final List<String> modIds;
private final List<String> modNames;
private final ResourceLocation resourceLocation;
Expand All @@ -36,7 +37,7 @@ public static <V> IListElementInfo<V> create(IListElement<V> element, IIngredien
ITypedIngredient<V> value = element.getTypedIngredient();
IIngredientHelper<V> ingredientHelper = ingredientManager.getIngredientHelper(value.getType());
try {
return new ListElementInfo<>(element, ingredientHelper, modIdHelper);
return new ListElementInfo<>(element, ingredientHelper, ingredientManager, modIdHelper);
} catch (RuntimeException e) {
try {
String ingredientInfo = ingredientHelper.getErrorInfo(value.getIngredient());
Expand All @@ -48,7 +49,7 @@ public static <V> IListElementInfo<V> create(IListElement<V> element, IIngredien
}
}

protected ListElementInfo(IListElement<V> element, IIngredientHelper<V> ingredientHelper, IModIdHelper modIdHelper) {
protected ListElementInfo(IListElement<V> element, IIngredientHelper<V> ingredientHelper, IIngredientManager ingredientManager, IModIdHelper modIdHelper) {
this.element = element;
ITypedIngredient<V> value = element.getTypedIngredient();
V ingredient = value.getIngredient();
Expand All @@ -65,12 +66,24 @@ protected ListElementInfo(IListElement<V> element, IIngredientHelper<V> ingredie
modIdHelper.getModNameForModId(displayModId)
);
}
this.displayNameLowercase = DisplayNameUtil.getLowercaseDisplayNameForSearch(ingredient, ingredientHelper);

String displayNameLowercase = DisplayNameUtil.getLowercaseDisplayNameForSearch(ingredient, ingredientHelper);
Collection<String> aliases = ingredientManager.getIngredientAliases(value);
if (aliases.isEmpty()) {
this.names = List.of(displayNameLowercase);
} else {
this.names = new ArrayList<>(1 + aliases.size());
this.names.add(displayNameLowercase);
for (String alias : aliases) {
String lowercaseAlias = Translator.toLowercaseWithLocale(alias);
this.names.add(lowercaseAlias);
}
}
}

@Override
public String getName() {
return this.displayNameLowercase;
public List<String> getNames() {
return names;
}

@Override
Expand All @@ -91,20 +104,20 @@ public List<String> getModIds() {
@Override
@Unmodifiable
public final Set<String> getTooltipStrings(IIngredientFilterConfig config, IIngredientManager ingredientManager) {
String modName = this.modNames.getFirst();
String modId = this.modIds.getFirst();
String modNameLowercase = modName.toLowerCase(Locale.ENGLISH);
ITypedIngredient<V> value = element.getTypedIngredient();
IIngredientRenderer<V> ingredientRenderer = ingredientManager.getIngredientRenderer(value.getType());
ImmutableSet<String> toRemove = ImmutableSet.of(modId, modNameLowercase, displayNameLowercase, resourceLocation.getPath());
TooltipFlag.Default tooltipFlag = config.getSearchAdvancedTooltips() ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL;
tooltipFlag = tooltipFlag.asCreative();

ListElementInfoTooltip tooltip = new ListElementInfoTooltip();
SafeIngredientUtil.getTooltip(tooltip, ingredientManager, ingredientRenderer, value, tooltipFlag);

Set<String> strings = tooltip.getStrings();
strings.removeAll(toRemove);

strings.remove(this.names.getFirst());
strings.remove(this.modNames.getFirst().toLowerCase(Locale.ENGLISH));
strings.remove(this.modIds.getFirst());
strings.remove(resourceLocation.getPath());

return strings;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;

import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

Expand Down Expand Up @@ -51,11 +52,33 @@ public <T> void getIngredientTooltip(
addColorSearchInfoToTooltip(tooltip, typedIngredient, ingredientHelper);
}

if (ingredientFilterConfig.getSearchIngredientAliases()) {
addIngredientAliasesToTooltip(tooltip, typedIngredient, ingredientManager);
}

if (toggleState.isEditModeEnabled()) {
addEditModeInfoToTooltip(tooltip, keyBindings);
}
}

private <T> void addIngredientAliasesToTooltip(JeiTooltip tooltip, ITypedIngredient<T> typedIngredient, IIngredientManager ingredientManager) {
Collection<String> aliases = ingredientManager.getIngredientAliases(typedIngredient);
if (aliases.isEmpty()) {
return;
}
tooltip.add(Component.empty());
tooltip.add(
Component.translatable("jei.tooltip.item.search.aliases")
.withStyle(ChatFormatting.GRAY)
);
for (String alias : aliases) {
tooltip.add(
Component.literal("• " + alias)
.withStyle(ChatFormatting.GRAY)
);
}
}

private <T> void addColorSearchInfoToTooltip(JeiTooltip tooltip, ITypedIngredient<T> typedIngredient, IIngredientHelper<T> ingredientHelper) {
Iterable<Integer> colors = ingredientHelper.getColors(typedIngredient.getIngredient());
String colorNamesString = StreamSupport.stream(colors.spliterator(), false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class ElementPrefixParser {
public static final PrefixInfo<IListElementInfo<?>> NO_PREFIX = new PrefixInfo<>(
'\0',
() -> SearchMode.ENABLED,
i -> List.of(i.getName()),
IListElementInfo::getNames,
GeneralizedSuffixTree::new
);
private static final Pattern SPACE_PATTERN = Pattern.compile("\\s");
Expand Down
Loading