output) {
58 | var additionalContent = getAdditionalMinecraftJarContent(versionInfo);
59 | output.accept(new PillowServerProvider(additionalContent,
60 | List.of(QuiltLoader.getModContainer("minecraft").orElseThrow().rootPath())));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/net/pillowmc/pillow/launch/copied/MinecraftModInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) NeoForged and contributors
3 | * SPDX-License-Identifier: LGPL-2.1-only
4 | */
5 |
6 | // PillowMC: Changed package.
7 | package net.pillowmc.pillow.launch.copied;
8 |
9 | import com.electronwill.nightconfig.core.Config;
10 | import java.util.List;
11 | import net.neoforged.fml.loading.FMLLoader;
12 | import net.neoforged.fml.loading.moddiscovery.ModFile;
13 | import net.neoforged.fml.loading.moddiscovery.ModFileInfo;
14 | import net.neoforged.fml.loading.moddiscovery.NightConfigWrapper;
15 | import net.neoforged.neoforgespi.language.IModFileInfo;
16 | import net.neoforged.neoforgespi.locating.IModFile;
17 |
18 | final class MinecraftModInfo {
19 | private MinecraftModInfo() {
20 | }
21 |
22 | public static IModFileInfo buildMinecraftModInfo(final IModFile iModFile) {
23 | final ModFile modFile = (ModFile) iModFile;
24 |
25 | // We haven't changed this in years, and I can't be asked right now to special
26 | // case this one file in the path.
27 | final var conf = Config.inMemory();
28 | conf.set("modLoader", "minecraft");
29 | conf.set("loaderVersion", "1");
30 | conf.set("license", "Mojang Studios, All Rights Reserved");
31 | final var mods = Config.inMemory();
32 | mods.set("modId", "minecraft");
33 | mods.set("version", FMLLoader.versionInfo().mcVersion());
34 | mods.set("displayName", "Minecraft");
35 | mods.set("description", "Minecraft");
36 | conf.set("mods", List.of(mods));
37 |
38 | final NightConfigWrapper configWrapper = new NightConfigWrapper(conf);
39 | return new ModFileInfo(modFile, configWrapper, configWrapper::setFile, List.of());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/net/pillowmc/pillow/launch/copied/PillowClientProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) NeoForged and contributors
3 | * SPDX-License-Identifier: LGPL-2.1-only
4 | */
5 |
6 | // PillowMC: Changed package, renamed.
7 | package net.pillowmc.pillow.launch.copied;
8 |
9 | import cpw.mods.jarhandling.JarContents;
10 | import cpw.mods.jarhandling.SecureJar;
11 | import java.nio.file.Files;
12 | import java.nio.file.Path;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import net.neoforged.fml.ModLoadingException;
16 | import net.neoforged.fml.ModLoadingIssue;
17 | import net.neoforged.fml.loading.FMLLoader;
18 | import net.neoforged.fml.loading.LibraryFinder;
19 | import net.neoforged.fml.loading.MavenCoordinate;
20 | import net.neoforged.fml.loading.moddiscovery.ModJarMetadata;
21 | import net.neoforged.neoforgespi.ILaunchContext;
22 | import net.neoforged.neoforgespi.locating.IDiscoveryPipeline;
23 | import net.neoforged.neoforgespi.locating.IModFile;
24 | import net.neoforged.neoforgespi.locating.IModFileCandidateLocator;
25 |
26 | /**
27 | * Locates the Minecraft client files in a production environment.
28 | *
29 | * It assumes that the installer produced two artifacts, one containing the
30 | * Minecraft classes ("srg") which have been renamed to Mojangs official names
31 | * using their mappings, and another containing only the Minecraft resource
32 | * files ("extra"), and searches for these artifacts in the library directory.
33 | */
34 | public class PillowClientProvider implements IModFileCandidateLocator {
35 | private final List additionalContent;
36 | // PillowMC: Added additionalFiles
37 | private final List additionalFiles;
38 |
39 | // PillowMC: Added additionalFiles
40 | public PillowClientProvider(List additionalContent, List additionalFiles) {
41 | this.additionalContent = additionalContent;
42 | this.additionalFiles = additionalFiles;
43 | }
44 |
45 | @Override
46 | public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) {
47 | var vers = FMLLoader.versionInfo();
48 |
49 | var content = new ArrayList();
50 | addRequiredLibrary(new MavenCoordinate("net.minecraft", "client", "", "srg", vers.mcAndNeoFormVersion()),
51 | content);
52 | addRequiredLibrary(new MavenCoordinate("net.minecraft", "client", "", "extra", vers.mcAndNeoFormVersion()),
53 | content);
54 | for (var artifact : additionalContent) {
55 | addRequiredLibrary(artifact, content);
56 | }
57 |
58 | // PillowMC: Added additionalFiles (3 lines)
59 | content.addAll(additionalFiles);
60 |
61 | try {
62 | var mcJarContents = JarContents.of(content);
63 |
64 | var mcJarMetadata = new ModJarMetadata(mcJarContents);
65 | var mcSecureJar = SecureJar.from(mcJarContents, mcJarMetadata);
66 | var mcjar = IModFile.create(mcSecureJar, MinecraftModInfo::buildMinecraftModInfo);
67 | mcJarMetadata.setModFile(mcjar);
68 |
69 | pipeline.addModFile(mcjar);
70 | } catch (Exception e) {
71 | pipeline.addIssue(ModLoadingIssue.error("fml.modloading.corrupted_installation").withCause(e));
72 | }
73 | }
74 |
75 | private static void addRequiredLibrary(MavenCoordinate coordinate, List content) {
76 | var path = LibraryFinder.findPathForMaven(coordinate);
77 | if (!Files.exists(path)) {
78 | throw new ModLoadingException(
79 | ModLoadingIssue.error("fml.modloading.corrupted_installation").withAffectedPath(path));
80 | } else {
81 | content.add(path);
82 | }
83 | }
84 |
85 | @Override
86 | public String toString() {
87 | var result = new StringBuilder("production client provider");
88 | for (var mavenCoordinate : additionalContent) {
89 | result.append(" +").append(mavenCoordinate);
90 | }
91 | return result.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/net/pillowmc/pillow/launch/copied/PillowServerProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) NeoForged and contributors
3 | * SPDX-License-Identifier: LGPL-2.1-only
4 | */
5 |
6 | // PillowMC: Changed package, renamed.
7 | package net.pillowmc.pillow.launch.copied;
8 |
9 | import cpw.mods.jarhandling.JarContents;
10 | import cpw.mods.jarhandling.JarContentsBuilder;
11 | import cpw.mods.jarhandling.SecureJar;
12 | import java.nio.file.Files;
13 | import java.nio.file.Path;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import net.neoforged.fml.ModLoadingIssue;
17 | import net.neoforged.fml.loading.FMLLoader;
18 | import net.neoforged.fml.loading.LibraryFinder;
19 | import net.neoforged.fml.loading.MavenCoordinate;
20 | import net.neoforged.fml.loading.moddiscovery.ModJarMetadata;
21 | import net.neoforged.neoforgespi.ILaunchContext;
22 | import net.neoforged.neoforgespi.locating.IDiscoveryPipeline;
23 | import net.neoforged.neoforgespi.locating.IModFile;
24 | import net.neoforged.neoforgespi.locating.IModFileCandidateLocator;
25 |
26 | /**
27 | * Locates the Minecraft server files in a production environment.
28 | */
29 | public class PillowServerProvider implements IModFileCandidateLocator {
30 | private final List additionalContent;
31 | // PillowMC: Added additionalFiles.
32 | private final List additionalFiles;
33 |
34 | public PillowServerProvider(List additionalContent, List additionalFiles) {
35 | this.additionalContent = additionalContent;
36 | // PillowMC: Added additionalFiles.
37 | this.additionalFiles = additionalFiles;
38 | }
39 |
40 | @Override
41 | public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) {
42 | var vers = FMLLoader.versionInfo();
43 |
44 | try {
45 | var mc = LibraryFinder.findPathForMaven("net.minecraft", "server", "", "srg", vers.mcAndNeoFormVersion());
46 | if (!Files.exists(mc)) {
47 | pipeline.addIssue(ModLoadingIssue.error("fml.modloading.corrupted_installation").withAffectedPath(mc));
48 | return;
49 | }
50 | var mcextra = LibraryFinder.findPathForMaven("net.minecraft", "server", "", "extra",
51 | vers.mcAndNeoFormVersion());
52 | if (!Files.exists(mcextra)) {
53 | pipeline.addIssue(ModLoadingIssue.error("fml.modloading.corrupted_installation").withAffectedPath(mc));
54 | return;
55 | }
56 |
57 | var mcextra_filtered = SecureJar.from(new JarContentsBuilder()
58 | // We only want it for its resources. So filter everything else out.
59 | .pathFilter((path, base) -> path.equals("META-INF/versions/") || // This is required because it
60 | // bypasses our filter
61 | // for the manifest, and it's a multi-release jar.
62 | (!path.endsWith(".class") && !path.startsWith("META-INF/")))
63 | .paths(mcextra).build());
64 |
65 | var content = new ArrayList();
66 | content.add(mc);
67 | content.add(mcextra_filtered.getRootPath());
68 | for (var artifact : additionalContent) {
69 | var extraPath = LibraryFinder.findPathForMaven(artifact);
70 | if (!Files.exists(extraPath)) {
71 | pipeline.addIssue(
72 | ModLoadingIssue.error("fml.modloading.corrupted_installation").withAffectedPath(extraPath));
73 | return;
74 | }
75 | content.add(extraPath);
76 | }
77 | // PillowMC: Added additionalFiles. (3 lines)
78 | content.addAll(additionalFiles);
79 |
80 | var mcJarContents = JarContents.of(content);
81 |
82 | var mcJarMetadata = new ModJarMetadata(mcJarContents);
83 | var mcSecureJar = SecureJar.from(mcJarContents, mcJarMetadata);
84 | var mcjar = IModFile.create(mcSecureJar, MinecraftModInfo::buildMinecraftModInfo);
85 | mcJarMetadata.setModFile(mcjar);
86 |
87 | pipeline.addModFile(mcjar);
88 | } catch (Exception e) {
89 | pipeline.addIssue(ModLoadingIssue.error("fml.modloading.corrupted_installation").withCause(e));
90 | }
91 | }
92 |
93 | @Override
94 | public String toString() {
95 | var result = new StringBuilder("production server provider");
96 | for (var mavenCoordinate : additionalContent) {
97 | result.append(" +").append(mavenCoordinate);
98 | }
99 | return result.toString();
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ILaunchHandlerService:
--------------------------------------------------------------------------------
1 | net.pillowmc.pillow.launch.PillowServerLaunchHandler
2 | net.pillowmc.pillow.launch.PillowClientLaunchHandler
3 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService:
--------------------------------------------------------------------------------
1 | net.pillowmc.pillow.asm.PillowTransformationService
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/net.neoforged.neoforgespi.locating.IModFileCandidateLocator:
--------------------------------------------------------------------------------
1 | net.pillowmc.pillow.PillowModLocator
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.quiltmc.loader.impl.game.GameProvider:
--------------------------------------------------------------------------------
1 | net.pillowmc.pillow.PillowGameProvider
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService:
--------------------------------------------------------------------------------
1 | net.pillowmc.pillow.asm.MixinServicePillow
2 |
--------------------------------------------------------------------------------
/src/main/resources/assets/pillow/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PillowMC/pillow/1c1cf89acbb068beb2749ceeeea2e352754278f9/src/main/resources/assets/pillow/icon.png
--------------------------------------------------------------------------------
/src/main/resources/assets/pillow/icon_pillowmc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PillowMC/pillow/1c1cf89acbb068beb2749ceeeea2e352754278f9/src/main/resources/assets/pillow/icon_pillowmc.png
--------------------------------------------------------------------------------
/src/main/resources/assets/pillow/icon_shearapi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PillowMC/pillow/1c1cf89acbb068beb2749ceeeea2e352754278f9/src/main/resources/assets/pillow/icon_shearapi.png
--------------------------------------------------------------------------------
/src/main/resources/assets/pillow/lang/zh_cn.json:
--------------------------------------------------------------------------------
1 | {
2 | "modmenu.nameTranslation.pillow-loader": "枕头模组加载器",
3 | "modmenu.descriptionTranslation.pillow-loader": "让 Quilt 加载器和 FML 在 ModLauncher 和反混淆后的 Minecraft(Mojang 反映射表)上运行。"
4 | }
--------------------------------------------------------------------------------
/src/main/resources/quilt.mod.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema_version": 1,
3 | "quilt_loader": {
4 | "group": "net.pillowmc",
5 | "id": "pillow-loader",
6 | "version": "${version}",
7 | "metadata": {
8 | "name": "Pillow Mod Loader",
9 | "description": "Allows Quilt Loader and FML work on ModLauncher with deobfuscated Minecraft (Mojang Mappings), which NeoForge uses.",
10 | "contributors": {
11 | "PillowMC": "Owner"
12 | },
13 | "contact": {
14 | "homepage": "https://pillowmc.github.io",
15 | "issues": "https://github.com/PillowMC/Pillow/issues",
16 | "sources": "https://github.com/PillowMC/Pillow"
17 | },
18 | "license": "MIT",
19 | "icon": "assets/pillow/icon.png"
20 | },
21 | "intermediate_mappings": "net.fabricmc:intermediary"
22 | },
23 | "modmenu": {
24 | "badges": ["library"]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------