diff --git a/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingMessage.java b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingMessage.java
new file mode 100644
index 00000000..2450de72
--- /dev/null
+++ b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingMessage.java
@@ -0,0 +1,20 @@
+package com.codedisaster.steamworks;
+
+public class SteamNetworkingMessage {
+
+ public byte[] payload;
+
+ public int connectionHandle;
+
+ public SteamNetworkingMessage() {
+
+ }
+
+ public byte[] getPayload() {
+ return payload;
+ }
+
+ public long getConnectionHandle() {
+ return connectionHandle;
+ }
+}
diff --git a/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSockets.java b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSockets.java
new file mode 100644
index 00000000..9b4e88ee
--- /dev/null
+++ b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSockets.java
@@ -0,0 +1,176 @@
+package com.codedisaster.steamworks;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SteamNetworkingSockets extends SteamInterface {
+
+ public static final int SEND_FLAG_UNRELIABLE = 0;
+ public static final int SEND_FLAG_NO_NAGLE = 1;
+ public static final int SEND_FLAG_NO_DELAY = 4;
+ public static final int SEND_FLAG_RELIABLE = 8;
+ public static final int SEND_FLAG_AUTO_RESTART = 32;
+
+ public SteamNetworkingSockets(SteamNetworkingSocketsCallback callback) {
+ super(SteamNetworkingSocketsNative.createCallback(callback));
+ }
+
+ public int connectP2P(long steamID, int numVirtualPorts){
+ return SteamNetworkingSocketsNative.connectP2P(steamID, numVirtualPorts);
+ }
+
+ public int createListenSocketP2P(int numVirtualPorts){
+ return SteamNetworkingSocketsNative.createListenSocketP2P(numVirtualPorts);
+ }
+
+ /**
+ * Accepts an incoming connection request.
+ *
+ * @param connectionHandle The handle of the connection to be accepted.
+ * @return {@link SteamResult} indicating the result of the operation:
+ *
+ * - {@link SteamResult#OK}: Connection successfully accepted.
+ * - {@link SteamResult#InvalidParam}: The provided handle is invalid.
+ * - {@link SteamResult#InvalidState}: The connection state is not appropriate for acceptance (e.g., not in a pending state).
+ *
+ * This method communicates with the native SteamNetworkingSockets API to accept a connection.
+ */
+ public SteamResult acceptConnection(int connectionHandle) {
+ int result = SteamNetworkingSocketsNative.acceptConnection(connectionHandle);
+ return SteamResult.byValue(result);
+ }
+
+
+ public boolean closeConnection(int connectionHandle, int reason, boolean linger){
+ return SteamNetworkingSocketsNative.closeConnection(connectionHandle, reason, linger);
+ }
+
+ public boolean closeListenSocket(int socketHandle){
+ return SteamNetworkingSocketsNative.closeListenSocket(socketHandle);
+ }
+
+ /**
+ * Sends a message to a specified connection.
+ *
+ * @param connectionHandle The handle of the connection to which the message is sent.
+ * @param data The byte array containing the message to be sent.
+ * @param sendFlags Flags controlling how the message is sent.
+ * @return {@link SteamResult} indicating the result of the operation. Possible values include:
+ *
+ * - {@link SteamResult#InvalidParam}: Invalid connection handle, or the message size exceeds the maximum allowed limit (refer to {@code k_cbMaxSteamNetworkingSocketsMessageSizeSend}).
+ * - {@link SteamResult#InvalidState}: Connection is in an invalid state.
+ * - {@link SteamResult#NoConnection}: Connection has ended.
+ * - {@link SteamResult#Ignored}: Message dropped due to usage of {@code k_nSteamNetworkingSend_NoDelay} and unavailability of immediate sending capacity.
+ * - {@link SteamResult#LimitExceeded}: Queue limit for outgoing messages exceeded (refer to {@code k_ESteamNetworkingConfig_SendBufferSize}).
+ *
+ * This method interfaces with the native SteamNetworkingSockets API for message transmission.
+ */
+ public SteamResult sendMessageToConnection(int connectionHandle, byte[] data, int sendFlags) {
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(data.length);
+ buffer.put(data);
+
+ int result = SteamNetworkingSocketsNative.sendMessageToConnection(connectionHandle, buffer, data.length, sendFlags);
+ return SteamResult.byValue(result);
+ }
+
+
+ /**
+ * Flushes messages for a specified connection.
+ *
+ * @param connectionHandle The handle of the connection to flush messages for.
+ * @return {@link SteamResult} indicating the result of the operation. Possible values include:
+ *
+ * - {@link SteamResult#InvalidParam}: Invalid connection handle.
+ * - {@link SteamResult#InvalidState}: Connection is in an invalid state.
+ * - {@link SteamResult#NoConnection}: Connection has ended.
+ * - {@link SteamResult#Ignored}: No effective operation as the connection was not yet established.
+ *
+ * This method communicates with the native SteamNetworkingSockets API to perform the operation.
+ */
+ public SteamResult flushMessages(int connectionHandle) {
+ int result = SteamNetworkingSocketsNative.flushMessages(connectionHandle);
+ return SteamResult.byValue(result);
+ }
+
+
+ public int receiveMessagesOnConnection(int connectionHandle, SteamNetworkingMessage[] messages){
+ return SteamNetworkingSocketsNative.receiveMessagesOnConnection(connectionHandle, messages, messages.length);
+ }
+
+ public int createPollGroup(){
+ return SteamNetworkingSocketsNative.createPollGroup();
+ }
+
+ public boolean destroyPollGroup(int handle){
+ return SteamNetworkingSocketsNative.destroyPollGroup(handle);
+ }
+
+ public boolean setConnectionPollGroup(int connectionHandle, int pollGroupHandle){
+ return SteamNetworkingSocketsNative.setConnectionPollGroup(connectionHandle, pollGroupHandle);
+ }
+
+ public int receiveMessagesOnPollGroup(int pollGroupHandle, SteamNetworkingMessage[] messages){
+ return SteamNetworkingSocketsNative.receiveMessagesOnPollGroup(pollGroupHandle, messages, messages.length);
+ }
+
+ public SteamNetworkingAvailability initAuthentication(){
+ int state = SteamNetworkingSocketsNative.initAuthentication();
+ return SteamNetworkingAvailability.fromValue(state);
+ }
+
+ public SteamNetworkingAvailability getAuthenticationStatus(){
+ int state = SteamNetworkingSocketsNative.getAuthenticationStatus();
+ return SteamNetworkingAvailability.fromValue(state);
+ }
+
+ public void initRelayNetworkAccess(){
+ SteamNetworkingSocketsNative.initRelayNetworkAccess();
+ }
+
+ public SteamNetworkingAvailability getRelayNetworkStatus(){
+ int state = SteamNetworkingSocketsNative.getRelayNetworkStatus();
+ return SteamNetworkingAvailability.fromValue(state);
+ }
+
+ public enum SteamNetworkingAvailability {
+ // Enum values
+ CANNOT_TRY(-102),
+ FAILED(-101),
+ PREVIOUSLY(-100),
+ RETRYING(-10),
+ NEVER_TRIED(1),
+ WAITING(2),
+ ATTEMPTING(3),
+ CURRENT(100),
+ UNKNOWN(0);
+
+ private final int value;
+
+ // Static map to store the mapping from int values to enum constants
+ private static final Map valueToEnumMap = new HashMap<>();
+
+ // Static block to populate the map
+ static {
+ for (SteamNetworkingAvailability availability : values()) {
+ valueToEnumMap.put(availability.value, availability);
+ }
+ }
+
+ SteamNetworkingAvailability(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ // Function to get enum by its value
+ public static SteamNetworkingAvailability fromValue(int value) {
+ return valueToEnumMap.getOrDefault(value, UNKNOWN);
+ }
+ }
+
+
+}
diff --git a/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsCallback.java b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsCallback.java
new file mode 100644
index 00000000..26dc12ad
--- /dev/null
+++ b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsCallback.java
@@ -0,0 +1,65 @@
+package com.codedisaster.steamworks;
+
+public interface SteamNetworkingSocketsCallback {
+
+ void onConnectionStatusChanged(int connectionHandle, long steamID, int connectionState, int prevState);
+
+ public static enum ConnectionState {
+ /**
+ * Indicates an error condition in the API. The specified connection doesn't exist or has already been closed.
+ */
+ NONE(0),
+
+ /**
+ * The process of establishing a connection is ongoing. This includes basic authentication, key exchange, etc.
+ * For client-side connections, this means the connection attempt is in progress.
+ * For server-side connections, it means the connection is ready to be accepted.
+ * Unreliable packets sent now are likely to be dropped.
+ */
+ CONNECTING(1),
+
+ /**
+ * The connection is in the process of finding a route (for certain connection types).
+ * Unreliable messages are likely to be discarded during this state.
+ */
+ FINDING_ROUTE(2),
+
+ /**
+ * A stable connection has been established. Reliable data sent before closing will be flushed and acknowledged.
+ */
+ CONNECTED(3),
+
+ /**
+ * The connection has been closed by the peer but not yet closed locally. The connection still exists,
+ * and any inbound messages can be retrieved before closing it.
+ */
+ CLOSED_BY_PEER(4),
+
+ /**
+ * A local disruption in the connection (e.g., timeout, local internet connection issue) has been detected.
+ * The connection still exists, but attempts to send messages will fail.
+ */
+ PROBLEM_DETECTED_LOCALLY(5);
+
+ private final int value;
+
+ ConnectionState(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static ConnectionState fromValue(int value) {
+ for (ConnectionState state : values()) {
+ if (state.value == value) {
+ return state;
+ }
+ }
+ return null; // or throw an exception
+ }
+ }
+
+
+}
diff --git a/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsNative.java b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsNative.java
new file mode 100644
index 00000000..7a0f4dde
--- /dev/null
+++ b/java-wrapper/src/main/java/com/codedisaster/steamworks/SteamNetworkingSocketsNative.java
@@ -0,0 +1,170 @@
+package com.codedisaster.steamworks;
+
+import java.nio.ByteBuffer;
+
+final class SteamNetworkingSocketsNative {
+
+ // @off
+
+ /*JNI
+ #include
+ #include "SteamNetworkingSocketsCallback.h"
+ #include
+ */
+
+ static native void initRelayNetworkAccess(); /*
+ SteamNetworkingUtils()->InitRelayNetworkAccess();
+ */
+
+ static native int getRelayNetworkStatus();/*
+ return SteamNetworkingUtils()->GetRelayNetworkStatus(NULL);
+ */
+
+ static native long createCallback(SteamNetworkingSocketsCallback javaCallback); /*
+ return (intp) new SteamNetworkingSocketsCallback(env, javaCallback);
+ */
+
+ public static native int connectP2P(long steamID, int numVirtualPorts);/*
+ SteamNetworkingIdentity identity;
+ identity.m_eType = k_ESteamNetworkingIdentityType_SteamID;
+ identity.SetSteamID64(steamID);
+
+ HSteamNetConnection connection = SteamNetworkingSockets()->ConnectP2P(identity, numVirtualPorts, 0, NULL);
+
+ return connection;
+ */
+
+ public static native int createListenSocketP2P(int numVirtualPorts);/*
+ HSteamListenSocket socket = SteamNetworkingSockets()->CreateListenSocketP2P(numVirtualPorts, 0, NULL);
+
+ return socket;
+ */
+
+ public static native int acceptConnection(int netConnectionHandle);/*
+ return SteamNetworkingSockets()->AcceptConnection(netConnectionHandle);
+ */
+
+ public static native boolean closeConnection(int netConnectionHandle, int reason, boolean linger);/*
+ return SteamNetworkingSockets()->CloseConnection(netConnectionHandle, reason, NULL, linger);
+ */
+
+ public static native boolean closeListenSocket(int socketHandle);/*
+ return SteamNetworkingSockets()->CloseListenSocket(socketHandle);
+ */
+
+ public static native int sendMessageToConnection(int netConnectionHandle, ByteBuffer data, int dataLength, int sendFlags);/*
+ return SteamNetworkingSockets()->SendMessageToConnection(netConnectionHandle, (const void*) data, dataLength, sendFlags, NULL);
+ */
+
+ public static native int receiveMessagesOnConnection(int netConnectionHandle, SteamNetworkingMessage[] messageBuffer, int maxMessages);/*
+
+ if(maxMessages <= 0){
+ return 0;
+ }
+
+ jsize arrayLength = env->GetArrayLength(messageBuffer);
+
+ if(arrayLength < maxMessages){
+ return 0;
+ }
+
+ SteamNetworkingMessage_t** ppOutMessages = new SteamNetworkingMessage_t*[maxMessages];
+
+ int num = SteamNetworkingSockets()->ReceiveMessagesOnConnection(netConnectionHandle, ppOutMessages, maxMessages);
+
+ for(int i = 0; i < num;i++){
+ SteamNetworkingMessage_t* netMessage = ppOutMessages[i];
+
+ jobject message = env->GetObjectArrayElement(messageBuffer, i);
+ jclass clazz = env->GetObjectClass(message);
+
+ jfieldID payloadField = env->GetFieldID(clazz, "payload", "[B");
+ jfieldID connectionField = env->GetFieldID(clazz, "connectionHandle", "I");
+
+ jbyteArray javaByteArray = env->NewByteArray(netMessage->m_cbSize);
+
+ env->SetByteArrayRegion(javaByteArray, 0, netMessage->m_cbSize, (const jbyte*) netMessage->m_pData);
+
+ env->SetIntField(message, connectionField, netMessage->m_conn);
+ env->SetObjectField(message, payloadField, javaByteArray);
+
+ env->DeleteLocalRef(javaByteArray);
+ env->DeleteLocalRef(message);
+
+ netMessage->Release();
+ }
+
+ delete[] ppOutMessages;
+
+ return num;
+ */
+
+ public static native int flushMessages(int connectionHandle);/*
+ return SteamNetworkingSockets()->FlushMessagesOnConnection(connectionHandle);
+ */
+
+ public static native int createPollGroup(); /*
+ HSteamNetPollGroup pollGroup = SteamNetworkingSockets()->CreatePollGroup();
+
+ return pollGroup;
+ */
+
+ public static native boolean destroyPollGroup(int handle); /*
+ return SteamNetworkingSockets()->DestroyPollGroup(handle);
+ */
+
+ public static native boolean setConnectionPollGroup(int connectionHandle, int pollGroupHandle); /*
+ return SteamNetworkingSockets()->SetConnectionPollGroup(connectionHandle, pollGroupHandle);
+ */
+
+ public static native int receiveMessagesOnPollGroup(int pollGroupHandle, SteamNetworkingMessage[] messageBuffer, int maxMessages);/*
+ if(maxMessages <= 0){
+ return 0;
+ }
+
+ jsize arrayLength = env->GetArrayLength(messageBuffer);
+
+ if(arrayLength < maxMessages){
+ return 0;
+ }
+
+ SteamNetworkingMessage_t** ppOutMessages = new SteamNetworkingMessage_t*[maxMessages];
+
+ int num = SteamNetworkingSockets()->ReceiveMessagesOnPollGroup(pollGroupHandle, ppOutMessages, maxMessages);
+
+ for(int i = 0; i < num;i++){
+ SteamNetworkingMessage_t* netMessage = ppOutMessages[i];
+
+ jobject message = env->GetObjectArrayElement(messageBuffer, i);
+ jclass clazz = env->GetObjectClass(message);
+
+ jfieldID payloadField = env->GetFieldID(clazz, "payload", "[B");
+ jfieldID connectionField = env->GetFieldID(clazz, "connectionHandle", "I");
+
+ jbyteArray javaByteArray = env->NewByteArray(netMessage->m_cbSize);
+
+ env->SetByteArrayRegion(javaByteArray, 0, netMessage->m_cbSize, (const jbyte*) netMessage->m_pData);
+
+ env->SetIntField(message, connectionField, netMessage->m_conn);
+ env->SetObjectField(message, payloadField, javaByteArray);
+
+ env->DeleteLocalRef(javaByteArray);
+ env->DeleteLocalRef(message);
+
+ netMessage->Release();
+ }
+
+ delete[] ppOutMessages;
+
+ return num;
+ */
+
+ public static native int initAuthentication();/*
+ return SteamNetworkingSockets()->InitAuthentication();
+ */
+
+ public static native int getAuthenticationStatus();/*
+ return SteamNetworkingSockets()->GetAuthenticationStatus(NULL);
+ */
+
+}
diff --git a/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.cpp b/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.cpp
new file mode 100644
index 00000000..655c8c64
--- /dev/null
+++ b/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.cpp
@@ -0,0 +1,18 @@
+#include "SteamNetworkingSocketsCallback.h"
+
+SteamNetworkingSocketsCallback::SteamNetworkingSocketsCallback(JNIEnv* env, jobject callback) :
+ SteamCallbackAdapter(env, callback) {
+}
+
+SteamNetworkingSocketsCallback::~SteamNetworkingSocketsCallback() {
+}
+
+void SteamNetworkingSocketsCallback::onConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* callback) {
+ invokeCallback({
+ callVoidMethod(env, "onConnectionStatusChanged", "(IJII)V",
+ callback->m_hConn,
+ callback->m_info.m_identityRemote.GetSteamID64(),
+ callback->m_info.m_eState,
+ callback->m_eOldState);
+ });
+}
\ No newline at end of file
diff --git a/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.h b/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.h
new file mode 100644
index 00000000..a70c30d6
--- /dev/null
+++ b/java-wrapper/src/main/native/SteamNetworkingSocketsCallback.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "SteamCallbackAdapter.h"
+#include
+
+class SteamNetworkingSocketsCallback : public SteamCallbackAdapter {
+
+public:
+ SteamNetworkingSocketsCallback(JNIEnv* env, jobject callback);
+ ~SteamNetworkingSocketsCallback();
+
+ STEAM_CALLBACK(SteamNetworkingSocketsCallback, onConnectionStatusChanged, SteamNetConnectionStatusChangedCallback_t);
+
+};
\ No newline at end of file
diff --git a/java-wrapper/src/main/resources/steamworks4j.dll b/java-wrapper/src/main/resources/steamworks4j.dll
index 86dc3a55..608dd75d 100644
Binary files a/java-wrapper/src/main/resources/steamworks4j.dll and b/java-wrapper/src/main/resources/steamworks4j.dll differ
diff --git a/java-wrapper/src/main/resources/steamworks4j64.dll b/java-wrapper/src/main/resources/steamworks4j64.dll
index f1649909..4037cb26 100644
Binary files a/java-wrapper/src/main/resources/steamworks4j64.dll and b/java-wrapper/src/main/resources/steamworks4j64.dll differ
diff --git a/server/src/main/resources/steamworks4j-encryptedappticket.dll b/server/src/main/resources/steamworks4j-encryptedappticket.dll
index 53f560e7..d126e478 100644
Binary files a/server/src/main/resources/steamworks4j-encryptedappticket.dll and b/server/src/main/resources/steamworks4j-encryptedappticket.dll differ
diff --git a/server/src/main/resources/steamworks4j-encryptedappticket64.dll b/server/src/main/resources/steamworks4j-encryptedappticket64.dll
index 7752c99e..d88e17b5 100644
Binary files a/server/src/main/resources/steamworks4j-encryptedappticket64.dll and b/server/src/main/resources/steamworks4j-encryptedappticket64.dll differ
diff --git a/server/src/main/resources/steamworks4j-server.dll b/server/src/main/resources/steamworks4j-server.dll
index 7bfd18c1..b36271a6 100644
Binary files a/server/src/main/resources/steamworks4j-server.dll and b/server/src/main/resources/steamworks4j-server.dll differ
diff --git a/server/src/main/resources/steamworks4j-server64.dll b/server/src/main/resources/steamworks4j-server64.dll
index 8a85d72c..b25df386 100644
Binary files a/server/src/main/resources/steamworks4j-server64.dll and b/server/src/main/resources/steamworks4j-server64.dll differ