mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-25 11:35:18 +01:00
Reduce boxing in protocol path getting
More of its implementation should probably be cleaned up later
This commit is contained in:
parent
63356207a3
commit
d918fd27b6
@ -24,7 +24,6 @@ package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
@ -87,10 +86,10 @@ public interface ProtocolManager {
|
||||
*
|
||||
* @param clientVersion input client version
|
||||
* @param serverVersion desired output server version
|
||||
* @return path it generated, null if it failed
|
||||
* @return path it generated, null if not supported
|
||||
*/
|
||||
@Nullable
|
||||
List<Pair<Integer, Protocol>> getProtocolPath(int clientVersion, int serverVersion);
|
||||
List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion);
|
||||
|
||||
/**
|
||||
* Returns the maximum protocol path size applied to {@link #getProtocolPath(int, int)}.
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
public interface ProtocolPathEntry {
|
||||
|
||||
/**
|
||||
* Returns the resulting protocol after transformation using
|
||||
* the {@link #getProtocol()} protocol handlers.
|
||||
*
|
||||
* @return output protocol version after transformation
|
||||
*/
|
||||
int getOutputProtocolVersion();
|
||||
|
||||
/**
|
||||
* Returns the protocol to be applied with this entry.
|
||||
*
|
||||
* @return protocol to be applied with this entry
|
||||
*/
|
||||
Protocol getProtocol();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
public interface ProtocolPathKey {
|
||||
|
||||
/**
|
||||
* @return client protocol version
|
||||
*/
|
||||
int getClientProtocolVersion();
|
||||
|
||||
/**
|
||||
* @return server protocol version
|
||||
*/
|
||||
int getServerProtocolVersion();
|
||||
}
|
@ -28,6 +28,7 @@ import us.myles.ViaVersion.ViaManager;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
@ -104,7 +105,16 @@ public class ProtocolRegistry {
|
||||
*/
|
||||
@Nullable
|
||||
public static List<Pair<Integer, Protocol>> getProtocolPath(int clientVersion, int serverVersion) {
|
||||
return Via.getManager().getProtocolManager().getProtocolPath(clientVersion, serverVersion);
|
||||
List<ProtocolPathEntry> pathList = Via.getManager().getProtocolManager().getProtocolPath(clientVersion, serverVersion);
|
||||
if (pathList == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Pair<Integer, Protocol>> list = new ArrayList<>();
|
||||
for (ProtocolPathEntry entry : pathList) {
|
||||
list.add(new Pair<>(entry.getOutputProtocolVersion(), entry.getProtocol()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,12 +26,12 @@ import net.md_5.bungee.api.score.Team;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.ExternalJoinGameListener;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPathEntry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
@ -92,7 +92,7 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
|
||||
List<Pair<Integer, Protocol>> protocols = Via.getManager().getProtocolManager().getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
|
||||
List<ProtocolPathEntry> protocols = Via.getManager().getProtocolManager().getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
|
||||
|
||||
// Check if ViaVersion can support that version
|
||||
try {
|
||||
@ -175,7 +175,7 @@ public class BungeeServerHandler implements Listener {
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
// Refresh the pipes
|
||||
List<Pair<Integer, Protocol>> protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
List<ProtocolPathEntry> protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
|
||||
user.clearStoredObjects();
|
||||
pipeline.cleanPipes();
|
||||
@ -183,8 +183,8 @@ public class BungeeServerHandler implements Listener {
|
||||
// TODO Check Bungee Supported Protocols? *shrugs*
|
||||
protocolId = info.getProtocolVersion();
|
||||
} else {
|
||||
for (Pair<Integer, Protocol> prot : protocols) {
|
||||
pipeline.add(prot.getValue());
|
||||
for (ProtocolPathEntry prot : protocols) {
|
||||
pipeline.add(prot.getProtocol());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
// Input Version -> Output Version & Protocol (Allows fast lookup)
|
||||
private final Int2ObjectMap<Int2ObjectMap<Protocol>> registryMap = new Int2ObjectOpenHashMap<>(32);
|
||||
private final Map<Class<? extends Protocol>, Protocol> protocols = new HashMap<>();
|
||||
private final Map<Pair<Integer, Integer>, List<Pair<Integer, Protocol>>> pathCache = new ConcurrentHashMap<>();
|
||||
private final Map<ProtocolPathKey, List<ProtocolPathEntry>> pathCache = new ConcurrentHashMap<>();
|
||||
private final Set<Integer> supportedVersions = new HashSet<>();
|
||||
private final List<Pair<Range<Integer>, Protocol>> baseProtocols = Lists.newCopyOnWriteArrayList();
|
||||
private final List<Protocol> registerList = new ArrayList<>();
|
||||
@ -201,26 +201,27 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
|
||||
supportedVersions.add(serverProtocol);
|
||||
for (ProtocolVersion versions : ProtocolVersion.getProtocols()) {
|
||||
List<Pair<Integer, Protocol>> paths = getProtocolPath(versions.getVersion(), serverProtocol);
|
||||
List<ProtocolPathEntry> paths = getProtocolPath(versions.getVersion(), serverProtocol);
|
||||
if (paths == null) continue;
|
||||
supportedVersions.add(versions.getVersion());
|
||||
for (Pair<Integer, Protocol> path : paths) {
|
||||
supportedVersions.add(path.getKey());
|
||||
for (ProtocolPathEntry path : paths) {
|
||||
supportedVersions.add(path.getOutputProtocolVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Pair<Integer, Protocol>> getProtocolPath(int clientVersion, int serverVersion) {
|
||||
Pair<Integer, Integer> protocolKey = new Pair<>(clientVersion, serverVersion);
|
||||
public List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion) {
|
||||
ProtocolPathKey protocolKey = new ProtocolPathKeyImpl(clientVersion, serverVersion);
|
||||
// Check cache
|
||||
List<Pair<Integer, Protocol>> protocolList = pathCache.get(protocolKey);
|
||||
List<ProtocolPathEntry> protocolList = pathCache.get(protocolKey);
|
||||
if (protocolList != null) {
|
||||
return protocolList;
|
||||
}
|
||||
|
||||
// Generate path
|
||||
List<Pair<Integer, Protocol>> outputPath = getProtocolPath(new ArrayList<>(), clientVersion, serverVersion);
|
||||
List<ProtocolPathEntry> outputPath = getProtocolPath(new ArrayList<>(), clientVersion, serverVersion);
|
||||
// If it found a path, cache it.
|
||||
if (outputPath != null) {
|
||||
pathCache.put(protocolKey, outputPath);
|
||||
@ -237,7 +238,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
* @return path that has been generated, null if failed
|
||||
*/
|
||||
@Nullable
|
||||
private List<Pair<Integer, Protocol>> getProtocolPath(List<Pair<Integer, Protocol>> current, int clientVersion, int serverVersion) {
|
||||
private List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) {
|
||||
if (clientVersion == serverVersion) return null; // We're already there
|
||||
if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated.
|
||||
|
||||
@ -250,30 +251,31 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
// Next check there isn't an obvious path
|
||||
Protocol protocol = inputMap.get(serverVersion);
|
||||
if (protocol != null) {
|
||||
current.add(new Pair<>(serverVersion, protocol));
|
||||
current.add(new ProtocolPathEntryImpl(serverVersion, protocol));
|
||||
return current; // Easy solution
|
||||
}
|
||||
|
||||
// There might be a more advanced solution... So we'll see if any of the others can get us there
|
||||
List<Pair<Integer, Protocol>> shortest = null;
|
||||
List<ProtocolPathEntry> shortest = null;
|
||||
for (Int2ObjectMap.Entry<Protocol> entry : inputMap.int2ObjectEntrySet()) {
|
||||
// Ensure it wasn't caught by the other loop
|
||||
if (entry.getIntKey() == (serverVersion)) continue;
|
||||
if (entry.getIntKey() == serverVersion) continue;
|
||||
|
||||
Pair<Integer, Protocol> pair = new Pair<>(entry.getIntKey(), entry.getValue());
|
||||
ProtocolPathEntry pathEntry = new ProtocolPathEntryImpl(entry.getIntKey(), entry.getValue());
|
||||
// Ensure no recursion
|
||||
if (current.contains(pair)) continue;
|
||||
if (current.contains(pathEntry)) continue;
|
||||
|
||||
// Create a copy
|
||||
List<Pair<Integer, Protocol>> newCurrent = new ArrayList<>(current);
|
||||
newCurrent.add(pair);
|
||||
// Calculate the rest of the protocol using the current
|
||||
newCurrent = getProtocolPath(newCurrent, entry.getKey(), serverVersion);
|
||||
if (newCurrent != null) {
|
||||
// If it's shorter then choose it
|
||||
if (shortest == null || shortest.size() > newCurrent.size()) {
|
||||
shortest = newCurrent;
|
||||
}
|
||||
List<ProtocolPathEntry> newCurrent = new ArrayList<>(current);
|
||||
newCurrent.add(pathEntry);
|
||||
|
||||
// Calculate the rest of the protocol using the current path entry
|
||||
newCurrent = getProtocolPath(newCurrent, entry.getIntKey(), serverVersion);
|
||||
|
||||
// If it's shorter then choose it
|
||||
if (newCurrent != null
|
||||
&& (shortest == null || shortest.size() > newCurrent.size())) {
|
||||
shortest = newCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
public class ProtocolPathEntryImpl implements ProtocolPathEntry {
|
||||
private final int outputProtocolVersion;
|
||||
private final Protocol protocol;
|
||||
|
||||
public ProtocolPathEntryImpl(int outputProtocolVersion, Protocol protocol) {
|
||||
this.outputProtocolVersion = outputProtocolVersion;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOutputProtocolVersion() {
|
||||
return outputProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Protocol getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final ProtocolPathEntryImpl that = (ProtocolPathEntryImpl) o;
|
||||
if (outputProtocolVersion != that.outputProtocolVersion) return false;
|
||||
return protocol.equals(that.protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = outputProtocolVersion;
|
||||
result = 31 * result + protocol.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package us.myles.ViaVersion.api.protocol;
|
||||
|
||||
public class ProtocolPathKeyImpl implements ProtocolPathKey {
|
||||
private final int clientProtocolVersion;
|
||||
private final int serverProtocolVersion;
|
||||
|
||||
public ProtocolPathKeyImpl(int clientProtocolVersion, int serverProtocolVersion) {
|
||||
this.clientProtocolVersion = clientProtocolVersion;
|
||||
this.serverProtocolVersion = serverProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getClientProtocolVersion() {
|
||||
return clientProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerProtocolVersion() {
|
||||
return serverProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final ProtocolPathKeyImpl that = (ProtocolPathKeyImpl) o;
|
||||
if (clientProtocolVersion != that.clientProtocolVersion) return false;
|
||||
return serverProtocolVersion == that.serverProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = clientProtocolVersion;
|
||||
result = 31 * result + serverProtocolVersion;
|
||||
return result;
|
||||
}
|
||||
}
|
@ -18,11 +18,10 @@
|
||||
package us.myles.ViaVersion.protocols.base;
|
||||
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.platform.providers.ViaProviders;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPathEntry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.protocol.SimpleProtocol;
|
||||
@ -60,7 +59,7 @@ public class BaseProtocol extends SimpleProtocol {
|
||||
// Choose the pipe
|
||||
int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
|
||||
info.setServerProtocolVersion(serverProtocol);
|
||||
List<Pair<Integer, Protocol>> protocols = null;
|
||||
List<ProtocolPathEntry> protocols = null;
|
||||
|
||||
// Only allow newer clients or (1.9.2 on 1.9.4 server if the server supports it)
|
||||
if (info.getProtocolVersion() >= serverProtocol || Via.getPlatform().isOldClientsAllowed()) {
|
||||
@ -69,10 +68,10 @@ public class BaseProtocol extends SimpleProtocol {
|
||||
|
||||
ProtocolPipeline pipeline = wrapper.user().getProtocolInfo().getPipeline();
|
||||
if (protocols != null) {
|
||||
for (Pair<Integer, Protocol> prot : protocols) {
|
||||
pipeline.add(prot.getValue());
|
||||
for (ProtocolPathEntry prot : protocols) {
|
||||
pipeline.add(prot.getProtocol());
|
||||
// Ensure mapping data has already been loaded
|
||||
Via.getManager().getProtocolManager().completeMappingDataLoading(prot.getValue().getClass());
|
||||
Via.getManager().getProtocolManager().completeMappingDataLoading(prot.getProtocol().getClass());
|
||||
}
|
||||
|
||||
// Set the original snapshot version if present
|
||||
|
@ -23,10 +23,9 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolManagerImpl;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPathEntry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.protocol.SimpleProtocol;
|
||||
import us.myles.ViaVersion.api.remapper.PacketHandler;
|
||||
@ -94,7 +93,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
|
||||
}
|
||||
|
||||
int protocol = versionProvider.getServerProtocol(wrapper.user());
|
||||
List<Pair<Integer, Protocol>> protocols = null;
|
||||
List<ProtocolPathEntry> protocols = null;
|
||||
|
||||
// Only allow newer clients or (1.9.2 on 1.9.4 server if the server supports it)
|
||||
if (info.getProtocolVersion() >= protocol || Via.getPlatform().isOldClientsAllowed()) {
|
||||
|
Loading…
Reference in New Issue
Block a user