raknet #
raknet
raknet is a RakNet implementation for V, focused on the classic RakNet protocol used by Minecraft: Bedrock Edition.
The API is plain-structed and inspired by Sandertv's go-raknet.
Basic Server
import raknet
mut listener := raknet.listen('0.0.0.0:19132')!
defer {
listener.close() or {}
}
listener.set_pong_data('raknet server'.bytes())!
mut conn := listener.accept()!
mut buf := []u8{len: 4096}
n := conn.read(mut buf)!
conn.write(buf[..n])!
Basic Client
import raknet
mut conn := raknet.dial('127.0.0.1:19132')!
defer {
conn.close() or {}
}
conn.write('ping'.bytes())!
packet := conn.read_packet()!
println(packet.bytestr())
Basic Ping
import raknet
data := raknet.ping('127.0.0.1:19132')!
println(data.bytestr())
IPv6 addresses use bracket notation:
mut conn := raknet.dial('[::1]:19133')!
Configuration
import time
import raknet
mut listener := raknet.ListenConfig{
max_mtu: 1200
disable_cookies: false
handshake_timeout: 10 * time.second
}.listen('0.0.0.0:19132')!
dialer := raknet.Dialer{
max_mtu: 1200
timeout: 2 * time.second
}
mut conn := dialer.dial(listener.addr())!
Logging
ListenConfig and Dialer both accept an optional error_log hook for diagnostic events (blocked reads, transient UDP errors, close-drain progress...) that would otherwise be silently dropped:
fn on_event(msg string, fields map[string]string) {
eprintln('${msg}: ${fields}')
}
mut listener := raknet.ListenConfig{
error_log: on_event
}.listen('0.0.0.0:19132')!
Tests
v test .
Constants #
const protocol_version = u8(11)
const min_mtu_size = u16(400)
const max_mtu_size = u16(1492)
const err_code_connection_closed = 110001
const err_code_listener_closed = 110002
const err_code_read_deadline_exceeded = 110003
const err_code_write_deadline_exceeded = 110004
const err_code_connection_timed_out = 110005
const err_code_not_supported = 110006
const err_code_protocol_mismatch = 110007
const err_code_invalid_packet = 110008
const err_code_pong_data_too_large = 110009
const err_connection_closed = error_with_code('connection closed', err_code_connection_closed)
const err_listener_closed = error_with_code('listener closed', err_code_listener_closed)
const err_read_deadline_exceeded = error_with_code('read deadline exceeded',
err_code_read_deadline_exceeded)
const err_write_deadline_exceeded = error_with_code('write deadline exceeded',
err_code_write_deadline_exceeded)
const err_connection_timed_out = error_with_code('connection timed out',
err_code_connection_timed_out)
const err_not_supported = error_with_code('not supported', err_code_not_supported)
const err_invalid_packet = error_with_code('invalid packet', err_code_invalid_packet)
const err_pong_data_too_large = error_with_code('pong data must be no longer than ${max_i16} bytes',
err_code_pong_data_too_large)
fn dial #
fn dial(address string) !&Conn
fn dial_timeout #
fn dial_timeout(address string, timeout time.Duration) !&Conn
fn listen #
fn listen(address string) !&Listener
fn load_uint24 #
fn load_uint24(b []u8) Uint24
fn ping #
fn ping(address string) ![]u8
fn ping_timeout #
fn ping_timeout(address string, timeout time.Duration) ![]u8
fn safe_load_uint24 #
fn safe_load_uint24(b []u8) !Uint24
fn write_uint24 #
fn write_uint24(mut b []u8, v Uint24)
fn Reliability.from #
fn Reliability.from[W](input W) !Reliability
type LogFunc #
type LogFunc = fn (msg string, fields map[string]string)
LogFunc is an optional diagnostic hook. msg is a short, stable event name (e.g. "read from", "blocked read", "transient udp error", "close drain timeout") and fields carries event-specific context such as the remote address or underlying error.
type PongDataFunc #
type PongDataFunc = fn (net.Addr) []u8
type Uint24 #
type Uint24 = u32
fn (Uint24) inc #
fn (mut u Uint24) inc() Uint24
In V, a mutable receiver for an alias type behaves pointer-like here, so copy the underlying value explicitly before incrementing.
struct Conn #
struct Conn {
mut:
udp &net.UdpConn = unsafe { nil }
remote net.Addr
remote_key string
mtu u16
seq Uint24
message_idx Uint24
sequence_idx Uint24
order_idx Uint24
split_id u32
packets PacketChan = new_packet_chan(packet_chan_initial_cap, packet_chan_max_cap,
packet_chan_max_bytes)
connected chan bool
splits map[u16][][]u8
resend ResendMap
win DatagramWindow
packet_queue PacketQueue
pending_ack []Uint24
pending_nack []Uint24
sent_raw [][]u8
rtt time.Duration
last_activity time.Time
idle_timeout time.Duration
keepalive_interval time.Duration
read_deadline time.Time
write_deadline time.Time
read_timeout time.Duration
is_server bool
listener &Listener = unsafe { nil }
mutex &sync.Mutex = sync.new_mutex()
ack_mutex &sync.Mutex = sync.new_mutex()
lifecycle_mutex &sync.Mutex = sync.new_mutex()
closed_chan chan bool = chan bool{cap: 1}
connected_confirmed bool
closing_deadline time.Time
closing bool
closed bool
error_log LogFunc = unsafe { nil }
}
fn (Conn) remote_addr #
fn (mut c Conn) remote_addr() string
fn (Conn) local_addr #
fn (mut c Conn) local_addr() string
fn (Conn) latency #
fn (mut c Conn) latency() time.Duration
fn (Conn) set_read_deadline #
fn (mut c Conn) set_read_deadline(deadline time.Time)
fn (Conn) set_write_deadline #
fn (mut c Conn) set_write_deadline(deadline time.Time)
fn (Conn) set_deadline #
fn (mut c Conn) set_deadline(deadline time.Time)
fn (Conn) set_read_timeout #
fn (mut c Conn) set_read_timeout(timeout time.Duration)
fn (Conn) set_write_timeout #
fn (mut c Conn) set_write_timeout(timeout time.Duration)
fn (Conn) set_idle_timeout #
fn (mut c Conn) set_idle_timeout(timeout time.Duration)
fn (Conn) set_keepalive_interval #
fn (mut c Conn) set_keepalive_interval(interval time.Duration)
fn (Conn) write #
fn (mut c Conn) write(data []u8) !int
fn (Conn) write_reliable_ordered #
fn (mut c Conn) write_reliable_ordered(data []u8) !int
fn (Conn) write_reliable #
fn (mut c Conn) write_reliable(data []u8) !int
fn (Conn) write_unreliable #
fn (mut c Conn) write_unreliable(data []u8) !int
fn (Conn) write_unreliable_sequenced #
fn (mut c Conn) write_unreliable_sequenced(data []u8) !int
fn (Conn) write_reliable_sequenced #
fn (mut c Conn) write_reliable_sequenced(data []u8) !int
fn (Conn) read #
fn (mut c Conn) read(mut buf []u8) !int
fn (Conn) read_packet #
fn (mut c Conn) read_packet() ![]u8
fn (Conn) close #
fn (mut c Conn) close() !
struct Dialer #
struct Dialer {
pub mut:
max_mtu u16
timeout time.Duration
max_transient_errors int
error_log LogFunc = unsafe { nil }
}
fn (Dialer) ping #
fn (dialer Dialer) ping(address string) ![]u8
fn (Dialer) ping_timeout #
fn (dialer Dialer) ping_timeout(address string, timeout time.Duration) ![]u8
fn (Dialer) dial #
fn (dialer Dialer) dial(address string) !&Conn
struct ListenConfig #
struct ListenConfig {
pub mut:
disable_cookies bool
max_mtu u16
block_duration time.Duration
capture_packets bool
handshake_timeout time.Duration
error_log LogFunc = unsafe { nil }
}
fn (ListenConfig) listen #
fn (conf ListenConfig) listen(address string) !&Listener
struct Listener #
struct Listener {
mut:
udp &net.UdpConn = unsafe { nil }
incoming chan &Conn
connections map[string]&Conn
connections_mutex &sync.Mutex = sync.new_mutex()
id i64
closed bool
lifecycle_mutex &sync.Mutex = sync.new_mutex()
pong_data []u8
pong_data_func PongDataFunc = unsafe { nil }
pong_data_mutex &sync.Mutex = sync.new_mutex()
max_mtu u16
disable_cookies bool
cookie_salt u64
previous_cookie_salt u64
block_duration time.Duration
blocks map[string]time.Time
security_mutex &sync.Mutex = sync.new_mutex()
capture_packets bool
captured [][]u8
capture_mutex &sync.Mutex = sync.new_mutex()
handshake_timeout time.Duration
error_log LogFunc = unsafe { nil }
}
fn (Listener) addr #
fn (l &Listener) addr() string
fn (Listener) accept #
fn (l &Listener) accept() !&Conn
fn (Listener) accept_timeout #
fn (l &Listener) accept_timeout(timeout time.Duration) !&Conn
fn (Listener) close #
fn (mut l Listener) close() !
fn (Listener) set_pong_data #
fn (mut l Listener) set_pong_data(data []u8) !
fn (Listener) set_pong_data_func #
fn (mut l Listener) set_pong_data_func(f PongDataFunc)
fn (Listener) clear_pong_data_func #
fn (mut l Listener) clear_pong_data_func()
fn (Listener) block #
fn (mut l Listener) block(addr net.Addr)
fn (Listener) block_for #
fn (mut l Listener) block_for(addr net.Addr, duration time.Duration)
fn (Listener) captured_packets #
fn (mut l Listener) captured_packets() [][]u8
- README
- Constants
- fn dial
- fn dial_timeout
- fn listen
- fn load_uint24
- fn ping
- fn ping_timeout
- fn safe_load_uint24
- fn write_uint24
- fn Reliability.from
- type LogFunc
- type PongDataFunc
- type Uint24
- struct Conn
- fn remote_addr
- fn local_addr
- fn latency
- fn set_read_deadline
- fn set_write_deadline
- fn set_deadline
- fn set_read_timeout
- fn set_write_timeout
- fn set_idle_timeout
- fn set_keepalive_interval
- fn write
- fn write_reliable_ordered
- fn write_reliable
- fn write_unreliable
- fn write_unreliable_sequenced
- fn write_reliable_sequenced
- fn read
- fn read_packet
- fn close
- struct Dialer
- struct ListenConfig
- struct Listener