/* * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion * Copyright (C) 2016-2024 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 . */ package com.viaversion.viaversion.configuration; import com.google.gson.JsonElement; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.configuration.ViaVersionConfig; 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 java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.IntPredicate; import org.checkerframework.checker.nullness.qual.Nullable; public abstract class AbstractViaConfig extends Config implements ViaVersionConfig { private boolean checkForUpdates; private boolean preventCollision; private boolean useNewEffectIndicator; private boolean useNewDeathmessages; private boolean suppressMetadataErrors; private boolean shieldBlocking; private boolean noDelayShieldBlocking; private boolean showShieldWhenSwordInHand; private boolean hologramPatch; private boolean pistonAnimationPatch; private boolean bossbarPatch; private boolean bossbarAntiFlicker; private double hologramOffset; private int maxPPS; private String maxPPSKickMessage; private int trackingPeriod; private int warningPPS; private int maxPPSWarnings; private String maxPPSWarningsKickMessage; private boolean sendSupportedVersions; private boolean simulatePlayerTick; private boolean itemCache; private boolean nmsPlayerTicking; private boolean replacePistons; private int pistonReplacementId; private boolean chunkBorderFix; private boolean autoTeam; private boolean forceJsonTransform; private boolean nbtArrayFix; private BlockedProtocolVersions blockedProtocolVersions; private String blockedDisconnectMessage; private String reloadDisconnectMessage; private boolean suppressConversionWarnings; private boolean disable1_13TabComplete; private boolean minimizeCooldown; private boolean teamColourFix; private boolean serversideBlockConnections; private boolean reduceBlockStorageMemory; private boolean flowerStemWhenBlockAbove; private boolean vineClimbFix; private boolean snowCollisionFix; private boolean infestedBlocksFix; private int tabCompleteDelay; private boolean truncate1_14Books; private boolean leftHandedHandling; private boolean fullBlockLightFix; private boolean healthNaNFix; private boolean instantRespawn; private boolean ignoreLongChannelNames; private boolean forcedUse1_17ResourcePack; private JsonElement resourcePack1_17PromptMessage; private WorldIdentifiers map1_16WorldNames; private boolean cache1_17Light; protected AbstractViaConfig(final File configFile) { super(configFile); } @Override public void reload() { super.reload(); loadFields(); } protected void loadFields() { checkForUpdates = getBoolean("checkforupdates", true); preventCollision = getBoolean("prevent-collision", true); useNewEffectIndicator = getBoolean("use-new-effect-indicator", true); useNewDeathmessages = getBoolean("use-new-deathmessages", true); suppressMetadataErrors = getBoolean("suppress-metadata-errors", false); shieldBlocking = getBoolean("shield-blocking", true); noDelayShieldBlocking = getBoolean("no-delay-shield-blocking", false); showShieldWhenSwordInHand = getBoolean("show-shield-when-sword-in-hand", false); hologramPatch = getBoolean("hologram-patch", false); pistonAnimationPatch = getBoolean("piston-animation-patch", false); bossbarPatch = getBoolean("bossbar-patch", true); bossbarAntiFlicker = getBoolean("bossbar-anti-flicker", false); hologramOffset = getDouble("hologram-y", -0.96D); maxPPS = getInt("max-pps", 800); maxPPSKickMessage = getString("max-pps-kick-msg", "Sending packets too fast? lag?"); trackingPeriod = getInt("tracking-period", 6); warningPPS = getInt("tracking-warning-pps", 120); maxPPSWarnings = getInt("tracking-max-warnings", 3); maxPPSWarningsKickMessage = getString("tracking-max-kick-msg", "You are sending too many packets, :("); sendSupportedVersions = getBoolean("send-supported-versions", false); simulatePlayerTick = getBoolean("simulate-pt", true); itemCache = getBoolean("item-cache", true); nmsPlayerTicking = getBoolean("nms-player-ticking", true); replacePistons = getBoolean("replace-pistons", false); pistonReplacementId = getInt("replacement-piston-id", 0); chunkBorderFix = getBoolean("chunk-border-fix", false); autoTeam = getBoolean("auto-team", true); forceJsonTransform = getBoolean("force-json-transform", false); nbtArrayFix = getBoolean("chat-nbt-fix", true); 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); teamColourFix = getBoolean("team-colour-fix", true); suppressConversionWarnings = getBoolean("suppress-conversion-warnings", false); disable1_13TabComplete = getBoolean("disable-1_13-auto-complete", false); serversideBlockConnections = getBoolean("serverside-blockconnections", true); reduceBlockStorageMemory = getBoolean("reduce-blockstorage-memory", false); flowerStemWhenBlockAbove = getBoolean("flowerstem-when-block-above", false); vineClimbFix = getBoolean("vine-climb-fix", false); snowCollisionFix = getBoolean("fix-low-snow-collision", false); infestedBlocksFix = getBoolean("fix-infested-block-breaking", true); tabCompleteDelay = getInt("1_13-tab-complete-delay", 0); truncate1_14Books = getBoolean("truncate-1_14-books", false); leftHandedHandling = getBoolean("left-handed-handling", true); fullBlockLightFix = getBoolean("fix-non-full-blocklight", false); healthNaNFix = getBoolean("fix-1_14-health-nan", true); instantRespawn = getBoolean("use-1_15-instant-respawn", false); ignoreLongChannelNames = getBoolean("ignore-long-1_16-channel-names", true); forcedUse1_17ResourcePack = getBoolean("forced-use-1_17-resource-pack", false); resourcePack1_17PromptMessage = getSerializedComponent("resource-pack-1_17-prompt"); Map worlds = get("map-1_16-world-names", Map.class, new HashMap()); map1_16WorldNames = new WorldIdentifiers(worlds.getOrDefault("overworld", WorldIdentifiers.OVERWORLD_DEFAULT), worlds.getOrDefault("nether", WorldIdentifiers.NETHER_DEFAULT), worlds.getOrDefault("end", WorldIdentifiers.END_DEFAULT)); cache1_17Light = getBoolean("cache-1_17-light", true); } private BlockedProtocolVersions loadBlockedProtocolVersions() { List blockProtocols = getListSafe("block-protocols", Integer.class, "Invalid blocked version protocol found in config: '%s'"); List blockVersions = getListSafe("block-versions", String.class, "Invalid blocked version found in config: '%s'"); IntSet blockedProtocols = new IntOpenHashSet(blockProtocols); int lowerBound = -1; int upperBound = -1; for (String s : blockVersions) { 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) { LOGGER.warning("Already set lower bound " + lowerBound + " overridden by " + protocolVersion.getName()); } lowerBound = protocolVersion.getVersion(); } else { if (upperBound != -1) { LOGGER.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())) { LOGGER.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); LOGGER.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) { LOGGER.warning("Unknown protocol version in block-versions: " + s); return null; } return protocolVersion; } @Override public boolean isCheckForUpdates() { return checkForUpdates; } @Override public void setCheckForUpdates(boolean checkForUpdates) { this.checkForUpdates = checkForUpdates; set("checkforupdates", checkForUpdates); } @Override public boolean isPreventCollision() { return preventCollision; } @Override public boolean isNewEffectIndicator() { return useNewEffectIndicator; } @Override public boolean isShowNewDeathMessages() { return useNewDeathmessages; } @Override public boolean isSuppressMetadataErrors() { return suppressMetadataErrors; } @Override public boolean isShieldBlocking() { return shieldBlocking; } @Override public boolean isNoDelayShieldBlocking() { return noDelayShieldBlocking; } @Override public boolean isShowShieldWhenSwordInHand() { return showShieldWhenSwordInHand; } @Override public boolean isHologramPatch() { return hologramPatch; } @Override public boolean isPistonAnimationPatch() { return pistonAnimationPatch; } @Override public boolean isBossbarPatch() { return bossbarPatch; } @Override public boolean isBossbarAntiflicker() { return bossbarAntiFlicker; } @Override public double getHologramYOffset() { return hologramOffset; } @Override public int getMaxPPS() { return maxPPS; } @Override public String getMaxPPSKickMessage() { return maxPPSKickMessage; } @Override public int getTrackingPeriod() { return trackingPeriod; } @Override public int getWarningPPS() { return warningPPS; } @Override public int getMaxWarnings() { return maxPPSWarnings; } @Override public String getMaxWarningsKickMessage() { return maxPPSWarningsKickMessage; } @Override public boolean isSendSupportedVersions() { return sendSupportedVersions; } @Override public boolean isSimulatePlayerTick() { return simulatePlayerTick; } @Override public boolean isItemCache() { return itemCache; } @Override public boolean isNMSPlayerTicking() { return nmsPlayerTicking; } @Override public boolean isReplacePistons() { return replacePistons; } @Override public int getPistonReplacementId() { return pistonReplacementId; } @Override public boolean isChunkBorderFix() { return chunkBorderFix; } @Override public boolean isAutoTeam() { // Collision has to be enabled first return preventCollision && autoTeam; } @Override public boolean isForceJsonTransform() { return forceJsonTransform; } @Override public boolean is1_12NBTArrayFix() { return nbtArrayFix; } @Override public boolean shouldRegisterUserConnectionOnJoin() { return false; } @Override public boolean is1_12QuickMoveActionFix() { return false; } @Override public BlockedProtocolVersions blockedProtocolVersions() { return blockedProtocolVersions; } @Override public String getBlockedDisconnectMsg() { return blockedDisconnectMessage; } @Override public String getReloadDisconnectMsg() { return reloadDisconnectMessage; } @Override public boolean isMinimizeCooldown() { return minimizeCooldown; } @Override public boolean is1_13TeamColourFix() { return teamColourFix; } @Override public boolean isSuppressConversionWarnings() { return suppressConversionWarnings; } @Override public boolean isDisable1_13AutoComplete() { return disable1_13TabComplete; } @Override public boolean isServersideBlockConnections() { return serversideBlockConnections; } @Override public String getBlockConnectionMethod() { return "packet"; } @Override public boolean isReduceBlockStorageMemory() { return reduceBlockStorageMemory; } @Override public boolean isStemWhenBlockAbove() { return flowerStemWhenBlockAbove; } @Override public boolean isVineClimbFix() { return vineClimbFix; } @Override public boolean isSnowCollisionFix() { return snowCollisionFix; } @Override public boolean isInfestedBlocksFix() { return infestedBlocksFix; } @Override public int get1_13TabCompleteDelay() { return tabCompleteDelay; } @Override public boolean isTruncate1_14Books() { return truncate1_14Books; } @Override public boolean isLeftHandedHandling() { return leftHandedHandling; } @Override public boolean is1_9HitboxFix() { return false; } @Override public boolean is1_14HitboxFix() { return false; } @Override public boolean isNonFullBlockLightFix() { return fullBlockLightFix; } @Override public boolean is1_14HealthNaNFix() { return healthNaNFix; } @Override public boolean is1_15InstantRespawn() { return instantRespawn; } @Override public boolean isIgnoreLong1_16ChannelNames() { return ignoreLongChannelNames; } @Override public boolean isForcedUse1_17ResourcePack() { return forcedUse1_17ResourcePack; } @Override public JsonElement get1_17ResourcePackPrompt() { return resourcePack1_17PromptMessage; } @Override public WorldIdentifiers get1_16WorldNamesMap() { return map1_16WorldNames; } @Override public boolean cache1_17Light() { return cache1_17Light; } @Override public boolean isArmorToggleFix() { return false; } }