3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-12-25 15:50:19 +01:00

Properly handle scoreboard removal while switching between servers

Dieser Commit ist enthalten in:
Andrew Steinborn 2018-07-30 18:21:25 -04:00
Ursprung 972ef73d35
Commit 2d4d9e42b5
4 geänderte Dateien mit 115 neuen und 16 gelöschten Zeilen

Datei anzeigen

@ -60,8 +60,11 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
}
} else {
// Just forward the packet on. We don't have anything to handle at this time.
if (packet.getClass().getName().contains("Scoreboard")) {
System.out.println(packet);
if (packet instanceof ScoreboardTeam ||
packet instanceof ScoreboardObjective ||
packet instanceof ScoreboardSetScore ||
packet instanceof ScoreboardDisplay) {
playerHandler.handleServerScoreboardPacket(packet);
}
connection.getProxyPlayer().getConnection().write(packet);
}

Datei anzeigen

@ -3,7 +3,10 @@ package com.velocitypowered.proxy.connection.client;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.backend.ServerConnection;
import com.velocitypowered.proxy.data.ServerInfo;
import com.velocitypowered.proxy.data.scoreboard.Objective;
import com.velocitypowered.proxy.data.scoreboard.Score;
import com.velocitypowered.proxy.data.scoreboard.Scoreboard;
import com.velocitypowered.proxy.data.scoreboard.Team;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packets.*;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
@ -149,6 +152,9 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
}
serverBossBars.clear();
// Remove scoreboard junk.
clearServerScoreboard();
// Tell the server about this client's plugin messages. Velocity will forward them on to the client.
if (!clientPluginMsgChannels.isEmpty()) {
player.getConnectedServer().getChannel().delayedWrite(
@ -218,6 +224,86 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
}
}
public void handleServerScoreboardPacket(MinecraftPacket packet) {
logger.info("Server scoreboard packet: {}", packet);
if (packet instanceof ScoreboardDisplay) {
ScoreboardDisplay sd = (ScoreboardDisplay) packet;
serverScoreboard.setPosition(sd.getPosition());
serverScoreboard.setDisplayName(sd.getDisplayName());
}
if (packet instanceof ScoreboardObjective) {
ScoreboardObjective so = (ScoreboardObjective) packet;
if (so.getMode() == 0) {
Objective o = new Objective(so.getId());
o.setDisplayName(so.getDisplayName());
o.setType(so.getType());
serverScoreboard.getObjectives().put(so.getId(), o);
} else {
serverScoreboard.getObjectives().remove(so.getId());
}
}
if (packet instanceof ScoreboardSetScore) {
ScoreboardSetScore sss = (ScoreboardSetScore) packet;
Objective objective = serverScoreboard.getObjectives().get(sss.getObjective());
if (objective == null) {
return;
}
switch (sss.getAction()) {
case 0:
Score score = new Score(sss.getEntity(), sss.getValue());
objective.getScores().put(sss.getEntity(), score);
break;
case 1:
objective.getScores().remove(sss.getEntity());
break;
}
}
if (packet instanceof ScoreboardTeam) {
ScoreboardTeam st = (ScoreboardTeam) packet;
switch (st.getMode()) {
case 0:
// TODO: Preserve other team information? We might not need to...
Team team = new Team(st.getId());
serverScoreboard.getTeams().put(st.getId(), team);
break;
case 1:
serverScoreboard.getTeams().remove(st.getId());
break;
}
}
}
private void clearServerScoreboard() {
logger.info("Scoreboard prior to cleaning: {}", serverScoreboard);
for (Objective objective : serverScoreboard.getObjectives().values()) {
for (Score score : objective.getScores().values()) {
ScoreboardSetScore sss = new ScoreboardSetScore();
sss.setObjective(objective.getId());
sss.setAction((byte) 1);
sss.setEntity(score.getTarget());
player.getConnection().delayedWrite(sss);
}
ScoreboardObjective so = new ScoreboardObjective();
so.setId(objective.getId());
so.setMode((byte) 1);
player.getConnection().delayedWrite(so);
}
for (Team team : serverScoreboard.getTeams().values()) {
ScoreboardTeam st = new ScoreboardTeam();
st.setId(team.getId());
st.setMode((byte) 1);
player.getConnection().delayedWrite(st);
}
serverScoreboard = new Scoreboard();
}
public Set<String> getClientPluginMsgChannels() {
return clientPluginMsgChannels;
}

Datei anzeigen

@ -36,6 +36,14 @@ public class Objective {
return scores;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return "Objective{" +

Datei anzeigen

@ -1,23 +1,20 @@
package com.velocitypowered.proxy.data.scoreboard;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
public class Scoreboard {
private String name;
private String displayName;
private byte position;
private final List<Objective> objectives = new ArrayList<>();
public Scoreboard() {
private final Map<String, Objective> objectives = new HashMap<>();
private final Map<String, Team> teams = new HashMap<>();
public String getDisplayName() {
return displayName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public byte getPosition() {
@ -28,16 +25,21 @@ public class Scoreboard {
this.position = position;
}
public List<Objective> getObjectives() {
public Map<String, Objective> getObjectives() {
return objectives;
}
public Map<String, Team> getTeams() {
return teams;
}
@Override
public String toString() {
return "Scoreboard{" +
"name='" + name + '\'' +
"displayName='" + displayName + '\'' +
", position=" + position +
", objectives=" + objectives +
", teams=" + teams +
'}';
}
}