use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.
the class BungeeServerHandler method checkServerChange.
public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
if (user == null)
return;
// Handle server/version change
if (user.has(BungeeStorage.class)) {
BungeeStorage storage = user.get(BungeeStorage.class);
ProxiedPlayer player = storage.getPlayer();
if (e.getServer() != null) {
if (!e.getServer().getInfo().getName().equals(storage.getCurrentServer())) {
// Clear auto-team
EntityTracker1_9 oldEntityTracker = user.getEntityTracker(Protocol1_9To1_8.class);
if (oldEntityTracker != null) {
if (oldEntityTracker.isAutoTeam() && oldEntityTracker.isTeamExists()) {
oldEntityTracker.sendTeamPacket(false, true);
}
}
String serverName = e.getServer().getInfo().getName();
storage.setCurrentServer(serverName);
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
if (protocolId <= ProtocolVersion.v1_8.getVersion()) {
// 1.8 doesn't have BossBar packet
if (storage.getBossbar() != null) {
// This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
for (UUID uuid : storage.getBossbar()) {
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, null, user);
wrapper.write(Type.UUID, uuid);
// remove
wrapper.write(Type.VAR_INT, 1);
wrapper.send(Protocol1_9To1_8.class);
}
}
storage.getBossbar().clear();
}
}
ProtocolInfo info = user.getProtocolInfo();
int previousServerProtocol = info.getServerProtocolVersion();
// Refresh the pipes
List<ProtocolPathEntry> protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId);
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
user.clearStoredObjects();
pipeline.cleanPipes();
if (protocolPath == null) {
// TODO Check Bungee Supported Protocols? *shrugs*
protocolId = info.getProtocolVersion();
} else {
List<Protocol> protocols = new ArrayList<>(protocolPath.size());
for (ProtocolPathEntry entry : protocolPath) {
protocols.add(entry.protocol());
}
pipeline.add(protocols);
}
info.setServerProtocolVersion(protocolId);
// Add version-specific base Protocol
pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(protocolId));
// Workaround 1.13 server change
int id1_13 = ProtocolVersion.v1_13.getVersion();
boolean toNewId = previousServerProtocol < id1_13 && protocolId >= id1_13;
boolean toOldId = previousServerProtocol >= id1_13 && protocolId < id1_13;
if (previousServerProtocol != -1 && (toNewId || toOldId)) {
Collection<String> registeredChannels = (Collection<String>) getRegisteredChannels.invoke(e.getPlayer().getPendingConnection());
if (!registeredChannels.isEmpty()) {
Collection<String> newChannels = new HashSet<>();
for (Iterator<String> iterator = registeredChannels.iterator(); iterator.hasNext(); ) {
String channel = iterator.next();
String oldChannel = channel;
if (toNewId) {
channel = InventoryPackets.getNewPluginChannelId(channel);
} else {
channel = InventoryPackets.getOldPluginChannelId(channel);
}
if (channel == null) {
iterator.remove();
continue;
}
if (!oldChannel.equals(channel)) {
iterator.remove();
newChannels.add(channel);
}
}
registeredChannels.addAll(newChannels);
}
PluginMessage brandMessage = (PluginMessage) getBrandMessage.invoke(e.getPlayer().getPendingConnection());
if (brandMessage != null) {
String channel = brandMessage.getTag();
if (toNewId) {
channel = InventoryPackets.getNewPluginChannelId(channel);
} else {
channel = InventoryPackets.getOldPluginChannelId(channel);
}
if (channel != null) {
brandMessage.setTag(channel);
}
}
}
user.put(storage);
user.setActive(protocolPath != null);
// Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist.
for (Protocol protocol : pipeline.pipes()) {
protocol.init(user);
}
EntityTracker1_9 newTracker = user.getEntityTracker(Protocol1_9To1_8.class);
if (newTracker != null) {
if (Via.getConfig().isAutoTeam()) {
String currentTeam = null;
for (Team team : player.getScoreboard().getTeams()) {
if (team.getPlayers().contains(info.getUsername())) {
currentTeam = team.getName();
}
}
// Reinitialize auto-team
newTracker.setAutoTeam(true);
if (currentTeam == null) {
// Send auto-team as it was cleared above
newTracker.sendTeamPacket(true, true);
newTracker.setCurrentTeam("viaversion");
} else {
// Auto-team will be sent when bungee send remove packet
newTracker.setAutoTeam(Via.getConfig().isAutoTeam());
newTracker.setCurrentTeam(currentTeam);
}
}
}
Object wrapper = channelWrapper.get(player);
setVersion.invoke(wrapper, protocolId);
Object entityMap = getEntityMap.invoke(null, protocolId);
entityRewrite.set(player, entityMap);
}
}
}
}
use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.
the class ProtocolManagerImpl method refreshVersions.
public void refreshVersions() {
supportedVersions.clear();
supportedVersions.add(serverProtocolVersion.lowestSupportedVersion());
for (ProtocolVersion version : ProtocolVersion.getProtocols()) {
List<ProtocolPathEntry> protocolPath = getProtocolPath(version.getVersion(), serverProtocolVersion.lowestSupportedVersion());
if (protocolPath == null)
continue;
supportedVersions.add(version.getVersion());
for (ProtocolPathEntry pathEntry : protocolPath) {
supportedVersions.add(pathEntry.outputProtocolVersion());
}
}
}
use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.
the class VersionedPacketTransformerImpl method transformPacket.
private void transformPacket(PacketWrapper packet) throws Exception {
// If clientbound: Constructor given inputProtocolVersion → Client version
// If serverbound: Constructor given inputProtocolVersion → Server version
PacketType packetType = packet.getPacketType();
UserConnection connection = packet.user();
boolean clientbound = packetType.direction() == Direction.CLIENTBOUND;
int serverProtocolVersion = clientbound ? this.inputProtocolVersion : connection.getProtocolInfo().getServerProtocolVersion();
int clientProtocolVersion = clientbound ? connection.getProtocolInfo().getProtocolVersion() : this.inputProtocolVersion;
// Construct protocol pipeline
List<ProtocolPathEntry> path = Via.getManager().getProtocolManager().getProtocolPath(clientProtocolVersion, serverProtocolVersion);
List<Protocol> protocolList = null;
if (path != null) {
protocolList = new ArrayList<>(path.size());
for (ProtocolPathEntry entry : path) {
protocolList.add(entry.protocol());
}
} else if (serverProtocolVersion != clientProtocolVersion) {
throw new RuntimeException("No protocol path between client version " + clientProtocolVersion + " and server version " + serverProtocolVersion);
}
if (protocolList != null) {
// Reset reader and apply pipeline
packet.resetReader();
try {
packet.apply(packetType.direction(), State.PLAY, 0, protocolList, clientbound);
} catch (Exception e) {
throw new Exception("Exception trying to transform packet between client version " + clientProtocolVersion + " and server version " + serverProtocolVersion + ". Are you sure you used the correct input version and packet write types?", e);
}
}
}
use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.
the class BaseProtocol1_7 method registerPackets.
@Override
protected void registerPackets() {
/* Outgoing Packets */
// Status Response Packet
registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new // Status Response Packet
PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ProtocolInfo info = wrapper.user().getProtocolInfo();
String originalStatus = wrapper.get(Type.STRING, 0);
try {
JsonElement json = GsonUtil.getGson().fromJson(originalStatus, JsonElement.class);
JsonObject version;
// Unknown!
int protocolVersion = 0;
if (json.isJsonObject()) {
if (json.getAsJsonObject().has("version")) {
version = json.getAsJsonObject().get("version").getAsJsonObject();
if (version.has("protocol")) {
protocolVersion = ((Long) version.get("protocol").getAsLong()).intValue();
}
} else {
json.getAsJsonObject().add("version", version = new JsonObject());
}
} else {
// Format properly
json = new JsonObject();
json.getAsJsonObject().add("version", version = new JsonObject());
}
if (Via.getConfig().isSendSupportedVersions()) {
// Send supported versions
version.add("supportedVersions", GsonUtil.getGson().toJsonTree(Via.getAPI().getSupportedVersions()));
}
if (!Via.getAPI().getServerVersion().isKnown()) {
// Set the Server protocol if the detection on startup failed
ProtocolManagerImpl protocolManager = (ProtocolManagerImpl) Via.getManager().getProtocolManager();
protocolManager.setServerProtocol(new ServerProtocolVersionSingleton(ProtocolVersion.getProtocol(protocolVersion).getVersion()));
}
// Ensure the server has a version provider
VersionProvider versionProvider = Via.getManager().getProviders().get(VersionProvider.class);
if (versionProvider == null) {
wrapper.user().setActive(false);
return;
}
int closestServerProtocol = versionProvider.getClosestServerProtocol(wrapper.user());
List<ProtocolPathEntry> protocols = null;
if (info.getProtocolVersion() >= closestServerProtocol || Via.getPlatform().isOldClientsAllowed()) {
protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), closestServerProtocol);
}
if (protocols != null) {
if (protocolVersion == closestServerProtocol || protocolVersion == 0) {
// Fix ServerListPlus
ProtocolVersion prot = ProtocolVersion.getProtocol(info.getProtocolVersion());
version.addProperty("protocol", prot.getOriginalVersion());
}
} else {
// not compatible :(, *plays very sad violin*
wrapper.user().setActive(false);
}
if (Via.getConfig().blockedProtocolVersions().contains(info.getProtocolVersion())) {
// Show blocked versions as outdated
version.addProperty("protocol", -1);
}
// Update value
wrapper.set(Type.STRING, 0, GsonUtil.getGson().toJson(json));
} catch (JsonParseException e) {
e.printStackTrace();
}
}
});
}
});
// Login Success Packet
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ProtocolInfo info = wrapper.user().getProtocolInfo();
info.setState(State.PLAY);
UUID uuid = passthroughLoginUUID(wrapper);
info.setUuid(uuid);
String username = wrapper.passthrough(Type.STRING);
info.setUsername(username);
// Add to ported clients
Via.getManager().getConnectionManager().onLoginSuccess(wrapper.user());
if (!info.getPipeline().hasNonBaseProtocols()) {
// Only base protocol
wrapper.user().setActive(false);
}
if (Via.getManager().isDebug()) {
// Print out the route to console
Via.getPlatform().getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}", new Object[] { username, info.getProtocolVersion(), Joiner.on(", ").join(info.getPipeline().pipes(), ", ") });
}
}
});
}
});
/* Incoming Packets */
// Login Start Packet
registerServerbound(ServerboundLoginPackets.HELLO, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(final PacketWrapper wrapper) throws Exception {
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
if (Via.getConfig().blockedProtocolVersions().contains(protocol)) {
if (!wrapper.user().getChannel().isOpen())
return;
if (!wrapper.user().shouldApplyBlockProtocol())
return;
// Disconnect Packet
PacketWrapper disconnectPacket = PacketWrapper.create(ClientboundLoginPackets.LOGIN_DISCONNECT, wrapper.user());
Protocol1_9To1_8.FIX_JSON.write(disconnectPacket, ChatColorUtil.translateAlternateColorCodes(Via.getConfig().getBlockedDisconnectMsg()));
// cancel current
wrapper.cancel();
// Send and close
ChannelFuture future = disconnectPacket.sendFuture(BaseProtocol.class);
future.addListener(f -> wrapper.user().getChannel().close());
}
}
});
}
});
}
use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project Geyser by GeyserMC.
the class GeyserSpigotPlugin method isViaVersionNeeded.
/**
* This function should not run unless ViaVersion is installed on the server.
*
* @return true if there is any block mappings difference between the server and client.
*/
private boolean isViaVersionNeeded() {
ProtocolVersion serverVersion = getServerProtocolVersion();
List<ProtocolPathEntry> protocolList = Via.getManager().getProtocolManager().getProtocolPath(MinecraftProtocol.getJavaProtocolVersion(), serverVersion.getVersion());
if (protocolList == null) {
// No translation needed!
return false;
}
for (int i = protocolList.size() - 1; i >= 0; i--) {
MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
if (mappingData != null) {
return true;
}
}
// All mapping data is null, which means client and server block states are the same
return false;
}
Aggregations