-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- paper support - outgoing packet injection - convert to java - move to multi module project
- Loading branch information
Showing
32 changed files
with
732 additions
and
443 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,3 +38,5 @@ hs_err_*.log | |
replay_*.log | ||
*.hprof | ||
*.jfr | ||
|
||
**/run*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
plugins { | ||
java | ||
`maven-publish` | ||
} | ||
|
||
fun prop(name: String) = project.rootProject.property(name) as String | ||
|
||
group = prop("group") | ||
version = prop("version") | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
compileOnly("io.netty:netty-all:4.1.97.Final") | ||
compileOnly("org.slf4j:slf4j-api:1.7.30") | ||
} | ||
|
||
publishing { | ||
publications { | ||
create<MavenPublication>("mavenJava") { | ||
artifactId = project.name | ||
from(components["java"]) | ||
} | ||
} | ||
|
||
repositories { | ||
runCatching { // getenv throws if variable doesn't exist | ||
val mavenUser = System.getenv("MAVEN_USERNAME_ANDANTE") | ||
val mavenPass = System.getenv("MAVEN_PASSWORD_ANDANTE") | ||
|
||
maven { | ||
name = "Andante" | ||
url = uri("https://maven.andante.dev/releases/") | ||
|
||
credentials { | ||
username = mavenUser | ||
password = mavenPass | ||
} | ||
} | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
api/src/main/java/net/mcbrawls/inject/api/InjectPlatform.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package net.mcbrawls.inject.api; | ||
|
||
/** | ||
* A platform for Inject, like Fabric or Paper. | ||
*/ | ||
public interface InjectPlatform { | ||
/** | ||
* Registers the injector. | ||
* @param injector The injector. | ||
*/ | ||
void registerInjector(Injector injector); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package net.mcbrawls.inject.api; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
import io.netty.channel.ChannelDuplexHandler; | ||
import io.netty.channel.ChannelHandler.Sharable; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import io.netty.channel.ChannelPromise; | ||
|
||
/** | ||
* A Netty injector. | ||
*/ | ||
@Sharable | ||
public abstract class Injector extends ChannelDuplexHandler { | ||
/** | ||
* Predicate for matching if this injector is relevant | ||
* to the given context. | ||
* @param ctx The context. | ||
* @param direction The direction in which this packet goes. | ||
* @return true if it's relevant and should be handled by this injector, false if not. | ||
*/ | ||
public boolean isRelevant(InjectorContext ctx, PacketDirection direction) { | ||
return false; | ||
} | ||
|
||
/** | ||
* Gets executed on every channel read. | ||
* @param ctx The context. | ||
* @param buf The read byte buffer. | ||
* @return true if the channel read was handled and should not get | ||
* delegated to the superclass, false if it should be delegated to the superclass. | ||
*/ | ||
public boolean onRead(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { | ||
return false; | ||
} | ||
|
||
/** | ||
* Gets executed on every channel write. | ||
* @param ctx The context. | ||
* @param buf The written byte buffer. | ||
* @param promise The mutable channel future. | ||
* @return true if the channel write was handled and should not get | ||
* delegated to the superclass, false if it should be delegated to the superclass. | ||
*/ | ||
public boolean onWrite(ChannelHandlerContext ctx, ByteBuf buf, ChannelPromise promise) { | ||
return false; | ||
} | ||
|
||
@Override | ||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { | ||
ByteBuf buf = (ByteBuf) msg; | ||
InjectorContext context = new InjectorContext(ctx.pipeline(), buf); | ||
if (!isRelevant(context, PacketDirection.INBOUND)) { | ||
super.channelRead(ctx, msg); | ||
return; | ||
} | ||
|
||
if (!onRead(ctx, buf)) super.channelRead(ctx, msg); | ||
} | ||
|
||
@Override | ||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { | ||
ByteBuf buf = (ByteBuf) msg; | ||
InjectorContext context = new InjectorContext(ctx.pipeline(), buf); | ||
if (!isRelevant(context, PacketDirection.OUTBOUND)) { | ||
super.write(ctx, msg, promise); | ||
return; | ||
} | ||
|
||
if (!onWrite(ctx, buf, promise)) super.write(ctx, msg, promise); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
api/src/main/java/net/mcbrawls/inject/api/InjectorContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package net.mcbrawls.inject.api; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
import io.netty.channel.ChannelPipeline; | ||
|
||
/** | ||
* Context of an injector. | ||
* @param pipeline The channel pipeline. | ||
* @param message The read byte buffer. | ||
*/ | ||
public record InjectorContext(ChannelPipeline pipeline, ByteBuf message) {} |
9 changes: 9 additions & 0 deletions
9
api/src/main/java/net/mcbrawls/inject/api/PacketDirection.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package net.mcbrawls.inject.api; | ||
|
||
/** | ||
* The direction in which packets can flow. | ||
*/ | ||
public enum PacketDirection { | ||
INBOUND, | ||
OUTBOUND | ||
} |
63 changes: 63 additions & 0 deletions
63
api/src/main/java/net/mcbrawls/inject/api/http/HttpByteBuf.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package net.mcbrawls.inject.api.http; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
/** | ||
* A custom ByteBuf used for sending HTTP responses using HttpInterceptor. | ||
*/ | ||
public class HttpByteBuf { | ||
private final ByteBuf inner; | ||
|
||
public HttpByteBuf(ByteBuf inner) { | ||
this.inner = inner; | ||
} | ||
|
||
/** | ||
* Writes the status line to the buffer. | ||
* Format is as following: | ||
* HTTP/{protocolVersion} {statusCode} {statusMessage} \n | ||
*/ | ||
public void writeStatusLine(String protocolVersion, int statusCode, String statusMessage) { | ||
inner.writeCharSequence("HTTP/" + protocolVersion + " " + statusCode + " " + statusMessage + "\n", StandardCharsets.US_ASCII); | ||
} | ||
|
||
/** | ||
* Writes an HTTP header to the buffer. | ||
*/ | ||
public void writeHeader(String header, String value) { | ||
inner.writeCharSequence(header + ": " + value + "\n", StandardCharsets.US_ASCII); | ||
} | ||
|
||
/** | ||
* Writes text to the buffer. | ||
*/ | ||
public void writeText(String text) { | ||
inner.writeCharSequence("\n" + text, StandardCharsets.US_ASCII); | ||
} | ||
|
||
/** | ||
* Writes a byte array to the buffer. | ||
*/ | ||
public void writeBytes(byte[] bytes) { | ||
inner.writeCharSequence("\n", StandardCharsets.US_ASCII); | ||
inner.writeBytes(bytes); | ||
} | ||
|
||
/** | ||
* @return the inner byte buf | ||
*/ | ||
public ByteBuf inner() { | ||
return inner; | ||
} | ||
|
||
/** | ||
* Creates a new {@link HttpByteBuf} based off a {@link ChannelHandlerContext}'s allocator. | ||
* @param ctx the context | ||
* @return the HTTP byte buf | ||
*/ | ||
public static HttpByteBuf httpBuf(ChannelHandlerContext ctx) { | ||
return new HttpByteBuf(ctx.alloc().buffer()); | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
api/src/main/java/net/mcbrawls/inject/api/http/HttpInjector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package net.mcbrawls.inject.api.http; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
import io.netty.channel.ChannelFutureListener; | ||
import io.netty.channel.ChannelHandler.Sharable; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import net.mcbrawls.inject.api.Injector; | ||
import net.mcbrawls.inject.api.InjectorContext; | ||
import net.mcbrawls.inject.api.PacketDirection; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
@Sharable | ||
public abstract class HttpInjector extends Injector { | ||
private final Logger logger = LoggerFactory.getLogger("HttpInjector " + hashCode()); | ||
|
||
public abstract boolean isRelevant(InjectorContext ctx, HttpRequest request); | ||
|
||
public abstract HttpByteBuf intercept(ChannelHandlerContext ctx, HttpRequest request); | ||
|
||
@Override | ||
public boolean isRelevant(InjectorContext ctx, PacketDirection direction) { | ||
return isRequestGet(ctx.message()); | ||
} | ||
|
||
@Override | ||
public boolean onRead(ChannelHandlerContext ctx, ByteBuf buf) throws Exception { | ||
HttpRequest request = HttpRequest.parse(buf); | ||
HttpByteBuf response = intercept(ctx, request); | ||
|
||
ctx.writeAndFlush(response.inner()) | ||
.addListener(ChannelFutureListener.CLOSE) | ||
.addListener(future -> { | ||
Throwable cause = future.cause(); | ||
if (cause == null) { | ||
logger.debug("Write successful"); | ||
} else { | ||
logger.error("Write failed: {}", String.valueOf(cause)); | ||
//noinspection CallToPrintStackTrace | ||
cause.printStackTrace(); | ||
} | ||
}); | ||
|
||
return true; | ||
} | ||
|
||
private boolean isRequestMethod(ByteBuf buf, @SuppressWarnings("SameParameterValue") String method) { | ||
for (int i = 0; i < method.length(); i++) { | ||
char charAt = method.charAt(i); | ||
int byteAt = buf.getUnsignedByte(i); | ||
if (charAt != byteAt) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
private boolean isRequestGet(ByteBuf buf) { | ||
return isRequestMethod(buf, "GET "); | ||
} | ||
} |
Oops, something went wrong.