mirror of
https://github.com/Suiranoil/SkinRestorer.git
synced 2026-01-16 04:42:12 +00:00
enhance translations
This commit is contained in:
@@ -2,7 +2,6 @@ package net.lionarius.skinrestorer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
import net.lionarius.skinrestorer.skin.SkinIO;
|
||||
import net.lionarius.skinrestorer.skin.SkinStorage;
|
||||
import net.lionarius.skinrestorer.skin.provider.MineskinSkinProvider;
|
||||
@@ -63,34 +62,22 @@ public final class SkinRestorer {
|
||||
SkinRestorer.skinStorage = new SkinStorage(new SkinIO(worldSkinDirectory));
|
||||
}
|
||||
|
||||
public static CompletableFuture<Pair<Collection<ServerPlayer>, Collection<GameProfile>>> setSkinAsync(
|
||||
public static CompletableFuture<Result<Collection<ServerPlayer>, String>> setSkinAsync(
|
||||
MinecraftServer server,
|
||||
Collection<GameProfile> targets,
|
||||
Supplier<Result<Optional<Property>, ?>> skinSupplier
|
||||
Supplier<Result<Optional<Property>, Exception>> skinSupplier
|
||||
) {
|
||||
return CompletableFuture.<Pair<Property, Collection<GameProfile>>>supplyAsync(() -> {
|
||||
var result = skinSupplier.get();
|
||||
if (result.isError()) {
|
||||
SkinRestorer.LOGGER.error("Could not get skin: {}", result.getErrorValue());
|
||||
return Pair.of(null, Collections.emptySet());
|
||||
return CompletableFuture.supplyAsync(skinSupplier)
|
||||
.thenApplyAsync(skinResult -> {
|
||||
if (skinResult.isError()) {
|
||||
return Result.<Collection<ServerPlayer>, String>error(skinResult.getErrorValue().getMessage());
|
||||
}
|
||||
|
||||
Property skin = result.getSuccessValue().orElse(null);
|
||||
var skin = skinResult.getSuccessValue().orElse(null);
|
||||
HashSet<ServerPlayer> acceptedPlayers = new HashSet<>();
|
||||
|
||||
for (GameProfile profile : targets) {
|
||||
SkinRestorer.getSkinStorage().setSkin(profile.getId(), skin);
|
||||
}
|
||||
|
||||
HashSet<GameProfile> acceptedProfiles = new HashSet<>(targets);
|
||||
|
||||
return Pair.of(skin, acceptedProfiles);
|
||||
}).<Pair<Collection<ServerPlayer>, Collection<GameProfile>>>thenApplyAsync(pair -> {
|
||||
Property skin = pair.left(); // NullPtrException will be caught by 'exceptionally'
|
||||
|
||||
Collection<GameProfile> acceptedProfiles = pair.right();
|
||||
HashSet<ServerPlayer> acceptedPlayers = new HashSet<>();
|
||||
|
||||
for (GameProfile profile : acceptedProfiles) {
|
||||
ServerPlayer player = server.getPlayerList().getPlayer(profile.getId());
|
||||
|
||||
if (player == null || PlayerUtils.areSkinPropertiesEquals(skin, PlayerUtils.getPlayerSkin(player)))
|
||||
@@ -100,12 +87,13 @@ public final class SkinRestorer {
|
||||
PlayerUtils.refreshPlayer(player);
|
||||
acceptedPlayers.add(player);
|
||||
}
|
||||
return Pair.of(acceptedPlayers, acceptedProfiles);
|
||||
return Result.<Collection<ServerPlayer>, String>success(acceptedPlayers);
|
||||
}, server)
|
||||
.orTimeout(10, TimeUnit.SECONDS)
|
||||
.exceptionally(e -> {
|
||||
SkinRestorer.LOGGER.error(String.valueOf(e));
|
||||
return Pair.of(Collections.emptySet(), Collections.emptySet());
|
||||
var cause = String.valueOf(e);
|
||||
SkinRestorer.LOGGER.error(cause);
|
||||
return Result.error(cause);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,8 @@ import net.lionarius.skinrestorer.util.TranslationUtils;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.GameProfileArgument;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -75,14 +71,14 @@ public final class SkinCommand {
|
||||
|
||||
private static ArgumentBuilder<CommandSourceStack, LiteralArgumentBuilder<CommandSourceStack>> buildAction(
|
||||
String name,
|
||||
Supplier<Result<Optional<Property>, ?>> supplier
|
||||
Supplier<Result<Optional<Property>, Exception>> supplier
|
||||
) {
|
||||
return buildArgument(literal(name), context -> supplier.get());
|
||||
}
|
||||
|
||||
private static <T extends ArgumentBuilder<CommandSourceStack, T>> ArgumentBuilder<CommandSourceStack, T> buildArgument(
|
||||
ArgumentBuilder<CommandSourceStack, T> argument,
|
||||
Function<CommandContext<CommandSourceStack>, Result<Optional<Property>, ?>> provider
|
||||
Function<CommandContext<CommandSourceStack>, Result<Optional<Property>, Exception>> provider
|
||||
) {
|
||||
return argument
|
||||
.executes(context -> skinAction(
|
||||
@@ -93,7 +89,7 @@ public final class SkinCommand {
|
||||
}
|
||||
|
||||
private static RequiredArgumentBuilder<CommandSourceStack, GameProfileArgument.Result> makeTargetsArgument(
|
||||
Function<CommandContext<CommandSourceStack>, Result<Optional<Property>, ?>> provider
|
||||
Function<CommandContext<CommandSourceStack>, Result<Optional<Property>, Exception>> provider
|
||||
) {
|
||||
return argument("targets", GameProfileArgument.gameProfile())
|
||||
.requires(source -> source.hasPermission(2))
|
||||
@@ -109,35 +105,46 @@ public final class SkinCommand {
|
||||
CommandSourceStack src,
|
||||
Collection<GameProfile> targets,
|
||||
boolean setByOperator,
|
||||
Supplier<Result<Optional<Property>, ?>> skinSupplier
|
||||
Supplier<Result<Optional<Property>, Exception>> skinSupplier
|
||||
) {
|
||||
SkinRestorer.setSkinAsync(src.getServer(), targets, skinSupplier).thenAccept(pair -> {
|
||||
Collection<GameProfile> profiles = pair.right();
|
||||
Collection<ServerPlayer> players = pair.left();
|
||||
|
||||
if (profiles.isEmpty()) {
|
||||
src.sendFailure(Component.nullToEmpty(TranslationUtils.getTranslation().skinActionFailed));
|
||||
SkinRestorer.setSkinAsync(src.getServer(), targets, skinSupplier).thenAccept(result -> {
|
||||
if (result.isError()) {
|
||||
src.sendFailure(TranslationUtils.translatableWithFallback(
|
||||
TranslationUtils.COMMAND_SKIN_FAILED_KEY,
|
||||
result.getErrorValue()
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
var updatedPlayers = result.getSuccessValue();
|
||||
|
||||
if (setByOperator) {
|
||||
src.sendSuccess(() -> Component.nullToEmpty(
|
||||
String.format(TranslationUtils.getTranslation().skinActionAffectedProfile,
|
||||
String.join(", ", profiles.stream().map(GameProfile::getName).toList()))), true);
|
||||
|
||||
if (!players.isEmpty()) {
|
||||
src.sendSuccess(() -> Component.nullToEmpty(
|
||||
String.format(TranslationUtils.getTranslation().skinActionAffectedPlayer,
|
||||
String.join(", ", players.stream().map(p -> p.getGameProfile().getName()).toList()))), true);
|
||||
if (!updatedPlayers.isEmpty()) {
|
||||
var playersComponent = Component.empty();
|
||||
int index = 0;
|
||||
for (var player : updatedPlayers) {
|
||||
playersComponent.append(Objects.requireNonNull(player.getDisplayName()));
|
||||
index++;
|
||||
if (index < updatedPlayers.size())
|
||||
playersComponent.append(", ");
|
||||
}
|
||||
|
||||
src.sendSuccess(() -> TranslationUtils.translatableWithFallback(
|
||||
TranslationUtils.COMMAND_SKIN_AFFECTED_PLAYERS_KEY,
|
||||
playersComponent
|
||||
), true);
|
||||
}
|
||||
} else {
|
||||
src.sendSuccess(() -> Component.nullToEmpty(TranslationUtils.getTranslation().skinActionOk), true);
|
||||
src.sendSuccess(() -> TranslationUtils.translatableWithFallback(
|
||||
TranslationUtils.COMMAND_SKIN_OK_KEY
|
||||
), true);
|
||||
}
|
||||
});
|
||||
|
||||
return targets.size();
|
||||
}
|
||||
|
||||
private static int skinAction(CommandSourceStack src, Supplier<Result<Optional<Property>, ?>> skinSupplier) {
|
||||
private static int skinAction(CommandSourceStack src, Supplier<Result<Optional<Property>, Exception>> skinSupplier) {
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
@@ -19,7 +21,11 @@ public final class JsonUtils {
|
||||
return GSON.fromJson(json, clazz);
|
||||
}
|
||||
|
||||
public static String toJson(Object obj) {
|
||||
public static <T> T fromJson(String json, Type type) {
|
||||
return GSON.fromJson(json, type);
|
||||
}
|
||||
|
||||
public static <T> String toJson(T obj) {
|
||||
return GSON.toJson(obj);
|
||||
}
|
||||
|
||||
@@ -34,7 +40,8 @@ public final class JsonUtils {
|
||||
json.remove("timestamp");
|
||||
|
||||
return json;
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception e) {
|
||||
SkinRestorer.LOGGER.error(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,60 @@
|
||||
package net.lionarius.skinrestorer.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import net.lionarius.skinrestorer.SkinRestorer;
|
||||
import net.lionarius.skinrestorer.skin.SkinIO;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class TranslationUtils {
|
||||
public static class Translation {
|
||||
public String skinActionAffectedProfile = "Skin has been saved for %s";
|
||||
public String skinActionAffectedPlayer = "Apply live skin changes for %s";
|
||||
public String skinActionFailed = "Failed to set skin";
|
||||
public String skinActionOk = "Skin changed";
|
||||
}
|
||||
|
||||
public static final String TRANSLATION_FILENAME = "translation";
|
||||
private static Translation translation = new Translation();
|
||||
|
||||
public static final String COMMAND_SKIN_AFFECTED_PLAYERS_KEY = "skinrestorer.command.skin.affected_players";
|
||||
public static final String COMMAND_SKIN_FAILED_KEY = "skinrestorer.command.skin.failed";
|
||||
public static final String COMMAND_SKIN_OK_KEY = "skinrestorer.command.skin.ok";
|
||||
|
||||
private static Map<String, String> translations;
|
||||
|
||||
private TranslationUtils() {}
|
||||
|
||||
public static Translation getTranslation() {
|
||||
return translation;
|
||||
public static String getTranslation(String key) {
|
||||
return TranslationUtils.translations.get(key);
|
||||
}
|
||||
|
||||
public static MutableComponent translatableWithFallback(String key) {
|
||||
return Component.translatableWithFallback(key, TranslationUtils.getTranslation(key));
|
||||
}
|
||||
|
||||
public static MutableComponent translatableWithFallback(String key, Object... args) {
|
||||
return Component.translatableWithFallback(key, TranslationUtils.getTranslation(key), args);
|
||||
}
|
||||
|
||||
static {
|
||||
Path path = SkinRestorer.getConfigDir().resolve(TRANSLATION_FILENAME + SkinIO.FILE_EXTENSION);
|
||||
translations = null;
|
||||
|
||||
if (Files.exists(path)) {
|
||||
try {
|
||||
translation = JsonUtils.fromJson(Objects.requireNonNull(FileUtils.readFile(path.toFile())), Translation.class);
|
||||
var mapType = new TypeToken<HashMap<String, String>>() {}.getType();
|
||||
translations = JsonUtils.fromJson(Objects.requireNonNull(FileUtils.readFile(path.toFile())), mapType);
|
||||
} catch (Exception ex) {
|
||||
SkinRestorer.LOGGER.error("Failed to load translation", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (translations == null) {
|
||||
translations = ImmutableMap.<String, String>builder()
|
||||
.put(COMMAND_SKIN_AFFECTED_PLAYERS_KEY, "Applied skin changes for %s")
|
||||
.put(COMMAND_SKIN_FAILED_KEY, "Failed to set skin: %s")
|
||||
.put(COMMAND_SKIN_OK_KEY, "Skin changed")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user