Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-06 00:00:47 +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
|
@Override
|
||||||
public void process(ByteBuf source) {
|
public void process(ByteBuf source) {
|
||||||
ensureNotDisposed();
|
ensureNotDisposed();
|
||||||
|
Preconditions.checkArgument(source.hasArray(), "No source array");
|
||||||
|
|
||||||
int inBytes = source.readableBytes();
|
int inBytes = source.readableBytes();
|
||||||
byte[] asBytes = ByteBufUtil.getBytes(source);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cipher.update(asBytes, 0, inBytes, asBytes);
|
cipher.update(source.array(), source.arrayOffset(), inBytes, source.array(),
|
||||||
|
source.arrayOffset());
|
||||||
} catch (ShortBufferException ex) {
|
} catch (ShortBufferException ex) {
|
||||||
/* This _really_ shouldn't happen - AES CFB8 will work in place.
|
/* 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
|
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
|
@Override
|
||||||
public BufferPreference preferredBufferType() {
|
public BufferPreference preferredBufferType() {
|
||||||
return BufferPreference.HEAP_PREFERRED;
|
return BufferPreference.HEAP_REQUIRED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package com.velocitypowered.natives.util;
|
package com.velocitypowered.natives.util;
|
||||||
|
|
||||||
public enum BufferPreference {
|
public enum BufferPreference {
|
||||||
|
/**
|
||||||
|
* A heap buffer is required.
|
||||||
|
*/
|
||||||
|
HEAP_REQUIRED,
|
||||||
/**
|
/**
|
||||||
* A heap buffer is preferred (but not required).
|
* A heap buffer is preferred (but not required).
|
||||||
*/
|
*/
|
||||||
|
@ -20,28 +20,30 @@ public class MoreByteBufUtils {
|
|||||||
* @return a buffer compatible with the native
|
* @return a buffer compatible with the native
|
||||||
*/
|
*/
|
||||||
public static ByteBuf ensureCompatible(ByteBufAllocator alloc, Native nativeStuff, ByteBuf buf) {
|
public static ByteBuf ensureCompatible(ByteBufAllocator alloc, Native nativeStuff, ByteBuf buf) {
|
||||||
if (nativeStuff.preferredBufferType() != BufferPreference.DIRECT_REQUIRED
|
if (isCompatible(nativeStuff, buf)) {
|
||||||
|| buf.hasMemoryAddress()) {
|
|
||||||
return buf.retain();
|
return buf.retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's not, so we must make a direct copy.
|
// 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);
|
newBuf.writeBytes(buf);
|
||||||
return newBuf;
|
return newBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static boolean isCompatible(Native nativeStuff, ByteBuf buf) {
|
||||||
* Creates a {@link ByteBuf} that will have the best performance with the specified
|
BufferPreference preferred = nativeStuff.preferredBufferType();
|
||||||
* {@code nativeStuff}.
|
switch (preferred) {
|
||||||
*
|
case DIRECT_PREFERRED:
|
||||||
* @param alloc the {@link ByteBufAllocator} to use
|
case HEAP_PREFERRED:
|
||||||
* @param nativeStuff the native we are working with
|
// The native prefers this type, but doesn't strictly require we provide it.
|
||||||
* @return a buffer compatible with the native
|
return true;
|
||||||
*/
|
case DIRECT_REQUIRED:
|
||||||
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff) {
|
return buf.hasMemoryAddress();
|
||||||
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED
|
case HEAP_REQUIRED:
|
||||||
? alloc.directBuffer() : alloc.heapBuffer();
|
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,
|
public static ByteBuf preferredBuffer(ByteBufAllocator alloc, Native nativeStuff,
|
||||||
int initialCapacity) {
|
int initialCapacity) {
|
||||||
return nativeStuff.preferredBufferType() != BufferPreference.HEAP_PREFERRED
|
switch (nativeStuff.preferredBufferType()) {
|
||||||
? alloc.directBuffer(initialCapacity) : alloc.heapBuffer(initialCapacity);
|
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
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
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 {
|
try {
|
||||||
cipher.process(compatible);
|
cipher.process(compatible);
|
||||||
out.add(compatible);
|
out.add(compatible);
|
||||||
|
in.skipBytes(in.readableBytes());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
compatible.release(); // compatible will never be used if we throw an exception
|
compatible.release(); // compatible will never be used if we throw an exception
|
||||||
throw e;
|
throw e;
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren