feat: 1.21 port
This commit is contained in:
13
build.gradle
13
build.gradle
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'dev.architectury.loom' version '1.11-SNAPSHOT' apply false
|
id 'dev.architectury.loom' version '1.11-SNAPSHOT' apply false
|
||||||
id 'architectury-plugin' version '3.4-SNAPSHOT'
|
id 'architectury-plugin' version '3.4-SNAPSHOT'
|
||||||
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
|
id 'com.gradleup.shadow' version '8.3.6' apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
@@ -31,6 +31,10 @@ subprojects {
|
|||||||
// for more information about repositories.
|
// for more information about repositories.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loom {
|
||||||
|
silentMojangMappingsLicense()
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraft:minecraft:$rootProject.minecraft_version"
|
minecraft "net.minecraft:minecraft:$rootProject.minecraft_version"
|
||||||
mappings loom.officialMojangMappings()
|
mappings loom.officialMojangMappings()
|
||||||
@@ -42,12 +46,12 @@ subprojects {
|
|||||||
// If you remove this line, sources will not be generated.
|
// If you remove this line, sources will not be generated.
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
tasks.withType(JavaCompile).configureEach {
|
||||||
it.options.release = 17
|
it.options.release = 21
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure Maven publishing.
|
// Configure Maven publishing.
|
||||||
@@ -65,6 +69,7 @@ subprojects {
|
|||||||
// Notice: This block does NOT have the same function as the block in the top level.
|
// Notice: This block does NOT have the same function as the block in the top level.
|
||||||
// The repositories here will be used for publishing your artifact, not for
|
// The repositories here will be used for publishing your artifact, not for
|
||||||
// retrieving dependencies.
|
// retrieving dependencies.
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ dependencies {
|
|||||||
// which get remapped to the correct annotations on each platform.
|
// which get remapped to the correct annotations on each platform.
|
||||||
// Do NOT use other classes from Fabric Loader.
|
// Do NOT use other classes from Fabric Loader.
|
||||||
modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version"
|
modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version"
|
||||||
compileOnly("com.mojang:authlib:4.0.43")
|
compileOnly("com.mojang:authlib:6.0.54")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,13 @@ package net.magicterra.skinfix.inject;
|
|||||||
import com.mojang.authlib.Environment;
|
import com.mojang.authlib.Environment;
|
||||||
import com.mojang.authlib.EnvironmentParser;
|
import com.mojang.authlib.EnvironmentParser;
|
||||||
import com.mojang.authlib.GameProfileRepository;
|
import com.mojang.authlib.GameProfileRepository;
|
||||||
import com.mojang.authlib.HttpAuthenticationService;
|
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
|
||||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||||
import com.mojang.authlib.minecraft.UserApiService;
|
import com.mojang.authlib.minecraft.client.MinecraftClient;
|
||||||
import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilEnvironment;
|
import com.mojang.authlib.yggdrasil.YggdrasilEnvironment;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo;
|
import com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilUserApiService;
|
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
@@ -37,13 +34,14 @@ public class InjectYggdrasilAuthenticationService extends YggdrasilAuthenticatio
|
|||||||
super(proxy, environment);
|
super(proxy, environment);
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
|
|
||||||
final URL publicKeySetUrl = HttpAuthenticationService.constantURL("https://mc.gardel.top/minecraftservices/publickeys");
|
final MinecraftClient client = MinecraftClient.unauthenticated(proxy);
|
||||||
this.servicesKeySet = YggdrasilServicesKeyInfo.get(publicKeySetUrl, this);
|
final URL publicKeySetUrl = constantURL("https://mc.gardel.top/minecraftservices/publickeys");
|
||||||
|
this.servicesKeySet = YggdrasilServicesKeyInfo.get(publicKeySetUrl, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MinecraftSessionService createMinecraftSessionService() {
|
public MinecraftSessionService createMinecraftSessionService() {
|
||||||
return new InjectYggdrasilMinecraftSessionService(this, environment);
|
return new InjectYggdrasilMinecraftSessionService(servicesKeySet, getProxy(), environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -53,21 +51,6 @@ public class InjectYggdrasilAuthenticationService extends YggdrasilAuthenticatio
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GameProfileRepository createProfileRepository() {
|
public GameProfileRepository createProfileRepository() {
|
||||||
return new YggdrasilGameProfileRepository(this, Environment.create(
|
return new YggdrasilGameProfileRepository(getProxy(), new Environment(environment.sessionHost(), "https://mc.gardel.top/minecraftservices", environment.name()));
|
||||||
environment.getAuthHost(),
|
|
||||||
"https://mc.gardel.top/api",
|
|
||||||
environment.getSessionHost(),
|
|
||||||
environment.getServicesHost(),
|
|
||||||
environment.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserApiService createUserApiService(String accessToken) throws AuthenticationException {
|
|
||||||
return new YggdrasilUserApiService(accessToken, getProxy(), Environment.create(
|
|
||||||
environment.getAuthHost(),
|
|
||||||
environment.getAccountsHost(),
|
|
||||||
environment.getSessionHost(),
|
|
||||||
"https://mc.gardel.top/minecraftservices",
|
|
||||||
environment.getName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
package net.magicterra.skinfix.inject;
|
package net.magicterra.skinfix.inject;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.mojang.authlib.Environment;
|
import com.mojang.authlib.Environment;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.SignatureState;
|
||||||
import com.mojang.authlib.minecraft.InsecurePublicKeyException;
|
|
||||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||||
|
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
|
||||||
import com.mojang.authlib.properties.Property;
|
import com.mojang.authlib.properties.Property;
|
||||||
import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
||||||
import com.mojang.authlib.yggdrasil.ServicesKeyType;
|
import com.mojang.authlib.yggdrasil.ServicesKeyType;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
||||||
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
|
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -28,12 +26,15 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @since 2025-04-26 22:11
|
* @since 2025-04-26 22:11
|
||||||
*/
|
*/
|
||||||
public class InjectYggdrasilMinecraftSessionService extends YggdrasilMinecraftSessionService {
|
public class InjectYggdrasilMinecraftSessionService extends YggdrasilMinecraftSessionService {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(InjectYggdrasilMinecraftSessionService.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(YggdrasilMinecraftSessionService.class);
|
||||||
|
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
|
|
||||||
protected InjectYggdrasilMinecraftSessionService(YggdrasilAuthenticationService service, Environment env) {
|
private final ServicesKeySet servicesKeySet;
|
||||||
super(service, env);
|
|
||||||
|
protected InjectYggdrasilMinecraftSessionService(ServicesKeySet servicesKeySet, Proxy proxy, Environment env) {
|
||||||
|
super(servicesKeySet, proxy, env);
|
||||||
|
this.servicesKeySet = servicesKeySet;
|
||||||
try {
|
try {
|
||||||
Field field = YggdrasilMinecraftSessionService.class.getDeclaredField("gson");
|
Field field = YggdrasilMinecraftSessionService.class.getDeclaredField("gson");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
@@ -44,52 +45,47 @@ public class InjectYggdrasilMinecraftSessionService extends YggdrasilMinecraftSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) throws InsecurePublicKeyException {
|
public MinecraftProfileTextures unpackTextures(Property packedTextures) {
|
||||||
final Property textureProperty = Iterables.getFirst(profile.getProperties().get("textures"), null);
|
final String value = packedTextures.value();
|
||||||
|
final SignatureState signatureState = getPropertySignatureState(packedTextures);
|
||||||
if (textureProperty == null) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
final String value = requireSecure ? getSecurePropertyValue(textureProperty) : textureProperty.getValue();
|
|
||||||
|
|
||||||
final MinecraftTexturesPayload result;
|
final MinecraftTexturesPayload result;
|
||||||
try {
|
try {
|
||||||
final String json = new String(Base64.getDecoder().decode(value), StandardCharsets.UTF_8);
|
final String json = new String(Base64.getDecoder().decode(value), StandardCharsets.UTF_8);
|
||||||
result = gson.fromJson(json, MinecraftTexturesPayload.class);
|
result = gson.fromJson(json, MinecraftTexturesPayload.class);
|
||||||
} catch (final JsonParseException e) {
|
} catch (final JsonParseException | IllegalArgumentException e) {
|
||||||
LOGGER.error("Could not decode textures payload", e);
|
LOGGER.error("Could not decode textures payload", e);
|
||||||
return new HashMap<>();
|
return MinecraftProfileTextures.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null || result.getTextures() == null) {
|
if (result == null || result.textures() == null || result.textures().isEmpty()) {
|
||||||
return new HashMap<>();
|
return MinecraftProfileTextures.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Map.Entry<MinecraftProfileTexture.Type, MinecraftProfileTexture> entry : result.getTextures().entrySet()) {
|
final Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> textures = result.textures();
|
||||||
|
for (final Map.Entry<MinecraftProfileTexture.Type, MinecraftProfileTexture> entry : textures.entrySet()) {
|
||||||
final String url = entry.getValue().getUrl();
|
final String url = entry.getValue().getUrl();
|
||||||
if (!InjectTextureUrlChecker.isAllowedTextureDomain(url)) {
|
if (!InjectTextureUrlChecker.isAllowedTextureDomain(url)) {
|
||||||
LOGGER.error("Textures payload contains blocked domain: {}", url);
|
LOGGER.error("Textures payload contains blocked domain: {}", url);
|
||||||
return new HashMap<>();
|
return MinecraftProfileTextures.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.getTextures();
|
return new MinecraftProfileTextures(
|
||||||
|
textures.get(MinecraftProfileTexture.Type.SKIN),
|
||||||
|
textures.get(MinecraftProfileTexture.Type.CAPE),
|
||||||
|
textures.get(MinecraftProfileTexture.Type.ELYTRA),
|
||||||
|
signatureState
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private SignatureState getPropertySignatureState(final Property property) {
|
||||||
public String getSecurePropertyValue(final Property property) throws InsecurePublicKeyException {
|
|
||||||
if (!property.hasSignature()) {
|
if (!property.hasSignature()) {
|
||||||
LOGGER.error("Signature is missing from Property {}", property.getName());
|
return SignatureState.UNSIGNED;
|
||||||
throw new InsecurePublicKeyException.MissingException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServicesKeySet servicesKeySet = getAuthenticationService().getServicesKeySet();
|
|
||||||
if (servicesKeySet.keys(ServicesKeyType.PROFILE_PROPERTY).stream().noneMatch(key -> key.validateProperty(property))) {
|
if (servicesKeySet.keys(ServicesKeyType.PROFILE_PROPERTY).stream().noneMatch(key -> key.validateProperty(property))) {
|
||||||
LOGGER.error("Property {} has been tampered with (signature invalid)", property.getName());
|
return SignatureState.INVALID;
|
||||||
throw new InsecurePublicKeyException.InvalidException("Property has been tampered with (signature invalid)");
|
|
||||||
}
|
}
|
||||||
|
return SignatureState.SIGNED;
|
||||||
return property.getValue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"package": "net.magicterra.skinfix.mixin",
|
"package": "net.magicterra.skinfix.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"client": [
|
"client": [
|
||||||
"MinecraftMixin"
|
"MinecraftMixin",
|
||||||
],
|
|
||||||
"mixins": [
|
|
||||||
"ProfilePublicKeyDataMixin"
|
"ProfilePublicKeyDataMixin"
|
||||||
],
|
],
|
||||||
|
"mixins": [],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.github.johnrengelman.shadow'
|
id 'com.gradleup.shadow'
|
||||||
}
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
@@ -46,5 +46,5 @@ shadowJar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
input.set shadowJar.archiveFile
|
inputFile.set shadowJar.archiveFile
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@
|
|||||||
"skinfix.mixins.json"
|
"skinfix.mixins.json"
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.17.2",
|
"fabricloader": ">=0.17",
|
||||||
"minecraft": "~1.20.1",
|
"minecraft": ">=1.21",
|
||||||
"java": ">=17"
|
"java": ">=21"
|
||||||
},
|
},
|
||||||
"suggests": {
|
"suggests": {
|
||||||
"another-mod": "*"
|
"another-mod": "*"
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
loom.platform=forge
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package net.magicterra.skinfix.forge;
|
|
||||||
|
|
||||||
import net.magicterra.skinfix.SkinFixMod;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
|
|
||||||
@Mod(SkinFixMod.MOD_ID)
|
|
||||||
public final class SkinFixModForge {
|
|
||||||
public SkinFixModForge() {
|
|
||||||
// Run our common setup.
|
|
||||||
SkinFixMod.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"pack": {
|
|
||||||
"description": "skinfix resources",
|
|
||||||
"pack_format": 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,9 +5,9 @@ org.gradle.parallel=true
|
|||||||
mod_version=1.0-SNAPSHOT
|
mod_version=1.0-SNAPSHOT
|
||||||
maven_group=net.magicterra
|
maven_group=net.magicterra
|
||||||
archives_name=skinfix
|
archives_name=skinfix
|
||||||
enabled_platforms=fabric,forge
|
enabled_platforms=fabric,neoforge
|
||||||
# Minecraft properties
|
# Minecraft properties
|
||||||
minecraft_version=1.20.1
|
minecraft_version=1.21
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_loader_version=0.17.2
|
fabric_loader_version=0.17.2
|
||||||
forge_version=1.20.1-47.4.6
|
neoforge_version=21.0.167
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.github.johnrengelman.shadow'
|
id 'com.gradleup.shadow'
|
||||||
}
|
|
||||||
|
|
||||||
loom {
|
|
||||||
forge {
|
|
||||||
mixinConfig "skinfix.mixins.json"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
architectury {
|
architectury {
|
||||||
platformSetupLoomIde()
|
platformSetupLoomIde()
|
||||||
forge()
|
neoForge()
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
@@ -20,7 +14,7 @@ configurations {
|
|||||||
}
|
}
|
||||||
compileClasspath.extendsFrom common
|
compileClasspath.extendsFrom common
|
||||||
runtimeClasspath.extendsFrom common
|
runtimeClasspath.extendsFrom common
|
||||||
developmentForge.extendsFrom common
|
developmentNeoForge.extendsFrom common
|
||||||
|
|
||||||
// Files in this configuration will be bundled into your mod using the Shadow plugin.
|
// Files in this configuration will be bundled into your mod using the Shadow plugin.
|
||||||
// Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files.
|
// Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files.
|
||||||
@@ -30,18 +24,25 @@ configurations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = 'NeoForged'
|
||||||
|
url = 'https://maven.neoforged.net/releases'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
forge "net.minecraftforge:forge:$rootProject.forge_version"
|
neoForge "net.neoforged:neoforge:$rootProject.neoforge_version"
|
||||||
|
|
||||||
|
|
||||||
common(project(path: ':common', configuration: 'namedElements')) { transitive false }
|
common(project(path: ':common', configuration: 'namedElements')) { transitive false }
|
||||||
shadowBundle project(path: ':common', configuration: 'transformProductionForge')
|
shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge')
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
inputs.property 'version', project.version
|
inputs.property 'version', project.version
|
||||||
|
|
||||||
filesMatching('META-INF/mods.toml') {
|
filesMatching('META-INF/neoforge.mods.toml') {
|
||||||
expand version: project.version
|
expand version: project.version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,5 +53,5 @@ shadowJar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remapJar {
|
remapJar {
|
||||||
input.set shadowJar.archiveFile
|
inputFile.set shadowJar.archiveFile
|
||||||
}
|
}
|
||||||
1
neoforge/gradle.properties
Normal file
1
neoforge/gradle.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
loom.platform=neoforge
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package net.magicterra.skinfix.neoforge;
|
||||||
|
|
||||||
|
import net.magicterra.skinfix.SkinFixMod;
|
||||||
|
import net.neoforged.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod(SkinFixMod.MOD_ID)
|
||||||
|
public final class SkinFixModNeoForge {
|
||||||
|
public SkinFixModNeoForge() {
|
||||||
|
// Run our common setup.
|
||||||
|
SkinFixMod.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
modLoader = "javafml"
|
modLoader = "javafml"
|
||||||
loaderVersion = "[47,)"
|
loaderVersion = "[1,)"
|
||||||
#issueTrackerURL = ""
|
#issueTrackerURL = ""
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
@@ -14,16 +14,18 @@ Fix Minecraft does not load skin png not prefix with minecraft.net
|
|||||||
logoFile="assets/skinfix/icon.png"
|
logoFile="assets/skinfix/icon.png"
|
||||||
|
|
||||||
[[dependencies.skinfix]]
|
[[dependencies.skinfix]]
|
||||||
modId = "forge"
|
modId = "neoforge"
|
||||||
mandatory = true
|
type="required"
|
||||||
versionRange = "[47,)"
|
versionRange = "[21.0.0-beta,)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
[[dependencies.skinfix]]
|
[[dependencies.skinfix]]
|
||||||
modId = "minecraft"
|
modId = "minecraft"
|
||||||
mandatory = true
|
type="required"
|
||||||
versionRange = "[1.20.1,)"
|
versionRange = "[1.21,1.21.5)"
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
side = "BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
|
[[mixins]]
|
||||||
|
config="skinfix.mixins.json"
|
||||||
@@ -11,4 +11,4 @@ rootProject.name = 'skinfix'
|
|||||||
|
|
||||||
include 'common'
|
include 'common'
|
||||||
include 'fabric'
|
include 'fabric'
|
||||||
include 'forge'
|
include 'neoforge'
|
||||||
|
|||||||
Reference in New Issue
Block a user