diff --git a/Cargo.lock b/Cargo.lock index bd7252f..f2f2358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -320,7 +320,7 @@ dependencies = [ [[package]] name = "steamworks" version = "0.11.0" -source = "git+https://github.com/Noxime/steamworks-rs/?rev=fbb79635b06b4feea8261e5ca3e8ea3ef42facf9#fbb79635b06b4feea8261e5ca3e8ea3ef42facf9" +source = "git+https://github.com/Noxime/steamworks-rs/?rev=5fc8ef13d52e82068f031535446d786cf0bd60a8#5fc8ef13d52e82068f031535446d786cf0bd60a8" dependencies = [ "bitflags 1.3.2", "lazy_static", @@ -333,7 +333,7 @@ dependencies = [ [[package]] name = "steamworks-sys" version = "0.11.0" -source = "git+https://github.com/Noxime/steamworks-rs/?rev=fbb79635b06b4feea8261e5ca3e8ea3ef42facf9#fbb79635b06b4feea8261e5ca3e8ea3ef42facf9" +source = "git+https://github.com/Noxime/steamworks-rs/?rev=5fc8ef13d52e82068f031535446d786cf0bd60a8#5fc8ef13d52e82068f031535446d786cf0bd60a8" [[package]] name = "steamworksjs" diff --git a/Cargo.toml b/Cargo.toml index c6d4428..0857e58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ napi = { version = "2.16.8", features = ["tokio_rt", "napi6", "serde-json"] } napi-derive = "2.16.9" lazy_static = "1" tokio = { version = "1", features = ["sync", "time"] } -steamworks = { git = "https://github.com/Noxime/steamworks-rs/", rev = "fbb79635b06b4feea8261e5ca3e8ea3ef42facf9", features = ["serde"] } +steamworks = { git = "https://github.com/Noxime/steamworks-rs/", rev = "5fc8ef13d52e82068f031535446d786cf0bd60a8", features = ["serde"] } serde = "1" serde_json = "1" diff --git a/client.d.ts b/client.d.ts index c2fbb50..d7b98e4 100644 --- a/client.d.ts +++ b/client.d.ts @@ -1,4 +1,4 @@ -export declare function init(appId?: number | undefined | null): void +export declare function init(appId?: number | undefined | null, networking?: boolean | undefined | null): void export declare function restartAppIfNecessary(appId: number): boolean export declare function runCallbacks(): void export interface PlayerSteamId { @@ -188,6 +188,83 @@ export declare namespace networking { export function readP2PPacket(size: number): P2PPacket export function acceptP2PSession(steamId64: bigint): void } +export declare namespace networking_messages { + /** The method used to send a packet */ + export const enum SendType { + /** + * Send the packet directly over udp. + * + * Can't be larger than 1200 bytes + */ + Unreliable = 0, + /** + * Like `Unreliable` but doesn't buffer packets + * sent before the connection has started. + */ + UnreliableNoDelay = 1, + /** + * Reliable packet sending. + * + * Can't be larger than 1 megabyte. + */ + Reliable = 2, + /** + * Like `Reliable` but applies the nagle + * algorithm to packets being sent + */ + ReliableWithBuffering = 3 + } + export function sendMessageToUser(steamId64: bigint, sendType: SendType, data: Buffer, channel?: number | undefined | null): void + export interface Message { + data: Buffer + steamId?: PlayerSteamId + } + export function receiveMessagesOnChannel(channel: number, batchSize?: number | undefined | null): Array +} +export declare namespace networking_sockets { + export function createListenSocketP2P(localVirtualPort?: number | undefined | null): boolean + export function createListenSocketIp(localVirtualPort?: number | undefined | null): boolean + export function setAmIServer(isServer: boolean): void + export function setAcceptNewP2PRequests(accept: boolean): void + export function connectP2P(steamId64: bigint, remoteVirtualPort: number): boolean + export function processListenP2PEvents(): void + export function processListenIpEvents(): void + export interface P2PPacket { + data: Buffer + steamId: bigint + } + export function receiveP2PMessages(batchSize?: number | undefined | null): Array + /** The method used to send a packet */ + export const enum SendType { + /** + * Send the packet directly over udp. + * + * Can't be larger than 1200 bytes + */ + Unreliable = 0, + /** + * Like `Unreliable` but doesn't buffer packets + * sent before the connection has started. + */ + UnreliableNoDelay = 1, + /** + * Reliable packet sending. + * + * Can't be larger than 1 megabyte. + */ + Reliable = 2, + /** + * Like `Reliable` but applies the nagle + * algorithm to packets being sent + */ + ReliableWithBuffering = 3 + } + export function sendP2PMessage(steamId64: bigint, data: Buffer, sendType: SendType): boolean +} +export declare namespace networking_utils { + export function initRelayNetworkAccess(): void + export function detailedRelayNetworkStatus(): string +} export declare namespace overlay { export const enum Dialog { Friends = 0, diff --git a/index.d.ts b/index.d.ts index e249a46..3b97ea5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,4 +1,4 @@ -export function init(appId?: number): Omit; +export function init(appId?: number, networking?: boolean): Omit; export function restartAppIfNecessary(appId: number): boolean; export function electronEnableSteamOverlay(disableEachFrameInvalidation?: boolean): void; export type Client = typeof import("./client.d"); diff --git a/index.js b/index.js index bc9e54d..2b93cb6 100644 --- a/index.js +++ b/index.js @@ -3,32 +3,49 @@ const { platform, arch } = process /** @typedef {typeof import('./client.d')} Client */ /** @type {Client} */ let nativeBinding = undefined - -if (platform === 'win32' && arch === 'x64') { - nativeBinding = require('./dist/win64/steamworksjs.win32-x64-msvc.node') -} else if (platform === 'linux' && arch === 'x64') { - nativeBinding = require('./dist/linux64/steamworksjs.linux-x64-gnu.node') -} else if (platform === 'darwin') { - if (arch === 'x64') { - nativeBinding = require('./dist/osx/steamworksjs.darwin-x64.node') - } else if (arch === 'arm64') { - nativeBinding = require('./dist/osx/steamworksjs.darwin-arm64.node') +if(process.env.IS_TESTING){ + if (platform === 'win32' && arch === 'x64') { + nativeBinding = require('./dist/win64/steamworksjs.win32-x64-msvc.node') + } else if (platform === 'linux' && arch === 'x64') { + nativeBinding = require('./dist/linux64/steamworksjs.linux-x64-gnu.node') + } else if (platform === 'darwin') { + if (arch === 'x64') { + nativeBinding = require('./dist/osx/steamworksjs.darwin-x64.node') + } else if (arch === 'arm64') { + nativeBinding = require('./dist/osx/steamworksjs.darwin-arm64.node') + } + } else { + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) } } else { - throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) + if (platform === 'win32' && arch === 'x64') { + nativeBinding = require('steamworks.js/dist/win64/steamworksjs.win32-x64-msvc.node') + } else if (platform === 'linux' && arch === 'x64') { + nativeBinding = require('steamworks.js/dist/linux64/steamworksjs.linux-x64-gnu.node') + } else if (platform === 'darwin') { + if (arch === 'x64') { + nativeBinding = require('steamworks.js/dist/osx/steamworksjs.darwin-x64.node') + } else if (arch === 'arm64') { + nativeBinding = require('steamworks.js/dist/osx/steamworksjs.darwin-arm64.node') + } + } else { + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) + } } + let runCallbacksInterval = undefined /** * Initialize the steam client or throw an error if it fails * @param {number} [appId] - App ID of the game to load, if undefined, will search for a steam_appid.txt file + * @param {boolean} [networking] - Enable networking * @returns {Omit} */ -module.exports.init = (appId) => { +module.exports.init = (appId, networking) => { const { init: internalInit, runCallbacks, restartAppIfNecessary, ...api } = nativeBinding - internalInit(appId) + internalInit(appId, networking) clearInterval(runCallbacksInterval) runCallbacksInterval = setInterval(runCallbacks, 1000 / 30) diff --git a/src/api/callback.rs b/src/api/callback.rs index 3978088..6a8d179 100644 --- a/src/api/callback.rs +++ b/src/api/callback.rs @@ -90,10 +90,10 @@ pub mod callback { where C: steamworks::Callback + serde::Serialize, { - let client = crate::client::get_client(); - client.register_callback(move |value: C| { - let value = serde_json::to_value(&value).unwrap(); - threadsafe_handler.call(value, ThreadsafeFunctionCallMode::Blocking); - }) + let client = crate::client::get_client(); + client.register_callback(move |value: C| { + let value = serde_json::to_value(&value).unwrap(); + threadsafe_handler.call(value, ThreadsafeFunctionCallMode::Blocking); + }) } } diff --git a/src/api/mod.rs b/src/api/mod.rs index 22161ba..28c5f1d 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -7,6 +7,9 @@ pub mod input; pub mod localplayer; pub mod matchmaking; pub mod networking; +pub mod networking_messages; +pub mod networking_sockets; +pub mod networking_utils; pub mod overlay; pub mod stats; pub mod utils; diff --git a/src/api/networking_messages.rs b/src/api/networking_messages.rs new file mode 100644 index 0000000..9f94489 --- /dev/null +++ b/src/api/networking_messages.rs @@ -0,0 +1,99 @@ +use napi_derive::napi; +// some credit here goes to https://github.com/apxapob as this was heavily inspired by his work + +#[napi] +pub mod networking_messages { + use napi::{ + bindgen_prelude::{BigInt, Buffer}, + Error + }; + use steamworks::{ + SteamId, + SteamError, + ClientManager, + networking_types::{ + SendFlags, + NetworkingIdentity, + NetworkingMessage, + }, + networking_messages::SessionRequest, + }; + + use crate::api::localplayer::PlayerSteamId; + + fn err(steam_err:SteamError) -> Result<(), Error> { + Err(Error::new( + napi::Status::GenericFailure, + steam_err.to_string() + )) + } + + #[napi] + /// The method used to send a packet + pub enum SendType { + /// Send the packet directly over udp. + /// + /// Can't be larger than 1200 bytes + Unreliable, + /// Like `Unreliable` but doesn't buffer packets + /// sent before the connection has started. + UnreliableNoDelay, + /// Reliable packet sending. + /// + /// Can't be larger than 1 megabyte. + Reliable, + /// Like `Reliable` but applies the nagle + /// algorithm to packets being sent + ReliableWithBuffering, + } + + #[napi] + pub fn send_message_to_user( + steam_id64: BigInt, + send_type: SendType, + data: Buffer, + channel: Option + ) -> Result<(), Error> { + let client = crate::client::get_client(); + let steam_id = SteamId::from_raw(steam_id64.get_u64().1); + let identity = NetworkingIdentity::new_steam_id(steam_id); + + client.networking_messages().send_message_to_user( + identity, + match send_type { + SendType::Unreliable => SendFlags::UNRELIABLE, + SendType::UnreliableNoDelay => SendFlags::UNRELIABLE_NO_DELAY, + SendType::ReliableWithBuffering => SendFlags::RELIABLE, // nagle is the new default + SendType::Reliable => SendFlags::RELIABLE_NO_NAGLE, + } & SendFlags::AUTO_RESTART_BROKEN_SESSION, + &data, + channel.unwrap_or(0) + ).or_else(err) + } + + #[napi(object)] + pub struct Message { + pub data: Buffer, + pub steam_id: Option, + } + + #[napi] + pub fn receive_messages_on_channel( + channel: u32, + batch_size: Option + ) -> Vec { + let client = crate::client::get_client(); + + client + .networking_messages() + .receive_messages_on_channel(channel, batch_size.unwrap_or(10).try_into().unwrap()) + .iter().map(|m:&NetworkingMessage| { + let steam_id = m.identity_peer().steam_id(); + + return Message { + data: m.data().into(), + steam_id: steam_id.map(|id| PlayerSteamId::from_steamid(id)) + } + }).collect() + } +} \ No newline at end of file diff --git a/src/api/networking_sockets.rs b/src/api/networking_sockets.rs new file mode 100644 index 0000000..3932b64 --- /dev/null +++ b/src/api/networking_sockets.rs @@ -0,0 +1,270 @@ +use napi_derive::napi; + +#[napi] +pub mod networking_sockets { + use napi::{bindgen_prelude::{BigInt, Buffer}, Error}; + use std::collections::HashMap; + use std::sync::Mutex; + use std::net::{ + Ipv4Addr, SocketAddr + }; + use steamworks::{ + ClientManager as Manager, + SteamId, + networking_types::{ + SendFlags, + NetworkingIdentity, + ListenSocketEvent + }, + networking_sockets::{ + ListenSocket, NetConnection, + }, + }; + use crate::api::localplayer::PlayerSteamId; + + lazy_static! { + static ref LISTEN_P2P: Mutex>> = Mutex::new(None); + static ref LISTEN_IP: Mutex>> = Mutex::new(None); + static ref CONNECTIONS: Mutex>> = Mutex::new(HashMap::new()); + static ref ACCEPT_NEW_REQUESTS: Mutex = Mutex::new(true); + static ref AM_I_SERVER: Mutex = Mutex::new(false); + } + + // used to wait for new connections + #[napi] + pub fn create_listen_socket_p2p(local_virtual_port: Option) -> Result { + let client = crate::client::get_client(); + let port = local_virtual_port.unwrap_or(0); + + let handle = client.networking_sockets().create_listen_socket_p2p(port, None); + + match handle { + Ok(socket) => { + let mut listen_p2p = LISTEN_P2P.lock().unwrap(); + *listen_p2p = Some(socket); + Ok(true) + } + Err(_) => Err(Error::from_reason("Failed to create listen socket")), + } + } + + // allow for ip as well -- we need this for the local client loopback + #[napi] + pub fn create_listen_socket_ip(local_virtual_port: Option) -> Result { + let client = crate::client::get_client(); + let port = local_virtual_port.unwrap_or(0); + + let handle = client.networking_sockets().create_listen_socket_ip( + SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), port.try_into().unwrap()), + vec![], + ); + + match handle { + Ok(socket) => { + let mut listen_ip = LISTEN_IP.lock().unwrap(); + *listen_ip = Some(socket); + Ok(true) + } + Err(_) => Err(Error::from_reason("Failed to create listen socket")), + } + } + + // used to toggle whether locally it is server functionality + #[napi] + pub fn set_am_i_server(is_server: bool) { + *AM_I_SERVER.lock().unwrap() = is_server; + } + + // used to allow or reject new connections + #[napi] + pub fn set_accept_new_p2p_requests(accept: bool) { + *ACCEPT_NEW_REQUESTS.lock().unwrap() = accept; + } + + // used to initiate connection + #[napi] + pub fn connect_p2p(steam_id64: BigInt, remote_virtual_port: i32) -> Result { + // first check if I am server and does the steam_id64 belong to me + // if it does, we can just skip this step and return true + let client = crate::client::get_client(); + let steam_id = SteamId::from_raw(steam_id64.get_u64().1); + + let local_steam_id = PlayerSteamId::from_steamid(client.user().steam_id()); + if local_steam_id.steam_id64.get_u64().1 == steam_id64.get_u64().1 { + // then we need to actually hijack and hit the local server via ip + + let handle = client.networking_sockets().connect_by_ip_address( + SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), remote_virtual_port.try_into().unwrap()), + None + ); + + match handle { + Ok(connection) => { + CONNECTIONS.lock().unwrap().insert(steam_id, connection); + return Ok(true) + } + Err(e) => { + eprintln!("Failed to connect P2P(by IP): {:?}", e); + return Err(Error::from_reason("Failed to connect P2P(by IP)")) + } + } + } + + let identity = NetworkingIdentity::new_steam_id(steam_id); + let handle = client.networking_sockets().connect_p2p(identity, remote_virtual_port, None); + match handle { + Ok(connection) => { + CONNECTIONS.lock().unwrap().insert(steam_id, connection); + Ok(true) + } + Err(e) => { + eprintln!("Failed to connect P2P: {:?}", e); + Err(Error::from_reason("Failed to connect P2P")) + } + } + } + + // used to accept incoming connections + #[napi] + pub fn process_listen_p2p_events() { + // Get the socket if it exists + let guard = LISTEN_P2P.lock().unwrap(); + let socket = if let Some(socket) = guard.as_ref() { + socket + } else { + return; + }; + + // Process all available events for this socket + while let Some(event) = socket.try_receive_event() { + match event { + ListenSocketEvent::Connecting(request) => { + // Check if we should accept the connection request + if *ACCEPT_NEW_REQUESTS.lock().unwrap() { + // Attempt to accept the connection request + if let Err(e) = request.accept() { + eprintln!("Failed to accept connection: {:?}", e); + } + } + } + ListenSocketEvent::Connected(connected) => { + // Grab the steam id of the connected user + let steam_id = connected.remote().steam_id().unwrap(); + // Insert the connection into the CONNECTIONS map + CONNECTIONS.lock().unwrap().insert(steam_id, connected.take_connection()); + } + _ => { + // Ignore other event types for now + } + } + } + } + + // have to accept the connection from own ip, gross but whatever + #[napi] + pub fn process_listen_ip_events() { + // Get the socket if it exists + let guard = LISTEN_IP.lock().unwrap(); + let socket = if let Some(socket) = guard.as_ref() { + socket + } else { + return; + }; + + // Process all available events for this socket + while let Some(event) = socket.try_receive_event() { + match event { + ListenSocketEvent::Connecting(request) => { + // Check if we should accept the connection request + if *ACCEPT_NEW_REQUESTS.lock().unwrap() { + // Attempt to accept the connection request + if let Err(e) = request.accept() { + eprintln!("Failed to accept connection: {:?}", e); + } + } + } + ListenSocketEvent::Connected(connected) => { + // Grab the steam id of the connected user + let steam_id = connected.remote().steam_id().unwrap(); + // Insert the connection into the CONNECTIONS map + CONNECTIONS.lock().unwrap().insert(steam_id, connected.take_connection()); + } + _ => { + // Ignore other event types for now + } + } + } + } + + // now we need a way to receive all mesages + #[napi(object)] + pub struct P2PPacket { + pub data: Buffer, + pub steam_id: BigInt, + } + + #[napi] + pub fn receive_p2p_messages( + batch_size: Option + ) -> Vec { + let mut messages = Vec::new(); + let mut connections = CONNECTIONS.lock().unwrap(); + + for (steam_id, connection) in connections.iter_mut() { + if let Ok(received_messages) = connection.receive_messages(batch_size.unwrap_or(10) as usize) { + for message in received_messages { + messages.push(P2PPacket { + steam_id: BigInt::from(steam_id.raw()), + data: Buffer::from(message.data()), + }); + } + } + } + + messages + } + + #[napi] + /// The method used to send a packet + pub enum SendType { + /// Send the packet directly over udp. + /// + /// Can't be larger than 1200 bytes + Unreliable, + /// Like `Unreliable` but doesn't buffer packets + /// sent before the connection has started. + UnreliableNoDelay, + /// Reliable packet sending. + /// + /// Can't be larger than 1 megabyte. + Reliable, + /// Like `Reliable` but applies the nagle + /// algorithm to packets being sent + ReliableWithBuffering, + } + + // and a way to send messages + #[napi] + pub fn send_p2p_message( + steam_id64: BigInt, + data: Buffer, + send_type: SendType + ) -> Result { + let steam_id = SteamId::from_raw(steam_id64.get_u64().1); + + let mut connections = CONNECTIONS.lock().unwrap(); + if let Some(connection) = connections.get_mut(&steam_id) { + let result = connection.send_message( + &data, + match send_type { + SendType::Unreliable => SendFlags::UNRELIABLE, + SendType::UnreliableNoDelay => SendFlags::UNRELIABLE_NO_DELAY, + SendType::ReliableWithBuffering => SendFlags::RELIABLE, // nagle is the new default + SendType::Reliable => SendFlags::RELIABLE_NO_NAGLE, + } & SendFlags::AUTO_RESTART_BROKEN_SESSION, + ); + return Ok(result.is_ok()); + } + Err(Error::from_reason("Failed to send message")) + } +} \ No newline at end of file diff --git a/src/api/networking_utils.rs b/src/api/networking_utils.rs new file mode 100644 index 0000000..1b26525 --- /dev/null +++ b/src/api/networking_utils.rs @@ -0,0 +1,22 @@ +use napi_derive::napi; + +#[napi] +pub mod networking_utils { + use napi::{ + bindgen_prelude::{BigInt, Buffer}, + Error + }; + + #[napi] + pub fn init_relay_network_access() { + let client = crate::client::get_client(); + client.networking_utils().init_relay_network_access() + } + + #[napi] + pub fn detailed_relay_network_status() -> Result { + let client = crate::client::get_client(); + let status = client.networking_utils().detailed_relay_network_status(); + Ok(status.debugging_message().to_string()) + } +} \ No newline at end of file diff --git a/src/client.rs b/src/client.rs index 78af348..0f952dd 100644 --- a/src/client.rs +++ b/src/client.rs @@ -22,4 +22,4 @@ pub fn set_client(client: Client) { pub fn drop_client() { let mut client_ref = STEAM_CLIENT.lock().unwrap(); *client_ref = None; -} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index f637028..d363c5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ use napi_derive::napi; use steamworks::AppId; use steamworks::Client; use steamworks::SteamAPIInitError; +use std::process; + pub mod client; @@ -10,7 +12,7 @@ pub mod client; extern crate lazy_static; #[napi] -pub fn init(app_id: Option) -> Result<(), Error> { +pub fn init(app_id: Option, networking: Option) -> Result<(), Error> { if client::has_client() { client::drop_client(); } @@ -26,6 +28,21 @@ pub fn init(app_id: Option) -> Result<(), Error> { steam_client.user_stats().request_current_stats(); + // https://github.com/Noxime/steamworks-rs/blob/master/examples/networking-messages/src/main.rs + // networking message acceptance is handled differently than regular callbacks and it cannot be serialized + // at most we allow you to control accepting or rejecting a session request at the rust level + + steam_client.networking_messages().session_request_callback(move |req| { + println!("Accepting session request from {:?}", req.remote()); + // assert!(req.accept()); + req.accept(); + // mimicing the assert! causes it to crash + }); + + steam_client.networking_messages().session_failed_callback(|info| { + println!("Session failed: {:?}", info); + }); + client::set_client(steam_client); Ok(()) } @@ -37,7 +54,22 @@ pub fn restart_app_if_necessary(app_id: u32) -> bool { #[napi] pub fn run_callbacks() { - client::get_client().run_callbacks(); + let c = client::get_client(); + /* + println!("running callbacks in thread {}", std::process::id()); + c.networking_messages().session_request_callback(move |req| { + + // assert!(req.accept()); + req.accept(); + // mimicing the assert! causes it to crash + println!("Accepting session request"); + }); + + c.networking_messages().session_failed_callback(|info| { + println!("Session failed: {:?}", info); + }); + */ + c.run_callbacks(); } pub mod api; diff --git a/test/networking_messages_receive.js b/test/networking_messages_receive.js new file mode 100644 index 0000000..108f0ec --- /dev/null +++ b/test/networking_messages_receive.js @@ -0,0 +1,33 @@ +process.env.IS_TESTING = true + +const { init } = require('../index.js') + +const client = init(480, true) + +client.networking_utils.initRelayNetworkAccess(); + +setInterval(() => { + console.log(client.networking_utils.detailedRelayNetworkStatus()) +}, 1000) + +const mySteamId = client.localplayer.getSteamId().steamId64; + +setInterval(() => { + let messages = [] + try { + messages = client.networking_messages.receiveMessagesOnChannel(1); + + while(messages.length > 0){ + const message = messages.shift(); + console.log("Received message") + console.log(message?.steamId) + console.log(message?.data.toString()); + + // client.networking_messages.sendMessageToUser(mySteamId, 1, Buffer.from("Hello from server!"), 0); + // console.log("Sent message") + } + + } catch (e) { + console.error(e) + } +}, 1000 / 60) diff --git a/test/networking_messages_send.js b/test/networking_messages_send.js new file mode 100644 index 0000000..c1db5ff --- /dev/null +++ b/test/networking_messages_send.js @@ -0,0 +1,48 @@ +process.env.IS_TESTING = true + +const { init } = require('../index.js') + +const client = init(480, false) + +client.networking_utils.initRelayNetworkAccess(); + +setInterval(() => { + console.log(client.networking_utils.detailedRelayNetworkStatus()) +}, 1000) + + +const mySteamId = client.localplayer.getSteamId().steamId64; +console.log(mySteamId) +setTimeout(() => { + setInterval(() => { + client.networking_messages.sendMessageToUser(mySteamId, 1, Buffer.from("Hello, from client!"), 1); + }, 1000) +}, 5000) + +/* +setInterval(() => { + let messages = [] + try { + messages = client.networking_messages.receiveMessagesOnChannel(0); + + while(messages.length > 0){ + const message = messages.shift(); + console.log("Received message") + console.log(message?.steamId) + console.log(message?.data.toString()); + + client.networking_messages.sendMessageToUser(message.steamId.steamId64, 1, Buffer.from("Hello, world!"), 1); + console.log("Sent message") + } + + } catch (e) { + console.error(e) + } +}, 1000 / 60) +*/ + + +//client.networking_messages.sendMessageToUser(mySteamId, 0, Buffer.from("Hello, world!"), 0); + +// client.networking_messages.sendMessageToUser(mySteamId, 1, Buffer.from("Hello, world!"), 0); +//client.networking_messages.sendMessageToUser(mySteamId, 3, Buffer.from("Hello, world!"), 0); \ No newline at end of file diff --git a/test/networking_sockets_receive.js b/test/networking_sockets_receive.js new file mode 100644 index 0000000..453ec0b --- /dev/null +++ b/test/networking_sockets_receive.js @@ -0,0 +1,36 @@ +process.env.IS_TESTING = true + +const { init } = require('../index.js') + +const client = init(480, true) + +client.networking_utils.initRelayNetworkAccess(); + +const socket = 0; +const localSocket = 6969; + +client.networking_sockets.createListenSocketP2P(socket); +client.networking_sockets.createListenSocketIP(localSocket); + +// enable p2p connections +client.networking_sockets.setAmIServer(true); + +// set up one listener just to process the listen p2p events +setInterval(() => { + console.log("Processing listen p2p events"); + client.networking_sockets.processListenP2PEvents(); +}, 1000 / 60) + +// and the local ip guh +setInterval(() => { + console.log("Processing listen ip events"); + client.networking_sockets.processListenIPEvents(); +}, 1000 / 60) + + +// now actually listen for new messages +setInterval(() => { + console.log("processing p2p messages"); + let messages = client.networking_sockets.receiveP2PMessages(10); // 10 _from each_ connection + messages.forEach(message => console.log(message)); +}, 1000 / 60); \ No newline at end of file diff --git a/test/networking_sockets_send.js b/test/networking_sockets_send.js new file mode 100644 index 0000000..2e5a2a3 --- /dev/null +++ b/test/networking_sockets_send.js @@ -0,0 +1,25 @@ +process.env.IS_TESTING = true + +const { init } = require('../index.js') + +const client = init(480, true) + +client.networking_utils.initRelayNetworkAccess(); + +// we shouldn't need to listen for p2p requests since we're sending it + +const mySteamId = client.localplayer.getSteamId().steamId64; +console.log(mySteamId); + +// now actually listen for new messages +/* +setInterval(() => { + let messages = client.networking_sockets.receiveP2PMessages(10); // 10 _from each_ connection + messages.forEach(message => console.log(message)); +}, 1000 / 60); +*/ + +// now let's send a connection request to the server +client.networking_sockets.connectP2P(mySteamId, 0); + +client.networking_sockets.sendP2PMessage(mySteamId, Buffer.from("Hello, from client!"), 1); \ No newline at end of file