mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
parent
50896a24e7
commit
86c0c009e7
5 changed files with 145 additions and 10 deletions
|
@ -28,6 +28,7 @@ package org.geysermc.connector.entity.player;
|
|||
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
|
@ -37,10 +38,7 @@ import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
|
|||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
|
||||
import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
@ -50,7 +48,10 @@ import org.geysermc.connector.entity.living.animal.tameable.ParrotEntity;
|
|||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||
import org.geysermc.connector.scoreboard.Objective;
|
||||
import org.geysermc.connector.scoreboard.Score;
|
||||
import org.geysermc.connector.scoreboard.Team;
|
||||
import org.geysermc.connector.scoreboard.UpdateType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
@ -85,6 +86,12 @@ public class PlayerEntity extends LivingEntity {
|
|||
|
||||
@Override
|
||||
public void spawnEntity(GeyserSession session) {
|
||||
// Check to see if the player should have a belowname counterpart added
|
||||
Objective objective = session.getWorldCache().getScoreboard().getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME);
|
||||
if (objective != null) {
|
||||
setBelowNameText(session, objective);
|
||||
}
|
||||
|
||||
AddPlayerPacket addPlayerPacket = new AddPlayerPacket();
|
||||
addPlayerPacket.setUuid(uuid);
|
||||
addPlayerPacket.setUsername(username);
|
||||
|
@ -326,4 +333,34 @@ public class PlayerEntity extends LivingEntity {
|
|||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
|
||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, height);
|
||||
}
|
||||
|
||||
public void setBelowNameText(GeyserSession session, Objective objective) {
|
||||
if (objective != null && objective.getUpdateType() != UpdateType.REMOVE) {
|
||||
int amount;
|
||||
Score score = objective.getScores().get(username);
|
||||
if (score != null) {
|
||||
amount = score.getCurrentData().getScore();
|
||||
} else {
|
||||
amount = 0;
|
||||
}
|
||||
String displayString = amount + " " + objective.getDisplayName();
|
||||
|
||||
metadata.put(EntityData.SCORE_TAG, displayString);
|
||||
if (valid) {
|
||||
// Already spawned - we still need to run the rest of this code because the spawn packet will be
|
||||
// providing the information
|
||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.getMetadata().put(EntityData.SCORE_TAG, displayString);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
} else {
|
||||
if (valid && metadata.remove(EntityData.SCORE_TAG) != null) {
|
||||
SetEntityDataPacket packet = new SetEntityDataPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.getMetadata().put(EntityData.SCORE_TAG, "");
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,6 +138,10 @@ public class EntityCache {
|
|||
return playerEntities.remove(uuid);
|
||||
}
|
||||
|
||||
public Collection<PlayerEntity> getAllPlayerEntities() {
|
||||
return playerEntities.values();
|
||||
}
|
||||
|
||||
public void addBossBar(UUID uuid, BossBar bossBar) {
|
||||
bossBars.put(uuid, bossBar);
|
||||
bossBar.addBossBar();
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
package org.geysermc.connector.network.translators.java.scoreboard;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ObjectiveAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.GeyserLogger;
|
||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.session.cache.WorldCache;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -63,7 +65,20 @@ public class JavaScoreboardObjectiveTranslator extends PacketTranslator<ServerSc
|
|||
switch (packet.getAction()) {
|
||||
case ADD, UPDATE -> objective.setDisplayName(MessageTranslator.convertMessage(packet.getDisplayName()))
|
||||
.setType(packet.getType().ordinal());
|
||||
case REMOVE -> scoreboard.unregisterObjective(packet.getName());
|
||||
case REMOVE -> {
|
||||
scoreboard.unregisterObjective(packet.getName());
|
||||
if (objective != null && objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME)) {
|
||||
// Clear the score tag from all players
|
||||
for (PlayerEntity entity : session.getEntityCache().getAllPlayerEntities()) {
|
||||
if (!entity.isValid()) {
|
||||
// Player hasn't spawned yet - don't bother
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.setBelowNameText(session, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (objective == null || !objective.isActive()) {
|
||||
|
|
|
@ -26,9 +26,13 @@
|
|||
package org.geysermc.connector.network.translators.java.scoreboard;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.GeyserLogger;
|
||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.session.cache.WorldCache;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
|
@ -58,19 +62,40 @@ public class JavaUpdateScoreTranslator extends PacketTranslator<ServerUpdateScor
|
|||
return;
|
||||
}
|
||||
|
||||
// If this is the objective that is in use to show the below name text, we need to update the player
|
||||
// attached to this score.
|
||||
boolean isBelowName = objective != null && objective == scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME);
|
||||
|
||||
switch (packet.getAction()) {
|
||||
case ADD_OR_UPDATE:
|
||||
case ADD_OR_UPDATE -> {
|
||||
objective.setScore(packet.getEntry(), packet.getValue());
|
||||
break;
|
||||
case REMOVE:
|
||||
if (isBelowName) {
|
||||
// Update the below name score on this player
|
||||
setBelowName(session, objective, packet.getEntry(), packet.getValue());
|
||||
}
|
||||
}
|
||||
case REMOVE -> {
|
||||
if (packet.getObjective().isEmpty()) {
|
||||
// An empty objective name means all scores are reset for that player (/scoreboard players reset PLAYERNAME)
|
||||
Objective belowName = scoreboard.getObjectiveSlots().get(ScoreboardPosition.BELOW_NAME);
|
||||
if (belowName != null) {
|
||||
setBelowName(session, belowName, packet.getEntry(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (objective != null) {
|
||||
objective.removeScore(packet.getEntry());
|
||||
|
||||
if (isBelowName) {
|
||||
// Update the score on this player to now reflect 0
|
||||
setBelowName(session, objective, packet.getEntry(), 0);
|
||||
}
|
||||
} else {
|
||||
for (Objective objective1 : scoreboard.getObjectives()) {
|
||||
objective1.removeScore(packet.getEntry());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ScoreboardUpdater will handle it for us if the packets per second
|
||||
|
@ -79,4 +104,43 @@ public class JavaUpdateScoreTranslator extends PacketTranslator<ServerUpdateScor
|
|||
scoreboard.onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objective the objective that currently resides on the below name display slot
|
||||
*/
|
||||
private void setBelowName(GeyserSession session, Objective objective, String username, int count) {
|
||||
PlayerEntity entity = getPlayerEntity(session, username);
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String displayString = count + " " + objective.getDisplayName();
|
||||
|
||||
// Of note: unlike Bedrock, if there is an objective in the below name slot, everyone has a display
|
||||
entity.getMetadata().put(EntityData.SCORE_TAG, displayString);
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().put(EntityData.SCORE_TAG, displayString);
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
}
|
||||
|
||||
private PlayerEntity getPlayerEntity(GeyserSession session, String username) {
|
||||
// We don't care about the session player, because... they're not going to be seeing their own score
|
||||
if (session.getPlayerEntity().getUsername().equals(username)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (PlayerEntity entity : session.getEntityCache().getAllPlayerEntities()) {
|
||||
if (entity.getUsername().equals(username)) {
|
||||
if (entity.isValid()) {
|
||||
return entity;
|
||||
} else {
|
||||
// The below name text will be applied on spawn
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.packet.SetScorePacket;
|
|||
import lombok.Getter;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.GeyserLogger;
|
||||
import org.geysermc.connector.entity.player.PlayerEntity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
|
@ -49,7 +50,8 @@ public final class Scoreboard {
|
|||
private final AtomicLong nextId = new AtomicLong(0);
|
||||
|
||||
private final Map<String, Objective> objectives = new ConcurrentHashMap<>();
|
||||
private final Map<ScoreboardPosition, Objective> objectiveSlots = new HashMap<>();
|
||||
@Getter
|
||||
private final Map<ScoreboardPosition, Objective> objectiveSlots = new EnumMap<>(ScoreboardPosition.class);
|
||||
private final Map<String, Team> teams = new ConcurrentHashMap<>(); // updated on multiple threads
|
||||
|
||||
private int lastAddScoreCount = 0;
|
||||
|
@ -103,6 +105,19 @@ public final class Scoreboard {
|
|||
objective.pendingRemove();
|
||||
}
|
||||
objectiveSlots.put(displaySlot, objective);
|
||||
|
||||
if (displaySlot == ScoreboardPosition.BELOW_NAME) {
|
||||
// Display the below name score option to all players
|
||||
// Of note: unlike Bedrock, if there is an objective in the below name slot, everyone has a display
|
||||
for (PlayerEntity entity : session.getEntityCache().getAllPlayerEntities()) {
|
||||
if (!entity.isValid()) {
|
||||
// Player hasn't spawned yet - don't bother, it'll be done then
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.setBelowNameText(session, objective);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Team registerNewTeam(String teamName, String[] players) {
|
||||
|
|
Loading…
Reference in a new issue