Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-27 08:30:12 +01:00
Better handling of fake cooldown
Because of Bedrock limitations, if a player has text background opacity enabled, they'll see an empty section where the title is usually displayed as the fake cooldown is shown. This commit minimizes the time that is shown by clearing the text as soon as possible. Reference issue: https://github.com/GeyserMC/Geyser/issues/1710 This commit also removes starting the fake cooldown process if the client switches to an inventory slot with the same Java ID.
Dieser Commit ist enthalten in:
Ursprung
c610e98f4c
Commit
f639be6362
@ -26,24 +26,36 @@
|
|||||||
package org.geysermc.geyser.session.cache;
|
package org.geysermc.geyser.session.cache;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
|
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.SetTitlePacket;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
|
||||||
import org.geysermc.geyser.scoreboard.Scoreboard;
|
import org.geysermc.geyser.scoreboard.Scoreboard;
|
||||||
import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession;
|
import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
@Getter
|
public final class WorldCache {
|
||||||
public class WorldCache {
|
|
||||||
private final GeyserSession session;
|
private final GeyserSession session;
|
||||||
|
@Getter
|
||||||
private final ScoreboardSession scoreboardSession;
|
private final ScoreboardSession scoreboardSession;
|
||||||
|
@Getter
|
||||||
private Scoreboard scoreboard;
|
private Scoreboard scoreboard;
|
||||||
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private Difficulty difficulty = Difficulty.EASY;
|
private Difficulty difficulty = Difficulty.EASY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether our cooldown changed the title time, and the true title times need to be re-sent.
|
||||||
|
*/
|
||||||
|
private boolean titleTimesNeedReset = false;
|
||||||
|
private int trueTitleFadeInTime;
|
||||||
|
private int trueTitleStayTime;
|
||||||
|
private int trueTitleFadeOutTime;
|
||||||
|
|
||||||
public WorldCache(GeyserSession session) {
|
public WorldCache(GeyserSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.scoreboard = new Scoreboard(session);
|
this.scoreboard = new Scoreboard(session);
|
||||||
scoreboardSession = new ScoreboardSession(session);
|
scoreboardSession = new ScoreboardSession(session);
|
||||||
|
resetTitleTimes(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeScoreboard() {
|
public void removeScoreboard() {
|
||||||
@ -58,4 +70,53 @@ public class WorldCache {
|
|||||||
int pps = scoreboardSession.getPacketsPerSecond();
|
int pps = scoreboardSession.getPacketsPerSecond();
|
||||||
return Math.max(pps, pendingPps);
|
return Math.max(pps, pendingPps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markTitleTimesAsIncorrect() {
|
||||||
|
titleTimesNeedReset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the true active title times.
|
||||||
|
*/
|
||||||
|
public void setTitleTimes(int fadeInTime, int stayTime, int fadeOutTime) {
|
||||||
|
trueTitleFadeInTime = fadeInTime;
|
||||||
|
trueTitleStayTime = stayTime;
|
||||||
|
trueTitleFadeOutTime = fadeOutTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If needed, ensure that the Bedrock client will use the correct timings for titles.
|
||||||
|
*/
|
||||||
|
public void synchronizeCorrectTitleTimes() {
|
||||||
|
if (titleTimesNeedReset) {
|
||||||
|
forceSyncCorrectTitleTimes();
|
||||||
|
titleTimesNeedReset = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forceSyncCorrectTitleTimes() {
|
||||||
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
|
titlePacket.setType(SetTitlePacket.Type.TIMES);
|
||||||
|
titlePacket.setText("");
|
||||||
|
titlePacket.setFadeInTime(trueTitleFadeInTime);
|
||||||
|
titlePacket.setStayTime(trueTitleStayTime);
|
||||||
|
titlePacket.setFadeOutTime(trueTitleFadeOutTime);
|
||||||
|
titlePacket.setPlatformOnlineId("");
|
||||||
|
titlePacket.setXuid("");
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(titlePacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the true active title times to the (Java Edition 1.18.2) defaults.
|
||||||
|
*/
|
||||||
|
public void resetTitleTimes(boolean clientSync) {
|
||||||
|
trueTitleFadeInTime = 10;
|
||||||
|
trueTitleStayTime = 70;
|
||||||
|
trueTitleFadeOutTime = 20;
|
||||||
|
|
||||||
|
if (clientSync) {
|
||||||
|
forceSyncCorrectTitleTimes();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -30,6 +30,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.Server
|
|||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket;
|
import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket;
|
||||||
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
@ -42,8 +43,9 @@ public class BedrockMobEquipmentTranslator extends PacketTranslator<MobEquipment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, MobEquipmentPacket packet) {
|
public void translate(GeyserSession session, MobEquipmentPacket packet) {
|
||||||
if (!session.isSpawned() || packet.getHotbarSlot() > 8 ||
|
int newSlot = packet.getHotbarSlot();
|
||||||
packet.getContainerId() != ContainerId.INVENTORY || session.getPlayerInventory().getHeldItemSlot() == packet.getHotbarSlot()) {
|
if (!session.isSpawned() || newSlot > 8 || packet.getContainerId() != ContainerId.INVENTORY
|
||||||
|
|| session.getPlayerInventory().getHeldItemSlot() == newSlot) {
|
||||||
// For the last condition - Don't update the slot if the slot is the same - not Java Edition behavior and messes with plugins such as Grief Prevention
|
// For the last condition - Don't update the slot if the slot is the same - not Java Edition behavior and messes with plugins such as Grief Prevention
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -51,12 +53,15 @@ public class BedrockMobEquipmentTranslator extends PacketTranslator<MobEquipment
|
|||||||
// Send book update before switching hotbar slot
|
// Send book update before switching hotbar slot
|
||||||
session.getBookEditCache().checkForSend();
|
session.getBookEditCache().checkForSend();
|
||||||
|
|
||||||
session.getPlayerInventory().setHeldItemSlot(packet.getHotbarSlot());
|
GeyserItemStack oldItem = session.getPlayerInventory().getItemInHand();
|
||||||
|
session.getPlayerInventory().setHeldItemSlot(newSlot);
|
||||||
|
|
||||||
ServerboundSetCarriedItemPacket setCarriedItemPacket = new ServerboundSetCarriedItemPacket(packet.getHotbarSlot());
|
ServerboundSetCarriedItemPacket setCarriedItemPacket = new ServerboundSetCarriedItemPacket(newSlot);
|
||||||
session.sendDownstreamPacket(setCarriedItemPacket);
|
session.sendDownstreamPacket(setCarriedItemPacket);
|
||||||
|
|
||||||
if (session.isSneaking() && session.getPlayerInventory().getItemInHand().getJavaId() == session.getItemMappings().getStoredItems().shield().getJavaId()) {
|
GeyserItemStack newItem = session.getPlayerInventory().getItemInHand();
|
||||||
|
|
||||||
|
if (session.isSneaking() && newItem.getJavaId() == session.getItemMappings().getStoredItems().shield().getJavaId()) {
|
||||||
// Activate shield since we are already sneaking
|
// Activate shield since we are already sneaking
|
||||||
// (No need to send a release item packet - Java doesn't do this when swapping items)
|
// (No need to send a release item packet - Java doesn't do this when swapping items)
|
||||||
// Required to do it a tick later or else it doesn't register
|
// Required to do it a tick later or else it doesn't register
|
||||||
@ -64,8 +69,10 @@ public class BedrockMobEquipmentTranslator extends PacketTranslator<MobEquipment
|
|||||||
50, TimeUnit.MILLISECONDS);
|
50, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Java sends a cooldown indicator whenever you switch an item
|
if (oldItem.getJavaId() != newItem.getJavaId()) {
|
||||||
CooldownUtils.sendCooldown(session);
|
// Java sends a cooldown indicator whenever you switch to a new item type
|
||||||
|
CooldownUtils.sendCooldown(session);
|
||||||
|
}
|
||||||
|
|
||||||
// Update the interactive tag, if an entity is present
|
// Update the interactive tag, if an entity is present
|
||||||
if (session.getMouseoverEntity() != null) {
|
if (session.getMouseoverEntity() != null) {
|
||||||
|
@ -37,11 +37,14 @@ public class JavaClearTitlesTranslator extends PacketTranslator<ClientboundClear
|
|||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundClearTitlesPacket packet) {
|
public void translate(GeyserSession session, ClientboundClearTitlesPacket packet) {
|
||||||
SetTitlePacket titlePacket = new SetTitlePacket();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
// TODO handle packet.isResetTimes()
|
|
||||||
titlePacket.setType(SetTitlePacket.Type.CLEAR);
|
titlePacket.setType(SetTitlePacket.Type.CLEAR);
|
||||||
titlePacket.setText("");
|
titlePacket.setText("");
|
||||||
titlePacket.setXuid("");
|
titlePacket.setXuid("");
|
||||||
titlePacket.setPlatformOnlineId("");
|
titlePacket.setPlatformOnlineId("");
|
||||||
session.sendUpstreamPacket(titlePacket);
|
session.sendUpstreamPacket(titlePacket);
|
||||||
|
|
||||||
|
if (packet.isResetTimes()) {
|
||||||
|
session.getWorldCache().resetTitleTimes(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ public class JavaSetTitleTextTranslator extends PacketTranslator<ClientboundSetT
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundSetTitleTextPacket packet) {
|
public void translate(GeyserSession session, ClientboundSetTitleTextPacket packet) {
|
||||||
|
session.getWorldCache().synchronizeCorrectTitleTimes();
|
||||||
|
|
||||||
String text;
|
String text;
|
||||||
if (packet.getText() == null || Component.empty().equals(packet.getText())) { // This can happen, see https://github.com/KyoriPowered/adventure/issues/447
|
if (packet.getText() == null || Component.empty().equals(packet.getText())) { // This can happen, see https://github.com/KyoriPowered/adventure/issues/447
|
||||||
text = " ";
|
text = " ";
|
||||||
|
@ -36,12 +36,17 @@ public class JavaSetTitlesAnimationTranslator extends PacketTranslator<Clientbou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundSetTitlesAnimationPacket packet) {
|
public void translate(GeyserSession session, ClientboundSetTitlesAnimationPacket packet) {
|
||||||
|
int fadeInTime = packet.getFadeIn();
|
||||||
|
int stayTime = packet.getStay();
|
||||||
|
int fadeOutTime = packet.getFadeOut();
|
||||||
|
session.getWorldCache().setTitleTimes(fadeInTime, stayTime, fadeOutTime);
|
||||||
|
|
||||||
SetTitlePacket titlePacket = new SetTitlePacket();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
titlePacket.setType(SetTitlePacket.Type.TIMES);
|
titlePacket.setType(SetTitlePacket.Type.TIMES);
|
||||||
titlePacket.setText("");
|
titlePacket.setText("");
|
||||||
titlePacket.setFadeInTime(packet.getFadeIn());
|
titlePacket.setFadeInTime(fadeInTime);
|
||||||
titlePacket.setFadeOutTime(packet.getFadeOut());
|
titlePacket.setFadeOutTime(fadeOutTime);
|
||||||
titlePacket.setStayTime(packet.getStay());
|
titlePacket.setStayTime(stayTime);
|
||||||
titlePacket.setXuid("");
|
titlePacket.setXuid("");
|
||||||
titlePacket.setPlatformOnlineId("");
|
titlePacket.setPlatformOnlineId("");
|
||||||
session.sendUpstreamPacket(titlePacket);
|
session.sendUpstreamPacket(titlePacket);
|
||||||
|
@ -57,8 +57,19 @@ public class CooldownUtils {
|
|||||||
if (sessionPreference == CooldownType.DISABLED) return;
|
if (sessionPreference == CooldownType.DISABLED) return;
|
||||||
|
|
||||||
if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used
|
if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used
|
||||||
// Needs to be sent or no subtitle packet is recognized by the client
|
// Set the times to stay a bit with no fade in nor out
|
||||||
SetTitlePacket titlePacket = new SetTitlePacket();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
|
titlePacket.setType(SetTitlePacket.Type.TIMES);
|
||||||
|
titlePacket.setStayTime(1000);
|
||||||
|
titlePacket.setText("");
|
||||||
|
titlePacket.setXuid("");
|
||||||
|
titlePacket.setPlatformOnlineId("");
|
||||||
|
session.sendUpstreamPacket(titlePacket);
|
||||||
|
|
||||||
|
session.getWorldCache().markTitleTimesAsIncorrect();
|
||||||
|
|
||||||
|
// Needs to be sent or no subtitle packet is recognized by the client
|
||||||
|
titlePacket = new SetTitlePacket();
|
||||||
titlePacket.setType(SetTitlePacket.Type.TITLE);
|
titlePacket.setType(SetTitlePacket.Type.TITLE);
|
||||||
titlePacket.setText(" ");
|
titlePacket.setText(" ");
|
||||||
titlePacket.setXuid("");
|
titlePacket.setXuid("");
|
||||||
@ -85,9 +96,6 @@ public class CooldownUtils {
|
|||||||
titlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
titlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
||||||
}
|
}
|
||||||
titlePacket.setText(getTitle(session));
|
titlePacket.setText(getTitle(session));
|
||||||
titlePacket.setFadeInTime(0);
|
|
||||||
titlePacket.setFadeOutTime(5);
|
|
||||||
titlePacket.setStayTime(2);
|
|
||||||
titlePacket.setXuid("");
|
titlePacket.setXuid("");
|
||||||
titlePacket.setPlatformOnlineId("");
|
titlePacket.setPlatformOnlineId("");
|
||||||
session.sendUpstreamPacket(titlePacket);
|
session.sendUpstreamPacket(titlePacket);
|
||||||
@ -96,11 +104,7 @@ public class CooldownUtils {
|
|||||||
computeCooldown(session, sessionPreference, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
|
computeCooldown(session, sessionPreference, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
|
||||||
} else {
|
} else {
|
||||||
SetTitlePacket removeTitlePacket = new SetTitlePacket();
|
SetTitlePacket removeTitlePacket = new SetTitlePacket();
|
||||||
if (sessionPreference == CooldownType.ACTIONBAR) {
|
removeTitlePacket.setType(SetTitlePacket.Type.CLEAR);
|
||||||
removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
|
|
||||||
} else {
|
|
||||||
removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
|
||||||
}
|
|
||||||
removeTitlePacket.setText(" ");
|
removeTitlePacket.setText(" ");
|
||||||
removeTitlePacket.setXuid("");
|
removeTitlePacket.setXuid("");
|
||||||
removeTitlePacket.setPlatformOnlineId("");
|
removeTitlePacket.setPlatformOnlineId("");
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren