-
-
Notifications
You must be signed in to change notification settings - Fork 707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add client setting for cooldown type, refactor show-coordinates #2193
Changes from 4 commits
5d5aa47
5dd4fa9
ba040cc
8767aac
93e7cde
ae47870
0723f2e
185d268
9d8292a
31f963d
4e9b1bc
14ad6e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
* | ||
* @author GeyserMC | ||
* @link https://github.com/GeyserMC/Geyser | ||
*/ | ||
|
||
package org.geysermc.connector.network.session.cache; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
import org.geysermc.connector.configuration.GeyserConfiguration; | ||
import org.geysermc.connector.network.session.GeyserSession; | ||
import org.geysermc.connector.utils.CooldownUtils; | ||
|
||
@Getter | ||
public class PreferencesCache { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this name should be changed, but I'm not sure to what. I'm going to have a PR after OptionalPack is merged that allows a plugin to change if a client can Bedrock godbridge or not, so the boolean for that might as well be stuck here. Open to suggestions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it would stop all connected geyser players from god-bridging, why would the boolean be stored in every session instance? Do you mean the PR would allow plugins to change an allowGodbridging value that geyser uses to prevent god-bridging, or it would allow an extension plugin to do the work of preventing god-bridging? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We can't do that because of GeyserConnect, or if server owners only wanted to block per-world for example. The plugin would be separate and use plugin messages to communicate to Geyser. |
||
private final GeyserSession session; | ||
|
||
/** | ||
* True if the client prefers being shown their coordinates, regardless if they're being shown or not. | ||
* This will be true everytime the client joins the server because neither the client nor server store the preference permanently. | ||
*/ | ||
@Setter | ||
private boolean prefersShowCoordinates = true; | ||
/** | ||
* If the client's preference will be ignored, this will return false. | ||
*/ | ||
private boolean allowShowCoordinates; | ||
|
||
/** | ||
* Which CooldownType the client prefers. Initially set to {@link CooldownUtils#getDefaultShowCooldown()}. | ||
*/ | ||
@Setter | ||
private CooldownUtils.CooldownType cooldownPreference = CooldownUtils.getDefaultShowCooldown(); | ||
|
||
public PreferencesCache(GeyserSession session) { | ||
this.session = session; | ||
} | ||
|
||
/** | ||
* Tell the client to hide or show the coordinates. | ||
* | ||
* If {@link #prefersShowCoordinates} is true, coordinates will be shown, unless either of the following conditions apply: <br> | ||
* <br> | ||
* {@link GeyserSession#reducedDebugInfo} is enabled | ||
* {@link GeyserConfiguration#isShowCoordinates()} is disabled | ||
*/ | ||
public void updateShowCoordinates() { | ||
allowShowCoordinates = !session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates(); | ||
session.sendGameRule("showcoordinates", allowShowCoordinates && prefersShowCoordinates); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; | ||
import lombok.Getter; | ||
import org.geysermc.connector.network.session.GeyserSession; | ||
import org.geysermc.connector.network.session.cache.PreferencesCache; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
|
@@ -36,18 +37,24 @@ | |
* Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind | ||
*/ | ||
public class CooldownUtils { | ||
private static CooldownType SHOW_COOLDOWN; | ||
private static CooldownType DEFAULT_SHOW_COOLDOWN; | ||
|
||
public static void setShowCooldown(String showCooldown) { | ||
SHOW_COOLDOWN = CooldownType.getByName(showCooldown); | ||
public static void setDefaultShowCooldown(String showCooldown) { | ||
DEFAULT_SHOW_COOLDOWN = CooldownType.getByName(showCooldown); | ||
} | ||
Camotoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public static CooldownType getDefaultShowCooldown() { | ||
return DEFAULT_SHOW_COOLDOWN; | ||
} | ||
|
||
/** | ||
* Starts sending the fake cooldown to the Bedrock client. | ||
* Starts sending the fake cooldown to the Bedrock client. If the cooldown is not disabled, the sent type is {@link PreferencesCache#getCooldownPreference()} | ||
* @param session GeyserSession | ||
*/ | ||
public static void sendCooldown(GeyserSession session) { | ||
if (SHOW_COOLDOWN == CooldownType.DISABLED) return; | ||
if (DEFAULT_SHOW_COOLDOWN == CooldownType.DISABLED) return; | ||
CooldownType sessionPreference = session.getPreferencesCache().getCooldownPreference(); | ||
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 | ||
// Needs to be sent or no subtitle packet is recognized by the client | ||
SetTitlePacket titlePacket = new SetTitlePacket(); | ||
|
@@ -56,19 +63,20 @@ public static void sendCooldown(GeyserSession session) { | |
session.sendUpstreamPacket(titlePacket); | ||
session.setLastHitTime(System.currentTimeMillis()); | ||
long lastHitTime = session.getLastHitTime(); // Used later to prevent multiple scheduled cooldown threads | ||
computeCooldown(session, lastHitTime); | ||
computeCooldown(session, sessionPreference, lastHitTime); | ||
} | ||
|
||
/** | ||
* Keeps updating the cooldown until the bar is complete. | ||
* @param session GeyserSession | ||
* @param sessionPreference The type of cooldown the client prefers | ||
* @param lastHitTime The time of the last hit. Used to gauge how long the cooldown is taking. | ||
*/ | ||
private static void computeCooldown(GeyserSession session, long lastHitTime) { | ||
private static void computeCooldown(GeyserSession session, CooldownType sessionPreference, long lastHitTime) { | ||
if (session.isClosed()) return; // Don't run scheduled tasks if the client left | ||
if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one | ||
SetTitlePacket titlePacket = new SetTitlePacket(); | ||
if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { | ||
if (sessionPreference == CooldownType.ACTIONBAR) { | ||
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR); | ||
} else { | ||
titlePacket.setType(SetTitlePacket.Type.SUBTITLE); | ||
|
@@ -79,10 +87,10 @@ private static void computeCooldown(GeyserSession session, long lastHitTime) { | |
titlePacket.setStayTime(2); | ||
session.sendUpstreamPacket(titlePacket); | ||
if (hasCooldown(session)) { | ||
session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50 | ||
session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, sessionPreference, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50 | ||
} else { | ||
SetTitlePacket removeTitlePacket = new SetTitlePacket(); | ||
if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) { | ||
if (sessionPreference == CooldownType.ACTIONBAR) { | ||
removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR); | ||
} else { | ||
removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); | ||
|
@@ -149,7 +157,7 @@ public static CooldownType getByName(String name) { | |
return type; | ||
} | ||
} | ||
return DISABLED; | ||
return TITLE; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't do this because legacy configs that have their cooldown settings set to false will break. |
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,11 +57,24 @@ public static void buildForm(GeyserSession session) { | |
CustomFormBuilder builder = new CustomFormBuilder(LanguageUtils.getPlayerLocaleString("geyser.settings.title.main", language)); | ||
builder.setIcon(new FormImage(FormImage.FormImageType.PATH, "textures/ui/settings_glyph_color_2x.png")); | ||
|
||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config. | ||
if (!session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates()) { | ||
// Only show the client title if any of the client settings are available | ||
if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) { | ||
builder.addComponent(new LabelComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.title.client", language))); | ||
|
||
builder.addComponent(new ToggleComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.option.coordinates", language), session.getWorldCache().isPrefersShowCoordinates())); | ||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config. | ||
if (session.getPreferencesCache().isAllowShowCoordinates()) { | ||
builder.addComponent(new ToggleComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.option.coordinates", language), session.getPreferencesCache().isPrefersShowCoordinates())); | ||
} | ||
|
||
if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) { | ||
DropdownComponent cooldownDropdown = new DropdownComponent(); | ||
cooldownDropdown.setText("Attack Cooldown Animation"); | ||
cooldownDropdown.setOptions(new ArrayList<>()); | ||
Camotoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cooldownDropdown.addOption("Under Crosshair", session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.TITLE); | ||
cooldownDropdown.addOption("Action Bar", session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.ACTIONBAR); | ||
cooldownDropdown.addOption("Hide Animation", session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.DISABLED); | ||
builder.addComponent(cooldownDropdown); | ||
} | ||
} | ||
|
||
|
||
|
@@ -121,13 +134,23 @@ public static boolean handleSettingsForm(GeyserSession session, String response) | |
} | ||
int offset = 0; | ||
|
||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config. | ||
if (!session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates()) { | ||
if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) { | ||
offset++; // Client settings title | ||
|
||
session.getWorldCache().setPrefersShowCoordinates(settingsResponse.getToggleResponses().get(offset)); | ||
session.getWorldCache().updateShowCoordinates(); | ||
offset++; | ||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config. | ||
if (session.getPreferencesCache().isAllowShowCoordinates()) { | ||
session.getPreferencesCache().setPrefersShowCoordinates(settingsResponse.getToggleResponses().get(offset)); | ||
session.getPreferencesCache().updateShowCoordinates(); | ||
offset++; | ||
} | ||
|
||
if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) { | ||
CooldownUtils.CooldownType cooldownType = CooldownUtils.CooldownType.values()[settingsResponse.getDropdownResponses().get(offset).getElementID()]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use CooldownType.VALUES here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, I wasn't sure if there was a significant difference There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the same apply to the gamemode and difficulty stuff below this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not believe those have a VALUES static field. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the gamerule enum is ours, but the VALUES static field is private. the difficulty enum is mcprotocollibs and doesn't have one. not sure if this is going out of the scope of this pr |
||
if (cooldownType != null) { | ||
Camotoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
session.getPreferencesCache().setCooldownPreference(cooldownType); | ||
} | ||
offset++; | ||
} | ||
} | ||
|
||
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.server")) { | ||
|
+0 −18 | run-help/be_BY.txt | |
+6 −5 | run-help/hi_IN.txt | |
+0 −192 | texts/be_BY.properties | |
+1 −1 | texts/da_DK.properties | |
+50 −50 | texts/de_DE.properties | |
+0 −2 | texts/en_US.properties | |
+8 −8 | texts/es_ES.properties | |
+8 −8 | texts/es_MX.properties | |
+161 −161 | texts/hi_IN.properties | |
+5 −5 | texts/id_ID.properties | |
+1 −1 | texts/ko_KR.properties | |
+44 −44 | texts/pl_PL.properties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be the Lombok call, and can just be
preferencesCache.updateShowCoordinates()