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 hacked together support for ico and icns #26

Open
wants to merge 1 commit into
base: 1.12
Choose a base branch
from
Open
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
226 changes: 146 additions & 80 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.gradle.api.java.archives.internal.DefaultManifest

buildscript {
repositories {
maven { url = 'https://maven.minecraftforge.net' }
Expand All @@ -7,111 +9,175 @@ buildscript {
classpath group: "net.minecraftforge.gradle", name: "ForgeGradle", version: "4.1.+", changing: true
}
}


plugins {
id "com.github.johnrengelman.shadow" version "6.1.0"
id "java" // java plugin is needed for the shadow plugin to work
id "eclipse"
id "maven-publish"
}
apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

version = '1.12.x-1.0.4'
group = 'dk.zlepper.itlt' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'itlt'
version = "1.12.x-1.0.5"
group = "dk.zlepper.itlt" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "itlt"

java.toolchain.languageVersion = JavaLanguageVersion.of(8) // Mojang ships Java 8 to end users, so your mod should target Java 8.
// Target Java 8 but use a Java 11 compiler
java.toolchain.languageVersion = JavaLanguageVersion.of(8)
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = "1.8"
tasks.withType(JavaCompile).configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(11)
}
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = "1.8"

// You can verify this is working correctly by running the build task, extracting itlt.class from
// the built jar and checking if the bytecode version is 52 using the command "javap -verbose ./itlt.class"
}

println("Java: " + System.getProperty("java.version") + " JVM: " + System.getProperty("java.vm.version") + "(" + System.getProperty("java.vendor") + ") Arch: " + System.getProperty("os.arch"))
// Use Java 8 for run tasks (e.g. runClient)
tasks.withType(JavaExec).configureEach {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
}

// You can verify this is working correctly by running the runClient task and checking the debug.log
// in the run folder for "[dk.zlepper.itlt.itlt/]: javaVerInt: 8"
}

println "Java: ${System.getProperty "java.version"}, JVM: ${System.getProperty "java.vm.version"} (${System.getProperty "java.vendor"}), Arch: ${System.getProperty "os.arch"}"
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
//mappings channel: 'snapshot', version: '20171003-1.12'
mappings channel: 'snapshot', version: '20180814-1.12'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.

// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')

// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
mappings channel: "snapshot", version: "20180814-1.12"

// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'REGISTRIES'
accessTransformer = file("src/main/resources/META-INF/accesstransformer.cfg")

// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
runs {
final File runFile = project.file("run")
client {
workingDirectory runFile
property "forge.logging.console.level", "info"
mods {
itlt {
source sourceSets.main
}
}
}

server {
workingDirectory runFile
property "forge.logging.console.level", "info"
mods {
itlt {
source sourceSets.main
}
}
}

// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'REGISTRIES'

// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
data {
workingDirectory runFile
property "forge.logging.console.level", "info"
args "--mod", "itlt", "--all", "--output", file("src/generated/resources/")
mods {
itlt {
source sourceSets.main
}
}
}
}
}

configurations {
shade
}

repositories {
maven {
url = "https://cursemaven.com"
content { includeGroup "curse.maven" }
}
mavenCentral()
maven { url = "https://repository.mulesoft.org/nexus/content/repositories/public/" }
}

dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
// Forge
minecraft 'net.minecraftforge:forge:1.12.2-14.23.5.2854'

// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"
// itlt uses the "image4j" library to read .ico files
implementation "com.github.imcdonagh:image4j:0.7.2"
shade "com.github.imcdonagh:image4j:0.7.2"

// itlt uses the "Apache Commons Imaging" library to read .icns files
/*implementation "org.apache.commons:commons-imaging:1.0-alpha2"
shade "org.apache.commons:commons-imaging:1.0-alpha2"*/
// due to it being such a big library and not supporting class removal, I've made a single method return null,
// removed jpeg, tiff, examples and tests and then compiled it. This fork supports removing classes for formats we
// don't use, therefore allowing us to drastically reduce the shrunk jar's filesize
implementation files("thirdPartyLibs/commons-imaging-1.0-alpha2-custom.jar")
shade files("thirdPartyLibs/commons-imaging-1.0-alpha2-custom.jar")
}

// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
ext {
MANIFEST = manifest {
attributes([
"Specification-Title": "itlt",
"Specification-Vendor": "Paint_Ninja",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": project.version,
"Implementation-Vendor" : "Paint_Ninja",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"Main-Class": "dk.zlepper.itlt.Main" // so that the pop-up window code works
])
} as DefaultManifest
}

// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
jar {
manifest.from(MANIFEST)
}

// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
shadowJar {
archiveClassifier.set("")
configurations = [project.configurations.shade]

// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
// Apache Commons Imaging needs to be put somewhere else to prevent a NoClassDefFoundError
relocate "org.apache.commons.imaging", "${project.group}.shadow.org.apache.commons.imaging"

manifest.from(MANIFEST)
}

// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "itlt",
"Specification-Vendor": "Paint_Ninja",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "${version}",
"Implementation-Vendor" :"Paint_Ninja",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
}
reobf {
shadowJar { }
}

// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')
task shrinkJar(type: Jar, dependsOn: reobfShadowJar) {
archiveClassifier.set("shrunk")

publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
repositories {
maven {
url "file:///${project.projectDir}/mcmodsrepo"
}
}
}
final File inputJar = file("${buildDir}/libs/${archivesBaseName}-${project.version}.jar")
final String shadowGroup = project.group.replace('.','/') + "/shadow"
final String apacheImaging = "${shadowGroup}/org/apache/commons/imaging"

from zipTree(inputJar)

exclude "net/sf/image4j/example/**", "net/sf/image4j/test/**"

exclude "${apacheImaging}/formats/gif/**", "${apacheImaging}/formats/psd/**", "${apacheImaging}/formats/rgbe/**",
"${apacheImaging}/formats/xbm/**", "${apacheImaging}/formats/xpm/**", "${apacheImaging}/formats/pnm/**",
"${apacheImaging}/formats/pcx/**", "${apacheImaging}/formats/dcx/**", "${apacheImaging}/formats/png/**",
"${apacheImaging}/formats/bmp/**", "${apacheImaging}/formats/wbmp/**", "${apacheImaging}/formats/ico/**"

exclude "${apacheImaging}/common/itu_t4/**", "${apacheImaging}/common/mylzw/**", "${apacheImaging}/common/BasicCParser**",
"${apacheImaging}/common/RationalNumber**", "${apacheImaging}/common/GenericImageMetadata**",
"${apacheImaging}/common/ZlibDeflate**", "${apacheImaging}/common/PackBits**", "${apacheImaging}/icc/**",
"${apacheImaging}/palette/**", "${apacheImaging}/color/**", "${apacheImaging}/ImageDump**",
"${apacheImaging}/ColorTools**", "${apacheImaging}/internal/**"

exclude "META-INF/LICENSE.txt", "META-INF/NOTICE.txt"

manifest.from(MANIFEST)
}

//tasks.build.dependsOn reobfShadowJar
//jar.finalizedBy reobfShadowJar
tasks.build.dependsOn shrinkJar
jar.finalizedBy shrinkJar
23 changes: 18 additions & 5 deletions src/main/java/dk/zlepper/itlt/Itlt.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dk.zlepper.itlt;

import com.google.gson.Gson;
import dk.zlepper.itlt.helpers.IconHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import dk.zlepper.itlt.about.mod;
Expand Down Expand Up @@ -43,7 +44,8 @@ public final class Itlt {

@Mod.EventHandler
@SideOnly(Side.CLIENT)
public void preinit(FMLPreInitializationEvent event) {
public void preinit(FMLPreInitializationEvent event) throws IOException
{
logger = event.getModLog();

if (proxy instanceof ClientProxy) {
Expand Down Expand Up @@ -77,13 +79,24 @@ public void preinit(FMLPreInitializationEvent event) {
Property customIconProp = config.get("Display", "loadCustomIcon", true);
customIconProp.setComment("Set to true to load a custom icon from config" + File.separator + "itlt" + File.separator + "icon.png");
if (customIconProp.getBoolean()) {
File customIcon = null;
final File di = Paths.get(event.getModConfigurationDirectory().getAbsolutePath(), "itlt").toFile();
logger.info(di);
if (di.exists()) {
final File icon = Paths.get(di.getAbsolutePath(), "icon.png").toFile();
logger.info(icon.exists() ? "Custom modpack icon found" : "Custom modpack icon NOT found.");
if (icon.exists() && !icon.isDirectory()) {
Display.setIcon(IconLoader.load(icon));
final File icoIcon = Paths.get(di.getAbsolutePath(), "icon.ico").toFile();
final File icnsIcon = Paths.get(di.getAbsolutePath(), "icon.icns").toFile();
final File pngIcon = Paths.get(di.getAbsolutePath(), "icon.png").toFile();
logger.info(icoIcon.exists() ? "Custom modpack .ico found" : "Custom modpack .ico NOT found.");
logger.info(icnsIcon.exists() ? "Custom modpack .icns found" : "Custom modpack .icns NOT found.");
logger.info(pngIcon.exists() ? "Custom modpack .png found" : "Custom modpack .png NOT found.");

if (icoIcon.exists() && !icoIcon.isDirectory()) customIcon = icoIcon;
else if (icnsIcon.exists() && !icnsIcon.isDirectory()) customIcon = icnsIcon;
else if (pngIcon.exists() && !pngIcon.isDirectory()) customIcon = pngIcon;
if(customIcon != null) {
IconHandler.setWindowIcon(customIcon);
} else {
logger.warn("loadCustomIcon is true but icon.ico/icns/png is missing or invalid.");
}
} else {
logger.error("Directory for custom modpack icon not found!");
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/dk/zlepper/itlt/helpers/IconHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package dk.zlepper.itlt.helpers;

import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.List;

import dk.zlepper.itlt.Itlt;
import net.sf.image4j.codec.ico.ICODecoder;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.formats.icns.IcnsImageParser;
import org.lwjgl.opengl.Display;

public class IconHandler
{
//Backport some of 2.X ico and icns support
public static void setWindowIcon(final File inputIconFile) throws IOException {
final ByteBuffer[] buffer = new ByteBuffer[1];
List<BufferedImage> bufferedImageList;

final String inputIconFilenameAndExt = inputIconFile.getName().toLowerCase();
if (inputIconFilenameAndExt.endsWith(".ico")) {
// load all of the images inside the `.ico` file as a list of `BufferedImage`s
bufferedImageList = ICODecoder.read(inputIconFile);
buffer[0] = IconLoader.convertToByteBuffer(bufferedImageList.get(0));
Display.setIcon(buffer);
Itlt.logger.info("ICO file found, using that");
return;
} else if (inputIconFilenameAndExt.endsWith(".icns")) {
// try to load all of the images inside the `.icns` file as a list of `BufferedImage`s
try {
bufferedImageList = new IcnsImageParser().getAllBufferedImages(inputIconFile);
buffer[0] = IconLoader.convertToByteBuffer(bufferedImageList.get(0));
Display.setIcon(buffer);
Itlt.logger.info("ICNS file found, using that");
return;
} catch (final ImageReadException e) {
e.printStackTrace();
return;
}
} else if (inputIconFilenameAndExt.endsWith(".png")) {
// load the `.png` file directly as an `InputStream`
Display.setIcon(IconLoader.load(inputIconFile));
Itlt.logger.info("PNG file found, using that");
return;
}
}
}
Loading