1
0
mirror of https://github.com/chylex/Resource-Pack-Organizer.git synced 2025-01-21 12:46:04 +01:00

Update to Minecraft 1.8.9

This commit is contained in:
chylex 2016-06-15 18:41:30 +02:00
parent 7e1ba9ab06
commit 05817d1524
14 changed files with 120 additions and 104 deletions

2
.gitignore vendored
View File

@ -1,9 +1,11 @@
bin/
build/
eclipse/
run/
.gradle/
.settings/
.classpath
.project
.DS_Store
Thumbs.db
*.launch

View File

@ -1,28 +1,23 @@
buildscript{
repositories{
mavenCentral()
jcenter()
maven{
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven{
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies{
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT'
}
}
apply plugin: 'forge'
archivesBaseName = "BetterResourcePacks"
apply plugin: 'net.minecraftforge.gradle.forge'
minecraft{
version = "1.7.10-10.13.4.1614-1.7.10"
runDir = "eclipse"
version = "1.8.9-11.15.1.1902-1.8.9"
runDir = "run"
mappings = "stable_20"
makeObfSourceJar = false
}
String modid = ""
@ -39,4 +34,4 @@ processResources{
jar{
archiveName = modid+" MC-"+project.minecraft.version+" v"+modver+".jar"
}
}

Binary file not shown.

View File

@ -1,6 +1,6 @@
#Wed Jul 02 15:54:47 CDT 2014
#Mon Sep 14 12:28:28 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip

View File

@ -4,10 +4,10 @@ import java.util.ArrayList;
import java.util.List;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import cpw.mods.fml.client.config.ConfigGuiType;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.config.GuiUtils;
import cpw.mods.fml.client.config.IConfigElement;
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;
public class ConfigHandler{
private final Configuration config;

View File

@ -4,20 +4,20 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreenResourcePacks;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.FMLLog;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import chylex.respack.ConfigHandler.DisplayPosition;
import chylex.respack.gui.GuiCustomResourcePacks;
import chylex.respack.render.RenderPackListOverlay;
import cpw.mods.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.network.NetworkCheckHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@Mod(modid = ResourcePackOrganizer.MODID, name = ResourcePackOrganizer.MODNAME, useMetadata = true, guiFactory = "chylex.respack.gui.GuiModConfig")
public final class ResourcePackOrganizer{
@ -41,7 +41,6 @@ public final class ResourcePackOrganizer{
onConfigLoaded();
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
RenderPackListOverlay.refreshPackNames();
}

View File

@ -1,5 +1,6 @@
package chylex.respack.gui;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.Iterator;
@ -13,16 +14,17 @@ import net.minecraft.client.gui.GuiScreenResourcePacks;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.resources.ResourcePackListEntry;
import net.minecraft.client.resources.ResourcePackListEntryDefault;
import net.minecraft.client.resources.ResourcePackListEntryFound;
import net.minecraft.client.resources.ResourcePackRepository;
import net.minecraft.client.resources.ResourcePackRepository.Entry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import chylex.respack.packs.ResourcePackListEntryFolder;
import chylex.respack.packs.ResourcePackListProcessor;
import chylex.respack.render.RenderPackListOverlay;
import com.google.common.collect.Lists;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
@ -31,8 +33,8 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
private GuiTextField searchField;
private GuiResourcePackAvailable guiPacksAvailable;
private GuiResourcePackSelected guiPacksSelected;
private List<ResourcePackListEntryFound> listPacksAvailable, listPacksAvailableProcessed, listPacksDummy;
private List<ResourcePackListEntryFound> listPacksSelected;
private List<ResourcePackListEntry> listPacksAvailable, listPacksAvailableProcessed, listPacksDummy;
private List<ResourcePackListEntry> listPacksSelected;
private ResourcePackListProcessor listProcessor;
private File currentFolder;
@ -55,7 +57,7 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
buttonList.add(new GuiOptionButton(11,width/2-204+44,height-26,40,20,"Z-A"));
buttonList.add(new GuiOptionButton(20,width/2-74,height-26,70,20,"Refresh"));
searchField = new GuiTextField(fontRendererObj,width/2-203,height-46,198,16);
searchField = new GuiTextField(30,fontRendererObj,width/2-203,height-46,198,16);
listPacksAvailable = Lists.newArrayListWithCapacity(8);
listPacksAvailableProcessed = Lists.newArrayListWithCapacity(8);
@ -68,9 +70,11 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
currentFolder = repository.getDirResourcepacks();
listPacksAvailable.addAll(createAvailablePackList(repository));
for(Entry entry:(List<Entry>)Lists.reverse(repository.getRepositoryEntries())){
for(Entry entry:Lists.reverse(repository.getRepositoryEntries())){
listPacksSelected.add(new ResourcePackListEntryFound(this,entry));
}
listPacksSelected.add(new ResourcePackListEntryDefault(this));
guiPacksAvailable = new GuiResourcePackAvailable(mc,200,height,listPacksAvailableProcessed);
guiPacksAvailable.setSlotXBoundsFromLeft(width/2-204);
@ -119,24 +123,33 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
@Override
protected void mouseClicked(int mouseX, int mouseY, int buttonId){
if (buttonId == 0){
for(GuiButton button:(List<GuiButton>)buttonList){
for(GuiButton button:buttonList){
if (button.mousePressed(mc,mouseX,mouseY)){
selectedButton = button;
button.func_146113_a(mc.getSoundHandler());
button.playPressSound(mc.getSoundHandler());
actionPerformed(button);
}
}
}
guiPacksAvailable.func_148179_a(mouseX,mouseY,buttonId);
guiPacksSelected.func_148179_a(mouseX,mouseY,buttonId);
guiPacksAvailable.mouseClicked(mouseX,mouseY,buttonId);
guiPacksSelected.mouseClicked(mouseX,mouseY,buttonId);
searchField.mouseClicked(mouseX,mouseY,buttonId);
listProcessor.refresh();
}
@Override
protected void mouseMovedOrUp(int mouseX, int mouseY, int eventType){
public void handleMouseInput() throws IOException{
try{
super.handleMouseInput();
}catch(NullPointerException e){
// calls super.handleMouseInput and then attempts to use selectedResourcePacksList and availableResourcePacksList which are null
}
}
@Override
protected void mouseReleased(int mouseX, int mouseY, int eventType){
if (eventType == 0 && selectedButton != null){
selectedButton.mouseReleased(mouseX,mouseY);
selectedButton = null;
@ -144,7 +157,7 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
}
@Override
protected void keyTyped(char keyChar, int keyCode){
protected void keyTyped(char keyChar, int keyCode) throws IOException{
super.keyTyped(keyChar,keyCode);
if (searchField.isFocused()){
@ -184,15 +197,19 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
public List<Entry> refreshSelectedPacks(){
List<Entry> selected = Lists.newArrayListWithCapacity(listPacksSelected.size());
for(ResourcePackListEntryFound entry:listPacksSelected){
if (entry.func_148318_i() != null){
selected.add(entry.func_148318_i());
for(ResourcePackListEntry entry:listPacksSelected){
if (!(entry instanceof ResourcePackListEntryFound))continue;
ResourcePackListEntryFound packEntry = (ResourcePackListEntryFound)entry;
if (packEntry.func_148318_i() != null){
selected.add(packEntry.func_148318_i());
}
}
Collections.reverse(selected);
mc.getResourcePackRepository().func_148527_a(selected);
mc.getResourcePackRepository().setRepositories(selected);
return selected;
}
@ -203,7 +220,7 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
guiPacksSelected.drawScreen(mouseX,mouseY,partialTickTime);
searchField.drawTextBox();
for(GuiButton button:(List<GuiButton>)buttonList){
for(GuiButton button:buttonList){
button.drawButton(mc,mouseX,mouseY);
}
}
@ -253,24 +270,24 @@ public class GuiCustomResourcePacks extends GuiScreenResourcePacks{
// OVERRIDES FROM GuiScreenResourcePacks
@Override
public boolean func_146961_a(ResourcePackListEntry entry){
public boolean hasResourcePackEntry(ResourcePackListEntry entry){
return listPacksSelected.contains(entry);
}
@Override
public List func_146962_b(ResourcePackListEntry entry){
return func_146961_a(entry) ? listPacksSelected : listPacksAvailable;
public List getListContaining(ResourcePackListEntry entry){
return hasResourcePackEntry(entry) ? listPacksSelected : listPacksAvailable;
}
@Override
public List func_146964_g(){
public List<ResourcePackListEntry> getAvailableResourcePacks(){
hasUpdated = true;
listPacksDummy.clear();
return listPacksDummy;
}
@Override
public List func_146963_h(){
public List<ResourcePackListEntry> getSelectedResourcePacks(){
hasUpdated = true;
return listPacksSelected;
}

View File

@ -2,11 +2,11 @@ package chylex.respack.gui;
import java.util.Set;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.IModGuiFactory;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import chylex.respack.ResourcePackOrganizer;
import cpw.mods.fml.client.IModGuiFactory;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public final class GuiModConfig implements IModGuiFactory{
@Override

View File

@ -4,13 +4,13 @@ import java.net.URI;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.Util;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.Sys;
import org.lwjgl.opengl.GL11;
import chylex.respack.packs.ResourcePackListEntryFolder;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public final class GuiUtils{
@ -44,33 +44,33 @@ public final class GuiUtils{
}
}
public static void renderFolderEntry(ResourcePackListEntryFolder entry, int p_148279_1_, int p_148279_2_, int p_148279_3_, int p_148279_4_, int p_148279_5_, Tessellator p_148279_6_, int p_148279_7_, int p_148279_8_, boolean p_148279_9_){
public static void renderFolderEntry(ResourcePackListEntryFolder entry, int x, int y, boolean isSelected){
entry.func_148313_c();
GL11.glColor4f(1.0F,1.0F,1.0F,1.0F);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA);
Gui.func_146110_a(p_148279_2_,p_148279_3_,0.0F,0.0F,32,32,32.0F,32.0F);
GL11.glDisable(GL11.GL_BLEND);
GlStateManager.color(1F,1F,1F,1F);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA);
Gui.drawModalRectWithCustomSizedTexture(x,y,0F,0F,32,32,32F,32F);
GlStateManager.disableBlend();
int i2;
if ((mc.gameSettings.touchscreen||p_148279_9_)&&entry.func_148310_d()){
Gui.drawRect(p_148279_2_,p_148279_3_,p_148279_2_+32,p_148279_3_+32,-1601138544);
GL11.glColor4f(1.0F,1.0F,1.0F,1.0F);
if ((mc.gameSettings.touchscreen||isSelected)&&entry.func_148310_d()){
Gui.drawRect(x,y,x+32,y+32,-1601138544);
GlStateManager.color(1F,1F,1F,1F);
}
String s = entry.func_148312_b();
i2 = mc.fontRenderer.getStringWidth(s);
i2 = mc.fontRendererObj.getStringWidth(s);
if (i2>157){
s = mc.fontRenderer.trimStringToWidth(s,157-mc.fontRenderer.getStringWidth("..."))+"...";
s = mc.fontRendererObj.trimStringToWidth(s,157-mc.fontRendererObj.getStringWidth("..."))+"...";
}
mc.fontRenderer.drawStringWithShadow(s,p_148279_2_+32+2,p_148279_3_+1,16777215);
List list = mc.fontRenderer.listFormattedStringToWidth(entry.func_148311_a(),157);
mc.fontRendererObj.drawStringWithShadow(s,x+32+2,y+1,16777215);
List list = mc.fontRendererObj.listFormattedStringToWidth(entry.func_148311_a(),157);
for(int j2 = 0; j2<2&&j2<list.size(); ++j2){
mc.fontRenderer.drawStringWithShadow((String)list.get(j2),p_148279_2_+32+2,p_148279_3_+12+10*j2,8421504);
mc.fontRendererObj.drawStringWithShadow((String)list.get(j2),x+32+2,y+12+10*j2,8421504);
}
}
}

View File

@ -1,8 +1,8 @@
package chylex.respack.packs;
import chylex.respack.gui.GuiCustomResourcePacks;
import net.minecraft.client.resources.ResourcePackListEntryFound;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import chylex.respack.gui.GuiCustomResourcePacks;
@SideOnly(Side.CLIENT)
public abstract class ResourcePackListEntryCustom extends ResourcePackListEntryFound{

View File

@ -1,11 +1,10 @@
package chylex.respack.packs;
import java.io.File;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import chylex.respack.gui.GuiCustomResourcePacks;
import chylex.respack.gui.GuiUtils;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ResourcePackListEntryFolder extends ResourcePackListEntryCustom{
@ -35,7 +34,7 @@ public class ResourcePackListEntryFolder extends ResourcePackListEntryCustom{
@Override
public void func_148313_c(){
field_148317_a.getTextureManager().bindTexture(folderResource);
mc.getTextureManager().bindTexture(folderResource);
}
@Override
@ -55,7 +54,7 @@ public class ResourcePackListEntryFolder extends ResourcePackListEntryCustom{
}
@Override
public void drawEntry(int p_148279_1_, int p_148279_2_, int p_148279_3_, int p_148279_4_, int p_148279_5_, Tessellator p_148279_6_, int p_148279_7_, int p_148279_8_, boolean p_148279_9_){
GuiUtils.renderFolderEntry(this,p_148279_1_,p_148279_2_,p_148279_3_,p_148279_4_,p_148279_5_,p_148279_6_,p_148279_7_,p_148279_8_,p_148279_9_);
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected){
GuiUtils.renderFolderEntry(this,x,y,isSelected);
}
}

View File

@ -3,15 +3,17 @@ import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import net.minecraft.client.resources.ResourcePackListEntry;
import net.minecraft.client.resources.ResourcePackListEntryFound;
public class ResourcePackListProcessor{
private static String name(ResourcePackListEntryFound entry){
private static String name(ResourcePackListEntry entry){
if (entry instanceof ResourcePackListEntryCustom)return ((ResourcePackListEntryCustom)entry).func_148312_b();
return entry.func_148318_i().getResourcePackName();
else if (entry instanceof ResourcePackListEntryFound)return ((ResourcePackListEntryFound)entry).func_148318_i().getResourcePackName();
else return "<INVALID>";
}
private static String nameSort(ResourcePackListEntryFound entry, boolean reverse){
private static String nameSort(ResourcePackListEntry entry, boolean reverse){
String pfx1 = !reverse ? "a" : "z";
String pfx2 = !reverse ? "b" : "z";
String pfx3 = !reverse ? "z" : "a";
@ -22,40 +24,42 @@ public class ResourcePackListProcessor{
}
if (entry instanceof ResourcePackListEntryCustom)return pfx3+((ResourcePackListEntryCustom)entry).func_148312_b();
return pfx3+entry.func_148318_i().getResourcePackName();
else if (entry instanceof ResourcePackListEntryFound)return pfx3+((ResourcePackListEntryFound)entry).func_148318_i().getResourcePackName();
else return pfx3+"<INVALID>";
}
private static String description(ResourcePackListEntryFound entry){
private static String description(ResourcePackListEntry entry){
if (entry instanceof ResourcePackListEntryCustom)return ((ResourcePackListEntryCustom)entry).func_148311_a();
return entry.func_148318_i().getTexturePackDescription();
else if (entry instanceof ResourcePackListEntryFound)return ((ResourcePackListEntryFound)entry).func_148318_i().getTexturePackDescription();
else return "<INVALID>";
}
public static final Comparator<ResourcePackListEntryFound> sortAZ = new Comparator<ResourcePackListEntryFound>(){
public static final Comparator<ResourcePackListEntry> sortAZ = new Comparator<ResourcePackListEntry>(){
@Override
public int compare(ResourcePackListEntryFound entry1, ResourcePackListEntryFound entry2){
public int compare(ResourcePackListEntry entry1, ResourcePackListEntry entry2){
return String.CASE_INSENSITIVE_ORDER.compare(nameSort(entry1,false),nameSort(entry2,false));
};
};
public static final Comparator<ResourcePackListEntryFound> sortZA = new Comparator<ResourcePackListEntryFound>(){
public static final Comparator<ResourcePackListEntry> sortZA = new Comparator<ResourcePackListEntry>(){
@Override
public int compare(ResourcePackListEntryFound entry1, ResourcePackListEntryFound entry2){
public int compare(ResourcePackListEntry entry1, ResourcePackListEntry entry2){
return -String.CASE_INSENSITIVE_ORDER.compare(nameSort(entry1,true),nameSort(entry2,true));
};
};
private final List<ResourcePackListEntryFound> sourceList, targetList;
private final List<ResourcePackListEntry> sourceList, targetList;
private Comparator<ResourcePackListEntryFound> sorter;
private Comparator<ResourcePackListEntry> sorter;
private Pattern textFilter;
public ResourcePackListProcessor(List<ResourcePackListEntryFound> sourceList, List<ResourcePackListEntryFound> targetList){
public ResourcePackListProcessor(List<ResourcePackListEntry> sourceList, List<ResourcePackListEntry> targetList){
this.sourceList = sourceList;
this.targetList = targetList;
refresh();
}
public void setSorter(Comparator<ResourcePackListEntryFound> comparator){
public void setSorter(Comparator<ResourcePackListEntry> comparator){
this.sorter = comparator;
refresh();
}
@ -74,7 +78,7 @@ public class ResourcePackListProcessor{
public void refresh(){
targetList.clear();
for(ResourcePackListEntryFound entry:sourceList){
for(ResourcePackListEntry entry:sourceList){
if (checkFilter(name(entry)) || checkFilter(description(entry))){
targetList.add(entry);
}

View File

@ -8,12 +8,12 @@ import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.MinecraftForge;
import chylex.respack.ResourcePackOrganizer;
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;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public final class RenderPackListOverlay{
private static final RenderPackListOverlay instance = new RenderPackListOverlay();
@ -61,7 +61,7 @@ public final class RenderPackListOverlay{
return;
}
final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
final FontRenderer font = Minecraft.getMinecraft().fontRendererObj;
final int color = ResourcePackOrganizer.getConfig().options.getDisplayColor();
final int edgeDist = 3, topOffset = 2;

View File

@ -4,7 +4,7 @@
"name": "Resource Pack Organizer",
"description": "Enhances the Resource Pack menu by adding folder support for easier pack organization, ability to search packs by name or description, new sorting options, and quick refresh button directly in the GUI.\n\nThe mod uses a folder icon by FatCow under the CC BY 3.0 US license: http://fatcow.com/free-icons",
"version": "1.0",
"mcversion": "1.7.10",
"mcversion": "1.8.9",
"url": "http://chylex.com",
"authorList": ["chylex"],
"logoFile": "rpo_logo.png"