Skip to content

Commit

Permalink
Pushed 2.6
Browse files Browse the repository at this point in the history
- Rewrote the main menu GUI detection code to be much cleaner
- Removed the class path config since it's no longer needed
- Refactored some code parts in anticipation for 3.0
- Bumped Zip4J version to 2.11.5
- Bumped version number to 2.6
  • Loading branch information
HRudyPlayZ committed Mar 8, 2023
1 parent 854cae9 commit 5d495e6
Show file tree
Hide file tree
Showing 29 changed files with 162 additions and 265 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ buildscript {

apply plugin: 'forge'

version = "2.5"
version = "2.6"
group= "com.hrudyplayz.mcinstanceloader" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "mcinstanceloader"

Expand Down
2 changes: 0 additions & 2 deletions src/main/java/com/hrudyplayz/mcinstanceloader/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public class Config {
public static String curseforgeURL;
public static String curseforgeAPIKey;

public static String[] mainMenuClassPaths;
public static int closeGameTimer;
public static int amountOfDisplayedErrors;
public static String[] successMessage;
Expand Down Expand Up @@ -59,7 +58,6 @@ public static void createConfigFile() {

curseforgeAPIKey = config.getString("CFCore API key", CATEGORY_BEHAVIOR, "", "The API key to use if you use the official Curseforge API.");

mainMenuClassPaths = config.getStringList("Menu class paths", CATEGORY_GUI, new String[]{"net.minecraft.client.gui.GuiMainMenu"}, "List of Java class paths for menus that will get interrupted by this mod's GUI. May be useful for mods that change the main menu.");
closeGameTimer = config.getInt("Close game timer",CATEGORY_GUI, 10, 0, Integer.MAX_VALUE, "Delay before automatically closing the game on the success/fail screen. Set to 0 to disable.");
amountOfDisplayedErrors = config.getInt("Maximum amount of displayed errors", CATEGORY_GUI, 5, 0, 64, "Maximum number of errors that can be displayed on the error screen at once.");
successMessage = config.getStringList("Success message", CATEGORY_GUI, new String[]{"The modpack succcesfully installed.", "In order to see the applied changes, please restart your game."}, "Sentence displayed to the player after the pack finishes installing.");
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/hrudyplayz/mcinstanceloader/ForgeMod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.hrudyplayz.mcinstanceloader;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import com.hrudyplayz.mcinstanceloader.utils.LogHelper;
import org.apache.logging.log4j.Level;


@Mod(modid = ModProperties.MODID, name = ModProperties.NAME, version = ModProperties.VERSION)
public class ForgeMod {

@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
// The preInit event, that gets called as soon as possible in Forge's loading. Basically the entire mod.
// First phrase of the mod, gets ran at the game launch.

// ===== STEP 0: The mod's initialisation. =====
Main.initMod(event);

// ===== STEP 1: Cleanup phase =====
Main.cleanupFiles();
LogHelper.appendToLog(Level.INFO, "", true); // Adds an empty line to the log file, to make it more readable.

// ===== STEP 2: Check for updates =====
Main.updateChecker();

Main.secondPhase();
}
}
23 changes: 1 addition & 22 deletions src/main/java/com/hrudyplayz/mcinstanceloader/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
import net.minecraftforge.common.MinecraftForge;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.common.ProgressManager;
Expand All @@ -33,7 +31,6 @@


@SuppressWarnings("unused")
@Mod(modid = ModProperties.MODID, name = ModProperties.NAME, version = ModProperties.VERSION)
public class Main {
// This class defines the main mod class, and registers stuff like Events.

Expand All @@ -54,24 +51,6 @@ public class Main {

public static String[] blacklist; // List of strings that is later used to store the StopModReposts list.

@EventHandler
public void preInit(FMLPreInitializationEvent event) {
// The preInit event, that gets called as soon as possible in Forge's loading. Basically the entire mod.
// First phrase of the mod, gets ran at the game launch.

// ===== STEP 0: The mod's initialisation. =====
initMod(event);

// ===== STEP 1: Cleanup phase =====
cleanupFiles();
LogHelper.appendToLog(Level.INFO, "", true); // Adds an empty line to the log file, to make it more readable.

// ===== STEP 2: Check for updates =====
updateChecker();

secondPhase();
}

public static void secondPhase() {
// Second phase of the mod, used for the continue option in the update GUI.

Expand Down Expand Up @@ -151,7 +130,7 @@ public static void initMod(FMLPreInitializationEvent event) {
// Registers the GuiOpenEventHandler when on client side, and sets the variable to easily check which side is running.
if (FMLCommonHandler.instance().getSide() == Side.CLIENT) {
side = "client";
MinecraftForge.EVENT_BUS.register(GuiOpenEventHandler.instance);
MinecraftForge.EVENT_BUS.register(GuiOpenEventHandler.INSTANCE);
}
else side = "server";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ModProperties {
// General values
public static final String MODID = "mcinstanceloader";
public static final String NAME = "MCInstance Loader";
public static final String VERSION = "2.5";
public static final String VERSION = "2.6";
public static final String MC_VERSION = "1.7.10";
public static final String URL = "https://github.com/HRudyPlayZ/MCInstanceLoader/";

Expand Down Expand Up @@ -48,7 +48,7 @@ public class ModProperties {
"Also try ResourcceLoader",
"Finally updated!",
"Check the documentation on Github.",
"2.2, finally bug-free (i hope).",
"2.6, finally bug-free (i hope).",
"Since you're here, you might want to support the mod on Github and Modrinth!",
"The most memes you can get, in one package.",
"Every modpack needs this!",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;

import net.minecraft.client.gui.GuiMainMenu;
import com.hrudyplayz.mcinstanceloader.Main;
import com.hrudyplayz.mcinstanceloader.Config;
import com.hrudyplayz.mcinstanceloader.utils.LogHelper;
Expand All @@ -17,29 +18,23 @@
public class GuiOpenEventHandler {
// This class is the hook used to determine whenever a GUI gets displayed.

public static int callCounter = 0;
public static GuiOpenEventHandler instance = new GuiOpenEventHandler(); // Creates the instance, so we can register it as an EVENT_BUS.
public static final GuiOpenEventHandler INSTANCE = new GuiOpenEventHandler(); // Creates the instance, so we can register it as an EVENT_BUS.

@SubscribeEvent
@SideOnly(Side.CLIENT)
public void openMainMenu(GuiOpenEvent event) {
// Checks if the main menu gets shown.
if (!Main.hasUpdate && !Main.shouldDoSomething) return;

// If the event and the GUI are valid and the displayed GUI is part of the given class list (for mod support), it shows the results screen.
if (event != null && event.gui != null && Arrays.asList(Config.mainMenuClassPaths).contains(event.gui.getClass().toString().substring(6))) {
if (!Main.hasUpdate && !Main.shouldDoSomething) return;

if (event != null && event.gui != null && event.gui.getClass().isAssignableFrom(GuiMainMenu.class)) {
LogHelper.info("Displaying GUI.");

if (Main.hasUpdate && Config.updateCheckerMode < 2) event.gui = new InfoGui(event.gui);
else if (Main.shouldDoSomething) event.gui = new OptionalModsGui(event.gui);

MinecraftForge.EVENT_BUS.unregister(instance);
return;
MinecraftForge.EVENT_BUS.unregister(INSTANCE);
}

callCounter += 1; // Just a security to prevent this from getting fired too much.
if (callCounter >= 20) MinecraftForge.EVENT_BUS.unregister(instance);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ private static boolean isInvalidPath(String path) {
return false; // If nothing weird was found, then i guess it is valid.
}


/**
Creates a new directory at the specified path.
If the directory already exists, it doesn't do anything and succeeds.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/lingala/zip4j/crypto/AESDecrypter.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public int decryptData(byte[] buff, int start, int len) throws ZipException {
return len;
}

public byte[] getCalculatedAuthenticationBytes() {
return mac.doFinal();
public byte[] getCalculatedAuthenticationBytes(int numberOfBytesPushedBack) {
return mac.doFinal(numberOfBytesPushedBack);
}
}
41 changes: 34 additions & 7 deletions src/main/java/net/lingala/zip4j/crypto/PBKDF2/MacBasedPRF.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@

package net.lingala.zip4j.crypto.PBKDF2;

import net.lingala.zip4j.util.InternalZipConstants;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import static net.lingala.zip4j.util.InternalZipConstants.AES_BLOCK_SIZE;

/*
* Source referred from Matthias Gartner's PKCS#5 implementation -
* see http://rtner.de/software/PBKDF2.html
Expand All @@ -30,9 +35,11 @@ public class MacBasedPRF implements PRF {
private Mac mac;
private int hLen;
private String macAlgorithm;
private ByteArrayOutputStream macCache;

public MacBasedPRF(String macAlgorithm) {
this.macAlgorithm = macAlgorithm;
this.macCache = new ByteArrayOutputStream(InternalZipConstants.BUFF_SIZE);
try {
mac = Mac.getInstance(macAlgorithm);
hLen = mac.getMacLength();
Expand All @@ -42,10 +49,20 @@ public MacBasedPRF(String macAlgorithm) {
}

public byte[] doFinal(byte[] M) {
if (macCache.size() > 0) {
doMacUpdate(0);
}
return mac.doFinal(M);
}

public byte[] doFinal() {
return doFinal(0);
}

public byte[] doFinal(int numberOfBytesToPushbackForMac) {
if (macCache.size() > 0) {
doMacUpdate(numberOfBytesToPushbackForMac);
}
return mac.doFinal();
}

Expand All @@ -61,19 +78,29 @@ public void init(byte[] P) {
}
}

public void update(byte[] U) {
public void update(byte[] u) {
update(u, 0, u.length);
}

public void update(byte[] u, int start, int len) {
try {
mac.update(U);
if (macCache.size() + len > InternalZipConstants.BUFF_SIZE) {
doMacUpdate(0);
}
macCache.write(u, start, len);
} catch (IllegalStateException e) {
throw new RuntimeException(e);
}
}

public void update(byte[] U, int start, int len) {
try {
mac.update(U, start, len);
} catch (IllegalStateException e) {
throw new RuntimeException(e);
private void doMacUpdate(int numberOfBytesToPushBack) {
byte[] macBytes = macCache.toByteArray();
int numberOfBytesToRead = macBytes.length - numberOfBytesToPushBack;
int updateLength;
for (int i = 0; i < numberOfBytesToRead; i += InternalZipConstants.AES_BLOCK_SIZE) {
updateLength = (i + AES_BLOCK_SIZE) <= numberOfBytesToRead ? AES_BLOCK_SIZE : numberOfBytesToRead - i;
mac.update(macBytes, i, updateLength);
}
macCache.reset();
}
}
4 changes: 4 additions & 0 deletions src/main/java/net/lingala/zip4j/headers/HeaderReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public class HeaderReader {

public ZipModel readAllHeaders(RandomAccessFile zip4jRaf, Zip4jConfig zip4jConfig) throws IOException {

if (zip4jRaf.length() == 0) {
return new ZipModel();
}

if (zip4jRaf.length() < ENDHDR) {
throw new ZipException("Zip file size less than minimum expected zip file size. " +
"Probably not a zip file or a corrupted zip file");
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/net/lingala/zip4j/headers/HeaderWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public void writeLocalFileHeader(ZipModel zipModel, LocalFileHeader localFileHea
rawIO.writeShortLittleEndian(byteArrayOutputStream, (int) aesExtraDataRecord.getSignature().getValue());
rawIO.writeShortLittleEndian(byteArrayOutputStream, aesExtraDataRecord.getDataSize());
rawIO.writeShortLittleEndian(byteArrayOutputStream, aesExtraDataRecord.getAesVersion().getVersionNumber());
byteArrayOutputStream.write(aesExtraDataRecord.getVendorID().getBytes());
byteArrayOutputStream.write(getBytesFromString(aesExtraDataRecord.getVendorID(), charset));

byte[] aesStrengthBytes = new byte[1];
aesStrengthBytes[0] = (byte) aesExtraDataRecord.getAesKeyStrength().getRawCode();
Expand Down Expand Up @@ -221,7 +221,7 @@ public void finalizeZipFileWithoutValidations(ZipModel zipModel, OutputStream ou
}

try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
long offsetCentralDir = zipModel.getEndOfCentralDirectoryRecord().getOffsetOfStartOfCentralDirectory();
long offsetCentralDir = getOffsetOfCentralDirectory(zipModel);
writeCentralDirectory(zipModel, byteArrayOutputStream, rawIO, charset);
int sizeOfCentralDir = byteArrayOutputStream.size();

Expand Down Expand Up @@ -496,7 +496,7 @@ private void writeFileHeader(ZipModel zipModel, FileHeader fileHeader, ByteArray
rawIO.writeShortLittleEndian(byteArrayOutputStream, (int) aesExtraDataRecord.getSignature().getValue());
rawIO.writeShortLittleEndian(byteArrayOutputStream, aesExtraDataRecord.getDataSize());
rawIO.writeShortLittleEndian(byteArrayOutputStream, aesExtraDataRecord.getAesVersion().getVersionNumber());
byteArrayOutputStream.write(aesExtraDataRecord.getVendorID().getBytes());
byteArrayOutputStream.write(getBytesFromString(aesExtraDataRecord.getVendorID(), charset));

byte[] aesStrengthBytes = new byte[1];
aesStrengthBytes[0] = (byte) aesExtraDataRecord.getAesKeyStrength().getRawCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.AESExtraDataRecord;
import net.lingala.zip4j.model.LocalFileHeader;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.util.InternalZipConstants;
import net.lingala.zip4j.util.Zip4jUtil;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -119,22 +117,12 @@ private void copyBytesFromBuffer(byte[] b, int off) {
}

@Override
protected void endOfEntryReached(InputStream inputStream) throws IOException {
verifyContent(readStoredMac(inputStream));
protected void endOfEntryReached(InputStream inputStream, int numberOfBytesPushedBack) throws IOException {
verifyContent(readStoredMac(inputStream), numberOfBytesPushedBack);
}

private void verifyContent(byte[] storedMac) throws IOException {
if (getLocalFileHeader().isDataDescriptorExists()
&& CompressionMethod.DEFLATE.equals(Zip4jUtil.getCompressionMethod(getLocalFileHeader()))) {
// Skip content verification in case of Deflate compression and if data descriptor exists.
// In this case, we do not know the exact size of compressed data before hand and it is possible that we read
// and pass more than required data into inflater, thereby corrupting the aes mac bytes.
// See usage of PushBackInputStream in the project for how this push back of data is done
// Unfortunately, in this case we cannot perform a content verification and have to skip
return;
}

byte[] calculatedMac = getDecrypter().getCalculatedAuthenticationBytes();
private void verifyContent(byte[] storedMac, int numberOfBytesPushedBack) throws IOException {
byte[] calculatedMac = getDecrypter().getCalculatedAuthenticationBytes(numberOfBytesPushedBack);
byte[] first10BytesOfCalculatedMac = new byte[AES_AUTH_LENGTH];
System.arraycopy(calculatedMac, 0, first10BytesOfCalculatedMac, 0, InternalZipConstants.AES_AUTH_LENGTH);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public T getDecrypter() {
return decrypter;
}

protected void endOfEntryReached(InputStream inputStream) throws IOException {
protected void endOfEntryReached(InputStream inputStream, int numberOfBytesPushedBack) throws IOException {
// is optional but useful for AES
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

abstract class DecompressedInputStream extends InputStream {

private CipherInputStream cipherInputStream;
private CipherInputStream<?> cipherInputStream;
protected byte[] oneByteBuffer = new byte[1];

public DecompressedInputStream(CipherInputStream cipherInputStream) {
public DecompressedInputStream(CipherInputStream<?> cipherInputStream) {
this.cipherInputStream = cipherInputStream;
}

Expand Down Expand Up @@ -39,12 +39,13 @@ public void close() throws IOException {
cipherInputStream.close();
}

public void endOfEntryReached(InputStream inputStream) throws IOException {
cipherInputStream.endOfEntryReached(inputStream);
public void endOfEntryReached(InputStream inputStream, int numberOfBytesPushedBack) throws IOException {
cipherInputStream.endOfEntryReached(inputStream, numberOfBytesPushedBack);
}

public void pushBackInputStreamIfNecessary(PushbackInputStream pushbackInputStream) throws IOException {
public int pushBackInputStreamIfNecessary(PushbackInputStream pushbackInputStream) throws IOException {
// Do nothing by default
return 0;
}

protected byte[] getLastReadRawDataCache() {
Expand Down
Loading

0 comments on commit 5d495e6

Please sign in to comment.