mirror of
https://github.com/Suiranoil/SkinRestorer.git
synced 2026-01-16 04:42:12 +00:00
Merge branch '1.20.5-multiloader' into 1.20.3-multiloader
This commit is contained in:
88
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
88
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
name: Bug Report
|
||||
description: Report a bug encountered with SkinRestorer
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
🐛 **Before submitting:**
|
||||
- Ensure you're using the latest mod version
|
||||
- Ensure this bug is reproducible consistently
|
||||
- Check existing issues for duplicates
|
||||
|
||||
- type: input
|
||||
id: mod-version
|
||||
attributes:
|
||||
label: SkinRestorer Version
|
||||
description: Exact version of the mod
|
||||
placeholder: e.g., 2.2.1
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: minecraft-version
|
||||
attributes:
|
||||
label: Minecraft Version
|
||||
description: Full Minecraft version
|
||||
placeholder: e.g., 1.21.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: loader-version
|
||||
attributes:
|
||||
label: Mod Loader & Version
|
||||
description: Fabric/Quilt/Forge/NeoForge version
|
||||
placeholder: e.g., Fabric 0.15.7
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: java-version
|
||||
attributes:
|
||||
label: Java Version
|
||||
placeholder: e.g. 17, 21
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Bug Description
|
||||
description: What happened vs what you expected to happen
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant Logs
|
||||
description: |
|
||||
Please provide any relevant logs, especially error logs from your server console or `latest.log` file.
|
||||
**Important**: Paste the FULL log content. Use a service like [mclo.gs](https://mclo.gs/).
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: confirmations
|
||||
attributes:
|
||||
label: Confirmations
|
||||
options:
|
||||
- label: I've checked for existing issues
|
||||
required: true
|
||||
- label: This bug is reproducible consistently
|
||||
required: true
|
||||
- label: I've tested without other mods
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: true
|
||||
52
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
52
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature for SkinRestorer
|
||||
title: "[Feature Request]: "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
💡 **Before submitting:**
|
||||
- Check existing feature requests for duplicates
|
||||
- Be clear and concise
|
||||
- Explain the *why* and the *how*
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
description: Detailed description of the feature
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: motivation
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: Why is this feature needed? What problem does it solve?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: use-cases
|
||||
attributes:
|
||||
label: Use Cases
|
||||
description: How would this feature be used and who would benefit?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: implementation-ideas
|
||||
attributes:
|
||||
label: Implementation Ideas (Optional)
|
||||
description: Any thoughts on how it could be implemented?
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
id: confirmations
|
||||
attributes:
|
||||
label: Confirmations
|
||||
options:
|
||||
- label: I've checked for existing feature requests
|
||||
required: true
|
||||
@@ -1,7 +1,7 @@
|
||||
# SkinRestorer
|
||||
|
||||
<a href="https://modrinth.com/mod/skinrestorer"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/minecraft/platform/modrinth/mini/badge.svg" alt="Modrinth" height="32"></a>
|
||||
<a href="https://www.curseforge.com/minecraft/mc-mods/skinrestorer"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/minecraft/platform/curseforge/mini/badge.svg" alt="CurseForge" height="32"></a>
|
||||
<a href="https://modrinth.com/mod/skinrestorer"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/minecraft/platform/modrinth/mini/badge.svg" alt="Modrinth"></a>
|
||||
<a href="https://www.curseforge.com/minecraft/mc-mods/skinrestorer"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/minecraft/platform/curseforge/mini/badge.svg" alt="CurseForge"></a>
|
||||
|
||||
A server-side mod for managing and restoring player skins.
|
||||
|
||||
@@ -33,7 +33,9 @@ the [commands wiki page](https://github.com/Suiranoil/SkinRestorer/wiki/Commands
|
||||
If you enjoy using **SkinRestorer** and would like to support its development, you can contribute through the following
|
||||
platforms:
|
||||
|
||||
[](https://ko-fi.com/lionarius)
|
||||
<a href="https://ko-fi.com/lionarius"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/donation/kofi/mini/badge.svg" alt="Ko-fi" height="32"></a>
|
||||
|
||||
<a href="https://boosty.to/lionarius"><img src="https://raw.githubusercontent.com/Suiranoil/badges/main/assets/donation/boosty/mini/badge.svg" alt="Boosty" height="32"></a>
|
||||
|
||||
Bitcoin (BTC): `1Ndbwny8pxdnWXFgadp95fp97y5JqMJKTX`
|
||||
USDT (TRC20): `TGXn8wrqku5KLzwPWQAeH7wgnV4UzwHEae`
|
||||
|
||||
10
build.gradle
10
build.gradle
@@ -1,15 +1,15 @@
|
||||
plugins {
|
||||
// see https://fabricmc.net/develop/ for new versions
|
||||
id 'fabric-loom' version '1.8-SNAPSHOT' apply false
|
||||
// see https://projects.neoforged.net/neoforged/neogradle for new versions
|
||||
id 'net.neoforged.gradle.userdev' version '7.0.153' apply false
|
||||
id 'fabric-loom' version '1.10-SNAPSHOT' apply false
|
||||
// see https://projects.neoforged.net/neoforged/moddevgradle for new versions
|
||||
id 'net.neoforged.moddev' version '2.0.80' apply false
|
||||
// see https://files.minecraftforge.net/net/minecraftforge/gradle/ForgeGradle/ for new versions
|
||||
id 'net.minecraftforge.gradle' version '6.0.29' apply false
|
||||
id 'net.minecraftforge.gradle' version '6.0.35' apply false
|
||||
id 'org.parchmentmc.librarian.forgegradle' version '1.+' apply false
|
||||
|
||||
id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' apply false
|
||||
|
||||
id 'me.modmuss50.mod-publish-plugin' version '0.8.1' apply false
|
||||
id 'me.modmuss50.mod-publish-plugin' version '0.8.4' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
||||
@@ -5,6 +5,8 @@ plugins {
|
||||
publishMods {
|
||||
if (project.name == 'fabric')
|
||||
file = remapJar.archiveFile
|
||||
else if (project.name == 'neoforge')
|
||||
file = jar.archiveFile
|
||||
else
|
||||
file = tasks.named('jarJar').get().archiveFile
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public final class SkinCommand {
|
||||
private SkinCommand() {}
|
||||
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||
LiteralArgumentBuilder<CommandSourceStack> base =
|
||||
var base =
|
||||
literal("skin")
|
||||
.then(buildSetSubcommand("clear", SkinValue.EMPTY::toProviderContext))
|
||||
.then(literal("reset")
|
||||
@@ -44,7 +44,7 @@ public final class SkinCommand {
|
||||
)))
|
||||
.then(literal("refresh").executes(context -> refreshSubcommand(context.getSource())));
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> set = literal("set");
|
||||
var set = literal("set");
|
||||
|
||||
var providers = SkinRestorer.getProvidersRegistry().getPublicProviders();
|
||||
for (var entry : providers)
|
||||
@@ -92,7 +92,7 @@ public final class SkinCommand {
|
||||
Collection<GameProfile> targets,
|
||||
boolean setByOperator
|
||||
) {
|
||||
Collection<ServerPlayer> updatedPlayers = new HashSet<>();
|
||||
var updatedPlayers = new HashSet<ServerPlayer>();
|
||||
for (var profile : targets) {
|
||||
SkinValue skin = null;
|
||||
if (SkinRestorer.getSkinStorage().hasSavedSkin(profile.getId()))
|
||||
@@ -199,7 +199,7 @@ public final class SkinCommand {
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> buildSetSubcommand(String name, SkinProvider provider) {
|
||||
LiteralArgumentBuilder<CommandSourceStack> action = literal(name);
|
||||
var action = literal(name);
|
||||
|
||||
if (provider.hasVariantSupport()) {
|
||||
for (SkinVariant variant : SkinVariant.values()) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.lionarius.skinrestorer.platform.Services;
|
||||
import net.lionarius.skinrestorer.skin.SkinValue;
|
||||
import net.lionarius.skinrestorer.skin.provider.SkinShuffleSkinProvider;
|
||||
import net.lionarius.skinrestorer.util.PlayerUtils;
|
||||
import net.lionarius.skinrestorer.util.ServerUtils;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -40,7 +41,7 @@ public class SkinShuffleCompatibility {
|
||||
if (!property.hasSignature())
|
||||
return;
|
||||
|
||||
server.execute(() -> {
|
||||
ServerUtils.scheduleServerTask(server, () -> {
|
||||
SkinRestorer.applySkin(
|
||||
server,
|
||||
Collections.singleton(player.getGameProfile()),
|
||||
|
||||
@@ -18,6 +18,8 @@ public final class Config implements GsonPostProcessable {
|
||||
|
||||
private boolean refreshSkinOnJoin = true;
|
||||
|
||||
private int skinApplyDelayOnJoin = 0;
|
||||
|
||||
private boolean fetchSkinOnFirstJoin = true;
|
||||
|
||||
private FirstJoinSkinProvider firstJoinSkinProvider = FirstJoinSkinProvider.MOJANG;
|
||||
@@ -37,6 +39,10 @@ public final class Config implements GsonPostProcessable {
|
||||
return this.refreshSkinOnJoin;
|
||||
}
|
||||
|
||||
public int skinApplyDelayOnJoin() {
|
||||
return this.skinApplyDelayOnJoin;
|
||||
}
|
||||
|
||||
public boolean fetchSkinOnFirstJoin() {
|
||||
return this.fetchSkinOnFirstJoin;
|
||||
}
|
||||
@@ -82,6 +88,11 @@ public final class Config implements GsonPostProcessable {
|
||||
this.language = "en_us";
|
||||
}
|
||||
|
||||
if (this.skinApplyDelayOnJoin < 0) {
|
||||
SkinRestorer.LOGGER.warn("SkinApplyDelayOnJoin config is less than 0, defaulting to 0");
|
||||
this.skinApplyDelayOnJoin = 0;
|
||||
}
|
||||
|
||||
if (this.firstJoinSkinProvider == null) {
|
||||
SkinRestorer.LOGGER.warn("FirstJoinSkinProvider config is null, defaulting to MOJANG");
|
||||
this.firstJoinSkinProvider = FirstJoinSkinProvider.MOJANG;
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
package net.lionarius.skinrestorer.config.provider;
|
||||
|
||||
public interface BuiltInProviderConfig {
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.util.gson.GsonPostProcessable;
|
||||
|
||||
boolean enabled();
|
||||
|
||||
String name();
|
||||
|
||||
CacheConfig cache();
|
||||
public abstract class BuiltInProviderConfig implements GsonPostProcessable {
|
||||
protected boolean enabled;
|
||||
protected String name;
|
||||
protected CacheConfig cache;
|
||||
|
||||
public BuiltInProviderConfig(String name, CacheConfig cache) {
|
||||
this.enabled = true;
|
||||
this.name = name;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CacheConfig cache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
protected void validate(String defaultName, CacheConfig defaultCache) {
|
||||
if (this.name == null || this.name.isEmpty()) {
|
||||
SkinRestorer.LOGGER.warn("Provider name is null or empty, defaulting to '{}'", defaultName);
|
||||
this.name = defaultName;
|
||||
}
|
||||
|
||||
if (this.cache == null) {
|
||||
SkinRestorer.LOGGER.warn("Provider cache is null, using default");
|
||||
this.cache = defaultCache;
|
||||
} else {
|
||||
this.cache.validate(defaultCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +1,16 @@
|
||||
package net.lionarius.skinrestorer.config.provider;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.provider.ElyBySkinProvider;
|
||||
import net.lionarius.skinrestorer.util.gson.GsonPostProcessable;
|
||||
|
||||
public class ElyByProviderConfig implements BuiltInProviderConfig, GsonPostProcessable {
|
||||
public final class ElyByProviderConfig extends BuiltInProviderConfig {
|
||||
private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 60);
|
||||
|
||||
private boolean enabled;
|
||||
private String name;
|
||||
private CacheConfig cache;
|
||||
|
||||
public ElyByProviderConfig() {
|
||||
this.enabled = true;
|
||||
this.name = ElyBySkinProvider.PROVIDER_NAME;
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CacheConfig cache() {
|
||||
return cache;
|
||||
super(ElyBySkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gsonPostProcess() {
|
||||
if (this.name == null || this.name.isEmpty()) {
|
||||
SkinRestorer.LOGGER.warn("Ely.By provider name is null or empty, defaulting to '{}'", ElyBySkinProvider.PROVIDER_NAME);
|
||||
this.name = ElyBySkinProvider.PROVIDER_NAME;
|
||||
}
|
||||
|
||||
if (this.cache == null) {
|
||||
SkinRestorer.LOGGER.warn("Ely.By provider cache is null, using default");
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
} else {
|
||||
this.cache.validate(DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
super.validate(ElyBySkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,52 +2,25 @@ package net.lionarius.skinrestorer.config.provider;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.provider.MineskinSkinProvider;
|
||||
import net.lionarius.skinrestorer.util.gson.GsonPostProcessable;
|
||||
|
||||
public class MineskinProviderConfig implements BuiltInProviderConfig, GsonPostProcessable {
|
||||
public final class MineskinProviderConfig extends BuiltInProviderConfig {
|
||||
private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 300);
|
||||
|
||||
private boolean enabled;
|
||||
private String name;
|
||||
private CacheConfig cache;
|
||||
private String apiKey;
|
||||
|
||||
public MineskinProviderConfig() {
|
||||
this.enabled = true;
|
||||
this.name = MineskinSkinProvider.PROVIDER_NAME;
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
super(MineskinSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
|
||||
this.apiKey = "";
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CacheConfig cache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public String apiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gsonPostProcess() {
|
||||
if (this.name == null || this.name.isEmpty()) {
|
||||
SkinRestorer.LOGGER.warn("Mineskin provider name is null or empty, defaulting to '{}'", MineskinSkinProvider.PROVIDER_NAME);
|
||||
this.name = MineskinSkinProvider.PROVIDER_NAME;
|
||||
}
|
||||
|
||||
if (this.cache == null) {
|
||||
SkinRestorer.LOGGER.warn("Mineskin cache is null, using default");
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
} else {
|
||||
this.cache.validate(DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
super.validate(MineskinSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
|
||||
if (this.apiKey == null) {
|
||||
SkinRestorer.LOGGER.warn("Mineskin API key is null, defaulting to an empty string");
|
||||
|
||||
@@ -1,46 +1,16 @@
|
||||
package net.lionarius.skinrestorer.config.provider;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.provider.MojangSkinProvider;
|
||||
import net.lionarius.skinrestorer.util.gson.GsonPostProcessable;
|
||||
|
||||
public class MojangProviderConfig implements BuiltInProviderConfig, GsonPostProcessable {
|
||||
public final class MojangProviderConfig extends BuiltInProviderConfig {
|
||||
private static final CacheConfig DEFAULT_CACHE_VALUE = new CacheConfig(true, 60);
|
||||
|
||||
private boolean enabled;
|
||||
private String name;
|
||||
private CacheConfig cache;
|
||||
|
||||
public MojangProviderConfig() {
|
||||
this.enabled = true;
|
||||
this.name = MojangSkinProvider.PROVIDER_NAME;
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CacheConfig cache() {
|
||||
return cache;
|
||||
super(MojangSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gsonPostProcess() {
|
||||
if (this.name == null || this.name.isEmpty()) {
|
||||
SkinRestorer.LOGGER.warn("Mojang provider name is null or empty, defaulting to '{}'", MojangSkinProvider.PROVIDER_NAME);
|
||||
this.name = MojangSkinProvider.PROVIDER_NAME;
|
||||
}
|
||||
|
||||
if (this.cache == null) {
|
||||
SkinRestorer.LOGGER.warn("Mojang provider cache is null, using default");
|
||||
this.cache = DEFAULT_CACHE_VALUE;
|
||||
} else {
|
||||
this.cache.validate(DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
super.validate(MojangSkinProvider.PROVIDER_NAME, DEFAULT_CACHE_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.lionarius.skinrestorer.mixin;
|
||||
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.util.ServerUtils;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -9,6 +10,7 @@ import net.minecraft.server.players.PlayerList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -39,6 +41,22 @@ public abstract class PlayerListMixin {
|
||||
|
||||
@Inject(method = "placeNewPlayer", at = @At("HEAD"))
|
||||
private void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie, CallbackInfo ci) {
|
||||
var delay = SkinRestorer.getConfig().skinApplyDelayOnJoin();
|
||||
var uuid = player.getUUID();
|
||||
|
||||
if (delay <= 0) {
|
||||
skinrestorer$tryApplySkin(server, player);
|
||||
} else {
|
||||
ServerUtils.scheduleServerTask(server, () -> {
|
||||
var actualPlayer = server.getPlayerList().getPlayer(uuid);
|
||||
if (actualPlayer != null)
|
||||
skinrestorer$tryApplySkin(server, actualPlayer);
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void skinrestorer$tryApplySkin(MinecraftServer server, ServerPlayer player) {
|
||||
if (SkinRestorer.getSkinStorage().hasSavedSkin(player.getUUID()))
|
||||
SkinRestorer.applySkin(server, Collections.singleton(player.getGameProfile()), SkinRestorer.getSkinStorage().getSkin(player.getUUID()));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.lionarius.skinrestorer.util;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ServerUtils {
|
||||
|
||||
private ServerUtils() {}
|
||||
|
||||
public static void scheduleServerTask(MinecraftServer server, Consumer<MinecraftServer> task) {
|
||||
ServerUtils.scheduleServerTask(server, task, 0);
|
||||
}
|
||||
|
||||
public static void scheduleServerTask(MinecraftServer server, Runnable task) {
|
||||
ServerUtils.scheduleServerTask(server, task, 0);
|
||||
}
|
||||
|
||||
public static void scheduleServerTask(MinecraftServer server, Consumer<MinecraftServer> task, int tickDelay) {
|
||||
server.execute(new ScheduledTickTask(server, task, server.getTickCount() + tickDelay));
|
||||
}
|
||||
|
||||
public static void scheduleServerTask(MinecraftServer server, Runnable task, int tickDelay) {
|
||||
server.execute(new ScheduledTickTask(server, _server -> task.run(), server.getTickCount() + tickDelay));
|
||||
}
|
||||
|
||||
public record ScheduledTickTask(MinecraftServer server, Consumer<MinecraftServer> task,
|
||||
int tickTarget) implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
if (this.server.getTickCount() >= this.tickTarget)
|
||||
this.task.accept(this.server);
|
||||
else
|
||||
this.server.execute(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ minecraft {
|
||||
|
||||
runs {
|
||||
client {
|
||||
workingDirectory file('../run/client')
|
||||
workingDirectory rootProject.file('run/client')
|
||||
ideaModule "${rootProject.name}.${project.name}.main"
|
||||
taskName 'Client'
|
||||
mods {
|
||||
@@ -51,7 +51,7 @@ minecraft {
|
||||
}
|
||||
|
||||
server {
|
||||
workingDirectory file('../run/server')
|
||||
workingDirectory rootProject.file('run/server')
|
||||
ideaModule "${rootProject.name}.${project.name}.main"
|
||||
taskName 'Server'
|
||||
mods {
|
||||
|
||||
@@ -17,6 +17,7 @@ license=MIT
|
||||
credits=
|
||||
description=A server-side mod for managing skins.
|
||||
|
||||
# Dependencies
|
||||
mineskin_client_version=3.0.1-SNAPSHOT
|
||||
|
||||
# ParchmentMC mappings, see https://parchmentmc.org/docs/getting-started#choose-a-version for new versions
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
3
gradlew
vendored
3
gradlew
vendored
@@ -86,8 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
@@ -3,56 +3,58 @@ plugins {
|
||||
id 'idea'
|
||||
id 'eclipse'
|
||||
|
||||
id 'net.neoforged.gradle.userdev'
|
||||
id 'net.neoforged.moddev'
|
||||
|
||||
id 'multiloader-publish'
|
||||
}
|
||||
|
||||
// Automatically enable neoforge AccessTransformers if the file exists
|
||||
def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
if (at.exists()) {
|
||||
minecraft.accessTransformers.file(at)
|
||||
}
|
||||
|
||||
jarJar.enable()
|
||||
|
||||
tasks.named('jar') {
|
||||
archiveClassifier = 'thin'
|
||||
}
|
||||
|
||||
tasks.named('jarJar') {
|
||||
archiveClassifier = ''
|
||||
}
|
||||
|
||||
jar.finalizedBy('jarJar')
|
||||
|
||||
dependencies {
|
||||
implementation "net.neoforged:neoforge:${neoforge_version}"
|
||||
|
||||
implementation(jarJar(group: 'org.mineskin', name: 'java-client', version: mineskin_client_version)) {
|
||||
jarJar.ranged(it, "[${mineskin_client_version},)")
|
||||
neoForge {
|
||||
version = neoforge_version
|
||||
|
||||
// Automatically enable neoforge AccessTransformers if the file exists
|
||||
def at = project(':common').file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
if (at.exists()) {
|
||||
minecraft.accessTransformers.file(at)
|
||||
}
|
||||
}
|
||||
|
||||
subsystems {
|
||||
parchment {
|
||||
minecraftVersion = parchment_minecraft
|
||||
mappingsVersion = parchment_version
|
||||
}
|
||||
}
|
||||
|
||||
runs {
|
||||
configureEach {
|
||||
modSource project.sourceSets.main
|
||||
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
|
||||
runs {
|
||||
configureEach {
|
||||
ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric
|
||||
}
|
||||
|
||||
client {
|
||||
client()
|
||||
gameDirectory = rootProject.file('run/client')
|
||||
}
|
||||
|
||||
server {
|
||||
server()
|
||||
programArgument '--nogui'
|
||||
gameDirectory = rootProject.file('run/server')
|
||||
}
|
||||
}
|
||||
|
||||
client {
|
||||
workingDirectory = file('../run/client')
|
||||
}
|
||||
|
||||
server {
|
||||
programArgument '--nogui'
|
||||
workingDirectory = file('../run/server')
|
||||
mods {
|
||||
"${mod_id}" {
|
||||
sourceSet sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "net.neoforged:neoforge:${neoforge_version}"
|
||||
|
||||
jarJar(implementation('org.mineskin:java-client')) {
|
||||
version {
|
||||
strictly "[${mineskin_client_version},)"
|
||||
prefer mineskin_client_version
|
||||
}
|
||||
}
|
||||
|
||||
additionalRuntimeClasspath "org.mineskin:java-client:${mineskin_client_version}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user