Иконка ресурса

Кастомные плащи без миксинов (только один масенький access transformer)

Версия(и) Minecraft
да все, наверное
В accesstransformer.cfg надо добавить такую строчку (это не туториал по accesstransformer-ам, так что гуглите)
accesstransformer.cfg:
public-f net.minecraft.client.resources.SkinManager f_118809_ # sessionService
Делаем публичным и нефинальным поле SkinManager.sessionService, в зависимости от версии может быть другое имя класса/поля, но идею вы поняли.
Можно и без трансформера, если в вашей версии майна ещё есть ReflectionUtils (или как оно там называлось), и можно сеттить приватные финальные поля без него

И потом втупую делаем прокси вокруг ванильного sessionManager-а, где по условию добавляем ссылку на свой плащ в ретурн метода getTextures
Cape.java:
@EventBusSubscriber(value = Dist.CLIENT, modid = MODID, bus = Bus.MOD)
@OnlyIn(Dist.CLIENT)
public final class Cape {

    private static final List<UUID> CAPED = Collections.singletonList(NECAUQUA);

    @SubscribeEvent
    public static void on(FMLClientSetupEvent e) {
        var skinManager = Minecraft.getInstance().getSkinManager();
        var original = skinManager.sessionService;
        skinManager.sessionService = new MinecraftSessionService() {

            @Override
            public Map<Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) {
                var textures = original.getTextures(profile, requireSecure);
                if (CAPED.contains(profile.getId())) {
                    textures.put(Type.CAPE, new MinecraftProfileTexture("https://necauqua.dev/images/cape.png", emptyMap()));
                }
                return textures;
            }

            // в котлине было бы красиво с делегатой :|
            @Override
            public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
                original.joinServer(profile, authenticationToken, serverId);
            }

            @Override
            public GameProfile hasJoinedServer(GameProfile user, String serverId, InetAddress address) throws AuthenticationUnavailableException {
                return original.hasJoinedServer(user, serverId, address);
            }

            @Override
            public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
                return original.fillProfileProperties(profile, requireSecure);
            }
        };
    }
}

Как видите, я люблю оформлять эдакие независимые мини-модули при помощи @EventBusSubscriber (даже до него я что-то своё писал, чтобы были аннотации типа @Init @PreInit на рандомных методах по всему моду), но смысл просто в том чтобы когда-нибудь рано (те же иниты/преиниты) сделать обёртку этому сешион-менеджеру - и кстати если несколько модов так сделают то всё будет отлично работать (если они одному и тому-же игроку засетят плащ/скин/etc то просто последний победит).

Ещё момент в том что мы сеттим ссылку вместо текстуры в ассетах - ну тут я просто не разбирался ибо мне и так норм, но наверное можно найти как использовать текстуру, аналогичным способом можно сеттить прокси на всякие другие штуки тоже.
  • Like
Реакции: hohserg
Автор
necauqua
Просмотры
630
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок

Другие ресурсы пользователя necauqua

Сверху