Fix AWT frame. Fix LegacyMergeSort. Improve class loader

This commit is contained in:
Lassebq 2023-03-20 20:23:55 +02:00
parent 28b754d9a0
commit 0356277121
No known key found for this signature in database
GPG key ID: DE0866BB0C980B6E
8 changed files with 701 additions and 131 deletions

571
MultiMC.md Normal file
View file

@ -0,0 +1,571 @@
# How to use in MultiMC
- Make a new instance in MultiMC with the wanted version of Minecraft.
- Click `Edit Instance` - it should open the `Version` page of the instance.
- Select the `Minecraft` component and click `Customize` - `Edit`. If you have not configured an external Text Editor in MultiMC Settings, this will attempt to open your system JSON editor.
- If the opened JSON has the `legacyLaunch` trait (for Minecraft versions 1.5.2 and older), then add the `noapplet` trait after it as well.
- For Minecraft versions 1.5.2 and older, set up an empty `assetIndex` instead of the vanilla pre-1.6:
```json
"assetIndex": {
"id": "empty",
"sha1": "62ea787c1f800c091b98678b050453a5ae59d7bc",
"size": 14,
"totalSize": 0,
"url": "https://mcphackers.github.io/assets/empty.json"
}
```
- If the opened JSON does not have a `libraries` array object (right after the `formatVersion` object), then add one. Add LaunchWrapper and its dependencies to the libraries to get an array like this:
```json
"libraries": [
{
"downloads": {
"artifact": {
"sha1": "120f6fdeb2602fa2d979ad0bdcd3c443a48148a6",
"size": 107614,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/launchwrapper/1.0/launchwrapper-1.0.jar"
}
},
"name": "org.mcphackers:launchwrapper:1.0"
},
{
"downloads": {
"artifact": {
"sha1": "d96c99a30f5e1a19b0e609dbb19a44d8518ac01e",
"size": 52660,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar"
}
},
"name": "org.ow2.asm:asm-tree:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "81a03f76019c67362299c40e0ba13405f5467bff",
"size": 122004,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar"
}
},
"name": "org.ow2.asm:asm:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "d2c95f0a83b1b2b28131d46abfe8e68f7dc07ede",
"size": 65667,
"url": "https://mcphackers.github.io/libraries/org/json/json/20230311/json-20230311.jar"
}
},
"name": "org.json:json:20230311"
},
{
"downloads": {
"artifact": {
"sha1": "6fcff0b8d6173ac275f3728a9e5a987cfca88762",
"size": 79599,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/rdi/rdi/1.0/rdi-1.0.jar"
}
},
"name": "org.mcphackers.rdi:rdi:1.0"
}
]
```
- If the opened JSON does not have a `mainClass` string object (right before the `mainJar` object), then add one. Set or change the `mainClass` value to `org.mcphackers.launchwrapper.Launch`.
- If the opened JSON does not have a `minecraftArguments` string object (right after the `mainJar` object), then add one. Set or change the `minecraftArguments` value to something like `--username ${auth_player_name} --session ${auth_session} --gameDir ${game_directory} --assetsDir ${game_assets}` (you can see examples below or in [BetterJSONs](https://mcphackers.github.io/BetterJSONs/)).
## Examples
*Base your JSON on [BetterJSONs](https://mcphackers.github.io/BetterJSONs/)*
### c0.30_01c
```json
{
"+traits": [
"legacyLaunch",
"noapplet",
"no-texturepacks"
],
"appletClass": "com.mojang.minecraft.MinecraftApplet",
"assetIndex": {
"id": "empty",
"sha1": "62ea787c1f800c091b98678b050453a5ae59d7bc",
"size": 14,
"totalSize": 0,
"url": "https://mcphackers.github.io/assets/empty.json"
},
"formatVersion": 1,
"libraries": [
{
"downloads": {
"artifact": {
"sha1": "120f6fdeb2602fa2d979ad0bdcd3c443a48148a6",
"size": 107614,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/launchwrapper/1.0/launchwrapper-1.0.jar"
}
},
"name": "org.mcphackers:launchwrapper:1.0"
},
{
"downloads": {
"artifact": {
"sha1": "d96c99a30f5e1a19b0e609dbb19a44d8518ac01e",
"size": 52660,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar"
}
},
"name": "org.ow2.asm:asm-tree:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "81a03f76019c67362299c40e0ba13405f5467bff",
"size": 122004,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar"
}
},
"name": "org.ow2.asm:asm:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "d2c95f0a83b1b2b28131d46abfe8e68f7dc07ede",
"size": 65667,
"url": "https://mcphackers.github.io/libraries/org/json/json/20230311/json-20230311.jar"
}
},
"name": "org.json:json:20230311"
},
{
"downloads": {
"artifact": {
"sha1": "855b05d238b72b03197e6702a765f344a32b8291",
"size": 79599,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/rdi/rdi/1.0/rdi-1.0.jar"
}
},
"name": "org.mcphackers.rdi:rdi:1.0"
}
],
"mainClass": "org.mcphackers.launchwrapper.Launch",
"mainJar": {
"downloads": {
"artifact": {
"sha1": "54622801f5ef1bcc1549a842c5b04cb5d5583005",
"size": 297776,
"url": "https://launcher.mojang.com/v1/objects/54622801f5ef1bcc1549a842c5b04cb5d5583005/client.jar"
}
},
"name": "com.mojang:minecraft:c0.30_01c:client"
},
"minecraftArguments": "--username ${auth_player_name} --sessionid ${auth_session} --gameDir ${game_directory} --assetsDir ${game_assets} --resourcesProxyPort 11701 --skinProxy pre-b1.9-pre4",
"name": "Minecraft",
"releaseTime": "2009-12-22T00:00:00+02:00",
"requires": [
{
"suggests": "2.9.4",
"uid": "org.lwjgl"
}
],
"type": "old_alpha",
"uid": "net.minecraft",
"version": "c0.30_01c"
}
```
### a1.1.2_01
```json
{
"+traits": [
"legacyLaunch",
"noapplet",
"no-texturepacks"
],
"assetIndex": {
"id": "empty",
"sha1": "62ea787c1f800c091b98678b050453a5ae59d7bc",
"size": 14,
"totalSize": 0,
"url": "https://mcphackers.github.io/assets/empty.json"
},
"formatVersion": 1,
"libraries": [
{
"downloads": {
"artifact": {
"sha1": "120f6fdeb2602fa2d979ad0bdcd3c443a48148a6",
"size": 107614,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/launchwrapper/1.0/launchwrapper-1.0.jar"
}
},
"name": "org.mcphackers:launchwrapper:1.0"
},
{
"downloads": {
"artifact": {
"sha1": "d96c99a30f5e1a19b0e609dbb19a44d8518ac01e",
"size": 52660,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar"
}
},
"name": "org.ow2.asm:asm-tree:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "81a03f76019c67362299c40e0ba13405f5467bff",
"size": 122004,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar"
}
},
"name": "org.ow2.asm:asm:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "d2c95f0a83b1b2b28131d46abfe8e68f7dc07ede",
"size": 65667,
"url": "https://mcphackers.github.io/libraries/org/json/json/20230311/json-20230311.jar"
}
},
"name": "org.json:json:20230311"
},
{
"downloads": {
"artifact": {
"sha1": "855b05d238b72b03197e6702a765f344a32b8291",
"size": 79599,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/rdi/rdi/1.0/rdi-1.0.jar"
}
},
"name": "org.mcphackers.rdi:rdi:1.0"
}
],
"mainClass": "org.mcphackers.launchwrapper.Launch",
"mainJar": {
"downloads": {
"artifact": {
"sha1": "daa4b9f192d2c260837d3b98c39432324da28e86",
"size": 897164,
"url": "https://launcher.mojang.com/v1/objects/daa4b9f192d2c260837d3b98c39432324da28e86/client.jar"
}
},
"name": "com.mojang:minecraft:a1.1.2_01:client"
},
"minecraftArguments": "--username ${auth_player_name} --session ${auth_session} --gameDir ${game_directory} --assetsDir ${game_assets} --resourcesProxyPort 11702 --skinProxy pre-b1.9-pre4",
"name": "Minecraft",
"releaseTime": "2010-09-23T00:00:00+02:00",
"requires": [
{
"suggests": "2.9.4",
"uid": "org.lwjgl"
}
],
"type": "old_alpha",
"uid": "net.minecraft",
"version": "a1.1.2_01"
}
```
### b1.7.3
```json
{
"+traits": [
"legacyLaunch",
"noapplet",
"texturepacks"
],
"assetIndex": {
"id": "empty",
"sha1": "62ea787c1f800c091b98678b050453a5ae59d7bc",
"size": 14,
"totalSize": 0,
"url": "https://mcphackers.github.io/assets/empty.json"
},
"formatVersion": 1,
"libraries": [
{
"downloads": {
"artifact": {
"sha1": "120f6fdeb2602fa2d979ad0bdcd3c443a48148a6",
"size": 107614,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/launchwrapper/1.0/launchwrapper-1.0.jar"
}
},
"name": "org.mcphackers:launchwrapper:1.0"
},
{
"downloads": {
"artifact": {
"sha1": "d96c99a30f5e1a19b0e609dbb19a44d8518ac01e",
"size": 52660,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar"
}
},
"name": "org.ow2.asm:asm-tree:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "81a03f76019c67362299c40e0ba13405f5467bff",
"size": 122004,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar"
}
},
"name": "org.ow2.asm:asm:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "d2c95f0a83b1b2b28131d46abfe8e68f7dc07ede",
"size": 65667,
"url": "https://mcphackers.github.io/libraries/org/json/json/20230311/json-20230311.jar"
}
},
"name": "org.json:json:20230311"
},
{
"downloads": {
"artifact": {
"sha1": "855b05d238b72b03197e6702a765f344a32b8291",
"size": 79599,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/rdi/rdi/1.0/rdi-1.0.jar"
}
},
"name": "org.mcphackers.rdi:rdi:1.0"
}
],
"mainClass": "org.mcphackers.launchwrapper.Launch",
"mainJar": {
"downloads": {
"artifact": {
"sha1": "43db9b498cb67058d2e12d394e6507722e71bb45",
"size": 1465375,
"url": "https://launcher.mojang.com/v1/objects/43db9b498cb67058d2e12d394e6507722e71bb45/client.jar"
}
},
"name": "com.mojang:minecraft:b1.7.3:client"
},
"minecraftArguments": "--username ${auth_player_name} --session ${auth_session} --gameDir ${game_directory} --assetsDir ${game_assets} --resourcesProxyPort 11705 --skinProxy pre-b1.9-pre4",
"name": "Minecraft",
"releaseTime": "2011-07-08T00:00:00+02:00",
"requires": [
{
"suggests": "2.9.4",
"uid": "org.lwjgl"
}
],
"type": "old_beta",
"uid": "net.minecraft",
"version": "b1.7.3"
}
```
### 1.6.4
```json
{
"assetIndex": {
"id": "legacy",
"sha1": "770572e819335b6c0a053f8378ad88eda189fc14",
"size": 109634,
"totalSize": 153475165,
"url": "https://launchermeta.mojang.com/v1/packages/770572e819335b6c0a053f8378ad88eda189fc14/legacy.json"
},
"formatVersion": 1,
"libraries": [
{
"downloads": {
"artifact": {
"sha1": "6065cc95c661255349c1d0756657be17c29a4fd3",
"size": 61311,
"url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"
}
},
"name": "net.sf.jopt-simple:jopt-simple:4.5"
},
{
"downloads": {
"artifact": {
"sha1": "4e61cd854bbd3d9765bd7c46fc9008d654b29281",
"size": 102767,
"url": "https://mcphackers.github.io/libraries/com/paulscode/codecjorbis/20230120/codecjorbis-20230120.jar"
}
},
"name": "com.paulscode:codecjorbis:20230120"
},
{
"downloads": {
"artifact": {
"sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da",
"size": 5618,
"url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"
}
},
"name": "com.paulscode:codecwav:20101023"
},
{
"downloads": {
"artifact": {
"sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3",
"size": 21679,
"url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar"
}
},
"name": "com.paulscode:libraryjavasound:20101123"
},
{
"downloads": {
"artifact": {
"sha1": "73e80d0794c39665aec3f62eee88ca91676674ef",
"size": 18981,
"url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar"
}
},
"name": "com.paulscode:librarylwjglopenal:20100824"
},
{
"downloads": {
"artifact": {
"sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6",
"size": 65020,
"url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar"
}
},
"name": "com.paulscode:soundsystem:20120107"
},
{
"downloads": {
"artifact": {
"sha1": "751761ce15a3e3aaf3fc75b9f013ff8f7b88a585",
"size": 74953,
"url": "https://libraries.minecraft.net/argo/argo/2.25_fixed/argo-2.25_fixed.jar"
}
},
"name": "argo:argo:2.25_fixed"
},
{
"downloads": {
"artifact": {
"sha1": "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb",
"size": 1997327,
"url": "https://libraries.minecraft.net/org/bouncycastle/bcprov-jdk15on/1.47/bcprov-jdk15on-1.47.jar"
}
},
"name": "org.bouncycastle:bcprov-jdk15on:1.47"
},
{
"downloads": {
"artifact": {
"sha1": "67b7be4ee7ba48e4828a42d6d5069761186d4a53",
"size": 2189111,
"url": "https://libraries.minecraft.net/com/google/guava/guava/14.0/guava-14.0.jar"
}
},
"name": "com.google.guava:guava:14.0"
},
{
"downloads": {
"artifact": {
"sha1": "905075e6c80f206bbe6cf1e809d2caa69f420c76",
"size": 315805,
"url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar"
}
},
"name": "org.apache.commons:commons-lang3:3.1"
},
{
"downloads": {
"artifact": {
"sha1": "b1b6ea3b7e4aa4f492509a4952029cd8e48019ad",
"size": 185140,
"url": "https://libraries.minecraft.net/commons-io/commons-io/2.4/commons-io-2.4.jar"
}
},
"name": "commons-io:commons-io:2.4"
},
{
"downloads": {
"artifact": {
"sha1": "1f96456ca233dec780aa224bff076d8e8bca3908",
"size": 189285,
"url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar"
}
},
"name": "com.google.code.gson:gson:2.2.2"
},
{
"downloads": {
"artifact": {
"sha1": "120f6fdeb2602fa2d979ad0bdcd3c443a48148a6",
"size": 107614,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/launchwrapper/1.0/launchwrapper-1.0.jar"
}
},
"name": "org.mcphackers:launchwrapper:1.0"
},
{
"downloads": {
"artifact": {
"sha1": "d96c99a30f5e1a19b0e609dbb19a44d8518ac01e",
"size": 52660,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.jar"
}
},
"name": "org.ow2.asm:asm-tree:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "81a03f76019c67362299c40e0ba13405f5467bff",
"size": 122004,
"url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.jar"
}
},
"name": "org.ow2.asm:asm:9.2"
},
{
"downloads": {
"artifact": {
"sha1": "d2c95f0a83b1b2b28131d46abfe8e68f7dc07ede",
"size": 65667,
"url": "https://mcphackers.github.io/libraries/org/json/json/20230311/json-20230311.jar"
}
},
"name": "org.json:json:20230311"
},
{
"downloads": {
"artifact": {
"sha1": "855b05d238b72b03197e6702a765f344a32b8291",
"size": 79599,
"url": "https://mcphackers.github.io/libraries/org/mcphackers/rdi/rdi/1.0/rdi-1.0.jar"
}
},
"name": "org.mcphackers.rdi:rdi:1.0"
}
],
"mainClass": "org.mcphackers.launchwrapper.Launch",
"mainJar": {
"downloads": {
"artifact": {
"sha1": "1703704407101cf72bd88e68579e3696ce733ecd",
"size": 4745096,
"url": "https://launcher.mojang.com/v1/objects/1703704407101cf72bd88e68579e3696ce733ecd/client.jar"
}
},
"name": "com.mojang:minecraft:1.6.4:client"
},
"minecraftArguments": "--username ${auth_player_name} --session ${auth_session} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets} --skinProxy pre-1.8",
"name": "Minecraft",
"releaseTime": "2013-09-19T15:52:37+00:00",
"requires": [
{
"suggests": "2.9.4",
"uid": "org.lwjgl"
}
],
"type": "release",
"uid": "net.minecraft",
"version": "1.6.4"
}
```

View file

@ -4,7 +4,7 @@
LaunchWrapper is bundled in [BetterJSONs](https://github.com/MCPHackers/BetterJSONs) which are meant for official Minecraft Launcher.
# Features
## Features
- Strips game window from Java **AWT** (**Abstract Window Toolkit**) and lets the game use internal **LWJGL** frame
- BitDepthFix for versions before Beta 1.8
- Allows changing assets directory in 1.6 snapshots (the game didn't have a parameter to do that yet)
@ -28,8 +28,14 @@ LaunchWrapper is bundled in [BetterJSONs](https://github.com/MCPHackers/BetterJS
- The wrapper also fixes Beta 1.3, Pre-classic and Classic compatibility with Java 5
- Built-in [Modloader Fix](https://github.com/coffeenotfound/ModloaderFix-b1.7.3)
# How to use
*This is a more in-depth guide for those who will be using the wrapper*
## How to use
***There will be an installer eventually.***<br>
*For now, here is an in-depth guide for those who will be using the wrapper*
- If you are using MultiMC [follow this guide](https://github.com/MCPHackers/LaunchWrapper/blob/main/MultiMC.md).<br>
- If you are using Official Launcher (or any other launcher which follows the same versions folder structure) use [BetterJSONs](https://github.com/MCPHackers/BetterJSONs) and rename the JSONs if they are conflicting with any vanilla JSONs
### Setting up manually
Make sure all minecraft and wrapper libraries are on classpath<br>
Use `java -cp <classpath> org.mcphackers.launchwrapper.Launch <arguments>` to launch the game
@ -38,7 +44,7 @@ Arguments are formatted the same way as in Mojang launch wrapper. <br>
For example: `--username DemoUser --width 1280 --height 720 --title "Minecraft Demo" --demo`
Arguments may be as follows:
- `awtFrame` - disable LWJGL frame patch and use AWT (Does not work at that moment)
- `awtFrame` - disable LWJGL frame patch and use AWT
- `isom` - Launch IsomPreviewApplet
- `forceVsync` - Launch the game with VSync enabled
- `forceResizable` - Early Indev and Classic don't properly update viewport, so the wrapper disables frame resizing. To enable it anyway use this argument

View file

@ -34,7 +34,7 @@ public class AppletLaunchTarget extends LaunchTarget {
public void launch(LaunchClassLoader classLoader) {
Class<? extends Applet> appletClass;
try {
appletClass = classLoader.findClass(targetClass).asSubclass(Applet.class);
appletClass = classLoader.loadClass(targetClass).asSubclass(Applet.class);
} catch (Exception e) {
e.printStackTrace();
return;

View file

@ -1,6 +1,5 @@
package org.mcphackers.launchwrapper;
import org.mcphackers.launchwrapper.inject.Inject;
import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
import org.mcphackers.launchwrapper.tweak.Tweak;
@ -12,7 +11,14 @@ public class Launch {
public static final LaunchClassLoader CLASS_LOADER = LaunchClassLoader.instantiate();
static {
CLASS_LOADER.addException(Launch.class);
CLASS_LOADER.addException(Inject.class);
CLASS_LOADER.addException(LaunchConfig.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameter.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterEnum.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterFile.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterFileList.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterNumber.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterString.class);
CLASS_LOADER.addException(LaunchConfig.LaunchParameterSwitch.class);
}
private static Launch INSTANCE;

View file

@ -17,9 +17,12 @@ import org.mcphackers.launchwrapper.Launch;
import org.mcphackers.launchwrapper.tweak.AppletWrapper;
import org.mcphackers.launchwrapper.util.Util;
/**
* DO NOT use this class under any circumstances. This class is meant to be initialized in the context of LaunchClassLoader
* @author Lassebq
*
*/
public class Inject {
private static final BufferedImage DEFAULT_ICON = getIcon();
public static AppletWrapper getApplet() {
return new AppletWrapper(Launch.getConfig().getArgsAsMap());
}
@ -77,7 +80,7 @@ public class Inject {
return level;
}
public static ByteBuffer loadIcon(BufferedImage icon) {
private static ByteBuffer loadIcon(BufferedImage icon) {
final int[] rgb = icon.getRGB(0, 0, icon.getWidth(), icon.getHeight(), null, 0, icon.getWidth());
final ByteBuffer buffer = ByteBuffer.allocate(4 * rgb.length);
@ -88,53 +91,80 @@ public class Inject {
return buffer;
}
public static ByteBuffer[] loadDefaultIcon(boolean grassBlock) {
if(!grassBlock) {
public static ByteBuffer[] loadIcon(boolean favIcon) {
File[] iconPaths = Launch.getConfig().icon.get();
if(iconPaths != null && hasIcon(iconPaths)) {
List<ByteBuffer> processedIcons = new ArrayList<ByteBuffer>();
for(File icon : iconPaths) {
if(!icon.exists()) {
continue;
}
try {
processedIcons.add(loadIcon(ImageIO.read(icon)));
} catch (IOException e) {
System.err.println("Could not load icon at: " + icon.getAbsolutePath());
}
}
return processedIcons.toArray(new ByteBuffer[0]);
}
if(!favIcon) {
try {
return new ByteBuffer[] { loadIcon("/icon_16x16.png"), loadIcon("/icon_32x32.png") };
} catch (IOException e) {
e.printStackTrace();
System.err.println("Could not load the default icon");
}
}
return new ByteBuffer[] { loadIcon(DEFAULT_ICON) };
}
public static ByteBuffer[] loadIcons() {
List<ByteBuffer> processedIcons = new ArrayList<ByteBuffer>();
for(File icon : Launch.getConfig().icon.get()) {
if(!icon.exists()) {
continue;
}
try {
processedIcons.add(loadIcon(ImageIO.read(icon)));
} catch (IOException e) {
e.printStackTrace();
}
}
return processedIcons.toArray(new ByteBuffer[0]);
}
public static ByteBuffer[] loadIcon(File icon) {
try {
return new ByteBuffer[] { loadIcon(ImageIO.read(icon)) };
} catch (IOException e) {
return null;
}
}
private static ByteBuffer loadIcon(String icon) throws IOException {
return loadIcon(ImageIO.read(Inject.class.getResourceAsStream(icon)));
}
public static BufferedImage getIcon() {
if(DEFAULT_ICON != null) {
return DEFAULT_ICON;
}
try {
return ImageIO.read(Inject.class.getResourceAsStream("/favicon.png"));
return new ByteBuffer[] { loadIcon("/favicon.png") };
} catch (IOException e) {
e.printStackTrace();
System.err.println("Could not load favicon.png");
}
return null;
}
private static boolean hasIcon(File[] icons) {
for(File f : icons) {
if(f.exists()) {
return true;
}
}
return false;
}
public static BufferedImage getIcon(boolean favIcon) {
File[] iconPaths = Launch.getConfig().icon.get();
if(iconPaths != null && hasIcon(iconPaths)) {
for(File icon : iconPaths) {
if(!icon.exists()) {
continue;
}
try {
return ImageIO.read(icon);
} catch (IOException e) {
System.err.println("Could not load icon at: " + icon.getAbsolutePath());
}
}
}
if(!favIcon) {
try {
return getIcon("/icon_32x32.png");
} catch (IOException e) {
System.err.println("Could not load the default icon");
}
}
try {
return getIcon("/favicon.png");
} catch (IOException e) {
System.err.println("Could not load favicon.png");
}
return null;
}
private static BufferedImage getIcon(String icon) throws IOException {
return ImageIO.read(Inject.class.getResourceAsStream(icon));
}
private static ByteBuffer loadIcon(String icon) throws IOException {
return loadIcon(getIcon(icon));
}
}

View file

@ -38,8 +38,6 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
private ClassLoaderTweak tweak;
private Map<String, Class<?>> exceptions = new HashMap<String, Class<?>>();
/** Keys should contain dots */
private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
/** Keys should contain dots */
private Map<String, ClassNode> overridenClasses = new HashMap<String, ClassNode>();
/** Keys should contain slashes */
private Map<String, ClassNode> classNodeCache = new HashMap<String, ClassNode>();
@ -73,7 +71,6 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
}
public Enumeration<URL> getResources(String name) throws IOException {
//TODO ?
return parent.getResources(name);
}
@ -87,10 +84,6 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
if(cls != null) {
return cls;
}
cls = classes.get(name);
if(cls != null) {
return cls;
}
cls = transformedClass(name);
if(cls != null) {
return cls;
@ -101,7 +94,7 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
public void invokeMain(String launchTarget, String... args) {
classNodeCache.clear();
try {
Class<?> mainClass = findClass(launchTarget);
Class<?> mainClass = loadClass(launchTarget);
mainClass.getDeclaredMethod("main", String[].class).invoke(null, (Object) args);
} catch (InvocationTargetException e1) {
if(e1.getCause() != null) {
@ -197,6 +190,7 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
protected Class<?> redefineClass(String name) {
ClassNode classNode = getClass(name);
if(classNode != null && tweak != null && tweak.tweakClass(classNode)) {
saveDebugClass(classNode);
return redefineClass(classNode);
}
byte[] classData = getClassAsBytes(name);
@ -204,7 +198,6 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
return null;
}
Class<?> definedClass = defineClass(name, classData, 0, classData.length, getProtectionDomain(name));
classes.put(name, definedClass);
return definedClass;
}
@ -217,7 +210,6 @@ public class LaunchClassLoader extends URLClassLoader implements ClassNodeSource
byte[] classData = writer.toByteArray();
String name = className(node.name);
Class<?> definedClass = defineClass(name, classData, 0, classData.length, getProtectionDomain(name));
classes.put(name, definedClass);
return definedClass;
}

View file

@ -3,11 +3,15 @@ package org.mcphackers.launchwrapper.tweak;
import static org.mcphackers.launchwrapper.inject.InsnHelper.getLastReturn;
import static org.objectweb.asm.Opcodes.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.mcphackers.launchwrapper.AppletLaunchTarget;
import org.mcphackers.launchwrapper.Launch;
import org.mcphackers.launchwrapper.LaunchConfig;
import org.mcphackers.launchwrapper.LaunchTarget;
import org.mcphackers.launchwrapper.inject.ClassNodeSource;
import org.mcphackers.launchwrapper.inject.Inject;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
@ -78,7 +82,11 @@ public class IsomTweak extends LegacyTweak {
} else {
launchTarget.setTitle("IsomPreview");
}
launchTarget.setIcon(Inject.getIcon());
try {
launchTarget.setIcon(ImageIO.read(Launch.class.getClassLoader().getResourceAsStream("/favicon.png")));
} catch (IOException e) {
e.printStackTrace();
}
launchTarget.setResolution(launch.width.get(), launch.height.get());
return launchTarget;
}

View file

@ -78,6 +78,7 @@ public class LegacyTweak extends Tweak {
protected MethodNode main;
protected SkinType skinType = null;
protected int port = -1;
private boolean classic;
public LegacyTweak(ClassNodeSource source, LaunchConfig launch) {
super(source);
@ -407,7 +408,7 @@ public class LegacyTweak extends Tweak {
private void displayPatch(MethodNode init, boolean supportsResizing) {
boolean foundTitle = false; // TODO
boolean classic = isClassic();
this.classic = isClassic();
String canvasName = null;
int thisIndex = 0;
@ -726,7 +727,7 @@ public class LegacyTweak extends Tweak {
private void enableLegacyMergeSort() {
try {
Class<?> mergeSort = ClassLoader.getSystemClassLoader().loadClass("java.util.Arrays$LegacyMergeSort");
Class<?> mergeSort = Class.forName("java.util.Arrays$LegacyMergeSort");
Field userRequested = mergeSort.getDeclaredField("userRequested");
UnsafeUtils.setStaticBoolean(userRequested, true);
} catch (ClassNotFoundException e) {
@ -1136,35 +1137,21 @@ public class LegacyTweak extends Tweak {
private InsnList getIcon(boolean grassIcon) {
tweakInfo("Replaced icon");
InsnList insert = new InsnList();
if(launch.icon.get() != null && hasIcon(launch.icon.get())) {
insert.add(new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "loadIcons", "()[Ljava/nio/ByteBuffer;"));
} else {
insert.add(booleanInsn(grassIcon));
insert.add(new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "loadDefaultIcon", "(Z)[Ljava/nio/ByteBuffer;"));
}
insert.add(booleanInsn(grassIcon));
insert.add(new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "loadIcon", "(Z)[Ljava/nio/ByteBuffer;"));
insert.add(new MethodInsnNode(INVOKESTATIC, "org/lwjgl/opengl/Display", "setIcon", "([Ljava/nio/ByteBuffer;)I"));
insert.add(new InsnNode(POP));
return insert;
}
private boolean hasIcon(File[] icons) {
for(File f : icons) {
if(f.exists()) {
return true;
}
}
return false;
}
private MethodNode getMain() {
MethodNode node = new MethodNode(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
InsnList insns = node.instructions;
final int appletIndex = 1;
final int frameIndex = 2;
final int canvasIndex = 3;
final int mcIndex = 4;
final int threadIndex = 5;
final int mcIndex = 3;
final int threadIndex = 4;
final String listenerClass = "org/mcphackers/launchwrapper/inject/WindowListener";
@ -1190,32 +1177,29 @@ public class LegacyTweak extends Tweak {
if(!launch.lwjglFrame.get()) {
insns.add(new TypeInsnNode(NEW, "java/awt/Frame"));
insns.add(new InsnNode(DUP));
insns.add(new LdcInsnNode("Minecraft"));
insns.add(new LdcInsnNode(launch.title.get() == null ? "Minecraft" : launch.title.get()));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/awt/Frame", "<init>", "(Ljava/lang/String;)V"));
insns.add(new VarInsnNode(ASTORE, frameIndex));
insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new FieldInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "getIcon", "()Ljava/awt/image/BufferedImage;"));
insns.add(booleanInsn(classic));
insns.add(new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "getIcon", "(Z)Ljava/awt/image/BufferedImage;"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Frame", "setIconImage", "(Ljava/awt/Image;)V"));
insns.add(new TypeInsnNode(NEW, "java/awt/Canvas"));
insns.add(new InsnNode(DUP));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/awt/Canvas", "<init>", "()V"));
insns.add(new VarInsnNode(ASTORE, canvasIndex));
insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new TypeInsnNode(NEW, "java/awt/BorderLayout"));
insns.add(new InsnNode(DUP));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/awt/BorderLayout", "<init>", "()V"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Frame", "setLayout", "(Ljava/awt/LayoutManager;)V"));
insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new VarInsnNode(ALOAD, canvasIndex));
insns.add(new VarInsnNode(ALOAD, appletIndex));
insns.add(new LdcInsnNode("Center"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Frame", "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"));
insns.add(new VarInsnNode(ALOAD, canvasIndex));
insns.add(new VarInsnNode(ALOAD, appletIndex));
insns.add(new TypeInsnNode(NEW, "java/awt/Dimension"));
insns.add(new InsnNode(DUP));
insns.add(intInsn(launch.width.get()));
insns.add(intInsn(launch.height.get()));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/awt/Dimension", "<init>", "(II)V"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Canvas", "setPreferredSize", "(Ljava/awt/Dimension;)V"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Component", "setPreferredSize", "(Ljava/awt/Dimension;)V"));
insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Frame", "pack", "()V"));
insns.add(new VarInsnNode(ALOAD, frameIndex));
@ -1255,12 +1239,14 @@ public class LegacyTweak extends Tweak {
insns.add(booleanInsn(launch.applet.get()));
insns.add(new FieldInsnNode(PUTFIELD, minecraft.name, appletMode.name, appletMode.desc));
}
insns.add(new TypeInsnNode(NEW, "java/lang/Thread"));
insns.add(new InsnNode(DUP));
insns.add(new VarInsnNode(ALOAD, mcIndex));
insns.add(new LdcInsnNode("Minecraft main thread"));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Thread", "<init>", "(Ljava/lang/Runnable;Ljava/lang/String;)V"));
insns.add(new VarInsnNode(ASTORE, threadIndex));
if(launch.lwjglFrame.get()) {
insns.add(new TypeInsnNode(NEW, "java/lang/Thread"));
insns.add(new InsnNode(DUP));
insns.add(new VarInsnNode(ALOAD, mcIndex));
insns.add(new LdcInsnNode("Minecraft main thread"));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Thread", "<init>", "(Ljava/lang/Runnable;Ljava/lang/String;)V"));
insns.add(new VarInsnNode(ASTORE, threadIndex));
}
if(!launch.lwjglFrame.get()) {
insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new InsnNode(ICONST_1));
@ -1269,13 +1255,13 @@ public class LegacyTweak extends Tweak {
insns.add(new TypeInsnNode(NEW, listenerClass));
insns.add(new InsnNode(DUP));
insns.add(new VarInsnNode(ALOAD, mcIndex));
insns.add(new VarInsnNode(ALOAD, threadIndex));
insns.add(new MethodInsnNode(INVOKESPECIAL, listenerClass, "<init>", "(L" + minecraft.name + ";Ljava/lang/Thread;)V"));
insns.add(new MethodInsnNode(INVOKESPECIAL, listenerClass, "<init>", "(L" + minecraft.name + ";)V"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/awt/Frame", "addWindowListener", "(Ljava/awt/event/WindowListener;)V"));
createWindowListener(listenerClass);
} else {
insns.add(new VarInsnNode(ALOAD, threadIndex));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Thread", "start", "()V"));
}
insns.add(new VarInsnNode(ALOAD, threadIndex));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Thread", "start", "()V"));
insns.add(new InsnNode(RETURN));
tweakInfo("Added main");
return node;
@ -1382,16 +1368,12 @@ public class LegacyTweak extends Tweak {
ClassNode node = new ClassNode();
node.visit(49, ACC_PUBLIC, listenerClass, null, "java/awt/event/WindowAdapter", null);
node.fields.add(new FieldNode(ACC_PRIVATE, "mc", "L" + minecraft.name + ";", null, null));
node.fields.add(new FieldNode(ACC_PRIVATE, "thread", "Ljava/lang/Thread;", null, null));
MethodNode init = new MethodNode(ACC_PUBLIC, "<init>", "(L" + minecraft.name + ";Ljava/lang/Thread;)V", null, null);
MethodNode init = new MethodNode(ACC_PUBLIC, "<init>", "(L" + minecraft.name + ";)V", null, null);
InsnList insns = init.instructions;
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new VarInsnNode(ALOAD, 1));
insns.add(new FieldInsnNode(PUTFIELD, listenerClass, "mc", "L" + minecraft.name + ";"));
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new VarInsnNode(ALOAD, 2));
insns.add(new FieldInsnNode(PUTFIELD, listenerClass, "thread", "Ljava/lang/Thread;"));
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new MethodInsnNode(INVOKESPECIAL, "java/awt/event/WindowAdapter", "<init>", "()V"));
insns.add(new InsnNode(RETURN));
node.methods.add(init);
@ -1399,29 +1381,10 @@ public class LegacyTweak extends Tweak {
MethodNode windowClosing = new MethodNode(ACC_PUBLIC, "windowClosing", "(Ljava/awt/event/WindowEvent;)V", null, null);
insns = windowClosing.instructions;
LabelNode l0 = new LabelNode();
LabelNode l1 = new LabelNode();
LabelNode l2 = new LabelNode();
LabelNode l4 = new LabelNode();
windowClosing.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/InterruptedException"));
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new FieldInsnNode(GETFIELD, listenerClass, "mc", "L" + minecraft.name + ";"));
insns.add(new InsnNode(ICONST_0));
insns.add(new FieldInsnNode(PUTFIELD, minecraft.name, running.name, running.desc));
insns.add(l0);
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new FieldInsnNode(GETFIELD, listenerClass, "thread", "Ljava/lang/Thread;"));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Thread", "join", "()V"));
insns.add(l1);
insns.add(new JumpInsnNode(GOTO, l4));
insns.add(l2);
insns.add(new VarInsnNode(ASTORE, 2));
insns.add(new VarInsnNode(ALOAD, 2));
insns.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/InterruptedException", "printStackTrace", "()V"));
insns.add(l4);
insns.add(new InsnNode(ICONST_0));
insns.add(new MethodInsnNode(INVOKESTATIC, "java/lang/System", "exit", "(I)V"));
insns.add(new InsnNode(RETURN));
node.methods.add(windowClosing);
source.overrideClass(node);
@ -1438,10 +1401,6 @@ public class LegacyTweak extends Tweak {
throw new NullPointerException();
}
// final int appletIndex = 1;
// final int frameIndex = 2;
// final int canvasIndex = 3;
InsnList insns = new InsnList();
insns.add(new TypeInsnNode(NEW, minecraftImpl.name));
insns.add(new InsnNode(DUP));
@ -1455,7 +1414,6 @@ public class LegacyTweak extends Tweak {
if(launch.lwjglFrame.get()) {
insns.add(new InsnNode(ACONST_NULL));
} else {
// insns.add(new VarInsnNode(ALOAD, canvasIndex));
insns.add(new VarInsnNode(ALOAD, 0));
insns.add(new FieldInsnNode(GETFIELD, minecraftApplet.name, canvasField, "Ljava/awt/Canvas;"));
}
@ -1463,10 +1421,9 @@ public class LegacyTweak extends Tweak {
if(launch.lwjglFrame.get()) {
insns.add(new InsnNode(ACONST_NULL));
} else {
// insns.add(new VarInsnNode(ALOAD, frameIndex));
insns.add(new VarInsnNode(ALOAD, 0));
}
} else if(minecraftApplet != null && desc.equals("L" + minecraftApplet.name + ";")) {
// insns.add(new VarInsnNode(ALOAD, appletIndex));
insns.add(new VarInsnNode(ALOAD, 0));
} else if(desc.equals("I")) {
if(i == 0) {