1
0
mirror of https://github.com/Suiranoil/SkinRestorer.git synced 2026-01-16 04:42:12 +00:00

enhance translations

This commit is contained in:
2024-06-30 08:32:42 +03:00
parent bed53909a8
commit b9699486ab
4 changed files with 86 additions and 62 deletions

View File

@@ -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);
});
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}