releases: 0.1.0-alpha.3+mc1.20.6

* Switch to using Mojang mappings.
* Rewrite gradle scripts with kts.
* Fix an issues at create config file (config dir not exists).
This commit is contained in:
Puqns67 2024-05-24 13:21:05 +08:00
parent bafbc7384f
commit 821dee1f07
Signed by: Puqns67
GPG Key ID: 9669DF042554F536
20 changed files with 189 additions and 216 deletions

View File

@ -9,5 +9,4 @@ insert_final_newline = true
max_line_length = 120
[*.json]
indent_style = space
insert_final_newline = false

View File

@ -1,75 +0,0 @@
plugins {
id 'fabric-loom' version '1.6-SNAPSHOT'
id 'maven-publish'
}
version = project.mod_version
group = project.maven_group
base {
archivesName = project.archives_base_name
}
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
}
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
//modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
processResources {
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
}
}
tasks.withType(JavaCompile).configureEach {
it.options.release = 21
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
jar {
from("LICENSE") {
rename { "${it}_${project.base.archivesName.get()}"}
}
}
// configure the maven publication
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// 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
// retrieving dependencies.
}
}

43
build.gradle.kts Normal file
View File

@ -0,0 +1,43 @@
plugins {
id("java")
id("fabric-loom") version "1.6-SNAPSHOT"
id("idea")
}
java {
withSourcesJar()
sourceCompatibility = JavaVersion.valueOf("VERSION_${properties["java_version"]}")
targetCompatibility = JavaVersion.valueOf("VERSION_${properties["java_version"]}")
}
dependencies {
minecraft("com.mojang:minecraft:${properties["minecraft_version"]}")
mappings(loom.officialMojangMappings())
modImplementation("net.fabricmc:fabric-loader:${properties["fabric_version"]}")
}
base {
archivesName = "${properties["mod_id"]}-fabric"
version = "v${properties["mod_version"]}+mc${properties["minecraft_version"]}"
}
tasks {
processResources {
filesMatching("fabric.mod.json") {
expand(project.properties)
}
}
jar {
from("LICENSE") {
rename { "${it}_${project.properties["mod_id"]}" }
}
}
}
idea {
module {
isDownloadSources = true
isDownloadJavadoc = true
}
}

View File

@ -2,16 +2,14 @@
org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true
# Fabric Properties
# check these on https://fabricmc.net/develop
# Environment Properties
java_version=21
minecraft_version=1.20.6
yarn_mappings=1.20.6+build.1
loader_version=0.15.11
fabric_version=0.15.11
# Mod Properties
mod_version=0.1.0-alpha2
maven_group=icu.puqns67.skintypefix
archives_base_name=skintypefix-fabric
# Dependencies
fabric_version=0.98.0+1.20.6
mod_id=skintypefix
mod_name=Skin type fix
mod_version=0.1.0-alpha.3
mod_license=GPL-3.0-or-later
mod_description=Fix wrong skin type for some players.

View File

@ -1,10 +0,0 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
mavenCentral()
gradlePluginPortal()
}
}

17
settings.gradle.kts Normal file
View File

@ -0,0 +1,17 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
maven {
name = "Fabric"
url = uri("https://maven.fabricmc.net/")
}
mavenCentral()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
rootProject.name = "SkinTypeFix"

View File

@ -8,14 +8,13 @@ import net.fabricmc.api.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Environment(EnvType.CLIENT)
public class SkinTypeFix implements ClientModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("SkinTypeFix");
public static final Config CONFIG = ConfigLoader.load();
public static final Config CONFIG = ConfigLoader.get();
@Override
public void onInitializeClient() {
LOGGER.info("Loaded!");
LOGGER.info("[SkinTypeFix] Loaded!");
}
}

View File

@ -1,10 +0,0 @@
package icu.puqns67.skintypefix.accessor;
import net.minecraft.client.texture.NativeImage;
public interface PlayerSkinTextureAccessor {
void skinTypeFix$joinLoader();
NativeImage skinTypeFix$getImage();
}

View File

@ -1,6 +1,5 @@
package icu.puqns67.skintypefix.config;
public class Config {
public boolean skipFixForSlimPlayers = true;
}

View File

@ -5,25 +5,19 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import icu.puqns67.skintypefix.SkinTypeFix;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class ConfigLoader {
private static final Path PATH = Path.of("config", "skintypefix.json");
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.setPrettyPrinting()
.create();
public static Config load() {
if (!Files.exists(PATH)) {
SkinTypeFix.LOGGER.info("[SkinTypeFix] Config file does not exist, create a new one!");
var result = new Config();
save(result);
return result;
}
try (var reader = Files.newBufferedReader(PATH)) {
return GSON.fromJson(reader, Config.class);
} catch (Exception e) {
@ -33,10 +27,27 @@ public class ConfigLoader {
}
public static void save(Config config) {
if (!Files.exists(PATH.getParent())) {
try {
Files.createDirectories(PATH.getParent());
} catch (IOException e) {
SkinTypeFix.LOGGER.warn("[SkinTypeFix] Can't create config dir, changes may not be saved!", e);
}
}
try (var writer = Files.newBufferedWriter(PATH, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
GSON.toJson(config, writer);
} catch (Exception e) {
SkinTypeFix.LOGGER.warn("[SkinTypeFix] Can't save config file, changes may not be saved!", e);
}
}
public static Config get() {
if (!Files.exists(PATH)) {
SkinTypeFix.LOGGER.info("[SkinTypeFix] Config file does not exist, create a new one!");
var result = new Config();
save(result);
return result;
}
return load();
}
}

View File

@ -0,0 +1,9 @@
package icu.puqns67.skintypefix.mixin.accessor;
import com.mojang.blaze3d.platform.NativeImage;
public interface HttpTextureAccessor {
void skinTypeFix$joinLoader();
NativeImage skinTypeFix$getImage();
}

View File

@ -1,46 +1,45 @@
package icu.puqns67.skintypefix.mixin;
package icu.puqns67.skintypefix.mixin.patch;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.TextureUtil;
import icu.puqns67.skintypefix.SkinTypeFix;
import icu.puqns67.skintypefix.accessor.PlayerSkinTextureAccessor;
import icu.puqns67.skintypefix.mixin.accessor.HttpTextureAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.PlayerSkinTexture;
import net.minecraft.client.texture.ResourceTexture;
import net.minecraft.util.Identifier;
import net.minecraft.client.renderer.texture.HttpTexture;
import net.minecraft.client.renderer.texture.SimpleTexture;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.*;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
@Mixin(PlayerSkinTexture.class)
public abstract class PlayerSkinTextureMixin extends ResourceTexture implements PlayerSkinTextureAccessor {
@Mixin(HttpTexture.class)
public abstract class HttpTextureMixin extends SimpleTexture implements HttpTextureAccessor {
@Unique
@Nullable
protected NativeImage image = null;
@Shadow
@Nullable
private CompletableFuture<?> loader;
private CompletableFuture<?> future;
@Shadow
@Final
private boolean convertLegacy;
private boolean processLegacySkin;
public PlayerSkinTextureMixin(Identifier location) {
public HttpTextureMixin(ResourceLocation location) {
super(location);
}
@Shadow
@Nullable
protected abstract NativeImage remapTexture(NativeImage image);
protected abstract NativeImage processLegacySkin(NativeImage image);
@Unique
public void skinTypeFix$joinLoader() {
if (this.loader != null) {
this.loader.join();
if (this.future != null) {
this.future.join();
}
}
@ -51,20 +50,20 @@ public abstract class PlayerSkinTextureMixin extends ResourceTexture implements
/**
* @author Puqns67
* @reason test
* @reason Overwrite the load() function to create another NativeImage at loading, using for check skin.
*/
@Nullable
@Overwrite
private NativeImage loadTexture(InputStream stream) {
private NativeImage load(InputStream stream) {
try {
var buffer = TextureUtil.readResource(stream);
buffer.rewind();
this.image = NativeImage.read(buffer);
buffer.rewind();
var result = NativeImage.read(buffer);
if (this.convertLegacy) {
this.image = this.remapTexture(this.image);
result = this.remapTexture(result);
if (this.processLegacySkin) {
this.image = this.processLegacySkin(this.image);
result = this.processLegacySkin(result);
}
return result;
} catch (Exception exception) {

View File

@ -1,19 +1,19 @@
package icu.puqns67.skintypefix.mixin;
package icu.puqns67.skintypefix.mixin.patch;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.authlib.SignatureState;
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTextures;
import icu.puqns67.skintypefix.SkinTypeFix;
import icu.puqns67.skintypefix.accessor.PlayerSkinTextureAccessor;
import icu.puqns67.skintypefix.mixin.accessor.HttpTextureAccessor;
import icu.puqns67.skintypefix.util.Utils;
import icu.puqns67.skintypefix.util.image.Places;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.PlayerSkinProvider;
import net.minecraft.client.util.SkinTextures;
import net.minecraft.util.Identifier;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.client.resources.SkinManager;
import net.minecraft.resources.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -22,20 +22,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@Environment(EnvType.CLIENT)
@Mixin(PlayerSkinProvider.class)
public class PlayerSkinProviderMixin {
@Inject(method = "fetchSkinTextures(Ljava/util/UUID;Lcom/mojang/authlib/minecraft/MinecraftProfileTextures;)Ljava/util/concurrent/CompletableFuture;", at = @At("TAIL"), cancellable = true)
private void onFetchSkinTexturesPrivate(
@Mixin(SkinManager.class)
public class SkinManagerMixin {
@Inject(method = "registerTextures", at = @At("TAIL"), cancellable = true)
private void onRegisterTextures(
UUID uuid,
MinecraftProfileTextures textures,
CallbackInfoReturnable<CompletableFuture<SkinTextures>> cir,
CallbackInfoReturnable<CompletableFuture<PlayerSkin>> cir,
@Local(ordinal = 0) MinecraftProfileTexture skinTextureOrigin,
@Local(ordinal = 0) CompletableFuture<Identifier> skinFuture,
@Local(ordinal = 1) CompletableFuture<Identifier> capeFuture,
@Local(ordinal = 2) CompletableFuture<Identifier> elytraFuture,
@Local SkinTextures.Model skinModelOrigin,
@Local(ordinal = 0) CompletableFuture<ResourceLocation> skinFuture,
@Local(ordinal = 1) CompletableFuture<ResourceLocation> capeFuture,
@Local(ordinal = 2) CompletableFuture<ResourceLocation> elytraFuture,
@Local PlayerSkin.Model skinModelOrigin,
@Local String skinUrl
) {
// Skip fix if using internal skin or uuid is invalid uuid
@ -45,15 +44,15 @@ public class PlayerSkinProviderMixin {
// If model is defaults to SLIM, and config `skipFixForSlimPlayers` is set to true,
// checks are skipped because some skins have bad pixels
if (skinModelOrigin == SkinTextures.Model.SLIM && SkinTypeFix.CONFIG.skipFixForSlimPlayers) {
if (skinModelOrigin == PlayerSkin.Model.SLIM && SkinTypeFix.CONFIG.skipFixForSlimPlayers) {
return;
}
var textureManager = MinecraftClient.getInstance().getTextureManager();
var textureManager = Minecraft.getInstance().getTextureManager();
CompletableFuture<SkinTextures.Model> modelFuture = skinFuture.thenApply(v -> {
CompletableFuture<PlayerSkin.Model> modelFuture = skinFuture.thenApply(v -> {
// Get texture from TextureManager
var skinTexture = (PlayerSkinTextureAccessor) textureManager.getTexture(skinFuture.join());
var skinTexture = (HttpTextureAccessor) textureManager.getTexture(skinFuture.join());
// Wait skin loading if it needed fetch from web
skinTexture.skinTypeFix$joinLoader();
@ -84,7 +83,7 @@ public class PlayerSkinProviderMixin {
cir.setReturnValue(
CompletableFuture
.allOf(skinFuture, capeFuture, elytraFuture, modelFuture)
.thenApply(v -> new SkinTextures(
.thenApply(v -> new PlayerSkin(
skinFuture.join(),
skinUrl,
capeFuture.join(),

View File

@ -1,18 +1,16 @@
package icu.puqns67.skintypefix.util;
import net.minecraft.client.util.SkinTextures;
import org.jetbrains.annotations.NotNull;
import net.minecraft.client.resources.PlayerSkin;
import java.util.UUID;
public class Utils {
private static final UUID INVALID_UUID = new UUID(0, 0);
public static @NotNull SkinTextures.Model reverseModelType(SkinTextures.Model type) {
public static PlayerSkin.Model reverseModelType(PlayerSkin.Model type) {
return switch (type) {
case SLIM -> SkinTextures.Model.WIDE;
case WIDE -> SkinTextures.Model.SLIM;
case SLIM -> PlayerSkin.Model.WIDE;
case WIDE -> PlayerSkin.Model.SLIM;
};
}

View File

@ -1,10 +1,9 @@
package icu.puqns67.skintypefix.util.image;
import net.minecraft.client.texture.NativeImage;
import com.mojang.blaze3d.platform.NativeImage;
import java.util.ArrayList;
public class Places {
public static final Places PLAYER = Places.forPlayer();
private final ArrayList<Square> squares = new ArrayList<>();

View File

@ -1,7 +1,6 @@
package icu.puqns67.skintypefix.util.image;
import net.minecraft.client.texture.NativeImage;
import com.mojang.blaze3d.platform.NativeImage;
public record Point(int x, int y) {
public Point {
@ -11,6 +10,6 @@ public record Point(int x, int y) {
}
public boolean isBlack(NativeImage image) {
return image.getColor(x, y) == 0xff000000;
return image.getPixelRGBA(x, y) == 0xff000000;
}
}

View File

@ -1,10 +1,9 @@
package icu.puqns67.skintypefix.util.image;
import net.minecraft.client.texture.NativeImage;
import com.mojang.blaze3d.platform.NativeImage;
import java.util.ArrayList;
public record Square(Point p1, Point p2) {
public Square {
// The point close to (0,0) is p1

View File

@ -1,5 +1,5 @@
{
"modmenu.nameTranslation.skintypefix": "皮肤类型修复",
"modmenu.summaryTranslation.skintypefix": "为部分玩家修复错误的皮肤类型。",
"modmenu.descriptionTranslation.skintypefix": "修复部分玩家的皮肤类型与实际皮肤文件的皮肤类型不匹配的问题。"
"modmenu.descriptionTranslation.skintypefix": "修复部分玩家的皮肤类型与实际皮肤文件的实际皮肤类型不匹配的问题。"
}

View File

@ -1,36 +1,36 @@
{
"schemaVersion": 1,
"id": "skintypefix",
"version": "${version}",
"name": "Skin Type Fix",
"description": "Fix wrong skin type for some players.",
"authors": [
"Puqns67"
],
"contact": {
"homepage": "https://modrinth.com/project/skintypefix",
"sources": "https://github.com/Puqns67/SkinTypeFix"
},
"license": "GPL-3.0-or-later",
"icon": "assets/skintypefix/icon.png",
"environment": "client",
"entrypoints": {
"client": [
"icu.puqns67.skintypefix.SkinTypeFix"
]
},
"mixins": [
{
"config": "skintypefix.mixins.json",
"environment": "client"
}
],
"depends": {
"fabricloader": ">=0.15.11",
"minecraft": "~1.20.6",
"java": ">=21"
},
"suggests": {
"another-mod": "*"
"schemaVersion": 1,
"id": "${mod_id}",
"name": "${mod_name}",
"version": "${mod_version}",
"description": "${mod_description}",
"authors": [
"Puqns67"
],
"contact": {
"homepage": "https://modrinth.com/project/skintypefix",
"sources": "https://github.com/Puqns67/SkinTypeFix"
},
"license": "${mod_license}",
"icon": "assets/skintypefix/icon.png",
"environment": "client",
"entrypoints": {
"client": [
"icu.puqns67.skintypefix.SkinTypeFix"
]
},
"mixins": [
{
"config": "skintypefix.mixins.json",
"environment": "client"
}
],
"depends": {
"java": ">=${java_version}",
"minecraft": "~${minecraft_version}",
"fabricloader": ">=${fabric_version}"
},
"suggests": {
"another-mod": "*"
}
}

View File

@ -1,12 +1,12 @@
{
"required": true,
"package": "icu.puqns67.skintypefix.mixin",
"compatibilityLevel": "JAVA_21",
"injectors": {
"defaultRequire": 1
},
"client": [
"PlayerSkinProviderMixin",
"PlayerSkinTextureMixin"
]
"package": "icu.puqns67.skintypefix.mixin.patch",
"client": [
"HttpTextureMixin",
"SkinManagerMixin"
],
"compatibilityLevel": "JAVA_21",
"injectors": {
"defaultRequire": 1
},
"required": true
}