PlayerTickEvent: некорректная работа при использовании на двух игроках на выделенном сервере

Версия Minecraft
1.12.2
API
Forge
Общая цель: сменить шейдер клиента, если на игроке висит кастомный эффект.
Общий пайплайн: на игрока навешивается кастомный эффект. В методе, подписанном на PlayerTickEvent регистрируется, что на игроке висит кастомный эффект, после чего вызывается метод применения post-processing шейдера (те, что в ваниле есть, по типу notch.json)

На обычном клиенте (без выделенного сервера) всё работает отлично
Если мод запустить на сервере тогда:
1. Если на сервере один игрок, то после применения эффекта всё так же работает хорошо
2. На сам сервер заходят два игрока - применение шейдеров перестает работать правильно (вобще не работает)
3. Если на обоих игроках висят эффекты, и второй игрок отлетит на большое расстояние (или выйдет с сервера) - тогда шейдеры сразу же применятся и всё заработает как надо

PlayerTickEvent:
@SideOnly(Side.CLIENT)
    @SubscribeEvent
    public void shaderPotionActive(PlayerTickEvent event) {
        if (event.phase != Phase.START || event.player == null) return;
        if (event.player.getEntityWorld().isRemote) {
            Main.logger.info("Tick for " + event.player.getName());

            if (event.player.isPotionActive(PotionInit.SHADER_EFFECT_NV)) {
                Main.logger.info("Tick with potion On for " + event.player.getName());
                this.switchShaders(this.nightVision);
            }
            else {
                if (this.isShaderOn(this.nightVision)) {
                    this.shaderOff();
                }
            }
        }
    }
Метод shaderPotionActive находится в классе ClientHandler
Этот класс регистрируется на клиент-прокси через FMLCommonHandler
Также в ClientHandler находятся метод для смены шейдеров и HashMap с ResourceLocation и Boolean состояниями шейдеров
Дополнительно коды для смены шейдеров :
ClientEvent:
public class ClientEvent
{
    private static final Minecraft minecraft;


    private final ResourceLocation nightVision;
    private final ResourceLocation bits;
    private HashMap<ResourceLocation, Boolean> shaderStates;\

    public ClientEvent() {
        this.nightVision = new ResourceLocation("zv", "shaders/night_vision.json");
        this.bits= new ResourceLocation("zv", "shaders/default/bits.json");
        (this.shaderStates = new HashMap<ResourceLocation, Boolean>(1)).put(this.nightVision, false);
        this.shaderStates.put(this.bits, false);
    }
 
    //Switch shader by it's ResourceLocation
    private void switchShaders(final ResourceLocation shaderLocation) {
        if (!this.shaderStates.get(shaderLocation)) {
            //final Boolean b;
            //this.shaderStates.keySet().forEach(resourceLocation -> b = this.shaderStates.put(resourceLocation, false));
            for (ResourceLocation key : this.shaderStates.keySet()) {
                this.shaderStates.put(key, false);
            }
            ClientEvent.minecraft.entityRenderer.loadShader(shaderLocation);
            this.shaderStates.put(shaderLocation, true);
            System.out.println("Shader " + shaderLocation.toString() + " is turned On");
        }
    }
 
    //turns all shader off
    private void shaderOff() {
        for (ResourceLocation key : this.shaderStates.keySet()) {
            this.shaderStates.put(key, false);
        }
        ClientEvent.minecraft.entityRenderer.stopUseShader();
        System.out.println("Shaders Off");
    }
 
    private Boolean isShaderOn(final ResourceLocation shaderLocation) {
        return this.shaderStates.get(shaderLocation);
    }
    static {
        minecraft = Minecraft.getMinecraft();
    }
}

Логи клиентов на сервере:
Оба игрока не имеют эффектов:
log:
[19:24:42] [Client thread/INFO]: [CHAT] [@: Все эффекты удалены у ZiZZun4i_GG_278]
[19:24:42] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:42] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:42] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:42] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:42] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:42] [Client thread/INFO]: Tick for Pod_ReBrO
...

Оба игрока получают эффект:
log:
[19:24:59] [Client thread/INFO]: [CHAT] [@: Наложен эффект «effect.potion_shader_nightVision» (ID 0) * 99 на игрока Pod_ReBrO на 99 сек.]
[19:24:59] [Client thread/INFO]: [CHAT] [@: Наложен эффект «effect.potion_shader_nightVision» (ID 0) * 99 на игрока ZiZZun4i_GG_278 на 99 сек.]
[19:24:59] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: Tick with potion On for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:switchShaders:203]: Shader zv:shaders/night_vision.json is turned On
[19:24:59] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:shaderOff:212]: Shaders Off
[19:24:59] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: Tick with potion On for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:switchShaders:203]: Shader zv:shaders/night_vision.json is turned On
[19:24:59] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:shaderOff:212]: Shaders Off
То есть со второго игрока эффект не считывается, хотя должен. К тому же шейдер к первому игроку применяется несколько раз (в коде есть проверка, включен ли уже шейдер. состояние шейдеров хранится в HashMap, выходит, как будто при изменении состояния Boolean в HashMap изменения не сохраняются, из-за чего несколько раз применяется одно и то же)

Пример лога, который должен был бы получится, если бы всё работало правильно:
log_example:
[Client thread/INFO]: [CHAT] [@: Наложен эффект «effect.potion_shader_nightVision» (ID 0) * 99 на игрока Pod_ReBrO на 99 сек.]
[19:24:59] [Client thread/INFO]: [CHAT] [@: Наложен эффект «effect.potion_shader_nightVision» (ID 0) * 99 на игрока ZiZZun4i_GG_278 на 99 сек.]
[19:24:59] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: Tick with potion On for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:switchShaders:203]: Shader zv:shaders/night_vision.json is turned On
[19:24:59] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:59] [Client thread/INFO]: Tick with potion On for Pod_ReBrO
[19:24:59] [Client thread/INFO]: [zv.mod1.events.ClientEvent:switchShaders:203]: Shader zv:shaders/night_vision.json is turned On
[19:24:59] [Client thread/INFO]: Tick for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: Tick with potion On for ZiZZun4i_GG_278
[19:24:59] [Client thread/INFO]: Tick for Pod_ReBrO
[19:24:59] [Client thread/INFO]: Tick with potion On for Pod_ReBrO

Визуально у обоих игроков также шейдеры не применяются
В чём может быть проблема?
 
Последнее редактирование:
Решение
Визуально у обоих игроков также шейдеры не применяются
В чём может быть проблема?
Также в ClientHandler находятся метод для смены шейдеров и HashMap с ResourceLocation и Boolean состояниями шейдеров
Мне кажется это и есть причина проблемы - в ой мапе намешал ,,состояния шейдеров,, для разных игроков - вот оно и работает не пойми как
Проверить ,,собственный игрок или нет,, можно так player instanceof EntityPlayerSP
440
42
113
Визуально у обоих игроков также шейдеры не применяются
В чём может быть проблема?
Также в ClientHandler находятся метод для смены шейдеров и HashMap с ResourceLocation и Boolean состояниями шейдеров
Мне кажется это и есть причина проблемы - в ой мапе намешал ,,состояния шейдеров,, для разных игроков - вот оно и работает не пойми как
Проверить ,,собственный игрок или нет,, можно так player instanceof EntityPlayerSP
 
Сверху