Tags
Creators
Details
1.0.1
Compatibility
Changes
KrepAPI 1.0.1-Mod
Issues that have been fixed
ByteBuffer with Fixed-Size Allocation — No Bounds Check
In ProtocolMessages, ByteBuffer.allocate(65536) is used for bindings and 512 for Hello/ClientInfo. If a payload grows larger (e.g. many bindings with long strings), there's a silent BufferOverflowException crash. No dynamic growth, no try-catch.
c2s_key_action Handler is Empty
In the Fabric server code, the receiver for KrepapiKeyActionC2SPayload is completely empty — registerGlobalReceiver(..., (payload, context) -> {}). Key presses on the Fabric server are therefore silently ignored. This isn't a bug if you're using Paper, but it's entirely undocumented for Fabric server users.
No Input Validation in ProtocolBuf.readUtf()
Without a length limit on UTF string reads, a malicious client can send arbitrarily long strings in actionId or modVersion. This leads to uncontrolled heap growth during decoding. Standard practice in Minecraft protocol code: a fixed max-byte limit per string.
Dispatch Doesn't Cancel on First Match
In KrepapiKeyPipeline.dispatch(), consume = true is set when a listener returns true, but all subsequent listeners still run. This is a deliberate non-early-exit, but it means: a low-priority listener cannot set consume back to false afterwards — the variable is never reset. As a result, all downstream listeners always run to completion, even if the event was already consumed long before.
volatile Fields Instead of AtomicReference / Final Config
requireClientOnDedicatedServer, minimumModVersion, and handshakeTimeoutTicks are all volatile. For simple primitives this is correct, but for Strings (like minimumModVersion), volatile only protects the reference, not the contents — though this is sufficient here since Strings are immutable. Still stylistically questionable compared to a clean config class.
Lexicographic Version Comparison
With minimum-mod-version: "1.9" and then "1.10" — lexicographically "1.9" > "1.10" (since '9' > '1'). The project documents this as a known limitation, but it's a real footgun for server admins. No real SemVer parser.
HANDSHAKE_TICKS Map Doesn't Clean Up Reliably
In the tick event, HANDSHAKE_TICKS.remove(id) is only called on e.answered or timeout. If a player disconnects before the timeout fires, the entry is removed in the DISCONNECT event — but only from HANDSHAKE, not explicitly from HANDSHAKE_TICKS (which has its own separate remove). Fine in isolation, but with many rapid joins from unmodded clients the map could grow.
No Unit Tests
None. The :protocol module would be ideal for encode/decode roundtrip tests — it's independent of Minecraft, pure Java. Tests would be especially important for the ByteBuffer handling and the version policy logic.
Release Phase Not Wired Up
KeyAction.PHASE_RELEASE is defined in the code and transmitted in the protocol, but the client-side KeyMapping never fires a release event. Documented, but still an incomplete feature.
Notes
- Install a Fabric API build that matches the Minecraft version.
KrepAPI (for developers)
- Build version (Fabric mod release /
c2s_client_info.modVersion,gradle.properties→mod_version): 1.0.1 - Wire protocol version (
KrepapiProtocolVersion.CURRENT,protocolVersionins2c_hello/c2s_client_info): 1 — increment only when the binary packet layout or semantics change
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:uRt7iUC0:1vEgRo0L"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:uRt7iUC0:1vEgRo0L"
}

