- 1
- 0
Общая цель: сменить шейдер клиента, если на игроке висит кастомный эффект.
Общий пайплайн: на игрока навешивается кастомный эффект. В методе, подписанном на PlayerTickEvent регистрируется, что на игроке висит кастомный эффект, после чего вызывается метод применения post-processing шейдера (те, что в ваниле есть, по типу notch.json)
На обычном клиенте (без выделенного сервера) всё работает отлично
Если мод запустить на сервере тогда:
1. Если на сервере один игрок, то после применения эффекта всё так же работает хорошо
2. На сам сервер заходят два игрока - применение шейдеров перестает работать правильно (вобще не работает)
3. Если на обоих игроках висят эффекты, и второй игрок отлетит на большое расстояние (или выйдет с сервера) - тогда шейдеры сразу же применятся и всё заработает как надо
Метод shaderPotionActive находится в классе ClientHandler
Этот класс регистрируется на клиент-прокси через FMLCommonHandler
Также в ClientHandler находятся метод для смены шейдеров и HashMap с ResourceLocation и Boolean состояниями шейдеров
Дополнительно коды для смены шейдеров :
Логи клиентов на сервере:
Оба игрока не имеют эффектов:
Оба игрока получают эффект:
То есть со второго игрока эффект не считывается, хотя должен. К тому же шейдер к первому игроку применяется несколько раз (в коде есть проверка, включен ли уже шейдер. состояние шейдеров хранится в HashMap, выходит, как будто при изменении состояния Boolean в HashMap изменения не сохраняются, из-за чего несколько раз применяется одно и то же)
Пример лога, который должен был бы получится, если бы всё работало правильно:
Визуально у обоих игроков также шейдеры не применяются
В чём может быть проблема?
Общий пайплайн: на игрока навешивается кастомный эффект. В методе, подписанном на 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();
}
}
}
}
Этот класс регистрируется на клиент-прокси через 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
Пример лога, который должен был бы получится, если бы всё работало правильно:
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
Визуально у обоих игроков также шейдеры не применяются
В чём может быть проблема?
Последнее редактирование: