Refactoring of ModUtil
members
This commit is contained in:
parent
71ad055ea5
commit
3bb8fec4b2
11 changed files with 221 additions and 193 deletions
|
@ -9,6 +9,7 @@ import net.minecraft.nbt.NbtIo;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
import ru.bclib.api.datafixer.DataFixerAPI;
|
||||||
|
import ru.bclib.util.ModUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -143,6 +144,6 @@ public class WorldDataAPI {
|
||||||
* @return {@code int} mod version.
|
* @return {@code int} mod version.
|
||||||
*/
|
*/
|
||||||
public static int getIntModVersion(String modID) {
|
public static int getIntModVersion(String modID) {
|
||||||
return DataFixerAPI.getModVersion(getModVersion(modID));
|
return ModUtil.convertModVersion(getModVersion(modID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,9 @@ import ru.bclib.api.dataexchange.DataHandler;
|
||||||
import ru.bclib.api.dataexchange.SyncFileHash;
|
import ru.bclib.api.dataexchange.SyncFileHash;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.NeedTransferPredicate;
|
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.NeedTransferPredicate;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.SyncFolderDescriptor.SubFile;
|
import ru.bclib.api.dataexchange.handler.autosync.SyncFolderDescriptor.SubFile;
|
||||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
import ru.bclib.util.ModUtil;
|
||||||
import ru.bclib.util.Pair;
|
import ru.bclib.util.Pair;
|
||||||
import ru.bclib.util.PathUtil;
|
import ru.bclib.util.ModUtil.ModInfo;
|
||||||
import ru.bclib.util.PathUtil.ModInfo;
|
|
||||||
import ru.bclib.util.Triple;
|
import ru.bclib.util.Triple;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -56,7 +55,7 @@ class AutoFileSyncEntry extends AutoSyncID {
|
||||||
|
|
||||||
static class ForModFileRequest extends AutoFileSyncEntry {
|
static class ForModFileRequest extends AutoFileSyncEntry {
|
||||||
public static File getLocalPathForID(String modID, boolean matchLocalVersion){
|
public static File getLocalPathForID(String modID, boolean matchLocalVersion){
|
||||||
ModInfo mi = PathUtil.getModInfo(modID, matchLocalVersion);
|
ModInfo mi = ModUtil.getModInfo(modID, matchLocalVersion);
|
||||||
if (mi!=null){
|
if (mi!=null){
|
||||||
return mi.jarPath.toFile();
|
return mi.jarPath.toFile();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +69,7 @@ class AutoFileSyncEntry extends AutoSyncID {
|
||||||
BCLib.LOGGER.error("Unknown mod '"+modID+"'.");
|
BCLib.LOGGER.error("Unknown mod '"+modID+"'.");
|
||||||
}
|
}
|
||||||
if (version==null)
|
if (version==null)
|
||||||
this.version = PathUtil.getModVersion(modID);
|
this.version = ModUtil.getModVersion(modID);
|
||||||
else
|
else
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
@ -78,12 +77,12 @@ class AutoFileSyncEntry extends AutoSyncID {
|
||||||
@Override
|
@Override
|
||||||
public int serializeContent(FriendlyByteBuf buf) {
|
public int serializeContent(FriendlyByteBuf buf) {
|
||||||
final int res = super.serializeContent(buf);
|
final int res = super.serializeContent(buf);
|
||||||
buf.writeInt(DataFixerAPI.getModVersion(version));
|
buf.writeInt(ModUtil.convertModVersion(version));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AutoFileSyncEntry.ForModFileRequest finishDeserializeContent(String modID, FriendlyByteBuf buf) {
|
static AutoFileSyncEntry.ForModFileRequest finishDeserializeContent(String modID, FriendlyByteBuf buf) {
|
||||||
final String version = DataFixerAPI.getModVersion(buf.readInt());
|
final String version = ModUtil.convertModVersion(buf.readInt());
|
||||||
return new AutoFileSyncEntry.ForModFileRequest(modID, false, version);
|
return new AutoFileSyncEntry.ForModFileRequest(modID, false, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package ru.bclib.api.dataexchange.handler.autosync;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import ru.bclib.api.dataexchange.DataHandler;
|
import ru.bclib.api.dataexchange.DataHandler;
|
||||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
import ru.bclib.util.ModUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -62,11 +62,11 @@ public class AutoSyncID {
|
||||||
@Override
|
@Override
|
||||||
void serializeData(FriendlyByteBuf buf) {
|
void serializeData(FriendlyByteBuf buf) {
|
||||||
super.serializeData(buf);
|
super.serializeData(buf);
|
||||||
buf.writeInt(DataFixerAPI.getModVersion(version));
|
buf.writeInt(ModUtil.convertModVersion(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ForModFileRequest finishDeserialize(String modID, String uniqueID, FriendlyByteBuf buf){
|
static ForModFileRequest finishDeserialize(String modID, String uniqueID, FriendlyByteBuf buf){
|
||||||
final String version = DataFixerAPI.getModVersion(buf.readInt());
|
final String version = ModUtil.convertModVersion(buf.readInt());
|
||||||
return new ForModFileRequest(modID, version);
|
return new ForModFileRequest(modID, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,12 @@ import ru.bclib.api.dataexchange.handler.autosync.AutoSync.ClientConfig;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.Config;
|
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.Config;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.AutoSyncID.WithContentOverride;
|
import ru.bclib.api.dataexchange.handler.autosync.AutoSyncID.WithContentOverride;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.SyncFolderDescriptor.SubFile;
|
import ru.bclib.api.dataexchange.handler.autosync.SyncFolderDescriptor.SubFile;
|
||||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
|
||||||
import ru.bclib.gui.screens.SyncFilesScreen;
|
import ru.bclib.gui.screens.SyncFilesScreen;
|
||||||
import ru.bclib.gui.screens.WarnBCLibVersionMismatch;
|
import ru.bclib.gui.screens.WarnBCLibVersionMismatch;
|
||||||
|
import ru.bclib.util.ModUtil;
|
||||||
import ru.bclib.util.Pair;
|
import ru.bclib.util.Pair;
|
||||||
import ru.bclib.util.PathUtil;
|
import ru.bclib.util.PathUtil;
|
||||||
import ru.bclib.util.PathUtil.ModInfo;
|
import ru.bclib.util.ModUtil.ModInfo;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -46,7 +46,7 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getBCLibVersion() {
|
static String getBCLibVersion() {
|
||||||
return PathUtil.getModVersion(BCLib.MOD_ID);
|
return ModUtil.getModVersion(BCLib.MOD_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,14 +67,14 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
final List<String> mods = DataExchangeAPI.registeredMods();
|
final List<String> mods = DataExchangeAPI.registeredMods();
|
||||||
|
|
||||||
//write BCLibVersion (=protocol version)
|
//write BCLibVersion (=protocol version)
|
||||||
buf.writeInt(DataFixerAPI.getModVersion(vbclib));
|
buf.writeInt(ModUtil.convertModVersion(vbclib));
|
||||||
|
|
||||||
if (Config.isOfferingMods()) {
|
if (Config.isOfferingMods()) {
|
||||||
//write Plugin Versions
|
//write Plugin Versions
|
||||||
buf.writeInt(mods.size());
|
buf.writeInt(mods.size());
|
||||||
for (String modID : mods) {
|
for (String modID : mods) {
|
||||||
final String ver = PathUtil.getModVersion(modID);
|
final String ver = ModUtil.getModVersion(modID);
|
||||||
final ModInfo mi = PathUtil.getModInfo(modID);
|
final ModInfo mi = ModUtil.getModInfo(modID);
|
||||||
int size = 0;
|
int size = 0;
|
||||||
if (mi!=null) {
|
if (mi!=null) {
|
||||||
try {
|
try {
|
||||||
|
@ -86,7 +86,7 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
writeString(buf, modID);
|
writeString(buf, modID);
|
||||||
buf.writeInt(DataFixerAPI.getModVersion(ver));
|
buf.writeInt(ModUtil.convertModVersion(ver));
|
||||||
buf.writeInt(size);
|
buf.writeInt(size);
|
||||||
|
|
||||||
BCLib.LOGGER.info(" - Listing Mod " + modID + " v" + ver + " ("+PathUtil.humanReadableFileSize(size)+")");
|
BCLib.LOGGER.info(" - Listing Mod " + modID + " v" + ver + " ("+PathUtil.humanReadableFileSize(size)+")");
|
||||||
|
@ -139,8 +139,8 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
@Override
|
@Override
|
||||||
protected void deserializeIncomingDataOnClient(FriendlyByteBuf buf, PacketSender responseSender) {
|
protected void deserializeIncomingDataOnClient(FriendlyByteBuf buf, PacketSender responseSender) {
|
||||||
//read BCLibVersion (=protocol version)
|
//read BCLibVersion (=protocol version)
|
||||||
bclibVersion = DataFixerAPI.getModVersion(buf.readInt());
|
bclibVersion = ModUtil.convertModVersion(buf.readInt());
|
||||||
final boolean protocolVersion_0_4_1 = DataFixerAPI.isLargerOrEqualVersion(bclibVersion, "0.4.1");
|
final boolean protocolVersion_0_4_1 = ModUtil.isLargerOrEqualVersion(bclibVersion, "0.4.1");
|
||||||
|
|
||||||
|
|
||||||
//read Plugin Versions
|
//read Plugin Versions
|
||||||
|
@ -148,7 +148,7 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
int count = buf.readInt();
|
int count = buf.readInt();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
final String id = readString(buf);
|
final String id = readString(buf);
|
||||||
final String version = DataFixerAPI.getModVersion(buf.readInt());
|
final String version = ModUtil.convertModVersion(buf.readInt());
|
||||||
final int size;
|
final int size;
|
||||||
//since v0.4.1 we also send the size of the mod-File
|
//since v0.4.1 we also send the size of the mod-File
|
||||||
if (protocolVersion_0_4_1) {
|
if (protocolVersion_0_4_1) {
|
||||||
|
@ -289,7 +289,7 @@ public class HelloClient extends DataHandler.FromServer {
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
private void processModFileSync(final List<AutoSyncID> filesToRequest) {
|
private void processModFileSync(final List<AutoSyncID> filesToRequest) {
|
||||||
for (Entry<String, Pair<String, Integer>> e : modVersion.entrySet()) {
|
for (Entry<String, Pair<String, Integer>> e : modVersion.entrySet()) {
|
||||||
final String localVersion = PathUtil.getModVersion(e.getKey());
|
final String localVersion = ModUtil.getModVersion(e.getKey());
|
||||||
final Pair<String, Integer> serverInfo = e.getValue();
|
final Pair<String, Integer> serverInfo = e.getValue();
|
||||||
final boolean requestMod = !serverInfo.first.equals(localVersion) && serverInfo.second>0;
|
final boolean requestMod = !serverInfo.first.equals(localVersion) && serverInfo.second>0;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import ru.bclib.api.dataexchange.DataHandler;
|
||||||
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
|
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.ClientConfig;
|
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.ClientConfig;
|
||||||
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.Config;
|
import ru.bclib.api.dataexchange.handler.autosync.AutoSync.Config;
|
||||||
import ru.bclib.api.datafixer.DataFixerAPI;
|
import ru.bclib.util.ModUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ public class HelloServer extends DataHandler.FromClient {
|
||||||
@Override
|
@Override
|
||||||
protected void serializeDataOnClient(FriendlyByteBuf buf) {
|
protected void serializeDataOnClient(FriendlyByteBuf buf) {
|
||||||
BCLib.LOGGER.info("Sending hello to server.");
|
BCLib.LOGGER.info("Sending hello to server.");
|
||||||
buf.writeInt(DataFixerAPI.getModVersion(HelloClient.getBCLibVersion()));
|
buf.writeInt(ModUtil.convertModVersion(HelloClient.getBCLibVersion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deserializeIncomingDataOnServer(FriendlyByteBuf buf, PacketSender responseSender) {
|
protected void deserializeIncomingDataOnServer(FriendlyByteBuf buf, PacketSender responseSender) {
|
||||||
bclibVersion = DataFixerAPI.getModVersion(buf.readInt());
|
bclibVersion = ModUtil.convertModVersion(buf.readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class SyncFolderDescriptor {
|
||||||
|
|
||||||
final SyncFolderDescriptor desc;
|
final SyncFolderDescriptor desc;
|
||||||
if (localDescriptor != null) {
|
if (localDescriptor != null) {
|
||||||
desc = new SyncFolderDescriptor(folderID, localDescriptor.localFolder, remAddFiles);
|
desc = new SyncFolderDescriptor(folderID, localDescriptor.localFolder, localDescriptor.removeAdditionalFiles && remAddFiles);
|
||||||
desc.fileCache = new ArrayList<>(count);
|
desc.fileCache = new ArrayList<>(count);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -496,63 +496,4 @@ public class DataFixerAPI {
|
||||||
Patch.getALL().add(patch.get());
|
Patch.getALL().add(patch.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get mod version from string. String should be in format: %d.%d.%d
|
|
||||||
*
|
|
||||||
* @param version - {@link String} mod version.
|
|
||||||
* @return int mod version.
|
|
||||||
*/
|
|
||||||
public static int getModVersion(String version) {
|
|
||||||
if (version.isEmpty()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
int res = 0;
|
|
||||||
final String semanticVersionPattern = "(\\d+)\\.(\\d+)\\.(\\d+)\\D*";
|
|
||||||
final Matcher matcher = Pattern.compile(semanticVersionPattern)
|
|
||||||
.matcher(version);
|
|
||||||
if (matcher.find()) {
|
|
||||||
if (matcher.groupCount() > 0) res = (Integer.parseInt(matcher.group(1)) & 0xFF) << 22;
|
|
||||||
if (matcher.groupCount() > 1) res |= (Integer.parseInt(matcher.group(2)) & 0xFF) << 14;
|
|
||||||
if (matcher.groupCount() > 2) res |= Integer.parseInt(matcher.group(3)) & 0x3FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get mod version from integer. String will be in format %d.%d.%d
|
|
||||||
*
|
|
||||||
* @param version - mod version in integer form.
|
|
||||||
* @return {@link String} mod version.
|
|
||||||
*/
|
|
||||||
public static String getModVersion(int version) {
|
|
||||||
int a = (version >> 22) & 0xFF;
|
|
||||||
int b = (version >> 14) & 0xFF;
|
|
||||||
int c = version & 0x3FFF;
|
|
||||||
return String.format(Locale.ROOT, "%d.%d.%d", a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code true} if the version v1 is larger than v2
|
|
||||||
* @param v1 A Version string
|
|
||||||
* @param v2 Another Version string
|
|
||||||
* @return v1 > v2
|
|
||||||
*/
|
|
||||||
public static boolean isLargerVersion(String v1, String v2){
|
|
||||||
return getModVersion(v1) > getModVersion(v2);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* {@code true} if the version v1 is larger or equal v2
|
|
||||||
* @param v1 A Version string
|
|
||||||
* @param v2 Another Version string
|
|
||||||
* @return v1 ≥ v2
|
|
||||||
*/
|
|
||||||
public static boolean isLargerOrEqualVersion(String v1, String v2){
|
|
||||||
return getModVersion(v1) >= getModVersion(v2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.nbt.Tag;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
import ru.bclib.api.WorldDataAPI;
|
import ru.bclib.api.WorldDataAPI;
|
||||||
|
import ru.bclib.util.ModUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -133,7 +134,7 @@ public class MigrationProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int currentPatchLevel(@NotNull String modID) {
|
public int currentPatchLevel(@NotNull String modID) {
|
||||||
return DataFixerAPI.getModVersion(currentPatchVersion(modID));
|
return ModUtil.convertModVersion(currentPatchVersion(modID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAnyFixes() {
|
public boolean hasAnyFixes() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ru.bclib.api.datafixer;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import ru.bclib.util.ModUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -90,7 +91,7 @@ public abstract class Patch {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.level = DataFixerAPI.getModVersion(version);
|
this.level = ModUtil.convertModVersion(version);
|
||||||
if (!ALL.stream()
|
if (!ALL.stream()
|
||||||
.filter(p -> p.modID
|
.filter(p -> p.modID
|
||||||
.equals(modID))
|
.equals(modID))
|
||||||
|
|
191
src/main/java/ru/bclib/util/ModUtil.java
Normal file
191
src/main/java/ru/bclib/util/ModUtil.java
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
package ru.bclib.util;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||||
|
import net.fabricmc.loader.metadata.ModMetadataParser;
|
||||||
|
import net.fabricmc.loader.metadata.ParseMetadataException;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class ModUtil {
|
||||||
|
private static Map<String, ModInfo> mods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unloads the cache of available mods created from {@link #getMods()}
|
||||||
|
*/
|
||||||
|
public static void invalidateCachedMods() {
|
||||||
|
mods = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a map of all mods that were found in the 'mods'-folder.
|
||||||
|
* <p>
|
||||||
|
* The method will cache the results. You can clear that cache (and free the memory) by
|
||||||
|
* calling {@link #invalidateCachedMods()}
|
||||||
|
* <p>
|
||||||
|
* An error message is printed if a mod fails to load, but the parsing will continue.
|
||||||
|
*
|
||||||
|
* @return A map of all found mods. (key=ModID, value={@link ModInfo})
|
||||||
|
*/
|
||||||
|
public static Map<String, ModInfo> getMods() {
|
||||||
|
if (mods != null) return mods;
|
||||||
|
|
||||||
|
mods = new HashMap<>();
|
||||||
|
org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger("BCLib|ModLoader");
|
||||||
|
PathUtil.fileWalker(PathUtil.MOD_FOLDER.toFile(), false, (file -> {
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("jar:" + file.toUri());
|
||||||
|
|
||||||
|
try (FileSystem fs = FileSystems.getFileSystem(uri)) {
|
||||||
|
final JarFile jarFile = new JarFile(file.toString());
|
||||||
|
Path modMetaFile = fs.getPath("fabric.mod.json");
|
||||||
|
|
||||||
|
ModMetadata mc = ModMetadataParser.parseMetadata(logger, modMetaFile);
|
||||||
|
mods.put(mc.getId(), new ModInfo(mc, file));
|
||||||
|
}
|
||||||
|
catch (ParseMetadataException e) {
|
||||||
|
BCLib.LOGGER.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
BCLib.LOGGER.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link ModInfo} or {@code null} if the mod was not found.
|
||||||
|
* <p>
|
||||||
|
* The call will also return null if the mode-Version in the jar-File is not the same
|
||||||
|
* as the version of the loaded Mod.
|
||||||
|
*
|
||||||
|
* @param modID The mod ID to query
|
||||||
|
* @return A {@link ModInfo}-Object for the querried Mod.
|
||||||
|
*/
|
||||||
|
public static ModInfo getModInfo(String modID) {
|
||||||
|
return getModInfo(modID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ModInfo getModInfo(String modID, boolean matchVersion) {
|
||||||
|
getMods();
|
||||||
|
final ModInfo mi = mods.get(modID);
|
||||||
|
if (mi == null || !getModVersion(modID).equals(mi.getVersion())) return null;
|
||||||
|
return mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Mod Version for the queried Mod
|
||||||
|
*
|
||||||
|
* @param modID The mod ID to query
|
||||||
|
* @return The version of the locally installed Mod
|
||||||
|
*/
|
||||||
|
public static String getModVersion(String modID) {
|
||||||
|
Optional<ModContainer> optional = FabricLoader.getInstance()
|
||||||
|
.getModContainer(modID);
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
ModContainer modContainer = optional.get();
|
||||||
|
return modContainer.getMetadata()
|
||||||
|
.getVersion()
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
return "0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mod version from string. String should be in format: %d.%d.%d
|
||||||
|
*
|
||||||
|
* @param version - {@link String} mod version.
|
||||||
|
* @return int mod version.
|
||||||
|
*/
|
||||||
|
public static int convertModVersion(String version) {
|
||||||
|
if (version.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int res = 0;
|
||||||
|
final String semanticVersionPattern = "(\\d+)\\.(\\d+)\\.(\\d+)\\D*";
|
||||||
|
final Matcher matcher = Pattern.compile(semanticVersionPattern)
|
||||||
|
.matcher(version);
|
||||||
|
if (matcher.find()) {
|
||||||
|
if (matcher.groupCount() > 0) res = (Integer.parseInt(matcher.group(1)) & 0xFF) << 22;
|
||||||
|
if (matcher.groupCount() > 1) res |= (Integer.parseInt(matcher.group(2)) & 0xFF) << 14;
|
||||||
|
if (matcher.groupCount() > 2) res |= Integer.parseInt(matcher.group(3)) & 0x3FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mod version from integer. String will be in format %d.%d.%d
|
||||||
|
*
|
||||||
|
* @param version - mod version in integer form.
|
||||||
|
* @return {@link String} mod version.
|
||||||
|
*/
|
||||||
|
public static String convertModVersion(int version) {
|
||||||
|
int a = (version >> 22) & 0xFF;
|
||||||
|
int b = (version >> 14) & 0xFF;
|
||||||
|
int c = version & 0x3FFF;
|
||||||
|
return String.format(Locale.ROOT, "%d.%d.%d", a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code true} if the version v1 is larger than v2
|
||||||
|
* @param v1 A Version string
|
||||||
|
* @param v2 Another Version string
|
||||||
|
* @return v1 > v2
|
||||||
|
*/
|
||||||
|
public static boolean isLargerVersion(String v1, String v2){
|
||||||
|
return convertModVersion(v1) > convertModVersion(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code true} if the version v1 is larger or equal v2
|
||||||
|
* @param v1 A Version string
|
||||||
|
* @param v2 Another Version string
|
||||||
|
* @return v1 ≥ v2
|
||||||
|
*/
|
||||||
|
public static boolean isLargerOrEqualVersion(String v1, String v2){
|
||||||
|
return convertModVersion(v1) >= convertModVersion(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ModInfo {
|
||||||
|
public final ModMetadata metadata;
|
||||||
|
public final Path jarPath;
|
||||||
|
|
||||||
|
ModInfo(ModMetadata metadata, Path jarPath) {
|
||||||
|
this.metadata = metadata;
|
||||||
|
this.jarPath = jarPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ModInfo{" + "id=" + metadata.getId() + ", version=" + metadata.getVersion() + ", jarPath=" + jarPath + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
if (metadata == null) return "0.0.0";
|
||||||
|
return metadata.getVersion()
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,112 +87,6 @@ public class PathUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ModInfo {
|
|
||||||
public final ModMetadata metadata;
|
|
||||||
public final Path jarPath;
|
|
||||||
|
|
||||||
ModInfo(ModMetadata metadata, Path jarPath) {
|
|
||||||
this.metadata = metadata;
|
|
||||||
this.jarPath = jarPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ModInfo{" + "id=" + metadata.getId() + ", version=" + metadata.getVersion() + ", jarPath=" + jarPath + '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
if (metadata == null) return "0.0.0";
|
|
||||||
return metadata.getVersion()
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, ModInfo> mods;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unloads the cache of available mods created from {@link #getMods()}
|
|
||||||
*/
|
|
||||||
public static void invalidateCachedMods() {
|
|
||||||
mods = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return a map of all mods that were found in the 'mods'-folder.
|
|
||||||
* <p>
|
|
||||||
* The method will cache the results. You can clear that cache (and free the memory) by
|
|
||||||
* calling {@link #invalidateCachedMods()}
|
|
||||||
* <p>
|
|
||||||
* An error message is printed if a mod fails to load, but the parsing will continue.
|
|
||||||
*
|
|
||||||
* @return A map of all found mods. (key=ModID, value={@link ModInfo})
|
|
||||||
*/
|
|
||||||
public static Map<String, ModInfo> getMods() {
|
|
||||||
if (mods != null) return mods;
|
|
||||||
|
|
||||||
mods = new HashMap<>();
|
|
||||||
org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger("BCLib|ModLoader");
|
|
||||||
PathUtil.fileWalker(MOD_FOLDER.toFile(), false, (file -> {
|
|
||||||
try {
|
|
||||||
URI uri = URI.create("jar:" + file.toUri());
|
|
||||||
|
|
||||||
try (FileSystem fs = FileSystems.getFileSystem(uri)) {
|
|
||||||
final JarFile jarFile = new JarFile(file.toString());
|
|
||||||
Path modMetaFile = fs.getPath("fabric.mod.json");
|
|
||||||
|
|
||||||
ModMetadata mc = ModMetadataParser.parseMetadata(logger, modMetaFile);
|
|
||||||
mods.put(mc.getId(), new ModInfo(mc, file));
|
|
||||||
}
|
|
||||||
catch (ParseMetadataException e) {
|
|
||||||
BCLib.LOGGER.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
BCLib.LOGGER.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return mods;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link ModInfo} or {@code null} if the mod was not found.
|
|
||||||
* <p>
|
|
||||||
* The call will also return null if the mode-Version in the jar-File is not the same
|
|
||||||
* as the version of the loaded Mod.
|
|
||||||
*
|
|
||||||
* @param modID The mod ID to query
|
|
||||||
* @return A {@link ModInfo}-Object for the querried Mod.
|
|
||||||
*/
|
|
||||||
public static ModInfo getModInfo(String modID) {
|
|
||||||
return getModInfo(modID, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ModInfo getModInfo(String modID, boolean matchVersion) {
|
|
||||||
getMods();
|
|
||||||
final ModInfo mi = mods.get(modID);
|
|
||||||
if (mi == null || !getModVersion(modID).equals(mi.getVersion())) return null;
|
|
||||||
return mi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Local Mod Version for the queried Mod
|
|
||||||
*
|
|
||||||
* @param modID The mod ID to query
|
|
||||||
* @return The version of the locally installed Mod
|
|
||||||
*/
|
|
||||||
public static String getModVersion(String modID) {
|
|
||||||
Optional<ModContainer> optional = FabricLoader.getInstance()
|
|
||||||
.getModContainer(modID);
|
|
||||||
if (optional.isPresent()) {
|
|
||||||
ModContainer modContainer = optional.get();
|
|
||||||
return modContainer.getMetadata()
|
|
||||||
.getVersion()
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
return "0.0.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a human readable File-Size
|
* Creates a human readable File-Size
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue