Skip to content

Commit e090429

Browse files
committed
fix: Vendor in fml ModMetadata parsing to avoid unnecessary classloading
1 parent c017060 commit e090429

File tree

3 files changed

+140
-16
lines changed

3 files changed

+140
-16
lines changed

src/deploader/java/com/falsepattern/deploader/DependencyLoaderImpl.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
import org.jetbrains.annotations.NotNull;
4141
import org.jetbrains.annotations.Nullable;
4242

43-
import cpw.mods.fml.common.MetadataCollection;
44-
import cpw.mods.fml.common.ModMetadata;
4543
import cpw.mods.fml.fpdeploader.SystemExitBypassHelper;
4644

4745
import javax.swing.JFrame;
@@ -58,7 +56,6 @@
5856
import java.io.IOException;
5957
import java.io.InputStream;
6058
import java.io.InputStreamReader;
61-
import java.lang.reflect.Field;
6259
import java.net.MalformedURLException;
6360
import java.net.URISyntaxException;
6461
import java.net.URL;
@@ -103,7 +100,7 @@ public class DependencyLoaderImpl {
103100
private static final Map<String, String> loadedModIdMods = new ConcurrentHashMap<>();
104101
private static final Set<String> remoteMavenRepositories = new ConcurrentSet<>();
105102
private static final Set<String> localMavenRepositories = new ConcurrentSet<>();
106-
static final Logger LOG = LogManager.getLogger("FalsePatternLib DepLoader");
103+
public static final Logger LOG = LogManager.getLogger("FalsePatternLib DepLoader");
107104

108105
private static final AtomicLong counter = new AtomicLong(0);
109106
private static final ExecutorService executor = Executors.newCachedThreadPool(r -> {
@@ -115,21 +112,11 @@ public class DependencyLoaderImpl {
115112
private static final Path libDir;
116113
private static final Path modsDir;
117114
private static final Path tempDir;
118-
private static final Field metadataCollectionModListAccessor;
119115

120116
private static final AtomicBoolean needReboot = new AtomicBoolean(false);
121117
private static final Set<String> downloadedMods = new ConcurrentSet<>();
122118
private static final Set<String> downloadFailed = new ConcurrentSet<>();
123119

124-
static {
125-
try {
126-
metadataCollectionModListAccessor = MetadataCollection.class.getDeclaredField("modList");
127-
} catch (NoSuchFieldException e) {
128-
throw new RuntimeException(e);
129-
}
130-
metadataCollectionModListAccessor.setAccessible(true);
131-
}
132-
133120
private static void ensureExists(Path directory) {
134121
if (!Files.exists(directory)) {
135122
try {
@@ -300,8 +287,7 @@ public static CompletableFuture<Void> loadLibrariesAsync(Library... libraries) {
300287
private static void readMCMod(InputStream input, String name) {
301288
try {
302289
val meta = MetadataCollection.from(input, name);
303-
val modList = (ModMetadata[]) metadataCollectionModListAccessor.get(meta);
304-
for (val mod : modList) {
290+
for (val mod : meta.modList) {
305291
val id = mod.modId;
306292
if (id != null) {
307293
val versionStr = mod.version;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* This file is part of FalsePatternLib.
3+
*
4+
* Copyright (C) 2022-2025 FalsePattern
5+
* All Rights Reserved
6+
*
7+
* The above copyright notice and this permission notice shall be included
8+
* in all copies or substantial portions of the Software.
9+
*
10+
* FalsePatternLib is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Lesser General Public License as published by
12+
* the Free Software Foundation, only version 3 of the License.
13+
*
14+
* FalsePatternLib is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
21+
*/
22+
23+
package com.falsepattern.deploader;
24+
25+
import java.io.InputStream;
26+
import java.io.InputStreamReader;
27+
import java.util.Map;
28+
29+
import com.google.common.base.Throwables;
30+
import com.google.common.collect.Maps;
31+
import com.google.gson.Gson;
32+
import com.google.gson.GsonBuilder;
33+
import com.google.gson.JsonArray;
34+
import com.google.gson.JsonElement;
35+
import com.google.gson.JsonParseException;
36+
import com.google.gson.JsonParser;
37+
38+
class MetadataCollection
39+
{
40+
@SuppressWarnings("unused")
41+
private String modListVersion;
42+
ModMetadata[] modList;
43+
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
44+
45+
public static MetadataCollection from(InputStream inputStream, String sourceName)
46+
{
47+
if (inputStream == null)
48+
{
49+
return new MetadataCollection();
50+
}
51+
52+
InputStreamReader reader = new InputStreamReader(inputStream);
53+
try
54+
{
55+
MetadataCollection collection;
56+
Gson gson = new GsonBuilder().create();
57+
JsonParser parser = new JsonParser();
58+
JsonElement rootElement = parser.parse(reader);
59+
if (rootElement.isJsonArray())
60+
{
61+
collection = new MetadataCollection();
62+
JsonArray jsonList = rootElement.getAsJsonArray();
63+
collection.modList = new ModMetadata[jsonList.size()];
64+
int i = 0;
65+
for (JsonElement mod : jsonList)
66+
{
67+
collection.modList[i++]=gson.fromJson(mod, ModMetadata.class);
68+
}
69+
}
70+
else
71+
{
72+
collection = gson.fromJson(rootElement, MetadataCollection.class);
73+
}
74+
collection.parseModMetadataList();
75+
return collection;
76+
}
77+
catch (JsonParseException e)
78+
{
79+
DependencyLoaderImpl.LOG.error(e);
80+
DependencyLoaderImpl.LOG.error("The mcmod.info file in {} cannot be parsed as valid JSON. It will be ignored", sourceName);
81+
return new MetadataCollection();
82+
}
83+
catch (Exception e)
84+
{
85+
throw Throwables.propagate(e);
86+
}
87+
}
88+
89+
90+
private void parseModMetadataList()
91+
{
92+
for (ModMetadata modMetadata : modList)
93+
{
94+
metadatas.put(modMetadata.modId, modMetadata);
95+
}
96+
}
97+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This file is part of FalsePatternLib.
3+
*
4+
* Copyright (C) 2022-2025 FalsePattern
5+
* All Rights Reserved
6+
*
7+
* The above copyright notice and this permission notice shall be included
8+
* in all copies or substantial portions of the Software.
9+
*
10+
* FalsePatternLib is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Lesser General Public License as published by
12+
* the Free Software Foundation, only version 3 of the License.
13+
*
14+
* FalsePatternLib is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
21+
*/
22+
23+
package com.falsepattern.deploader;
24+
25+
import com.google.gson.annotations.SerializedName;
26+
27+
/**
28+
* @author cpw
29+
*
30+
*/
31+
class ModMetadata
32+
{
33+
@SerializedName("modid")
34+
public String modId;
35+
36+
public String version = "";
37+
38+
public ModMetadata()
39+
{
40+
}
41+
}

0 commit comments

Comments
 (0)