wip modding (3)

This commit is contained in:
Bixilon 2020-09-26 23:21:36 +02:00
parent 1fb09e8f40
commit 16f07b7e3b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 132 additions and 42 deletions

View File

@ -114,5 +114,10 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.xeustechnologies</groupId>
<artifactId>jcl-core</artifactId>
<version>2.8</version>
</dependency>
</dependencies>
</project>

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.gui.main.AccountListCell;
import de.bixilon.minosoft.gui.main.Server;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.logging.LogLevels;
import de.bixilon.minosoft.modding.loading.ModLoader;
import de.bixilon.minosoft.util.OSUtil;
import de.bixilon.minosoft.util.Util;
import de.bixilon.minosoft.util.mojang.api.MojangAccount;
@ -70,6 +71,9 @@ public class Minosoft {
selectAccount(accountList.get(config.getString(GameConfiguration.ACCOUNT_SELECTED)));
serverList = config.getServers();
Thread modThread = new Thread(ModLoader::loadMods);
modThread.setName("ModLoader");
modThread.start();
Launcher.start();
}

View File

@ -52,6 +52,9 @@ public class Ingredient {
if (super.equals(obj)) {
return true;
}
if (this.hashCode() != obj.hashCode()) {
return false;
}
Ingredient their = (Ingredient) obj;
return slotEquals(getSlot(), their.getSlot());
}

View File

@ -11,7 +11,9 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.modding.loading;
package de.bixilon.minosoft.modding;
import de.bixilon.minosoft.modding.loading.ModPhases;
interface MinosoftModInterface {
boolean start(ModPhases phase);

View File

@ -1,36 +0,0 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.modding;
import de.bixilon.minosoft.Config;
import java.io.File;
public class ModLoader {
ModPhases currentPhase;
public static void loadMods() {
// load all jars, parse the mod.json
// sort the list and prioritize
// load all lists and dependencies async
File[] files = new File(Config.homeDir + "mods").listFiles();
if (files == null) {
// no mods to load
return;
}
for (File modFile : files) {
}
}
}

View File

@ -28,7 +28,7 @@ public class ModInfo {
final String[] authors;
final String identifier;
final String mainClass;
LoadingInfo info;
LoadingInfo loadingInfo;
public ModInfo(JsonObject json) {
this.uuid = Util.uuidFromString(json.get("uuid").getAsString());
@ -46,9 +46,9 @@ public class ModInfo {
this.mainClass = json.get("mainClass").getAsString();
if (json.has("loading")) {
JsonObject loading = json.getAsJsonObject("loading");
this.info = new LoadingInfo();
this.loadingInfo = new LoadingInfo();
if (loading.has("priority")) {
this.info.setLoadingPriority(LoadingPriorities.valueOf(loading.get("priority").getAsString()));
this.loadingInfo.setLoadingPriority(LoadingPriorities.valueOf(loading.get("priority").getAsString()));
}
}
}
@ -81,7 +81,32 @@ public class ModInfo {
return mainClass;
}
public LoadingInfo getInfo() {
return info;
public LoadingInfo getLoadingInfo() {
return loadingInfo;
}
@Override
public String toString() {
return String.format("name=\"%s\", uuid=%s, versionName=\"%s\", versionId=%d", getName(), getUUID(), getVersionName(), getVersionId());
}
@Override
public int hashCode() {
return uuid.hashCode() * versionId;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this.hashCode() != obj.hashCode()) {
return false;
}
if (super.equals(obj)) {
return true;
}
ModInfo their = (ModInfo) obj;
return getUUID().equals(their.getUUID()) && getVersionId() == their.getVersionId();
}
}

View File

@ -0,0 +1,87 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.modding.loading;
import de.bixilon.minosoft.Config;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.modding.MinosoftMod;
import de.bixilon.minosoft.util.Util;
import org.xeustechnologies.jcl.JarClassLoader;
import org.xeustechnologies.jcl.JclObjectFactory;
import java.io.File;
import java.io.IOException;
import java.util.TreeMap;
import java.util.zip.ZipFile;
public class ModLoader {
static TreeMap<ModInfo, MinosoftMod> modMap;
ModPhases currentPhase;
public static void loadMods() {
modMap = new TreeMap<>((a, b) -> {
LoadingPriorities priorityA = getLoadingPriorityOrDefault(a);
LoadingPriorities priorityB = getLoadingPriorityOrDefault(b);
return -(priorityA.ordinal() - priorityB.ordinal());
});
// load all jars, parse the mod.json
// sort the list and prioritize
// load all lists and dependencies async
File[] files = new File(Config.homeDir + "mods").listFiles();
if (files == null) {
// no mods to load
return;
}
for (File modFile : files) {
if (modFile.isDirectory()) {
continue;
}
try {
Log.verbose(String.format("[MOD] Loading file %s", modFile.getAbsolutePath()));
ZipFile zipFile = new ZipFile(modFile);
ModInfo modInfo = new ModInfo(Util.readJsonFromZip("mod.json", zipFile));
if (modMap.containsKey(modInfo)) {
Log.warn(String.format("Mod %s:%d (uuid=%s) is loaded multiple times! Skipping", modInfo.getName(), modInfo.getVersionId(), modInfo.getUUID()));
continue;
}
JarClassLoader jcl = new JarClassLoader();
jcl.add(modFile.getAbsolutePath());
JclObjectFactory factory = JclObjectFactory.getInstance();
MinosoftMod instance = (MinosoftMod) factory.create(jcl, modInfo.getMainClass());
Log.verbose(String.format("[MOD] Mod file loaded (%s)", modInfo));
modMap.put(modInfo, instance);
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
Log.warn(String.format("Could not load mod: %s", modFile.getAbsolutePath()));
}
}
for (ModPhases phase : ModPhases.values()) {
Log.verbose(String.format("Map loading phase changed: %s", phase));
modMap.forEach((modInfo, instance) -> {
instance.start(phase);
});
}
}
private static LoadingPriorities getLoadingPriorityOrDefault(ModInfo info) {
if (info.getLoadingInfo() != null && info.getLoadingInfo().getLoadingPriority() != null) {
return info.getLoadingInfo().getLoadingPriority();
}
return LoadingPriorities.NORMAL;
}
}