Add more user friendly 'block-versions' option

This commit is contained in:
Nassim Jahnke 2021-09-20 15:15:25 +02:00
parent d67269c9fe
commit 0fcfd78b62
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
11 changed files with 237 additions and 27 deletions

View File

@ -64,7 +64,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes
*/
default int apiVersion() {
return 7;
return 8;
}
/**

View File

@ -23,8 +23,11 @@
package com.viaversion.viaversion.api.configuration;
import com.google.gson.JsonElement;
import it.unimi.dsi.fastutil.ints.IntSet;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.WorldIdentifiers;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
import it.unimi.dsi.fastutil.ints.IntSet;
public interface ViaVersionConfig {
@ -266,12 +269,23 @@ public interface ViaVersionConfig {
*/
boolean is1_12QuickMoveActionFix();
/**
* API to check for blocked protocol versions.
*
* @return blocked protocol versions
*/
BlockedProtocolVersions blockedProtocolVersions();
/**
* Get the blocked protocols
*
* @return An Integer list
* @deprecated use {@link #blockedProtocolVersions()}
*/
IntSet getBlockedProtocols();
@Deprecated/*(forRemoval = true)*/
default IntSet getBlockedProtocols() {
return blockedProtocolVersions().singleBlockedVersions();
}
/**
* Get the custom disconnect message
@ -432,11 +446,11 @@ public interface ViaVersionConfig {
JsonElement get1_17ResourcePackPrompt();
/***
* Get the world names which should be returned for each vanilla dimension
*
* Get the world names that should be returned for each Vanilla dimension.
* Note that this can be overriden per-user by using {@link UserConnection#put(StorableObject)} with
* a custom instance of {@link WorldIdentifiers} for the user's {@link UserConnection}.
*
* @return the global map from vanilla dimensions to world name
* Note that this can be overriden per-user by using {@link com.viaversion.viaversion.api.connection.UserConnection#put} with
* a custom instance of {@link WorldIdentifiers} for the user's {@link UserConnection}
*/
WorldIdentifiers get1_16WorldNamesMap();
}

View File

@ -291,7 +291,7 @@ public interface UserConnection {
boolean isClientSide();
/**
* Returns whether {@link ViaVersionConfig#getBlockedProtocols()} should be checked for this connection.
* Returns whether {@link ViaVersionConfig#blockedProtocolVersions()} should be checked for this connection.
*
* @return whether blocked protocols should be applied
*/

View File

@ -0,0 +1,57 @@
/*
* 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 com.viaversion.viaversion.api.protocol.version;
import it.unimi.dsi.fastutil.ints.IntSet;
public interface BlockedProtocolVersions {
/**
* Returns whether the given protocol version is blocked per boundary ranges or individually blocked versions.
*
* @param protocolVersion protocol version
* @return whether the given protocol version is blocked
*/
boolean contains(int protocolVersion);
/**
* Returns the boundary below which protocol versions are blocked, or -1 if none is set.
*
* @return exclusive boundary below which protocol versions are blocked, or -1 if none
*/
int blocksBelow();
/**
* Returns the boundary above which protocol versions are blocked, or -1 if none is set.
*
* @return exclusive boundary above which protocol versions are blocked, or -1 if none
*/
int blocksAbove();
/**
* Returns a set of blocked protocol versions between the outer block ranges.
*
* @return set of blocked protocol versions between the outer block ranges
*/
IntSet singleBlockedVersions();
}

View File

@ -21,6 +21,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.ViaAPI;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.legacy.LegacyViaAPI;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
import com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion;
import com.viaversion.viaversion.legacy.LegacyAPI;
import io.netty.buffer.ByteBuf;
@ -73,7 +74,8 @@ public abstract class ViaAPIBase<T> implements ViaAPI<T> {
@Override
public SortedSet<Integer> getSupportedVersions() {
SortedSet<Integer> outputSet = new TreeSet<>(Via.getManager().getProtocolManager().getSupportedVersions());
outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
BlockedProtocolVersions blockedVersions = Via.getPlatform().getConf().blockedProtocolVersions();
outputSet.removeIf(blockedVersions::contains);
return outputSet;
}

View File

@ -18,16 +18,21 @@
package com.viaversion.viaversion.configuration;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.util.Config;
import com.viaversion.viaversion.api.minecraft.WorldIdentifiers;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocol.BlockedProtocolVersionsImpl;
import com.viaversion.viaversion.util.Config;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.function.IntPredicate;
public abstract class AbstractViaConfig extends Config implements ViaVersionConfig {
@ -60,7 +65,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private boolean autoTeam;
private boolean forceJsonTransform;
private boolean nbtArrayFix;
private IntSet blockedProtocols;
private BlockedProtocolVersions blockedProtocolVersions;
private String blockedDisconnectMessage;
private String reloadDisconnectMessage;
private boolean suppressConversionWarnings;
@ -124,7 +129,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
autoTeam = getBoolean("auto-team", true);
forceJsonTransform = getBoolean("force-json-transform", false);
nbtArrayFix = getBoolean("chat-nbt-fix", true);
blockedProtocols = new IntOpenHashSet(getIntegerList("block-protocols"));
blockedProtocolVersions = loadBlockedProtocolVersions();
blockedDisconnectMessage = getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
reloadDisconnectMessage = getString("reload-disconnect-msg", "Server reload, please rejoin!");
minimizeCooldown = getBoolean("minimize-cooldown", true);
@ -152,6 +157,74 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
worlds.getOrDefault("end", WorldIdentifiers.END_DEFAULT));
}
private BlockedProtocolVersions loadBlockedProtocolVersions() {
IntSet blockedProtocols = new IntOpenHashSet(getIntegerList("block-protocols"));
int lowerBound = -1;
int upperBound = -1;
for (String s : getStringList("block-versions")) {
if (s.isEmpty()) {
continue;
}
char c = s.charAt(0);
if (c == '<' || c == '>') {
// Set lower/upper bound
ProtocolVersion protocolVersion = protocolVersion(s.substring(1));
if (protocolVersion == null) {
continue;
}
if (c == '<') {
if (lowerBound != -1) {
Via.getPlatform().getLogger().warning("Already set lower bound " + lowerBound + " overridden by " + protocolVersion.getName());
}
lowerBound = protocolVersion.getVersion();
} else {
if (upperBound != -1) {
Via.getPlatform().getLogger().warning("Already set upper bound " + upperBound + " overridden by " + protocolVersion.getName());
}
upperBound = protocolVersion.getVersion();
}
continue;
}
ProtocolVersion protocolVersion = protocolVersion(s);
if (protocolVersion == null) {
continue;
}
// Add single protocol version and check for duplication
if (!blockedProtocols.add(protocolVersion.getVersion())) {
Via.getPlatform().getLogger().warning("Duplicated blocked protocol version " + protocolVersion.getName() + "/" + protocolVersion.getVersion());
}
}
// Check for duplicated entries
if (lowerBound != -1 || upperBound != -1) {
final int finalLowerBound = lowerBound;
final int finalUpperBound = upperBound;
blockedProtocols.removeIf((IntPredicate) version -> {
if (finalLowerBound != -1 && version < finalLowerBound || finalUpperBound != -1 && version > finalUpperBound) {
ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(version);
Via.getPlatform().getLogger().warning("Blocked protocol version "
+ protocolVersion.getName() + "/" + protocolVersion.getVersion() + " already covered by upper or lower bound");
return true;
}
return false;
});
}
return new BlockedProtocolVersionsImpl(blockedProtocols, lowerBound, upperBound);
}
private @Nullable ProtocolVersion protocolVersion(String s) {
ProtocolVersion protocolVersion = ProtocolVersion.getClosest(s);
if (protocolVersion == null) {
Via.getPlatform().getLogger().warning("Unknown protocol version in block-versions: " + s);
return null;
}
return protocolVersion;
}
@Override
public boolean isCheckForUpdates() {
return checkForUpdates;
@ -315,8 +388,8 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
}
@Override
public IntSet getBlockedProtocols() {
return blockedProtocols;
public BlockedProtocolVersions blockedProtocolVersions() {
return blockedProtocolVersions;
}
@Override
@ -442,5 +515,5 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
@Override
public WorldIdentifiers get1_16WorldNamesMap() {
return map1_16WorldNames;
};
}
}

View File

@ -0,0 +1,55 @@
/*
* 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 com.viaversion.viaversion.protocol;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
import it.unimi.dsi.fastutil.ints.IntSet;
public class BlockedProtocolVersionsImpl implements BlockedProtocolVersions {
private final IntSet singleBlockedVersions;
private final int blocksBelow;
private final int blocksAbove;
public BlockedProtocolVersionsImpl(final IntSet singleBlockedVersions, final int blocksBelow, final int blocksAbove) {
this.singleBlockedVersions = singleBlockedVersions;
this.blocksBelow = blocksBelow;
this.blocksAbove = blocksAbove;
}
@Override
public boolean contains(final int protocolVersion) {
return blocksBelow != -1 && protocolVersion < blocksBelow
|| blocksAbove != -1 && protocolVersion > blocksAbove
|| singleBlockedVersions.contains(protocolVersion);
}
@Override
public int blocksBelow() {
return blocksBelow;
}
@Override
public int blocksAbove() {
return blocksAbove;
}
@Override
public IntSet singleBlockedVersions() {
return singleBlockedVersions;
}
}

View File

@ -111,7 +111,7 @@ public class BaseProtocol1_7 extends AbstractProtocol {
wrapper.user().setActive(false);
}
if (Via.getConfig().getBlockedProtocols().contains(info.getProtocolVersion())) {
if (Via.getConfig().blockedProtocolVersions().contains(info.getProtocolVersion())) {
version.addProperty("protocol", -1); // Show blocked versions as outdated
}
@ -169,7 +169,7 @@ public class BaseProtocol1_7 extends AbstractProtocol {
@Override
public void handle(final PacketWrapper wrapper) throws Exception {
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
if (Via.getConfig().getBlockedProtocols().contains(protocol)) {
if (Via.getConfig().blockedProtocolVersions().contains(protocol)) {
if (!wrapper.user().getChannel().isOpen()) return;
if (!wrapper.user().shouldApplyBlockProtocol()) return;

View File

@ -150,7 +150,11 @@ public class CommentStore {
}
for (String line : yaml.split("\n")) {
if (line.isEmpty()) continue; // Skip empty lines
if (line.isEmpty() || line.trim().charAt(0) == '-') {
fileData.append(line).append('\n');
continue;
}
int indent = getSuccessiveCharCount(line, ' ');
int indents = indent / indentLength;
String indentText = indent > 0 ? line.substring(0, indent) : "";
@ -162,7 +166,7 @@ public class CommentStore {
}
// Add new section to key
String separator = key.length() > 0 ? pathSeparator : "";
String separator = !key.isEmpty() ? pathSeparator : "";
String lineKey = line.contains(":") ? line.split(Pattern.quote(":"))[0] : line;
key += separator + lineKey.substring(indent);

View File

@ -204,11 +204,12 @@ public abstract class Config implements ConfigurationProvider {
public List<Integer> getIntegerList(String key) {
Object o = this.config.get(key);
if (o != null) {
return (List<Integer>) o;
} else {
return new ArrayList<>();
}
return o != null ? (List<Integer>) o : new ArrayList<>();
}
public List<String> getStringList(String key) {
Object o = this.config.get(key);
return o != null ? (List<String>) o : new ArrayList<>();
}
public @Nullable JsonElement getSerializedComponent(String key) {

View File

@ -13,8 +13,12 @@
checkforupdates: true
# Send the supported versions with the Status (Ping) response packet
send-supported-versions: false
# Block specific Minecraft protocols that ViaVersion allows
# List of all Minecraft protocol versions: http://wiki.vg/Protocol_version_numbers or use a generator: https://via.krusic22.com
# Easier to configure alternative to 'block-protocols'. Uses readable version strings with possible '<' and '>' prefixes.
# An example to block 1.16.4, everything below 1.16, as well as everything above 1.17.1 would be: ["<1.16", "1.16.4", ">1.17.1"]
# You can use both this and the block-protocols option at the same time as well.
block-versions: []
# Block specific Minecraft protocol version numbers.
# List of all Minecraft protocol versions: http://wiki.vg/Protocol_version_numbers, or use a generator: https://via.krusic22.com
block-protocols: []
# Change the blocked disconnect message
block-disconnect-msg: "You are using an unsupported Minecraft version!"