Geyser/core/src/main/java/org/geysermc/geyser/session/cache/WorldCache.java

188 lines
6.8 KiB
Java
Raw Normal View History

2019-07-30 02:57:43 +00:00
/*
2022-01-01 19:03:05 +00:00
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
2019-07-30 02:57:43 +00:00
*
* 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.session.cache;
2019-07-30 02:57:43 +00:00
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
2019-07-30 02:57:43 +00:00
import lombok.Getter;
import lombok.Setter;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.packet.SetTitlePacket;
import org.geysermc.geyser.scoreboard.Scoreboard;
import org.geysermc.geyser.scoreboard.ScoreboardUpdater.ScoreboardSession;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.ChunkUtils;
import java.util.Iterator;
2019-07-30 02:57:43 +00:00
public final class WorldCache {
2021-11-22 19:52:26 +00:00
private final GeyserSession session;
@Getter
private final ScoreboardSession scoreboardSession;
@Getter
private Scoreboard scoreboard;
@Getter
@Setter
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;
private int currentSequence;
private final Object2IntMap<Vector3i> unverifiedPredictions = new Object2IntOpenHashMap<>(1);
2023-05-18 00:11:14 +00:00
@Getter
@Setter
private boolean editingSignOnFront;
2021-11-22 19:52:26 +00:00
public WorldCache(GeyserSession session) {
2019-07-30 02:57:43 +00:00
this.session = session;
this.scoreboard = new Scoreboard(session);
scoreboardSession = new ScoreboardSession(session);
resetTitleTimes(false);
2019-07-30 02:57:43 +00:00
}
public void removeScoreboard() {
if (scoreboard != null) {
scoreboard.removeScoreboard();
Scoreboard improvements (#1166) * Added a way to check if debug logging is enabled * Improved scoreboard performance * Include Teams in pps and return pending pps instead when higher then pps Some servers have a huge amount of score packets when the player logs in, but before this commit, only after the first high pps (packets per second) the ScoreboardUpdater will be used (after pending packets per second have been moved to packets per second). But this commit fixes that the ScoreboardUpdater can be used on the second that the pps is getting high. * Fixed team pre + suffix "null" issue and added threshold config option Fixed team pre + suffix "null" issue. When the prefix and/or suffix of a Team is null, "null" will be returned instead of null (Due to the way that MCProtocolLib is made and designed). This is fixed by simply checking if the prefix and/or suffix equal "null" and if that is the case, replace it with "". Added threshold option. Gave the person who is running Geyser an option to specify the first Scoreboard packets per second threshold to further improve performance by lowering the setting or decrease performance by relaxing the setting a bit. The value can't be higher then 250 (the second threshold), because it'll always choose the lowest threshold. * Forgot to bump config version * Small changes * Reverted version bump, changed Sponge config, changed FloodgateKeyLoader Reverted version bump Camotoy said that you only need to bump the config version if the change is breaking, the config version bump has been reverted. Changed Sponge config The Sponge config has been modified to look like the other platform configurations. Changed FloodgateKeyLoader * Changed default-locale and (remote) address as requested by Camotoy * Reduce bandwidth and a few final tweaks * Made the scoreboard-packet-threshold a bit higher due to improvements
2020-08-28 15:47:52 +00:00
scoreboard = new Scoreboard(session);
}
2019-07-30 02:57:43 +00:00
}
Scoreboard improvements (#1166) * Added a way to check if debug logging is enabled * Improved scoreboard performance * Include Teams in pps and return pending pps instead when higher then pps Some servers have a huge amount of score packets when the player logs in, but before this commit, only after the first high pps (packets per second) the ScoreboardUpdater will be used (after pending packets per second have been moved to packets per second). But this commit fixes that the ScoreboardUpdater can be used on the second that the pps is getting high. * Fixed team pre + suffix "null" issue and added threshold config option Fixed team pre + suffix "null" issue. When the prefix and/or suffix of a Team is null, "null" will be returned instead of null (Due to the way that MCProtocolLib is made and designed). This is fixed by simply checking if the prefix and/or suffix equal "null" and if that is the case, replace it with "". Added threshold option. Gave the person who is running Geyser an option to specify the first Scoreboard packets per second threshold to further improve performance by lowering the setting or decrease performance by relaxing the setting a bit. The value can't be higher then 250 (the second threshold), because it'll always choose the lowest threshold. * Forgot to bump config version * Small changes * Reverted version bump, changed Sponge config, changed FloodgateKeyLoader Reverted version bump Camotoy said that you only need to bump the config version if the change is breaking, the config version bump has been reverted. Changed Sponge config The Sponge config has been modified to look like the other platform configurations. Changed FloodgateKeyLoader * Changed default-locale and (remote) address as requested by Camotoy * Reduce bandwidth and a few final tweaks * Made the scoreboard-packet-threshold a bit higher due to improvements
2020-08-28 15:47:52 +00:00
public int increaseAndGetScoreboardPacketsPerSecond() {
int pendingPps = scoreboardSession.getPendingPacketsPerSecond().incrementAndGet();
int pps = scoreboardSession.getPacketsPerSecond();
Scoreboard improvements (#1166) * Added a way to check if debug logging is enabled * Improved scoreboard performance * Include Teams in pps and return pending pps instead when higher then pps Some servers have a huge amount of score packets when the player logs in, but before this commit, only after the first high pps (packets per second) the ScoreboardUpdater will be used (after pending packets per second have been moved to packets per second). But this commit fixes that the ScoreboardUpdater can be used on the second that the pps is getting high. * Fixed team pre + suffix "null" issue and added threshold config option Fixed team pre + suffix "null" issue. When the prefix and/or suffix of a Team is null, "null" will be returned instead of null (Due to the way that MCProtocolLib is made and designed). This is fixed by simply checking if the prefix and/or suffix equal "null" and if that is the case, replace it with "". Added threshold option. Gave the person who is running Geyser an option to specify the first Scoreboard packets per second threshold to further improve performance by lowering the setting or decrease performance by relaxing the setting a bit. The value can't be higher then 250 (the second threshold), because it'll always choose the lowest threshold. * Forgot to bump config version * Small changes * Reverted version bump, changed Sponge config, changed FloodgateKeyLoader Reverted version bump Camotoy said that you only need to bump the config version if the change is breaking, the config version bump has been reverted. Changed Sponge config The Sponge config has been modified to look like the other platform configurations. Changed FloodgateKeyLoader * Changed default-locale and (remote) address as requested by Camotoy * Reduce bandwidth and a few final tweaks * Made the scoreboard-packet-threshold a bit higher due to improvements
2020-08-28 15:47:52 +00:00
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;
// The translator will sync this for us
titleTimesNeedReset = false;
}
/**
* If needed, ensure that the Bedrock client will use the correct timings for titles.
*/
public void synchronizeCorrectTitleTimes() {
if (titleTimesNeedReset) {
forceSyncCorrectTitleTimes();
}
}
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);
titleTimesNeedReset = false;
}
/**
* 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();
}
}
/* Code to support the prediction structure introduced in Java Edition 1.19.0
Blocks can be rolled back if invalid, but this requires some client-side information storage. */
/**
* This does not need to be called for all player action packets (as of 1.19.2) and can be set to 0 if blocks aren't
* changed in the action.
*/
public int nextPredictionSequence() {
return ++currentSequence;
}
/**
* Stores a note that this position may need to be rolled back at a future point in time.
*/
public void markPositionInSequence(Vector3i position) {
if (session.isEmulatePost1_18Logic()) {
// Cheap hack
// On non-Bukkit platforms, ViaVersion will always confirm the sequence before the block is updated,
// meaning we'd send two block updates after (ChunkUtils.updateBlockClientSide in endPredictionsUpTo
// and the packet updating from the client)
this.unverifiedPredictions.put(position, currentSequence);
}
}
public void updateServerCorrectBlockState(Vector3i position, int blockState) {
if (!this.unverifiedPredictions.isEmpty()) {
this.unverifiedPredictions.removeInt(position);
}
ChunkUtils.updateBlock(session, blockState, position);
}
public void endPredictionsUpTo(int sequence) {
if (this.unverifiedPredictions.isEmpty()) {
return;
}
Iterator<Object2IntMap.Entry<Vector3i>> it = Object2IntMaps.fastIterator(this.unverifiedPredictions);
while (it.hasNext()) {
Object2IntMap.Entry<Vector3i> entry = it.next();
if (entry.getIntValue() <= sequence) {
// This block may be out of sync with the server
// In 1.19.0 Java, you can verify this by trying to mine in spawn protection
Vector3i position = entry.getKey();
ChunkUtils.updateBlockClientSide(session, session.getGeyser().getWorldManager().getBlockAt(session, position), position);
it.remove();
}
}
}
2019-07-30 02:57:43 +00:00
}