Refactoring of ModUtil members

This commit is contained in:
Frank 2021-08-18 14:29:15 +02:00
parent 71ad055ea5
commit 3bb8fec4b2
11 changed files with 221 additions and 193 deletions

View file

@ -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));
} }
} }

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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;

View file

@ -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

View file

@ -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 {

View file

@ -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 &gt; 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 &ge; v2
*/
public static boolean isLargerOrEqualVersion(String v1, String v2){
return getModVersion(v1) >= getModVersion(v2);
}
} }

View file

@ -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() {

View file

@ -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))

View 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 &gt; 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 &ge; 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();
}
}
}

View file

@ -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
* *