Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-23 23:00:35 +01:00
Fix issues with decoding and Java fallback native
Dieser Commit ist enthalten in:
Ursprung
a16684564b
Commit
6ff5cac4d3
@ -37,12 +37,13 @@ public class JavaVelocityCipher implements VelocityCipher {
|
||||
@Override
|
||||
public void process(ByteBuf source) {
|
||||
ensureNotDisposed();
|
||||
Preconditions.checkArgument(source.hasArray(), "No source array");
|
||||
|
||||
int inBytes = source.readableBytes();
|
||||
byte[] asBytes = ByteBufUtil.getBytes(source);
|
||||
|
||||
try {
|
||||
cipher.update(asBytes, 0, inBytes, asBytes);
|
||||
cipher.update(source.array(), source.arrayOffset(), inBytes, source.array(),
|
||||
source.arrayOffset());
|
||||
} catch (ShortBufferException ex) {
|
||||
/* This _really_ shouldn't happen - AES CFB8 will work in place.
|
||||
If you run into this, that means that for whatever reason the Java Runtime has determined
|
||||
@ -64,6 +65,6 @@ public class JavaVelocityCipher implements VelocityCipher {
|
||||
|
||||
@Override
|
||||
public BufferPreference preferredBufferType() {
|
||||
return BufferPreference.HEAP_PREFERRED;
|
||||
return BufferPreference.HEAP_REQUIRED;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
package com.velocitypowered.natives.util;
|
||||
|
||||
public enum BufferPreference {
|
||||
/**
|
||||
* A heap buffer is required.
|
||||
*/
|
||||
HEAP_REQUIRED,
|
||||
/**
|
||||
* A heap buffer is preferred (but not required).
|
||||
*/
|
||||
|
@ -20,28 +20,30 @@ public class MoreByteBufUtils {
|
||||
* @return a buffer compatible with the native
|
||||
*/
|
||||
public static ByteBuf ensureCompatible(ByteBufAllocator alloc, Native nativeStuff, ByteBuf buf) {
|
||||
if (nativeStuff.preferredBufferType() != BufferPreference.DIRECT_REQUIRED
|
||||
|| buf.hasMemoryAddress()) {
|
||||
if (isCompatible(nativeStuff, buf)) {
|
||||
return buf.retain();
|
||||
}
|
||||
|
||||
// It's not, so we must make a direct copy.
|
||||
ByteBuf newBuf = alloc.directBuffer(buf.readableBytes());
|
||||
ByteBuf newBuf = preferredBuffer(alloc, nativeStuff, buf.readableBytes());
|
||||
newBuf.writeBytes(buf);
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ByteBuf} that will have the best performance with the specified
|
||||
* {@code nativeStuff}.
|
||||
*
|
||||
* @param alloc the {@link ByteBufAllocator} to use
|
||||
* @param nativeStuff the native we are working with
|
||||
* @return a buffer compatible with the native
|
||||
*/
|
||||
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff) {
|
||||
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED
|
||||
? alloc.directBuffer() : alloc.heapBuffer();
|
||||
private static boolean isCompatible(Native nativeStuff, ByteBuf buf) {
|
||||
BufferPreference preferred = nativeStuff.preferredBufferType();
|
||||
switch (preferred) {
|
||||
case DIRECT_PREFERRED:
|
||||
case HEAP_PREFERRED:
|
||||
// The native prefers this type, but doesn't strictly require we provide it.
|
||||
return true;
|
||||
case DIRECT_REQUIRED:
|
||||
return buf.hasMemoryAddress();
|
||||
case HEAP_REQUIRED:
|
||||
return buf.hasArray();
|
||||
default:
|
||||
throw new AssertionError("Preferred buffer type unknown");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +57,15 @@ public class MoreByteBufUtils {
|
||||
*/
|
||||
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff,
|
||||
int initialCapacity) {
|
||||
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED
|
||||
? alloc.directBuffer(initialCapacity) : alloc.heapBuffer(initialCapacity);
|
||||
switch (nativeStuff.preferredBufferType()) {
|
||||
case HEAP_REQUIRED:
|
||||
case HEAP_PREFERRED:
|
||||
return alloc.heapBuffer(initialCapacity);
|
||||
case DIRECT_PREFERRED:
|
||||
case DIRECT_REQUIRED:
|
||||
return alloc.directBuffer(initialCapacity);
|
||||
default:
|
||||
throw new AssertionError("Preferred buffer type unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,11 @@ public class MinecraftCipherDecoder extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
ByteBuf compatible = MoreByteBufUtils.ensureCompatible(ctx.alloc(), cipher, in);
|
||||
ByteBuf compatible = MoreByteBufUtils.ensureCompatible(ctx.alloc(), cipher, in).slice();
|
||||
try {
|
||||
cipher.process(compatible);
|
||||
out.add(compatible);
|
||||
in.skipBytes(in.readableBytes());
|
||||
} catch (Exception e) {
|
||||
compatible.release(); // compatible will never be used if we throw an exception
|
||||
throw e;
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren