Skip to content
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

Handle ClientboundTickingStatePacket correctly and fix Throwable Scales #4850

Merged
merged 52 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3d957e3
Proper tick rate handling
letsgoawaydev Jul 12, 2024
91a1a12
Fix frozen variable getter
letsgoawaydev Jul 13, 2024
83fab59
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 13, 2024
8418691
Fix formatting i think third attempt
letsgoawaydev Jul 13, 2024
fc04909
Formatting fix attempt 5 fsdiofhsdioufhvuisdhviuo9ds
letsgoawaydev Jul 13, 2024
f83e2fb
Fix stuff, also fixed the sizing of throwables as they were to big
letsgoawaydev Jul 13, 2024
4fd9cbe
Move update ticking state
letsgoawaydev Jul 13, 2024
dc130eb
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 14, 2024
d20b18a
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 15, 2024
0eb9134
Update core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
letsgoawaydev Jul 18, 2024
b2a5cd5
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 23, 2024
b8b0517
Fixes for spaces and documentation
letsgoawaydev Jul 24, 2024
02c0469
Missed a space
letsgoawaydev Jul 24, 2024
611b010
wait now ive fixed it
letsgoawaydev Jul 24, 2024
4f345c0
Fix languages
letsgoawaydev Jul 24, 2024
046d287
try again to fix languages
letsgoawaydev Jul 24, 2024
2da5599
Fix Java doc comments for tickable interface
letsgoawaydev Jul 25, 2024
09bfe4b
Fix javadoc comment in Geyser Session
letsgoawaydev Jul 25, 2024
dadd5ba
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 26, 2024
e86d11c
fix comment
letsgoawaydev Jul 26, 2024
8d4f259
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 28, 2024
0ce7240
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 29, 2024
e348d3e
fix some tick rate stuffs
letsgoawaydev Jul 29, 2024
7af831f
Fix build fail
letsgoawaydev Jul 30, 2024
c5f1f83
Merge branch 'master' into tick-rate-handling
letsgoawaydev Jul 31, 2024
e78568d
Merge branch 'master' into tick-rate-handling
letsgoawaydev Aug 6, 2024
ad3990b
Merge branch 'master' into tick-rate-handling
letsgoawaydev Aug 9, 2024
99e7385
fix some stuff
letsgoawaydev Aug 10, 2024
089d96c
Merge branch 'tick-rate-handling' of https://github.com/letsgoawaydev…
letsgoawaydev Aug 10, 2024
bd27743
Merge remote-tracking branch 'upstream/master' into tick-rate-handling
letsgoawaydev Aug 16, 2024
27de994
Merge remote-tracking branch 'upstream/master' into tick-rate-handling
letsgoawaydev Aug 16, 2024
e5a2ae4
merge
letsgoawaydev Aug 16, 2024
807881f
test
letsgoawaydev Aug 16, 2024
3602fc2
Update languages
letsgoawaydev Aug 16, 2024
21b87c8
Update mappings
letsgoawaydev Aug 16, 2024
dd40bb1
Merge branch 'master' into tick-rate-handling
letsgoawaydev Aug 31, 2024
079c4e6
delete broken stuff
letsgoawaydev Aug 31, 2024
90a0119
Fix cooldown
letsgoawaydev Aug 31, 2024
dcc3dce
fix cooldowns
letsgoawaydev Aug 31, 2024
4fc1d66
Update core/src/main/java/org/geysermc/geyser/util/CooldownUtils.java
letsgoawaydev Aug 31, 2024
4784e92
Merge remote-tracking branch 'upstream/master' into tick-rate-handling
letsgoawaydev Dec 7, 2024
c1dce5c
Update BoatEntity.java
letsgoawaydev Dec 7, 2024
8e26f57
Update GeyserSession.java
letsgoawaydev Dec 7, 2024
7f32afd
fix some stuff
letsgoawaydev Dec 7, 2024
c36b317
Update CooldownUtils.java
letsgoawaydev Dec 7, 2024
56cfe3b
fix some accidental formatting issues
letsgoawaydev Dec 7, 2024
26dafbe
Fix missing inport
letsgoawaydev Dec 7, 2024
01aaeba
Update GeyserSession.java
letsgoawaydev Dec 7, 2024
0a7e2f0
Update core/src/main/java/org/geysermc/geyser/entity/type/LivingEntit…
letsgoawaydev Dec 7, 2024
2d8d6c3
Update core/src/main/java/org/geysermc/geyser/entity/type/ThrowableIt…
letsgoawaydev Dec 7, 2024
a010f10
Fix missing import
letsgoawaydev Dec 8, 2024
a50368a
Merge branch 'master' into tick-rate-handling
letsgoawaydev Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public InteractionResult interact(Hand hand) {
@Override
public void tick() {
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
doTick = !doTick; // Run every 100 ms
doTick = !doTick; // Run every other tick
if (!doTick || passengers.isEmpty()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,4 @@ protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttrib
return type.getAttribute((float) AttributeUtils.calculateValue(javaAttribute));
}
}

letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@

package org.geysermc.geyser.entity.type;

import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;

import java.util.UUID;

Expand All @@ -48,6 +48,10 @@ public ThrowableItemEntity(GeyserSession session, int entityId, long geyserId, U
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
setFlag(EntityFlag.INVISIBLE, true);
invisible = false;
if (session.isFrozen()) {
age = 4;
checkVisibility();
}
}
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved

private void checkVisibility() {
Expand Down
98 changes: 55 additions & 43 deletions core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
/**
* Stores cookies sent by the Java server.
*/
@Setter @Getter
@Setter
@Getter
private Map<String, byte[]> cookies = new Object2ObjectOpenHashMap<>();
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved

private final GeyserCameraData cameraData;
Expand All @@ -559,6 +560,10 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {

private MinecraftProtocol protocol;

private float tickRate = 20.0f;

private boolean frozen = false;
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved

public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) {
this.geyser = geyser;
this.upstream = new UpstreamSession(bedrockServerSession);
Expand Down Expand Up @@ -656,7 +661,7 @@ public void connect() {
// Default move speed
// Bedrock clients move very fast by default until they get an attribute packet correcting the speed
attributesPacket.setAttributes(Collections.singletonList(
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
GeyserAttributeType.MOVEMENT_SPEED.getAttribute()));
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
upstream.sendPacket(attributesPacket);

GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
Expand Down Expand Up @@ -759,7 +764,7 @@ public void authenticateWithMicrosoftCode(boolean offlineAccess) {
sendUpstreamPacket(packet);

final PendingMicrosoftAuthentication.AuthenticationTask task = geyser.getPendingMicrosoftAuthentication().getOrCreateTask(
getAuthData().xuid()
getAuthData().xuid()
);
task.setOnline(true);
task.resetTimer();
Expand Down Expand Up @@ -800,13 +805,13 @@ public boolean onMicrosoftLoginComplete(PendingMicrosoftAuthentication.Authentic
GameProfile selectedProfile = service.getSelectedProfile();
if (selectedProfile == null) {
disconnect(GeyserLocale.getPlayerLocaleString(
"geyser.network.remote.invalid_account",
clientData.getLanguageCode()
"geyser.network.remote.invalid_account",
clientData.getLanguageCode()
));
} else {
this.protocol = new MinecraftProtocol(
selectedProfile,
service.getAccessToken()
selectedProfile,
service.getAccessToken()
);
try {
connectDownstream();
Expand All @@ -831,7 +836,7 @@ private void connectDownstream() {
GeyserImpl.getInstance().eventBus().fire(loginEvent);
if (loginEvent.isCancelled()) {
String disconnectReason = loginEvent.disconnectReason() == null ?
BedrockDisconnectReasons.DISCONNECTED : loginEvent.disconnectReason();
BedrockDisconnectReasons.DISCONNECTED : loginEvent.disconnectReason();
disconnect(disconnectReason);
return;
}
Expand All @@ -841,16 +846,16 @@ private void connectDownstream() {
boolean floodgate = this.remoteServer.authType() == AuthType.FLOODGATE;

// Start ticking
tickThread = eventLoop.scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS);
tickThread = eventLoop.scheduleAtFixedRate(this::tick, Math.round(1000 / tickRate), Math.round(1000 / tickRate), TimeUnit.MILLISECONDS);

this.protocol.setUseDefaultListeners(false);

TcpSession downstream;
if (geyser.getBootstrap().getSocketAddress() != null) {
// We're going to connect through the JVM and not through TCP
downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(),
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
this.protocol, this.protocol.createHelper());
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
this.protocol, this.protocol.createHelper());
this.downstream = new DownstreamSession(downstream);
} else {
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol);
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -917,16 +922,16 @@ public void packetSending(PacketSendingEvent event) {
}

encryptedData = cipher.encryptFromString(BedrockData.of(
clientData.getGameVersion(),
authData.name(),
authData.xuid(),
clientData.getDeviceOs().ordinal(),
clientData.getLanguageCode(),
clientData.getUiProfile().ordinal(),
clientData.getCurrentInputMode().ordinal(),
bedrockAddress,
skinUploader.getId(),
skinUploader.getVerifyCode()
clientData.getGameVersion(),
authData.name(),
authData.xuid(),
clientData.getDeviceOs().ordinal(),
clientData.getLanguageCode(),
clientData.getUiProfile().ordinal(),
clientData.getCurrentInputMode().ordinal(),
bedrockAddress,
skinUploader.getId(),
skinUploader.getVerifyCode()
).toString());
} catch (Exception e) {
geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.encrypt_fail"), e);
Expand Down Expand Up @@ -960,11 +965,11 @@ public void connected(ConnectedEvent event) {
if (downstream instanceof LocalSession) {
// Connected directly to the server
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.remote.connect_internal",
authData.name(), protocol.getProfile().getName()));
authData.name(), protocol.getProfile().getName()));
} else {
// Connected to an IP address
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.remote.connect",
authData.name(), protocol.getProfile().getName(), remoteServer.address()));
authData.name(), protocol.getProfile().getName(), remoteServer.address()));
}

UUID uuid = protocol.getProfile().getId();
Expand Down Expand Up @@ -1004,10 +1009,10 @@ public void disconnected(DisconnectedEvent event) {
disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.authentication_type_mismatch", locale());
// Explain that they may be looking for Floodgate.
geyser.getLogger().warning(GeyserLocale.getLocaleStringLog(
geyser.getPlatformType() == PlatformType.STANDALONE ?
"geyser.network.remote.floodgate_explanation_standalone"
: "geyser.network.remote.floodgate_explanation_plugin",
Constants.FLOODGATE_DOWNLOAD_LOCATION
geyser.getPlatformType() == PlatformType.STANDALONE ?
"geyser.network.remote.floodgate_explanation_standalone"
: "geyser.network.remote.floodgate_explanation_plugin",
Constants.FLOODGATE_DOWNLOAD_LOCATION
));
} else {
// Likely that Floodgate is not configured correctly.
Expand Down Expand Up @@ -1070,6 +1075,13 @@ public void packetError(PacketErrorEvent event) {
downstream.connect(false, loginEvent.transferring());
}

public void updateTickData(float tickRate, boolean frozen) {
tickThread.cancel(true);
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
this.tickRate = tickRate;
this.frozen = frozen;
tickThread = eventLoop.scheduleAtFixedRate(this::tick, Math.round(1000 / getTickRate()), Math.round(1000 / getTickRate()), TimeUnit.MILLISECONDS);
}

public void disconnect(String reason) {
if (!closed) {
loggedIn = false;
Expand Down Expand Up @@ -1159,7 +1171,7 @@ public ScheduledFuture<?> scheduleInEventLoop(Runnable runnable, long duration,
}

/**
* Called every 50 milliseconds - one Minecraft tick.
* Called every Minecraft tick - 1000/tickRate milliseconds.
*/
protected void tick() {
try {
Expand All @@ -1171,7 +1183,7 @@ protected void tick() {
// A null return value cancels the packet
if (position != null) {
ServerboundMovePlayerPosPacket packet = new ServerboundMovePlayerPosPacket(playerEntity.isOnGround(),
position.getX(), position.getY(), position.getZ());
position.getX(), position.getY(), position.getZ());
sendDownstreamGamePacket(packet);
}
lastMovementTimestamp = System.currentTimeMillis();
Expand All @@ -1197,11 +1209,11 @@ protected void tick() {
isInWorldBorderWarningArea = false;
}


for (Tickable entity : entityCache.getTickableEntities()) {
entity.tick();
if (!isFrozen()) {
letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
for (Tickable entity : entityCache.getTickableEntities()) {
entity.tick();
}
}

letsgoawaydev marked this conversation as resolved.
Show resolved Hide resolved
if (armAnimationTicks >= 0) {
// As of 1.18.2 Java Edition, it appears that the swing time is dynamically updated depending on the
// player's effect status, but the animation can cut short if the duration suddenly decreases
Expand Down Expand Up @@ -1316,7 +1328,7 @@ public void setGameMode(GameMode newGamemode) {
*/
public void useItem(Hand hand) {
sendDownstreamGamePacket(new ServerboundUseItemPacket(
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
}

/**
Expand Down Expand Up @@ -1365,7 +1377,7 @@ public void armSwingPending() {
private boolean disableBlocking() {
if (playerEntity.getFlag(EntityFlag.BLOCKING)) {
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM,
Vector3i.ZERO, Direction.DOWN, 0);
Vector3i.ZERO, Direction.DOWN, 0);
sendDownstreamGamePacket(releaseItemPacket);
playerEntity.setFlag(EntityFlag.BLOCKING, false);
return true;
Expand All @@ -1375,7 +1387,7 @@ private boolean disableBlocking() {

public void requestOffhandSwap() {
ServerboundPlayerActionPacket swapHandsPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, Vector3i.ZERO,
Direction.DOWN, 0);
Direction.DOWN, 0);
sendDownstreamGamePacket(swapHandsPacket);
}

Expand Down Expand Up @@ -1584,7 +1596,7 @@ public void confirmTeleport(Vector3d position) {
unconfirmedTeleport.resetUnconfirmedFor();
geyser.getLogger().debug("Resending teleport " + unconfirmedTeleport.getTeleportConfirmId());
getPlayerEntity().moveAbsolute(Vector3f.from(unconfirmedTeleport.getX(), unconfirmedTeleport.getY(), unconfirmedTeleport.getZ()),
unconfirmedTeleport.getYaw(), unconfirmedTeleport.getPitch(), playerEntity.isOnGround(), true);
unconfirmedTeleport.getYaw(), unconfirmedTeleport.getPitch(), playerEntity.isOnGround(), true);
}
}

Expand Down Expand Up @@ -1711,7 +1723,7 @@ public void setDaylightCycle(boolean doCycle) {
* Send a gamerule value to the client
*
* @param gameRule The gamerule to send
* @param value The value of the gamerule
* @param value The value of the gamerule
*/
public void sendGameRule(String gameRule, Object value) {
GameRulesChangedPacket gameRulesChangedPacket = new GameRulesChangedPacket();
Expand Down Expand Up @@ -1850,8 +1862,8 @@ private int getRenderDistance() {
*/
public void sendJavaClientSettings() {
ServerboundClientInformationPacket clientSettingsPacket = new ServerboundClientInformationPacket(locale(),
getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS,
HandPreference.RIGHT_HAND, false, true);
getRenderDistance(), ChatVisibility.FULL, true, SKIN_PARTS,
HandPreference.RIGHT_HAND, false, true);
sendDownstreamPacket(clientSettingsPacket);
}

Expand Down Expand Up @@ -1904,8 +1916,8 @@ public float getEyeHeight() {
return switch (pose) {
case SNEAKING -> 1.27f;
case SWIMMING,
FALL_FLYING, // Elytra
SPIN_ATTACK -> 0.4f; // Trident spin attack
FALL_FLYING, // Elytra
SPIN_ATTACK -> 0.4f; // Trident spin attack
case SLEEPING -> 0.2f;
default -> EntityDefinitions.PLAYER.offset();
};
Expand All @@ -1923,7 +1935,7 @@ public float getEyeHeight() {

@Override
public UUID javaUuid() {
return playerEntity != null ? playerEntity.getUuid() : null ;
return playerEntity != null ? playerEntity.getUuid() : null;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 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.geyser.translator.protocol.java;

import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundTickingStatePacket;

@Translator(packet = ClientboundTickingStatePacket.class)
public class JavaTickingStateTranslator extends PacketTranslator<ClientboundTickingStatePacket> {

@Override
public void translate(GeyserSession session, ClientboundTickingStatePacket packet) {
session.updateTickData(packet.getTickRate(), packet.isFrozen());
}
}