1
0
mirror of https://github.com/chylex/Resource-Pack-Organizer.git synced 2025-04-10 18:15:45 +02:00

Reimplement overlay rendering w/ configuration

This commit is contained in:
chylex 2020-02-23 05:43:45 +01:00
parent 84422d17b3
commit f87ff636a4
4 changed files with 161 additions and 191 deletions

View File

@ -1,113 +1,51 @@
package chylex.respack;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.config.ConfigGuiType;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.GuiUtils;
import net.minecraftforge.fml.client.config.IConfigElement;
import com.google.common.collect.ImmutableList;
import chylex.respack.gui.RenderPackListOverlay;
import com.electronwill.nightconfig.core.EnumGetMethod;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.ForgeConfigSpec.EnumValue;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.stream.Collectors;
public class ConfigHandler{
private final Configuration config;
public final Options options;
public final class ConfigHandler{
public static final ForgeConfigSpec SPEC;
ConfigHandler(File file){
this.config = new Configuration(file);
this.config.load();
this.options = new Options();
reload();
}
public static EnumValue<DisplayPosition> DISPLAY_POSITION;
public static EnumValue<TextFormatting> DISPLAY_COLOR;
public List<IConfigElement> getGuiConfigElements(){
List<IConfigElement> originalElements = new ConfigElement(config.getCategory("client")).getChildElements();
List<IConfigElement> usedElements = new ArrayList<>();
static{
ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
EnumGetMethod getter = EnumGetMethod.NAME_IGNORECASE;
for(IConfigElement element : originalElements){
if (element.getName().equals("displayColor")){
usedElements.add(new ConfigElement(config.getCategory("client").get("displayColor")){
@Override
public ConfigGuiType getType(){
return ConfigGuiType.COLOR;
}
});
}
else{
usedElements.add(element);
}
}
DISPLAY_POSITION = builder.defineEnum("displayPosition", DisplayPosition.DISABLED, getter);
DISPLAY_COLOR = builder.defineEnum("displayColor", TextFormatting.WHITE, getter, value -> getter.validate(value, TextFormatting.class) && getter.get(value, TextFormatting.class).isColor());
return usedElements;
}
public String getGuiConfigString(){
return GuiConfig.getAbridgedConfigPath(config.toString());
}
public void reload(){
options.updateOptions();
SPEC = builder.build();
if (config.hasChanged()){
config.save();
}
}
public class Options{
private String displayPosition = "disabled";
private char displayColor = 'f';
private String[] enabledPacks;
private Property propEnabledPacks;
void updateOptions(){
displayPosition = config.getString("displayPosition", "client", "disabled", "Sets the position of active resource pack list on the screen. Valid values are: disabled, top left, top right, bottom right, bottom left", DisplayPosition.validValues);
try{
String fixedComment = "Allowed Values: " + Arrays.stream(TextFormatting.values()).filter(TextFormatting::isColor).map(Enum::name).collect(Collectors.joining(", "));
String color = config.getString("displayColor", "client", "f", "Sets the color of active resource pack list. Valid value is a single lowercase hexadecimal character (0 to f) where '0' is black and 'f' is white", "f0123456789abcde".split(""));
if (!color.isEmpty())displayColor = color.charAt(0);
Object o = SPEC.get("displayColor");
Field f = o.getClass().getDeclaredField("comment");
f.setAccessible(true);
propEnabledPacks = config.get("client", "enabledPacks", new String[0], "Internal list of enabled resource packs.");
propEnabledPacks.setShowInGui(false);
enabledPacks = propEnabledPacks.getStringList();
if (enabledPacks.length == 0){
List<String> packs = Minecraft.getMinecraft().gameSettings.resourcePacks;
enabledPacks = packs.toArray(new String[packs.size()]);
}
}
public DisplayPosition getDisplayPosition(){
for(int index = 0; index < DisplayPosition.validValues.length; index++){
if (DisplayPosition.validValues[index].equals(displayPosition)){
return DisplayPosition.values()[index];
}
}
return DisplayPosition.DISABLED;
}
public int getDisplayColor(){
return GuiUtils.getColorCode(displayColor, true);
}
public List<String> getEnabledPacks(){
return ImmutableList.copyOf(enabledPacks);
}
public void updateEnabledPacks(){
List<String> packs = Minecraft.getMinecraft().gameSettings.resourcePacks;
propEnabledPacks.set(packs.toArray(new String[packs.size()]));
config.save();
}
FieldUtils.removeFinalModifier(f, true);
f.set(o, fixedComment);
}catch(Throwable ignored){}
}
public enum DisplayPosition{
DISABLED, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT;
static String[] validValues = new String[]{ "disabled", "top left", "top right", "bottom right", "bottom left" };
DISABLED, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, BOTTOM_LEFT
}
public static void onConfigUpdated(){
if (DISPLAY_POSITION.get() == DisplayPosition.DISABLED){
RenderPackListOverlay.unregister();
}
else{
RenderPackListOverlay.register();
}
}
}

View File

@ -1,6 +1,9 @@
package chylex.respack;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.config.ModConfig.Type;
import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@ -10,6 +13,17 @@ public final class ResourcePackOrganizer{
public ResourcePackOrganizer(){
FMLJavaModLoadingContext.get().getModEventBus().register(this);
ModLoadingContext.get().registerConfig(Type.CLIENT, ConfigHandler.SPEC);
}
@SubscribeEvent
public void onConfigLoading(ModConfig.Loading e){
ConfigHandler.onConfigUpdated();
}
@SubscribeEvent
public void onConfigReloading(ModConfig.Reloading e){
ConfigHandler.onConfigUpdated();
}
@SubscribeEvent

View File

@ -0,0 +1,110 @@
package chylex.respack.gui;
import chylex.respack.ConfigHandler;
import chylex.respack.ConfigHandler.DisplayPosition;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.screen.ResourcePacksScreen;
import net.minecraft.client.resources.ClientResourcePackInfo;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static chylex.respack.ConfigHandler.DisplayPosition.BOTTOM_LEFT;
import static chylex.respack.ConfigHandler.DisplayPosition.BOTTOM_RIGHT;
import static chylex.respack.ConfigHandler.DisplayPosition.TOP_LEFT;
import static chylex.respack.ConfigHandler.DisplayPosition.TOP_RIGHT;
@OnlyIn(Dist.CLIENT)
public final class RenderPackListOverlay{
private static final RenderPackListOverlay instance = new RenderPackListOverlay();
private static final Minecraft mc = Minecraft.getInstance();
private static boolean isRegistered;
public static void register(){
if (isRegistered){
return;
}
isRegistered = true;
MinecraftForge.EVENT_BUS.register(instance);
instance.refresh();
}
public static void unregister(){
if (!isRegistered){
return;
}
isRegistered = false;
MinecraftForge.EVENT_BUS.unregister(instance);
}
private List<String> packNames = new ArrayList<>(4);
private void refresh(){
packNames.clear();
List<ClientResourcePackInfo> packs = new ArrayList<>(mc.getResourcePackList().getEnabledPacks());
Collections.reverse(packs);
for(ClientResourcePackInfo pack : packs){
if (!pack.isAlwaysEnabled()){
packNames.add(StringUtils.removeEndIgnoreCase(pack.getTitle().getString(), ".zip"));
}
}
}
@SubscribeEvent(priority = EventPriority.HIGHEST, receiveCanceled = true)
public void onGuiOpen(GuiOpenEvent e){
if (mc.currentScreen instanceof ResourcePacksScreen){
refresh();
}
}
@SubscribeEvent
public void onRenderGameOverlay(RenderGameOverlayEvent.Post e){
if (e.getType() == ElementType.TEXT && !packNames.isEmpty()){
DisplayPosition position = ConfigHandler.DISPLAY_POSITION.get();
if ((position == TOP_LEFT || position == TOP_RIGHT) && mc.gameSettings.showDebugInfo){
return;
}
FontRenderer font = mc.fontRenderer;
int color = Objects.requireNonNull(ConfigHandler.DISPLAY_COLOR.get().getColor());
int edgeDist = 3, topOffset = 2;
int ySpacing = font.FONT_HEIGHT;
int x = position == TOP_LEFT || position == BOTTOM_LEFT ? edgeDist : e.getWindow().getScaledWidth() - edgeDist;
int y = position == TOP_LEFT || position == TOP_RIGHT ? edgeDist : e.getWindow().getScaledHeight() - edgeDist - topOffset - ySpacing * (1 + packNames.size());
boolean alignRight = position == TOP_RIGHT || position == BOTTOM_RIGHT;
renderText(font, TextFormatting.UNDERLINE + "Resource Packs", x, y, color, alignRight);
for(int line = 0; line < packNames.size(); line++){
renderText(font, packNames.get(line), x, y + topOffset + (line + 1) * ySpacing, color, alignRight);
}
}
}
private static void renderText(FontRenderer renderer, String line, int x, int y, int color, boolean alignRight){
if (color == 0){
renderer.drawString(line, alignRight ? x - renderer.getStringWidth(line) : x, y, color);
}
else{
renderer.drawStringWithShadow(line, alignRight ? x - renderer.getStringWidth(line) : x, y, color);
}
}
}

View File

@ -1,92 +0,0 @@
package chylex.respack.render;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.ResourcePackRepository;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import chylex.respack.ConfigHandler.DisplayPosition;
import chylex.respack.ResourcePackOrganizer;
import com.google.common.collect.Lists;
public final class RenderPackListOverlay{
private static final RenderPackListOverlay instance = new RenderPackListOverlay();
private static boolean isRegistered;
public static void register(){
if (isRegistered)return;
isRegistered = true;
MinecraftForge.EVENT_BUS.register(instance);
refreshPackNames();
}
public static void unregister(){
if (!isRegistered)return;
isRegistered = false;
MinecraftForge.EVENT_BUS.unregister(instance);
}
@SideOnly(Side.CLIENT)
public static void refreshPackNames(){
instance.refresh();
}
private List<String> packNames = new ArrayList<>(4);
@SideOnly(Side.CLIENT)
private void refresh(){
packNames.clear();
List<ResourcePackRepository.Entry> entries = Lists.reverse(Minecraft.getMinecraft().getResourcePackRepository().getRepositoryEntries());
for(ResourcePackRepository.Entry entry : entries){
String name = entry.getResourcePackName();
if (name.endsWith(".zip")){
name = name.substring(0, name.length()-4);
}
packNames.add(name);
}
}
@SubscribeEvent(receiveCanceled = true)
@SideOnly(Side.CLIENT)
public void onRenderGameOverlay(RenderGameOverlayEvent.Post e){
if (e.getType() == ElementType.TEXT && !packNames.isEmpty()){
DisplayPosition position = ResourcePackOrganizer.getConfig().options.getDisplayPosition();
if ((position == DisplayPosition.TOP_LEFT || position == DisplayPosition.TOP_RIGHT) && Minecraft.getMinecraft().gameSettings.showDebugInfo){
return;
}
final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
final int color = ResourcePackOrganizer.getConfig().options.getDisplayColor();
final int edgeDist = 3, topOffset = 2;
final int ySpacing = font.FONT_HEIGHT;
int x = position == DisplayPosition.TOP_LEFT || position == DisplayPosition.BOTTOM_LEFT ? edgeDist : e.getResolution().getScaledWidth()-edgeDist;
int y = position == DisplayPosition.TOP_LEFT || position == DisplayPosition.TOP_RIGHT ? edgeDist : e.getResolution().getScaledHeight()-edgeDist-topOffset-ySpacing*(1+packNames.size());
boolean alignRight = position == DisplayPosition.TOP_RIGHT || position == DisplayPosition.BOTTOM_RIGHT;
renderText(font, TextFormatting.UNDERLINE+"Resource Packs", x, y, color, alignRight);
for(int line = 0; line < packNames.size(); line++){
renderText(font, packNames.get(line), x, y+topOffset+(line+1)*ySpacing, color, alignRight);
}
}
}
private static void renderText(FontRenderer renderer, String line, int x, int y, int color, boolean alignRight){
renderer.drawString(line, alignRight ? x-renderer.getStringWidth(line) : x, y, color, color != 0);
}
}