Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 6 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
java-version: '21'

- name: validate gradle wrapper
- name: wrapper validation
uses: gradle/actions/wrapper-validation@v4

- name: make gradle wrapper executable
if: ${{ runner.os != 'Windows' }}
run: chmod +x ./gradlew

- name: build
run: ./gradlew build --stacktrace

10 changes: 7 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@ name: Release
on: [workflow_dispatch] # Manual trigger
jobs:
build:
runs-on: ${{ matrix.os }}
runs-on: ubuntu-24.04
steps:
- name: checkout repository
uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
java-version: '21'

- name: validate gradle wrapper
- name: wrapper validation
uses: gradle/actions/wrapper-validation@v4

- name: make gradle wrapper executable
if: ${{ runner.os != 'Windows' }}
run: chmod +x ./gradlew

- name: build
run: ./gradlew build publish --stacktrace
env:
Expand Down
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ plugins {
id 'eclipse'
id 'idea'
id 'maven-publish'
id 'fabric-loom' version '1.10-SNAPSHOT' apply false
id 'ploceus' version '1.10-SNAPSHOT' apply false
id 'fabric-loom' version '1.12-SNAPSHOT' apply false
id 'ploceus' version '1.12-SNAPSHOT' apply false
}

setUpJar(project)
Expand Down Expand Up @@ -49,7 +49,7 @@ def setUpJar(project) {
project.group = "${project.rootProject.root_maven_group}"

project.ploceus {
setGeneration(2)
setIntermediaryGeneration(2)
}

project.repositories {
Expand Down Expand Up @@ -194,7 +194,7 @@ def setUpModule(project, String... dependencies) {
}
}
project.ploceus {
setGeneration(2)
setIntermediaryGeneration(2)
}

def libraries = getLibraryDependencies(project, dependencies)
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
9 changes: 4 additions & 5 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -115,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""


# Determine the Java command to use to start the JVM.
Expand Down Expand Up @@ -206,15 +205,15 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

# Stop when "xargs" is not available.
Expand Down
4 changes: 2 additions & 2 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*

:end
@rem End local scope for the variables with windows NT shell
Expand Down
1 change: 1 addition & 0 deletions libraries/networking-impl/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
setUpLibrary(project)
2 changes: 2 additions & 0 deletions libraries/networking-impl/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
version = 0.1.0
archives_base_name = networking-impl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
setUpModule(project,
'entrypoints-mc13w16a-04192037-mc1.14.4',
'lifecycle-events-mc13w36a-09051446-mc1.13',
'networking-mc13w41a-mc18w30b'
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
environment = *
min_mc_version = 1.13-pre3
max_mc_version = 1.13-pre3
mc_version_range = >=1.13-rc.3 <=1.13-rc.3

minecraft_version = 1.13-pre3
feather_build = 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package net.ornithemc.osl.networking.impl;

import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;

import net.ornithemc.osl.entrypoints.api.ModInitializer;
import net.ornithemc.osl.entrypoints.api.client.ClientModInitializer;
import net.ornithemc.osl.entrypoints.api.server.ServerModInitializer;
import net.ornithemc.osl.lifecycle.api.client.MinecraftClientEvents;
import net.ornithemc.osl.lifecycle.api.server.MinecraftServerEvents;
import net.ornithemc.osl.networking.api.IdentifierChannelIdentifierParser;
import net.ornithemc.osl.networking.api.PacketBuffers;
import net.ornithemc.osl.networking.api.StringChannelIdentifierParser;
import net.ornithemc.osl.networking.api.client.ClientConnectionEvents;
import net.ornithemc.osl.networking.api.server.ServerConnectionEvents;
import net.ornithemc.osl.networking.impl.access.NetworkHandlerAccess;
import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl;
import net.ornithemc.osl.networking.impl.server.ServerPlayNetworkingImpl;

public class Networking implements ModInitializer, ClientModInitializer, ServerModInitializer {

@Override
public void init() {
MinecraftServerEvents.START.register(ServerPlayNetworkingImpl::setUp);
MinecraftServerEvents.STOP.register(ServerPlayNetworkingImpl::destroy);
ServerPlayNetworkingImpl.setUpPacketFactory((channel, data) ->
new CustomPayloadS2CPacket(IdentifierChannelIdentifierParser.toIdentifier(channel), PacketBuffers.unwrapped(data)));
ServerPlayNetworkingImpl.registerListener(HandshakePayload.CHANNEL, HandshakePayload::new, (context, payload) -> {
// send channel registration data as a response to receiving client channel registration data
ServerPlayNetworkingImpl.sendNoCheck(context.player(), HandshakePayload.CHANNEL, HandshakePayload.server());

((NetworkHandlerAccess)context.networkHandler()).osl$networking$registerChannels(payload.channels);
ServerConnectionEvents.PLAY_READY.invoker().accept(context.server(), context.player());
});
}

@Override
public void initClient() {
MinecraftClientEvents.START.register(ClientPlayNetworkingImpl::setUp);
MinecraftClientEvents.STOP.register(ClientPlayNetworkingImpl::destroy);
ClientPlayNetworkingImpl.setUpPacketFactory((channel, data) ->
new CustomPayloadC2SPacket(StringChannelIdentifierParser.toString(channel), PacketBuffers.unwrapped(data)));
ClientPlayNetworkingImpl.registerListener(HandshakePayload.CHANNEL, HandshakePayload::new, (context, payload) -> {
((NetworkHandlerAccess)context.networkHandler()).osl$networking$registerChannels(payload.channels);
ClientConnectionEvents.PLAY_READY.invoker().accept(context.minecraft());
});
}

@Override
public void initServer() {
// no-op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@
import net.minecraft.client.network.handler.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;

import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
import net.ornithemc.osl.networking.api.client.ClientConnectionEvents;
import net.ornithemc.osl.networking.impl.HandshakePayload;
import net.ornithemc.osl.networking.impl.access.NetworkHandlerAccess;
import net.ornithemc.osl.networking.impl.client.ClientPlayNetworkingImpl;
import net.ornithemc.osl.networking.impl.interfaces.mixin.INetworkHandler;

@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin implements INetworkHandler {
public class ClientPlayNetworkHandlerMixin implements NetworkHandlerAccess {

@Shadow @Final private Minecraft minecraft;

/**
* Channels that the server is listening to.
*/
@Unique private Set<String> serverChannels;
@Unique private Set<NamespacedIdentifier> serverChannels;

@Inject(
method = "handleLogin",
Expand All @@ -38,7 +39,7 @@ public class ClientPlayNetworkHandlerMixin implements INetworkHandler {
)
private void osl$networking$handleLogin(CallbackInfo ci) {
// send channel registration data as soon as login occurs
ClientPlayNetworkingImpl.doSend(HandshakePayload.CHANNEL, HandshakePayload.client());
ClientPlayNetworkingImpl.sendNoCheck(HandshakePayload.CHANNEL, HandshakePayload.client());

ClientConnectionEvents.LOGIN.invoker().accept(minecraft);
}
Expand All @@ -62,7 +63,7 @@ public class ClientPlayNetworkHandlerMixin implements INetworkHandler {
)
)
private void osl$networking$handleCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) {
if (ClientPlayNetworkingImpl.handle(minecraft, (ClientPlayNetworkHandler)(Object)this, packet)) {
if (ClientPlayNetworkingImpl.handlePacket(minecraft, (ClientPlayNetworkHandler)(Object)this, packet)) {
ci.cancel();
}
}
Expand All @@ -73,12 +74,12 @@ public class ClientPlayNetworkHandlerMixin implements INetworkHandler {
}

@Override
public void osl$networking$registerChannels(Set<String> channels) {
serverChannels = new LinkedHashSet<>(channels);
public boolean osl$networking$isPlayReady(NamespacedIdentifier channel) {
return serverChannels != null && serverChannels.contains(channel);
}

@Override
public boolean osl$networking$isRegisteredChannel(String channel) {
return serverChannels != null && serverChannels.contains(channel);
public void osl$networking$registerChannels(Set<NamespacedIdentifier> channels) {
serverChannels = new LinkedHashSet<>(channels);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.ornithemc.osl.networking.impl.mixin.client;

import org.spongepowered.asm.mixin.Mixin;

import net.minecraft.client.Minecraft;
import net.minecraft.util.BlockableEventLoop;

import net.ornithemc.osl.networking.impl.access.TaskRunnerAccess;

@Mixin(Minecraft.class)
public abstract class MinecraftMixin implements BlockableEventLoop, TaskRunnerAccess {

@Override
public boolean osl$networking$submit(Runnable task) {
this.submit(task);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package net.ornithemc.osl.networking.impl.mixin.common;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;

import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
import net.ornithemc.osl.networking.api.PacketBuffer;
import net.ornithemc.osl.networking.api.PacketBuffers;
import net.ornithemc.osl.networking.api.StringChannelIdentifierParser;
import net.ornithemc.osl.networking.impl.access.CustomPayloadPacketAccess;

@Mixin(CustomPayloadC2SPacket.class)
public class CustomPayloadC2SPacketMixin implements CustomPayloadPacketAccess {

@Shadow private String channel;
@Shadow private PacketByteBuf data;

@ModifyConstant(
method = "read",
constant = @Constant(
intValue = 20
)
)
private int osl$networking$modifyMaxChannelLength(int maxLength) {
return StringChannelIdentifierParser.MAX_LENGTH;
}

@Inject(
method = "m_9429910",
cancellable = true,
at = @At(
value = "INVOKE",
shift = Shift.AFTER,
target = "Lnet/minecraft/server/network/handler/ServerPlayPacketHandler;handleCustomPayload(Lnet/minecraft/network/packet/c2s/play/CustomPayloadC2SPacket;)V"
)
)
private void osl$networking$skipBufferRelease(CallbackInfo ci) {
// there's a call to ByteBuf.release() that we want to skip
// so that we can queue packet handling to the main thread
// Vanilla does this by throwing an exception but for the sake
// of version compat we cannot use the same approach
ci.cancel();
}

@Override
public NamespacedIdentifier osl$networking$getChannel() {
return StringChannelIdentifierParser.fromString(channel);
}

@Override
public PacketBuffer osl$networking$getData() {
return PacketBuffers.wrapped(data.copy());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.ornithemc.osl.networking.impl.mixin.common;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.resource.Identifier;

import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
import net.ornithemc.osl.networking.api.IdentifierChannelIdentifierParser;
import net.ornithemc.osl.networking.api.PacketBuffer;
import net.ornithemc.osl.networking.api.PacketBuffers;
import net.ornithemc.osl.networking.impl.access.CustomPayloadPacketAccess;

@Mixin(CustomPayloadS2CPacket.class)
public class CustomPayloadS2CPacketMixin implements CustomPayloadPacketAccess {

@Shadow private Identifier channel;
@Shadow private PacketByteBuf data;

@Override
public NamespacedIdentifier osl$networking$getChannel() {
return IdentifierChannelIdentifierParser.fromIdentifier(channel);
}

@Override
public PacketBuffer osl$networking$getData() {
return PacketBuffers.wrapped(data.copy());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.ornithemc.osl.networking.impl.mixin.common;

import org.spongepowered.asm.mixin.Mixin;

import net.minecraft.server.MinecraftServer;
import net.minecraft.util.BlockableEventLoop;

import net.ornithemc.osl.networking.impl.access.TaskRunnerAccess;

@Mixin(MinecraftServer.class)
public abstract class MinecraftServerMixin implements BlockableEventLoop, TaskRunnerAccess {

@Override
public boolean osl$networking$submit(Runnable task) {
this.submit(task);
return true;
}
}
Loading
Loading