|
4 | 4 | import com.fox2code.foxloader.commands.WorldSet; |
5 | 5 | import com.fox2code.foxloader.launcher.*; |
6 | 6 | import com.fox2code.foxloader.launcher.utils.SourceUtil; |
| 7 | +import com.fox2code.foxloader.loader.lua.LuaVMHelper; |
7 | 8 | import com.fox2code.foxloader.loader.packet.ServerHello; |
8 | 9 | import com.fox2code.foxloader.loader.rebuild.ClassDataProvider; |
9 | 10 | import com.fox2code.foxloader.network.NetworkPlayer; |
|
14 | 15 | import org.jetbrains.annotations.NotNull; |
15 | 16 | import org.semver4j.Semver; |
16 | 17 |
|
17 | | -import java.io.File; |
18 | | -import java.io.IOException; |
| 18 | +import java.io.*; |
19 | 19 | import java.net.MalformedURLException; |
| 20 | +import java.nio.charset.StandardCharsets; |
| 21 | +import java.nio.file.Files; |
20 | 22 | import java.util.*; |
21 | 23 | import java.util.jar.Attributes; |
22 | 24 | import java.util.jar.JarFile; |
23 | 25 | import java.util.jar.Manifest; |
| 26 | +import java.util.logging.Level; |
24 | 27 | import java.util.logging.Logger; |
25 | 28 |
|
26 | 29 | public class ModLoader extends Mod { |
@@ -102,16 +105,24 @@ static void initializeModdedInstance(boolean client) { |
102 | 105 | } |
103 | 106 | for (File mod : Objects.requireNonNull(mods.listFiles( |
104 | 107 | (dir, name) -> name.endsWith(".jar")))) { |
105 | | - loadModContainerFrom(mod, false); |
| 108 | + loadModContainerFromJar(mod, false); |
| 109 | + } |
| 110 | + for (File mod : Objects.requireNonNull(mods.listFiles( |
| 111 | + (dir, name) -> name.endsWith(".lua")))) { |
| 112 | + loadModContainerFromLua(mod); |
106 | 113 | } |
107 | 114 | for (File mod : Objects.requireNonNull(modsVersioned.listFiles( |
108 | 115 | (dir, name) -> name.endsWith(".jar")))) { |
109 | | - loadModContainerFrom(mod, false); |
| 116 | + loadModContainerFromJar(mod, false); |
| 117 | + } |
| 118 | + for (File mod : Objects.requireNonNull(modsVersioned.listFiles( |
| 119 | + (dir, name) -> name.endsWith(".lua")))) { |
| 120 | + loadModContainerFromLua(mod); |
110 | 121 | } |
111 | 122 | } |
112 | 123 | // Inject mod is used by the gradle plugin to load dev mod |
113 | 124 | if (DEV_MODE && INJECT_MOD != null && !INJECT_MOD.isEmpty()) { |
114 | | - loadModContainerFrom(new File(INJECT_MOD).getAbsoluteFile(), true); |
| 125 | + loadModContainerFromJar(new File(INJECT_MOD).getAbsoluteFile(), true); |
115 | 126 | } |
116 | 127 | if (!modContainers.containsKey("spark") && !disableSpark && |
117 | 128 | DependencyHelper.loadDependencySafe(DependencyHelper.sparkDependency)) { |
@@ -168,7 +179,7 @@ public void onPostInit() { |
168 | 179 | CommandCompat.registerCommand(new WorldReplace()); |
169 | 180 | } |
170 | 181 |
|
171 | | - private static void loadModContainerFrom(File file, boolean injected) { |
| 182 | + private static void loadModContainerFromJar(File file, boolean injected) { |
172 | 183 | Manifest manifest; |
173 | 184 | try (JarFile jarFile = new JarFile(file)) { |
174 | 185 | manifest = jarFile.getManifest(); |
@@ -244,6 +255,83 @@ private static void loadModContainerFrom(File file, boolean injected) { |
244 | 255 | } |
245 | 256 | } |
246 | 257 |
|
| 258 | + private static final String MOD_ID_LUA_PREFIX = "-- modId: "; |
| 259 | + private static final String MOD_NAME_LUA_PREFIX = "-- modName: "; |
| 260 | + private static final String MOD_VERSION_LUA_PREFIX = "-- version: "; |
| 261 | + private static final String MOD_DESC_LUA_PREFIX = "-- description: "; |
| 262 | + private static final String MOD_UNOFFICIAL_LUA_PREFIX = "-- unofficial: "; |
| 263 | + |
| 264 | + private static void loadModContainerFromLua(File file) { |
| 265 | + String id = null; |
| 266 | + String name = null; |
| 267 | + String version = null; |
| 268 | + String desc = null; |
| 269 | + boolean unofficial = false; |
| 270 | + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( |
| 271 | + Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { |
| 272 | + String line; |
| 273 | + while ((line = bufferedReader.readLine()) != null |
| 274 | + && line.startsWith("-- ")) { |
| 275 | + if (line.startsWith(MOD_ID_LUA_PREFIX)) { |
| 276 | + id = line.substring(MOD_ID_LUA_PREFIX.length()); |
| 277 | + } else if (line.startsWith(MOD_NAME_LUA_PREFIX)) { |
| 278 | + name = line.substring(MOD_NAME_LUA_PREFIX.length()); |
| 279 | + } else if (line.startsWith(MOD_VERSION_LUA_PREFIX)) { |
| 280 | + version = line.substring(MOD_VERSION_LUA_PREFIX.length()); |
| 281 | + } else if (line.startsWith(MOD_DESC_LUA_PREFIX)) { |
| 282 | + desc = line.substring(MOD_DESC_LUA_PREFIX.length()); |
| 283 | + } else if (line.startsWith(MOD_UNOFFICIAL_LUA_PREFIX)) { |
| 284 | + unofficial = Boolean.parseBoolean(line.substring( |
| 285 | + MOD_UNOFFICIAL_LUA_PREFIX.length())); |
| 286 | + } |
| 287 | + } |
| 288 | + } catch (IOException ioe) { |
| 289 | + ioe.printStackTrace(); |
| 290 | + return; |
| 291 | + } |
| 292 | + |
| 293 | + if (id == null || id.isEmpty()) { |
| 294 | + foxLoader.logger.warning("Unable to load " + file.getName() + |
| 295 | + " because it doesn't have a mod-id (Is it a core mod?)"); |
| 296 | + return; |
| 297 | + } |
| 298 | + if (FOX_LOADER_MOD_ID.equals(id) || "minecraft".equals(id) || "reindev".equals(id) || "null".equals(id)) { |
| 299 | + foxLoader.logger.warning("Unable to load " + file.getName() + |
| 300 | + " because it used the reserved mod id: " + id); |
| 301 | + return; |
| 302 | + } |
| 303 | + if (name == null || name.isEmpty()) { |
| 304 | + name = id.substring(0, 1).toLowerCase(Locale.ROOT) + id.substring(1); |
| 305 | + } |
| 306 | + if (version == null || (version = version.trim()).isEmpty()) { |
| 307 | + version = "1.0"; |
| 308 | + } |
| 309 | + Semver semver = "1.0".equals(version) || "1.0.0".equals(version) ? |
| 310 | + INITIAL_SEMVER : Semver.parse(version); |
| 311 | + if (semver == null) { |
| 312 | + int verExt = version.indexOf('-'); |
| 313 | + if (verExt != -1) { |
| 314 | + version = version.substring(0, verExt); |
| 315 | + } |
| 316 | + semver = Semver.coerce(version); |
| 317 | + } |
| 318 | + if (semver == null) { |
| 319 | + semver = INITIAL_SEMVER; |
| 320 | + } |
| 321 | + |
| 322 | + if (desc == null || desc.isEmpty()) { |
| 323 | + desc = "..."; |
| 324 | + } |
| 325 | + ModContainer modContainer = modContainers.get(id); |
| 326 | + if (modContainer != null) { |
| 327 | + foxLoader.logger.warning("Unable to load " + file.getName() + " because " + |
| 328 | + modContainer.file.getName() + " already uses the same mod id: " + id); |
| 329 | + return; |
| 330 | + } |
| 331 | + modContainer = new ModContainer(file, id, name, version, semver, desc, null, unofficial, false); |
| 332 | + modContainers.put(id, modContainer); |
| 333 | + } |
| 334 | + |
247 | 335 | public static boolean checkSemVerMismatch(String value, String accept) { |
248 | 336 | return accept == null || !checkSemVerMatch(value, accept); |
249 | 337 | } |
|
0 commit comments