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

Automatic LoreHolder Discovery #101

Merged
merged 3 commits into from
Jan 14, 2025
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
30 changes: 0 additions & 30 deletions src/main/java/com/gtnewhorizon/gtnhlib/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ public class ClientProxy extends CommonProxy {
public static boolean doThreadSafetyChecks = true;
private final Minecraft mc = Minecraft.getMinecraft();

@Override
public void preInit(FMLPreInitializationEvent event) {
super.preInit(event);
}

@Override
public void init(FMLInitializationEvent event) {
super.init(event);
Expand All @@ -59,31 +54,6 @@ public void postInit(FMLPostInitializationEvent event) {
LoreHandler.postInit();
}

@Override
public void serverAboutToStart(FMLServerAboutToStartEvent event) {
super.serverAboutToStart(event);
}

@Override
public void serverStarting(FMLServerStartingEvent event) {
super.serverStarting(event);
}

@Override
public void serverStarted(FMLServerStartedEvent event) {
super.serverStarted(event);
}

@Override
public void serverStopping(FMLServerStoppingEvent event) {
super.serverStopping(event);
}

@Override
public void serverStopped(FMLServerStoppedEvent event) {
super.serverStopped(event);
}

@Override
public void addDebugToChat(String message) {
addDebugToChat(new ChatComponentText(message));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package com.gtnewhorizon.gtnhlib.client.tooltip;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import net.minecraft.client.Minecraft;
Expand All @@ -27,10 +23,6 @@
*/
public final class LoreHandler implements IResourceManagerReloadListener {

/**
* key: field to be updated; value: translation key to use
*/
private static final Map<Field, String> LORE_HOLDERS = new HashMap<>();
private static final Random RANDOM = new Random();

public static void postInit() {
Expand All @@ -42,53 +34,28 @@ private LoreHandler() {}

@Override
public void onResourceManagerReload(IResourceManager p_110549_1_) {
updateLoreHolders();
}

/**
* Register a class containing one or more static fields of type {@link String} annotated with {@link LoreHolder}.
* When the resources are reloaded, the field(s) are updated with a random translation. The possible lines are
* defined via lang files, using the translation key defined by {@link LoreHolder#value()}, appended by an index
* (starting with 0). Blank translations are ignored. The translations may be weighted by using {@code <weight>:} as
* prefix, {@code <weight>} being a non-negative integer. If no weight is specified, a default value of 1 is used.
* To prevent ':' being used as delimiter, escape it using '\'.
*
* @param clazz The class containing the field(s) to be updated when the resources are reloaded
* @since 0.5.21
*/
public static void registerLoreHolder(Class<?> clazz) {
try {
for (Field field : clazz.getDeclaredFields()) {
if (!field.getType().isAssignableFrom(String.class) || !Modifier.isStatic(field.getModifiers()))
continue;

LoreHolder loreHolder = field.getDeclaredAnnotation(LoreHolder.class);
if (loreHolder == null) continue;

field.setAccessible(true);
LORE_HOLDERS.put(field, loreHolder.value());
}
} catch (Exception e) {
GTNHLib.LOG
.error("An exception occured while looking for @LoreHolder annotations in " + clazz.toString(), e);
}
}

private static void updateLoreHolders() {
LORE_HOLDERS.forEach((field, keyPrefix) -> {
LoreHolderDiscoverer.LORE_HOLDERS.forEach((field, keyPrefix) -> {
try {
field.set(null, getRandomLine(keyPrefix));
field.setValue(null, getRandomLine(keyPrefix));
} catch (Exception e) {
GTNHLib.LOG.warn(
"Unable to update LoreHolder in " + field.getDeclaringClass()
"Unable to update LoreHolder in " + field.javaField.getDeclaringClass()
+ " (Field: "
+ field.getName()
+ field.javaField.getName()
+ ")",
e);
}
});
}

/**
* @deprecated As of version 0.6.2, fields are discovered automatically.
* @param clazz The class containing the field(s) to be updated when the resources are reloaded
* @since 0.5.21
*/
@Deprecated
public static void registerLoreHolder(Class<?> clazz) {}

private static String getRandomLine(String keyPrefix) {
List<WeightedRandom.Item> lines = getAllLines(keyPrefix);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

/**
* Annotation used to identify fields which should be updated on a resource refresh. Annotated fields must be static and
* of type {@link String}. To use this, register the declaring class via {@link LoreHandler#registerLoreHolder(Class)}.
* of type {@link String}. When the resources are reloaded, the field(s) are updated with a random translation. The
* possible lines are defined via lang files, using the translation key defined by {@link #value()}, appended by an
* index (starting with 0). Blank translations are ignored. The translations may be weighted by using {@code <weight>:}
* as prefix, {@code <weight>} being a non-negative integer. If no weight is specified, a default value of 1 is used. To
* prevent ':' being used as delimiter, escape it using '\'.
*
* @since 0.5.21
* @author glowredman
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.gtnewhorizon.gtnhlib.client.tooltip;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.gtnewhorizon.gtnhlib.GTNHLib;
import com.gtnewhorizon.gtnhlib.reflect.Fields;
import com.gtnewhorizon.gtnhlib.reflect.Fields.ClassFields;
import com.gtnewhorizon.gtnhlib.reflect.Fields.LookupType;

import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;

public class LoreHolderDiscoverer {

/**
* key: field to be updated; value: translation key to use
*/
static final Map<ClassFields<?>.Field<String>, String> LORE_HOLDERS = new HashMap<>();

public static void harvestData(ASMDataTable table) {
for (ASMData asmData : table.getAll(LoreHolder.class.getName())) {
String className = asmData.getClassName();
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
GTNHLib.LOG.error("Class " + className + " could not be found!", e);
continue;
}

String fieldName = asmData.getObjectName();
ClassFields<?>.Field<String> field;
try {
field = Fields.ofClass(clazz).getField(LookupType.DECLARED, fieldName, String.class);
} catch (ClassCastException e) {
GTNHLib.LOG.error(
"Field " + fieldName + " of class " + className + " is not of type java.lang.String!",
e);
continue;
}
if (field == null) {
GTNHLib.LOG.error("Field {} of class {} could not be found!", fieldName, className);
continue;
}
if (!field.isStatic) {
GTNHLib.LOG.error("Field {} of class {} is not static!", fieldName, className);
continue;
}

String key = (String) asmData.getAnnotationInfo().get("value");
if (StringUtils.isNotBlank(key)) {
LORE_HOLDERS.put(field, key);
}
}
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/gtnewhorizon/gtnhlib/core/GTNHLibCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.gtnewhorizon.gtnhlib.Tags;
import com.gtnewhorizon.gtnhlib.client.tooltip.LoreHolderDiscoverer;
import com.gtnewhorizon.gtnhlib.eventbus.EventBusUtil;
import com.gtnewhorizon.gtnhlib.mixins.Mixins;
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
Expand Down Expand Up @@ -94,5 +95,8 @@ public boolean registerBus(EventBus bus, LoadController controller) {
@Subscribe
public void construct(FMLConstructionEvent event) {
EventBusUtil.harvestData(event.getASMHarvestedData());
if (event.getSide().isClient()) {
LoreHolderDiscoverer.harvestData(event.getASMHarvestedData());
}
}
}