geforkt von Mirrors/Paper
#1401: Add a config option to accept old keys in registry get calls
By: DerFrZocker <derrieple@gmail.com>
Dieser Commit ist enthalten in:
Ursprung
6f5d01226e
Commit
c955ea1663
@ -2,6 +2,7 @@ package org.bukkit.craftbukkit;
|
|||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
@ -302,6 +303,7 @@ public final class CraftServer implements Server {
|
|||||||
public boolean ignoreVanillaPermissions = false;
|
public boolean ignoreVanillaPermissions = false;
|
||||||
private final List<CraftPlayer> playerView;
|
private final List<CraftPlayer> playerView;
|
||||||
public int reloadCount;
|
public int reloadCount;
|
||||||
|
public Set<String> activeCompatibilities = Collections.emptySet();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||||
@ -377,6 +379,7 @@ public final class CraftServer implements Server {
|
|||||||
TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks");
|
TicketType.PLUGIN.timeout = configuration.getInt("chunk-gc.period-in-ticks");
|
||||||
minimumAPI = ApiVersion.getOrCreateVersion(configuration.getString("settings.minimum-api"));
|
minimumAPI = ApiVersion.getOrCreateVersion(configuration.getString("settings.minimum-api"));
|
||||||
loadIcon();
|
loadIcon();
|
||||||
|
loadCompatibilities();
|
||||||
|
|
||||||
// Set map color cache
|
// Set map color cache
|
||||||
if (configuration.getBoolean("settings.use-map-color-cache")) {
|
if (configuration.getBoolean("settings.use-map-color-cache")) {
|
||||||
@ -420,6 +423,25 @@ public final class CraftServer implements Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadCompatibilities() {
|
||||||
|
ConfigurationSection compatibilities = configuration.getConfigurationSection("settings.compatibility");
|
||||||
|
if (compatibilities == null) {
|
||||||
|
activeCompatibilities = Collections.emptySet();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeCompatibilities = compatibilities
|
||||||
|
.getKeys(false)
|
||||||
|
.stream()
|
||||||
|
.filter(compatibilities::getBoolean)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (!activeCompatibilities.isEmpty()) {
|
||||||
|
logger.info("Using following compatibilities: `" + Joiner.on("`, `").join(activeCompatibilities) + "`, this will affect performance and other plugins behavior.");
|
||||||
|
logger.info("Only use when necessary and prefer updating plugins if possible.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void loadPlugins() {
|
public void loadPlugins() {
|
||||||
pluginManager.registerInterface(JavaPluginLoader.class);
|
pluginManager.registerInterface(JavaPluginLoader.class);
|
||||||
|
|
||||||
@ -896,6 +918,7 @@ public final class CraftServer implements Server {
|
|||||||
printSaveWarning = false;
|
printSaveWarning = false;
|
||||||
console.autosavePeriod = configuration.getInt("ticks-per.autosave");
|
console.autosavePeriod = configuration.getInt("ticks-per.autosave");
|
||||||
loadIcon();
|
loadIcon();
|
||||||
|
loadCompatibilities();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
playerList.getIpBans().load();
|
playerList.getIpBans().load();
|
||||||
|
@ -12,6 +12,7 @@ import org.bukkit.craftbukkit.CraftRegistry;
|
|||||||
import org.bukkit.craftbukkit.legacy.fieldrename.FieldRenameData;
|
import org.bukkit.craftbukkit.legacy.fieldrename.FieldRenameData;
|
||||||
import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
|
import org.bukkit.craftbukkit.legacy.reroute.DoNotReroute;
|
||||||
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
|
import org.bukkit.craftbukkit.legacy.reroute.InjectPluginVersion;
|
||||||
|
import org.bukkit.craftbukkit.legacy.reroute.RequireCompatibility;
|
||||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodName;
|
import org.bukkit.craftbukkit.legacy.reroute.RerouteMethodName;
|
||||||
import org.bukkit.craftbukkit.legacy.reroute.RerouteStatic;
|
import org.bukkit.craftbukkit.legacy.reroute.RerouteStatic;
|
||||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||||
@ -55,6 +56,7 @@ public class FieldRename {
|
|||||||
return Enum.valueOf(enumClass, rename(apiVersion, enumClass.getName().replace('.', '/'), name));
|
return Enum.valueOf(enumClass, rename(apiVersion, enumClass.getName().replace('.', '/'), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequireCompatibility("allow-old-keys-in-registry")
|
||||||
public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
|
public static <T extends Keyed> T get(Registry<T> registry, NamespacedKey namespacedKey) {
|
||||||
// We don't have version-specific changes, so just use current, and don't inject a version
|
// We don't have version-specific changes, so just use current, and don't inject a version
|
||||||
return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
|
return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT);
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package org.bukkit.craftbukkit.legacy.reroute;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface RequireCompatibility {
|
||||||
|
|
||||||
|
String value();
|
||||||
|
}
|
@ -112,6 +112,11 @@ public class RerouteBuilder {
|
|||||||
|
|
||||||
boolean inBukkit = !method.isAnnotationPresent(NotInBukkit.class);
|
boolean inBukkit = !method.isAnnotationPresent(NotInBukkit.class);
|
||||||
|
|
||||||
return new RerouteMethodData(methodKey, sourceDesc, sourceOwner, methodName, rerouteStatic != null, targetType, Type.getInternalName(method.getDeclaringClass()), method.getName(), arguments, rerouteReturn, inBukkit);
|
String requiredCompatibility = null;
|
||||||
|
if (method.isAnnotationPresent(RequireCompatibility.class)) {
|
||||||
|
requiredCompatibility = method.getAnnotation(RequireCompatibility.class).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RerouteMethodData(methodKey, sourceDesc, sourceOwner, methodName, rerouteStatic != null, targetType, Type.getInternalName(method.getDeclaringClass()), method.getName(), arguments, rerouteReturn, inBukkit, requiredCompatibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package org.bukkit.craftbukkit.legacy.reroute;
|
package org.bukkit.craftbukkit.legacy.reroute;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
public record RerouteMethodData(String source, Type sourceDesc, Type sourceOwner, String sourceName,
|
public record RerouteMethodData(String source, Type sourceDesc, Type sourceOwner, String sourceName,
|
||||||
boolean staticReroute, Type targetType, String targetOwner, String targetName,
|
boolean staticReroute, Type targetType, String targetOwner, String targetName,
|
||||||
List<RerouteArgument> arguments, RerouteReturn rerouteReturn, boolean isInBukkit) {
|
List<RerouteArgument> arguments, RerouteReturn rerouteReturn, boolean isInBukkit,
|
||||||
|
@Nullable String requiredCompatibility) {
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -117,7 +118,7 @@ public class Commodore {
|
|||||||
byte[] b = ByteStreams.toByteArray(is);
|
byte[] b = ByteStreams.toByteArray(is);
|
||||||
|
|
||||||
if (entry.getName().endsWith(".class")) {
|
if (entry.getName().endsWith(".class")) {
|
||||||
b = convert(b, "dummy", ApiVersion.NONE);
|
b = convert(b, "dummy", ApiVersion.NONE, Collections.emptySet());
|
||||||
entry = new JarEntry(entry.getName());
|
entry = new JarEntry(entry.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ public class Commodore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] convert(byte[] b, final String pluginName, final ApiVersion pluginVersion) {
|
public static byte[] convert(byte[] b, final String pluginName, final ApiVersion pluginVersion, final Set<String> activeCompatibilities) {
|
||||||
final boolean modern = pluginVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING);
|
final boolean modern = pluginVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING);
|
||||||
ClassReader cr = new ClassReader(b);
|
ClassReader cr = new ClassReader(b);
|
||||||
ClassWriter cw = new ClassWriter(cr, 0);
|
ClassWriter cw = new ClassWriter(cr, 0);
|
||||||
@ -385,7 +386,7 @@ public class Commodore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkReroute(MethodPrinter visitor, Map<String, RerouteMethodData> rerouteMethodDataMap, int opcode, String owner, String name, String desc, Type samMethodType, Type instantiatedMethodType) {
|
private boolean checkReroute(MethodPrinter visitor, Map<String, RerouteMethodData> rerouteMethodDataMap, int opcode, String owner, String name, String desc, Type samMethodType, Type instantiatedMethodType) {
|
||||||
return rerouteMethods(rerouteMethodDataMap, opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.H_INVOKESTATIC, owner, name, desc, data -> {
|
return rerouteMethods(activeCompatibilities, rerouteMethodDataMap, opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.H_INVOKESTATIC, owner, name, desc, data -> {
|
||||||
visitor.visit(Opcodes.INVOKESTATIC, className, buildMethodName(data), buildMethodDesc(data), isInterface, samMethodType, instantiatedMethodType);
|
visitor.visit(Opcodes.INVOKESTATIC, className, buildMethodName(data), buildMethodDesc(data), isInterface, samMethodType, instantiatedMethodType);
|
||||||
rerouteMethodData.add(data);
|
rerouteMethodData.add(data);
|
||||||
});
|
});
|
||||||
@ -555,7 +556,7 @@ public class Commodore {
|
|||||||
But since it is only applied for each class and method call once when they get first loaded, it should not be that bad.
|
But since it is only applied for each class and method call once when they get first loaded, it should not be that bad.
|
||||||
(Although some load time testing could be done)
|
(Although some load time testing could be done)
|
||||||
*/
|
*/
|
||||||
public static boolean rerouteMethods(Map<String, RerouteMethodData> rerouteMethodDataMap, boolean staticCall, String owner, String name, String desc, Consumer<RerouteMethodData> consumer) {
|
public static boolean rerouteMethods(Set<String> activeCompatibilities, Map<String, RerouteMethodData> rerouteMethodDataMap, boolean staticCall, String owner, String name, String desc, Consumer<RerouteMethodData> consumer) {
|
||||||
Type ownerType = Type.getObjectType(owner);
|
Type ownerType = Type.getObjectType(owner);
|
||||||
Class<?> ownerClass;
|
Class<?> ownerClass;
|
||||||
try {
|
try {
|
||||||
@ -578,6 +579,10 @@ public class Commodore {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.requiredCompatibility() != null && !activeCompatibilities.contains(data.requiredCompatibility())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
consumer.accept(data);
|
consumer.accept(data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.CraftFeatureFlag;
|
import org.bukkit.craftbukkit.CraftFeatureFlag;
|
||||||
import org.bukkit.craftbukkit.CraftRegistry;
|
import org.bukkit.craftbukkit.CraftRegistry;
|
||||||
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.attribute.CraftAttribute;
|
import org.bukkit.craftbukkit.attribute.CraftAttribute;
|
||||||
import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
|
import org.bukkit.craftbukkit.attribute.CraftAttributeInstance;
|
||||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
@ -323,7 +324,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|||||||
@Override
|
@Override
|
||||||
public byte[] processClass(PluginDescriptionFile pdf, String path, byte[] clazz) {
|
public byte[] processClass(PluginDescriptionFile pdf, String path, byte[] clazz) {
|
||||||
try {
|
try {
|
||||||
clazz = Commodore.convert(clazz, pdf.getName(), ApiVersion.getOrCreateVersion(pdf.getAPIVersion()));
|
clazz = Commodore.convert(clazz, pdf.getName(), ApiVersion.getOrCreateVersion(pdf.getAPIVersion()), ((CraftServer) Bukkit.getServer()).activeCompatibilities);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Fatal error trying to convert " + pdf.getFullName() + ":" + path, ex);
|
Bukkit.getLogger().log(Level.SEVERE, "Fatal error trying to convert " + pdf.getFullName() + ":" + path, ex);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ settings:
|
|||||||
shutdown-message: Server closed
|
shutdown-message: Server closed
|
||||||
minimum-api: none
|
minimum-api: none
|
||||||
use-map-color-cache: true
|
use-map-color-cache: true
|
||||||
|
compatibility:
|
||||||
|
allow-old-keys-in-registry: false
|
||||||
spawn-limits:
|
spawn-limits:
|
||||||
monsters: 70
|
monsters: 70
|
||||||
animals: 10
|
animals: 10
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren