nex

package module
v2.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2024 License: AGPL-3.0 Imports: 30 Imported by: 66

README

NEX Go

GoDoc

Overview

NEX is the networking library used by all 1st party, and many 3rd party, games on the Nintendo Wii U, 3DS, and Switch which have online features. The NEX library has many different parts, ranging from low level packet transport to higher level service implementations

This library implements the lowest level parts of NEX, the transport protocols. For other parts of the NEX stack, see the below libraries. For detailed information on NEX as a whole, see our wiki docs https://nintendo-wiki.pretendo.network/docs/nex

Install
go get github.com/PretendoNetwork/nex-go
Other NEX libraries
Quazal Rendez-Vous

Nintendo did not make NEX from scratch. NEX is largely based on an existing library called Rendez-Vous (QRV), made by Canadian software company Quazal. Quazal licensed Rendez-Vous out to many other companies, and was eventually bought out by Ubisoft. Because of this, QRV is seen in many many other games on all major platforms, especially Ubisoft

Nintendo modified Rendez-Vous somewhat heavily, simplifying the library/transport protocol quite a bit, and adding several custom services

While the main goal of this library is to support games which use the NEX variant of Rendez-Vous made by Nintendo, we also aim to be compatible with games using the original Rendez-Vous library. Due to the extensible nature of Rendez-Vous, many games may feature customizations much like NEX and have non-standard features/behavior. We do our best to support these cases, but there may be times where supporting all variations becomes untenable. In those cases, a fork of these libraries should be made instead if they require heavy modifications

Supported features
  • Quazal compatibility mode/settings
  • HPP servers (NEX over HTTP)
  • PRUDP servers
    • UDP transport
    • WebSocket transport (Experimental, largely untested)
    • PRUDPv0 packets
    • PRUDPv1 packets
    • PRUDPLite packets
  • Fragmented packet payloads
  • Packet retransmission
  • Reliable packets
  • Unreliable packets
  • Virtual ports
  • Packet compression
  • RMC
    • Request messages
    • Response messages
    • "Packed" encoded messages
    • "Packed" (extended) encoded messages
    • "Verbose" encoded messages
  • Kerberos authentication
Example
package main

import (
	"fmt"

	"github.com/PretendoNetwork/nex-go/v2"
	"github.com/PretendoNetwork/nex-go/v2/types"
)

func main() {
	// Skeleton of a WiiU/3DS Friends server running on PRUDPv0 with a single endpoint

	authServer := nex.NewPRUDPServer() // The main PRUDP server
	endpoint := nex.NewPRUDPEndPoint(1) // A PRUDP endpoint for PRUDP connections to connect to. Bound to StreamID 1
	endpoint.ServerAccount = nex.NewAccount(types.NewPID(1), "Quazal Authentication", "password"))
	endpoint.AccountDetailsByPID = accountDetailsByPID
	endpoint.AccountDetailsByUsername = accountDetailsByUsername

	// Setup event handlers for the endpoint
	endpoint.OnData(func(packet nex.PacketInterface) {
		if packet, ok := packet.(nex.PRUDPPacketInterface); ok {
			request := packet.RMCMessage()

			fmt.Println("[AUTH]", request.ProtocolID, request.MethodID)

			if request.ProtocolID == 0xA { // TicketGrantingProtocol
				if request.MethodID == 0x1 { // TicketGrantingProtocol::Login
					handleLogin(packet)
				}

				if request.MethodID == 0x3 { // TicketGrantingProtocol::RequestTicket
					handleRequestTicket(packet)
				}
			}
		}
	})

	// Bind the endpoint to the server and configure it's settings
	authServer.BindPRUDPEndPoint(endpoint)
	authServer.SetFragmentSize(962)
	authServer.LibraryVersions.SetDefault(nex.NewLibraryVersion(1, 1, 0))
	authServer.SessionKeyLength = 16
	authServer.AccessKey = "ridfebb9"
	authServer.Listen(60000)
}

Documentation

Overview

Package nex provides a collection of utility structs, functions, and data types for making NEX/QRV servers

Index

Constants

This section is empty.

Variables

View Source
var ResultCodes resultCodes

ResultCodes provides a struct containing RDV result codes using dot-notation

View Source
var ResultNames = map[uint32]string{}

ResultNames contains a map of all the result code string names, indexed by the result code

Functions

func DeriveKerberosKey

func DeriveKerberosKey(pid *types.PID, password []byte) []byte

DeriveKerberosKey derives a users kerberos encryption key based on their PID and password

func ResultCodeToName

func ResultCodeToName(resultCode uint32) string

ResultCodeToName returns an error code string for the provided error code

Types

type Account

type Account struct {
	PID      *types.PID // * The PID of the account. PIDs are unique IDs per account. NEX PIDs start at 1800000000 and decrement with each new account.
	Username string     // * The username for the account. For NEX user accounts this is the same as the accounts PID.
	Password string     // * The password for the account. For NEX accounts this is always 16 characters long using seemingly any ASCII character
}

Account represents a game server account.

Game server accounts are separate from other accounts, like Uplay, Nintendo Accounts and NNIDs. These exist only on the game server. Account passwords are used as part of the servers Kerberos authentication. There are also a collection of non-user, special, accounts. These include a guest account, an account which represents the authentication server, and one which represents the secure server. See https://nintendo-wiki.pretendo.network/docs/nex/kerberos for more information.

func NewAccount

func NewAccount(pid *types.PID, username, password string) *Account

NewAccount returns a new instance of Account. This does not register an account, only creates a new struct instance.

type ByteStreamIn

type ByteStreamIn struct {
	*crunch.Buffer
	LibraryVersions *LibraryVersions
	Settings        *ByteStreamSettings
}

ByteStreamIn is an input stream abstraction of github.com/superwhiskers/crunch/v3 with nex type support

func NewByteStreamIn

func NewByteStreamIn(data []byte, libraryVersions *LibraryVersions, settings *ByteStreamSettings) *ByteStreamIn

NewByteStreamIn returns a new NEX input byte stream

func (*ByteStreamIn) PIDSize

func (bsi *ByteStreamIn) PIDSize() int

PIDSize returns the size of PID types

func (*ByteStreamIn) Read

func (bsi *ByteStreamIn) Read(length uint64) ([]byte, error)

Read reads the specified number of bytes. Returns an error if OOB

func (*ByteStreamIn) ReadPrimitiveBool

func (bsi *ByteStreamIn) ReadPrimitiveBool() (bool, error)

ReadPrimitiveBool reads a bool

func (*ByteStreamIn) ReadPrimitiveFloat32LE

func (bsi *ByteStreamIn) ReadPrimitiveFloat32LE() (float32, error)

ReadPrimitiveFloat32LE reads a Little-Endian encoded float32

func (*ByteStreamIn) ReadPrimitiveFloat64LE

func (bsi *ByteStreamIn) ReadPrimitiveFloat64LE() (float64, error)

ReadPrimitiveFloat64LE reads a Little-Endian encoded float64

func (*ByteStreamIn) ReadPrimitiveInt16LE

func (bsi *ByteStreamIn) ReadPrimitiveInt16LE() (int16, error)

ReadPrimitiveInt16LE reads a Little-Endian encoded int16

func (*ByteStreamIn) ReadPrimitiveInt32LE

func (bsi *ByteStreamIn) ReadPrimitiveInt32LE() (int32, error)

ReadPrimitiveInt32LE reads a Little-Endian encoded int32

func (*ByteStreamIn) ReadPrimitiveInt64LE

func (bsi *ByteStreamIn) ReadPrimitiveInt64LE() (int64, error)

ReadPrimitiveInt64LE reads a Little-Endian encoded int64

func (*ByteStreamIn) ReadPrimitiveInt8

func (bsi *ByteStreamIn) ReadPrimitiveInt8() (int8, error)

ReadPrimitiveInt8 reads a uint8

func (*ByteStreamIn) ReadPrimitiveUInt16LE

func (bsi *ByteStreamIn) ReadPrimitiveUInt16LE() (uint16, error)

ReadPrimitiveUInt16LE reads a Little-Endian encoded uint16

func (*ByteStreamIn) ReadPrimitiveUInt32LE

func (bsi *ByteStreamIn) ReadPrimitiveUInt32LE() (uint32, error)

ReadPrimitiveUInt32LE reads a Little-Endian encoded uint32

func (*ByteStreamIn) ReadPrimitiveUInt64LE

func (bsi *ByteStreamIn) ReadPrimitiveUInt64LE() (uint64, error)

ReadPrimitiveUInt64LE reads a Little-Endian encoded uint64

func (*ByteStreamIn) ReadPrimitiveUInt8

func (bsi *ByteStreamIn) ReadPrimitiveUInt8() (uint8, error)

ReadPrimitiveUInt8 reads a uint8

func (*ByteStreamIn) ReadRemaining

func (bsi *ByteStreamIn) ReadRemaining() []byte

ReadRemaining reads all the data left to be read in the buffer

func (*ByteStreamIn) Remaining

func (bsi *ByteStreamIn) Remaining() uint64

Remaining returns the amount of data left to be read in the buffer

func (*ByteStreamIn) StringLengthSize

func (bsi *ByteStreamIn) StringLengthSize() int

StringLengthSize returns the expected size of String length fields

func (*ByteStreamIn) UseStructureHeader

func (bsi *ByteStreamIn) UseStructureHeader() bool

UseStructureHeader determines if Structure headers should be used

type ByteStreamOut

type ByteStreamOut struct {
	*crunch.Buffer
	LibraryVersions *LibraryVersions
	Settings        *ByteStreamSettings
}

ByteStreamOut is an abstraction of github.com/superwhiskers/crunch with nex type support

func NewByteStreamOut

func NewByteStreamOut(libraryVersions *LibraryVersions, settings *ByteStreamSettings) *ByteStreamOut

NewByteStreamOut returns a new NEX writable byte stream

func (*ByteStreamOut) CopyNew

func (bso *ByteStreamOut) CopyNew() types.Writable

CopyNew returns a copy of the StreamOut but with a blank internal buffer. Returns as types.Writable

func (*ByteStreamOut) PIDSize

func (bso *ByteStreamOut) PIDSize() int

PIDSize returns the size of PID types

func (*ByteStreamOut) StringLengthSize

func (bso *ByteStreamOut) StringLengthSize() int

StringLengthSize returns the expected size of String length fields

func (*ByteStreamOut) UseStructureHeader

func (bso *ByteStreamOut) UseStructureHeader() bool

UseStructureHeader determines if Structure headers should be used

func (*ByteStreamOut) Write

func (bso *ByteStreamOut) Write(data []byte)

Writes the input data to the end of the StreamOut

func (*ByteStreamOut) WritePrimitiveBool

func (bso *ByteStreamOut) WritePrimitiveBool(b bool)

WritePrimitiveBool writes a bool

func (*ByteStreamOut) WritePrimitiveFloat32LE

func (bso *ByteStreamOut) WritePrimitiveFloat32LE(f32 float32)

WritePrimitiveFloat32LE writes a float32 as LE

func (*ByteStreamOut) WritePrimitiveFloat64LE

func (bso *ByteStreamOut) WritePrimitiveFloat64LE(f64 float64)

WritePrimitiveFloat64LE writes a float64 as LE

func (*ByteStreamOut) WritePrimitiveInt16LE

func (bso *ByteStreamOut) WritePrimitiveInt16LE(s16 int16)

WritePrimitiveInt16LE writes a uint16 as LE

func (*ByteStreamOut) WritePrimitiveInt32LE

func (bso *ByteStreamOut) WritePrimitiveInt32LE(s32 int32)

WritePrimitiveInt32LE writes a int32 as LE

func (*ByteStreamOut) WritePrimitiveInt64LE

func (bso *ByteStreamOut) WritePrimitiveInt64LE(s64 int64)

WritePrimitiveInt64LE writes a int64 as LE

func (*ByteStreamOut) WritePrimitiveInt8

func (bso *ByteStreamOut) WritePrimitiveInt8(s8 int8)

WritePrimitiveInt8 writes a int8

func (*ByteStreamOut) WritePrimitiveUInt16LE

func (bso *ByteStreamOut) WritePrimitiveUInt16LE(u16 uint16)

WritePrimitiveUInt16LE writes a uint16 as LE

func (*ByteStreamOut) WritePrimitiveUInt32LE

func (bso *ByteStreamOut) WritePrimitiveUInt32LE(u32 uint32)

WritePrimitiveUInt32LE writes a uint32 as LE

func (*ByteStreamOut) WritePrimitiveUInt64LE

func (bso *ByteStreamOut) WritePrimitiveUInt64LE(u64 uint64)

WritePrimitiveUInt64LE writes a uint64 as LE

func (*ByteStreamOut) WritePrimitiveUInt8

func (bso *ByteStreamOut) WritePrimitiveUInt8(u8 uint8)

WritePrimitiveUInt8 writes a uint8

type ByteStreamSettings

type ByteStreamSettings struct {
	StringLengthSize   int
	PIDSize            int
	UseStructureHeader bool
}

ByteStreamSettings defines some settings for how a ByteStream should handle certain data types

func NewByteStreamSettings

func NewByteStreamSettings() *ByteStreamSettings

NewByteStreamSettings returns a new ByteStreamSettings

type CalcRetransmissionTimeoutCallback added in v2.0.3

type CalcRetransmissionTimeoutCallback func(rtt float64, sendCount uint32) time.Duration

CalcRetransmissionTimeoutCallback is an optional callback which can be used to override the RTO calculation for packets sent by this `PRUDPEndpoint`

type ConnectionInterface

type ConnectionInterface interface {
	Endpoint() EndpointInterface
	Address() net.Addr
	PID() *types.PID
	SetPID(pid *types.PID)
}

ConnectionInterface defines all the methods a connection should have regardless of server type

type ConnectionState

type ConnectionState uint8

ConnectionState is an implementation of the nn::nex::EndPoint::_ConnectionState enum.

The state represents a PRUDP clients connection state. The original Rendez-Vous library supports states 0-6, though NEX only supports 0-4. The remaining 2 are unknown

const (
	// StateNotConnected indicates the client has not established a full PRUDP connection
	StateNotConnected ConnectionState = iota

	// StateConnecting indicates the client is attempting to establish a PRUDP connection
	StateConnecting

	// StateConnected indicates the client has established a full PRUDP connection
	StateConnected

	// StateDisconnecting indicates the client is disconnecting from a PRUDP connection. Currently unused
	StateDisconnecting

	// StateFaulty indicates the client connection is faulty. Currently unused
	StateFaulty
)

type Counter

type Counter[T numeric] struct {
	Value T
}

Counter represents an incremental counter of a specific numeric type

func NewCounter

func NewCounter[T numeric](start T) *Counter[T]

NewCounter returns a new Counter, with a starting number

func (*Counter[T]) Next

func (c *Counter[T]) Next() T

Next increments the counter by 1 and returns the new value

type EndpointInterface

type EndpointInterface interface {
	AccessKey() string
	SetAccessKey(accessKey string)
	Send(packet PacketInterface)
	LibraryVersions() *LibraryVersions
	ByteStreamSettings() *ByteStreamSettings
	SetByteStreamSettings(settings *ByteStreamSettings)
	UseVerboseRMC() bool // TODO - Move this to a RMCSettings struct?
	EnableVerboseRMC(enabled bool)
	EmitError(err *Error)
}

EndpointInterface defines all the methods an endpoint should have regardless of type

type Error

type Error struct {
	ResultCode uint32          // * NEX result code. See result_codes.go for details
	Message    string          // * The error base message
	Packet     PacketInterface // * The packet which caused the error. May not always be present
}

Error is a custom error type implementing the error interface.

func NewError

func NewError(resultCode uint32, message string) *Error

NewError returns a new NEX error with a RDV result code

func (Error) Error

func (e Error) Error() string

Error satisfies the error interface and prints the underlying error

type HPPClient

type HPPClient struct {
	// contains filtered or unexported fields
}

HPPClient represents a single HPP client

func NewHPPClient

func NewHPPClient(address *net.TCPAddr, server *HPPServer) *HPPClient

NewHPPClient creates and returns a new Client using the provided IP address and server

func (*HPPClient) Address

func (c *HPPClient) Address() net.Addr

Address returns the clients address as a net.Addr

func (*HPPClient) Endpoint

func (c *HPPClient) Endpoint() EndpointInterface

Endpoint returns the server the client is connecting to

func (*HPPClient) PID

func (c *HPPClient) PID() *types.PID

PID returns the clients NEX PID

func (*HPPClient) SetPID

func (c *HPPClient) SetPID(pid *types.PID)

SetPID sets the clients NEX PID

type HPPPacket

type HPPPacket struct {
	// contains filtered or unexported fields
}

HPPPacket holds all the data about an HPP request

func NewHPPPacket

func NewHPPPacket(client *HPPClient, payload []byte) (*HPPPacket, error)

NewHPPPacket creates and returns a new HPPPacket using the provided Client and payload

func (*HPPPacket) Payload

func (p *HPPPacket) Payload() []byte

Payload returns the packets payload

func (*HPPPacket) RMCMessage

func (p *HPPPacket) RMCMessage() *RMCMessage

RMCMessage returns the packets RMC Message

func (*HPPPacket) Sender

func (p *HPPPacket) Sender() ConnectionInterface

Sender returns the Client who sent the packet

func (*HPPPacket) SetPayload

func (p *HPPPacket) SetPayload(payload []byte)

SetPayload sets the packets payload

func (*HPPPacket) SetRMCMessage

func (p *HPPPacket) SetRMCMessage(message *RMCMessage)

SetRMCMessage sets the packets RMC Message

type HPPServer

type HPPServer struct {
	AccountDetailsByPID      func(pid *types.PID) (*Account, *Error)
	AccountDetailsByUsername func(username string) (*Account, *Error)
	// contains filtered or unexported fields
}

HPPServer represents a bare-bones HPP server

func NewHPPServer

func NewHPPServer() *HPPServer

NewHPPServer returns a new HPP server

func (*HPPServer) AccessKey

func (s *HPPServer) AccessKey() string

AccessKey returns the servers sandbox access key

func (*HPPServer) ByteStreamSettings

func (s *HPPServer) ByteStreamSettings() *ByteStreamSettings

ByteStreamSettings returns the settings to be used for ByteStreams

func (*HPPServer) EmitError

func (s *HPPServer) EmitError(err *Error)

EmitError calls all the endpoints error event handlers with the provided error

func (*HPPServer) EnableVerboseRMC

func (s *HPPServer) EnableVerboseRMC(enable bool)

EnableVerboseRMC enable or disables the use of verbose RMC

func (*HPPServer) LibraryVersions

func (s *HPPServer) LibraryVersions() *LibraryVersions

LibraryVersions returns the versions that the server has

func (*HPPServer) Listen

func (s *HPPServer) Listen(port int)

Listen starts a HPP server on a given port

func (*HPPServer) ListenSecure

func (s *HPPServer) ListenSecure(port int, certFile, keyFile string)

ListenSecure starts a HPP server on a given port using a secure (TLS) server

func (*HPPServer) OnData

func (s *HPPServer) OnData(handler func(packet PacketInterface))

OnData adds an event handler which is fired when a new HPP request is received

func (*HPPServer) RegisterServiceProtocol

func (s *HPPServer) RegisterServiceProtocol(protocol ServiceProtocol)

RegisterServiceProtocol registers a NEX service with the HPP server

func (*HPPServer) Send

func (s *HPPServer) Send(packet PacketInterface)

Send sends the packet to the packets sender

func (*HPPServer) SetAccessKey

func (s *HPPServer) SetAccessKey(accessKey string)

SetAccessKey sets the servers sandbox access key

func (*HPPServer) SetByteStreamSettings

func (s *HPPServer) SetByteStreamSettings(byteStreamSettings *ByteStreamSettings)

SetByteStreamSettings sets the settings to be used for ByteStreams

func (*HPPServer) UseVerboseRMC

func (s *HPPServer) UseVerboseRMC() bool

UseVerboseRMC checks whether or not the endpoint uses verbose RMC

type KerberosEncryption

type KerberosEncryption struct {
	// contains filtered or unexported fields
}

KerberosEncryption is a struct representing a Kerberos encryption utility

func NewKerberosEncryption

func NewKerberosEncryption(key []byte) *KerberosEncryption

NewKerberosEncryption creates a new KerberosEncryption instance with the given key.

func (*KerberosEncryption) Decrypt

func (ke *KerberosEncryption) Decrypt(buffer []byte) ([]byte, error)

Decrypt decrypts the provided buffer if it passes the integrity check

func (*KerberosEncryption) Encrypt

func (ke *KerberosEncryption) Encrypt(buffer []byte) []byte

Encrypt encrypts the given buffer and appends an HMAC checksum for integrity

func (*KerberosEncryption) Validate

func (ke *KerberosEncryption) Validate(buffer []byte) bool

Validate checks the integrity of the given buffer by verifying the HMAC checksum

type KerberosTicket

type KerberosTicket struct {
	SessionKey   []byte
	TargetPID    *types.PID
	InternalData *types.Buffer
}

KerberosTicket represents a ticket granting a user access to a secure server

func NewKerberosTicket

func NewKerberosTicket() *KerberosTicket

NewKerberosTicket returns a new Ticket instance

func (*KerberosTicket) Encrypt

func (kt *KerberosTicket) Encrypt(key []byte, stream *ByteStreamOut) ([]byte, error)

Encrypt writes the ticket data to the provided stream and returns the encrypted byte slice

type KerberosTicketInternalData

type KerberosTicketInternalData struct {
	Server     *PRUDPServer // TODO - Remove this dependency and make a settings struct
	Issued     *types.DateTime
	SourcePID  *types.PID
	SessionKey []byte
}

KerberosTicketInternalData holds the internal data for a kerberos ticket to be processed by the server

func NewKerberosTicketInternalData

func NewKerberosTicketInternalData(server *PRUDPServer) *KerberosTicketInternalData

NewKerberosTicketInternalData returns a new KerberosTicketInternalData instance

func (*KerberosTicketInternalData) Decrypt

func (ti *KerberosTicketInternalData) Decrypt(stream *ByteStreamIn, key []byte) error

Decrypt decrypts the given data and populates the struct

func (*KerberosTicketInternalData) Encrypt

func (ti *KerberosTicketInternalData) Encrypt(key []byte, stream *ByteStreamOut) ([]byte, error)

Encrypt writes the ticket data to the provided stream and returns the encrypted byte slice

type LibraryVersion

type LibraryVersion struct {
	Major             int
	Minor             int
	Patch             int
	GameSpecificPatch string
	// contains filtered or unexported fields
}

LibraryVersion represents a NEX library version

func NewLibraryVersion

func NewLibraryVersion(major, minor, patch int) *LibraryVersion

NewLibraryVersion returns a new LibraryVersion

func NewPatchedLibraryVersion

func NewPatchedLibraryVersion(major, minor, patch int, gameSpecificPatch string) *LibraryVersion

NewPatchedLibraryVersion returns a new LibraryVersion with a game specific patch

func (*LibraryVersion) Copy

func (lv *LibraryVersion) Copy() *LibraryVersion

Copy returns a new copied instance of LibraryVersion

func (*LibraryVersion) GreaterOrEqual

func (lv *LibraryVersion) GreaterOrEqual(compare string) bool

GreaterOrEqual compares if the given semver is greater than or equal to the current version

func (*LibraryVersion) LessOrEqual

func (lv *LibraryVersion) LessOrEqual(compare string) bool

LessOrEqual compares if the given semver is lesser than or equal to the current version

type LibraryVersions

type LibraryVersions struct {
	Main         *LibraryVersion
	DataStore    *LibraryVersion
	MatchMaking  *LibraryVersion
	Ranking      *LibraryVersion
	Ranking2     *LibraryVersion
	Messaging    *LibraryVersion
	Utility      *LibraryVersion
	NATTraversal *LibraryVersion
}

LibraryVersions contains a set of the NEX version that the server uses

func NewLibraryVersions

func NewLibraryVersions() *LibraryVersions

NewLibraryVersions returns a new set of LibraryVersions

func (*LibraryVersions) SetDefault

func (lvs *LibraryVersions) SetDefault(version *LibraryVersion)

SetDefault sets the default NEX protocol versions

type MutexMap

type MutexMap[K comparable, V any] struct {
	*sync.RWMutex
	// contains filtered or unexported fields
}

MutexMap implements a map type with go routine safe accessors through mutex locks. Embeds sync.RWMutex

func NewMutexMap

func NewMutexMap[K comparable, V any]() *MutexMap[K, V]

NewMutexMap returns a new instance of MutexMap with the provided key/value types

func (*MutexMap[K, V]) Clear

func (m *MutexMap[K, V]) Clear(callback func(key K, value V))

Clear removes all items from the `real` map Accepts an optional callback function ran for every item before it is deleted

func (*MutexMap[K, V]) Delete

func (m *MutexMap[K, V]) Delete(key K)

Delete removes a key from the internal map

func (*MutexMap[K, V]) DeleteIf added in v2.0.2

func (m *MutexMap[K, V]) DeleteIf(predicate func(key K, value V) bool) int

DeleteIf deletes every element if the predicate returns true. Returns the amount of elements deleted.

func (*MutexMap[K, V]) Each

func (m *MutexMap[K, V]) Each(callback func(key K, value V) bool) bool

Each runs a callback function for every item in the map The map should not be modified inside the callback function Returns true if the loop was terminated early

func (*MutexMap[K, V]) Get

func (m *MutexMap[K, V]) Get(key K) (V, bool)

Get returns the given key value and a bool if found

func (*MutexMap[K, V]) GetOrSetDefault added in v2.0.3

func (m *MutexMap[K, V]) GetOrSetDefault(key K, createDefault func() V) V

GetOrSetDefault returns the value for the given key if it exists. If it does not exist, it creates a default with the provided function and sets it for that key

func (*MutexMap[K, V]) Has

func (m *MutexMap[K, V]) Has(key K) bool

Has checks if a key exists in the map

func (*MutexMap[K, V]) RunAndDelete

func (m *MutexMap[K, V]) RunAndDelete(key K, callback func(key K, value V))

RunAndDelete runs a callback and removes the key afterwards

func (*MutexMap[K, V]) Set

func (m *MutexMap[K, V]) Set(key K, value V)

Set sets a key to a given value

func (*MutexMap[K, V]) Size

func (m *MutexMap[K, V]) Size() int

Size returns the length of the internal map

type MutexSlice

type MutexSlice[V comparable] struct {
	*sync.RWMutex
	// contains filtered or unexported fields
}

MutexSlice implements a slice type with go routine safe accessors through mutex locks.

Embeds sync.RWMutex.

func NewMutexSlice

func NewMutexSlice[V comparable]() *MutexSlice[V]

NewMutexSlice returns a new instance of MutexSlice with the provided value type

func (*MutexSlice[V]) Add

func (m *MutexSlice[V]) Add(value V)

Add adds a value to the slice

func (*MutexSlice[V]) At

func (m *MutexSlice[V]) At(index int) (V, bool)

At returns value at the given index.

Returns a bool indicating if the value was found successfully.

func (*MutexSlice[V]) Clear

func (m *MutexSlice[V]) Clear()

Clear removes all items from the slice.

func (*MutexSlice[V]) Delete

func (m *MutexSlice[V]) Delete(value V) bool

Delete removes the first instance of the given value from the slice.

Returns true if the value existed and was deleted, otherwise returns false.

func (*MutexSlice[V]) DeleteAll

func (m *MutexSlice[V]) DeleteAll(value V) bool

DeleteAll removes all instances of the given value from the slice.

Returns true if the value existed and was deleted, otherwise returns false.

func (*MutexSlice[V]) Each

func (m *MutexSlice[V]) Each(callback func(index int, value V) bool) bool

Each runs a callback function for every item in the slice.

The slice cannot be modified inside the callback function.

Returns true if the loop was terminated early.

func (*MutexSlice[V]) GetIndex

func (m *MutexSlice[V]) GetIndex(value V) int

GetIndex checks if the slice contains the given value and returns it's index.

Returns -1 if the value does not exist in the slice.

func (*MutexSlice[V]) Has

func (m *MutexSlice[V]) Has(value V) bool

Has checks if the slice contains the given value.

func (*MutexSlice[V]) Size

func (m *MutexSlice[V]) Size() int

Size returns the length of the internal slice

func (*MutexSlice[V]) Values

func (m *MutexSlice[V]) Values() []V

Values returns the internal slice.

type PRUDPConnection

type PRUDPConnection struct {
	Socket *SocketConnection // * The connections parent socket

	ConnectionState ConnectionState
	ID              uint32 // * Connection ID
	SessionID       uint8  // * Random value generated at the start of the session. Client and server IDs do not need to match
	ServerSessionID uint8  // * Random value generated at the start of the session. Client and server IDs do not need to match
	SessionKey      []byte // * Secret key generated at the start of the session. Used for encrypting packets to the secure server

	DefaultPRUDPVersion       int                  // * The PRUDP version the connection was established with. Used for sending PING packets
	StreamType                constants.StreamType // * rdv::Stream::Type used in this connection
	StreamID                  uint8                // * rdv::Stream ID, also called the "port number", used in this connection. 0-15 on PRUDPv0/v1, and 0-31 on PRUDPLite
	StreamSettings            *StreamSettings      // * Settings for this virtual connection
	Signature                 []byte               // * Connection signature for packets coming from the client, as seen by the server
	ServerConnectionSignature []byte               // * Connection signature for packets coming from the server, as seen by the client
	UnreliablePacketBaseKey   []byte               // * The base key used for encrypting unreliable DATA packets

	StationURLs *types.List[*types.StationURL]
	// contains filtered or unexported fields
}

PRUDPConnection implements an individual PRUDP virtual connection. Does not necessarily represent a socket connection. A single network socket may be used to open multiple PRUDP virtual connections

func NewPRUDPConnection

func NewPRUDPConnection(socket *SocketConnection) *PRUDPConnection

NewPRUDPConnection creates a new PRUDPConnection for a given socket

func (*PRUDPConnection) Address

func (pc *PRUDPConnection) Address() net.Addr

Address returns the socket address of the connection

func (*PRUDPConnection) ClearOutgoingBuffer added in v2.0.3

func (pc *PRUDPConnection) ClearOutgoingBuffer(substreamID uint8)

Clears the outgoing buffer for a given substream

func (*PRUDPConnection) CreatePacketDispatchQueue added in v2.0.3

func (pc *PRUDPConnection) CreatePacketDispatchQueue(substreamID uint8) *PacketDispatchQueue

CreatePacketDispatchQueue creates a new PacketDispatchQueue for the given substream and returns it

func (*PRUDPConnection) CreateSlidingWindow

func (pc *PRUDPConnection) CreateSlidingWindow(substreamID uint8) *SlidingWindow

CreateSlidingWindow creates a new SlidingWindow for the given substream and returns it if there is not a SlidingWindow for the given substream id it creates a new one

func (*PRUDPConnection) Endpoint

func (pc *PRUDPConnection) Endpoint() EndpointInterface

Endpoint returns the PRUDP endpoint the connections socket is connected to

func (*PRUDPConnection) GetIncomingFragmentBuffer added in v2.0.3

func (pc *PRUDPConnection) GetIncomingFragmentBuffer(substreamID uint8) []byte

Gets the incoming fragment buffer for the given substream

func (*PRUDPConnection) InitializePacketDispatchQueues added in v2.0.3

func (pc *PRUDPConnection) InitializePacketDispatchQueues(maxSubstreamID uint8)

InitializePacketDispatchQueues initializes the PacketDispatchQueues for all substreams

func (*PRUDPConnection) InitializeSlidingWindows

func (pc *PRUDPConnection) InitializeSlidingWindows(maxSubstreamID uint8)

InitializeSlidingWindows initializes the SlidingWindows for all substreams

func (*PRUDPConnection) Lock added in v2.0.3

func (pc *PRUDPConnection) Lock()

Lock locks the inner mutex for the Connection This is used internally when reordering incoming fragmented packets to prevent race conditions when multiple packets for the same fragmented message are processed at once

func (*PRUDPConnection) PID

func (pc *PRUDPConnection) PID() *types.PID

PID returns the clients unique PID

func (*PRUDPConnection) PacketDispatchQueue added in v2.0.3

func (pc *PRUDPConnection) PacketDispatchQueue(substreamID uint8) *PacketDispatchQueue

PacketDispatchQueue returns the PacketDispatchQueue for the given substream if there is not a PacketDispatchQueue for the given substream it creates a new one

func (*PRUDPConnection) SetIncomingFragmentBuffer added in v2.0.3

func (pc *PRUDPConnection) SetIncomingFragmentBuffer(substreamID uint8, buffer []byte)

Sets the incoming fragment buffer for a given substream

func (*PRUDPConnection) SetPID

func (pc *PRUDPConnection) SetPID(pid *types.PID)

SetPID sets the clients unique PID

func (*PRUDPConnection) SlidingWindow

func (pc *PRUDPConnection) SlidingWindow(substreamID uint8) *SlidingWindow

SlidingWindow returns the SlidingWindow for the given substream

func (*PRUDPConnection) Unlock added in v2.0.3

func (pc *PRUDPConnection) Unlock()

Unlock unlocks the inner mutex for the Connection This is used internally when reordering incoming fragmented packets to prevent race conditions when multiple packets for the same fragmented message are processed at once

type PRUDPEndPoint

type PRUDPEndPoint struct {
	Server                *PRUDPServer
	StreamID              uint8
	DefaultStreamSettings *StreamSettings
	Connections           *MutexMap[string, *PRUDPConnection]

	ConnectionIDCounter               *Counter[uint32]
	ServerAccount                     *Account
	AccountDetailsByPID               func(pid *types.PID) (*Account, *Error)
	AccountDetailsByUsername          func(username string) (*Account, *Error)
	IsSecureEndPoint                  bool
	CalcRetransmissionTimeoutCallback CalcRetransmissionTimeoutCallback
	// contains filtered or unexported fields
}

PRUDPEndPoint is an implementation of rdv::PRUDPEndPoint. A PRUDPEndPoint represents a remote server location the client may connect to using a given remote stream ID. Each PRUDPEndPoint handles it's own set of PRUDPConnections, state, and events.

In NEX there exists nn::nex::SecureEndPoint, which presumably is what differentiates between the authentication and secure servers. However the functionality of rdv::PRUDPEndPoint and nn::nex::SecureEndPoint is seemingly identical. Rather than duplicate the logic from PRUDPEndpoint, a IsSecureEndpoint flag has been added instead.

func NewPRUDPEndPoint

func NewPRUDPEndPoint(streamID uint8) *PRUDPEndPoint

NewPRUDPEndPoint returns a new PRUDPEndPoint for a server on the provided stream ID

func (*PRUDPEndPoint) AccessKey

func (pep *PRUDPEndPoint) AccessKey() string

AccessKey returns the servers sandbox access key

func (*PRUDPEndPoint) ByteStreamSettings

func (pep *PRUDPEndPoint) ByteStreamSettings() *ByteStreamSettings

ByteStreamSettings returns the settings to be used for ByteStreams

func (*PRUDPEndPoint) ComputeRetransmitTimeout added in v2.0.3

func (pep *PRUDPEndPoint) ComputeRetransmitTimeout(packet PRUDPPacketInterface) time.Duration

ComputeRetransmitTimeout computes the RTO (Retransmit timeout) for a given packet

func (*PRUDPEndPoint) EmitError

func (pep *PRUDPEndPoint) EmitError(err *Error)

EmitError calls all the endpoints error event handlers with the provided error

func (*PRUDPEndPoint) EnableVerboseRMC

func (pep *PRUDPEndPoint) EnableVerboseRMC(enable bool)

EnableVerboseRMC enable or disables the use of verbose RMC

func (*PRUDPEndPoint) FindConnectionByID

func (pep *PRUDPEndPoint) FindConnectionByID(connectedID uint32) *PRUDPConnection

FindConnectionByID returns the PRUDP client connected with the given connection ID

func (*PRUDPEndPoint) FindConnectionByPID

func (pep *PRUDPEndPoint) FindConnectionByPID(pid uint64) *PRUDPConnection

FindConnectionByPID returns the PRUDP client connected with the given PID

func (*PRUDPEndPoint) LibraryVersions

func (pep *PRUDPEndPoint) LibraryVersions() *LibraryVersions

LibraryVersions returns the versions that the server has

func (*PRUDPEndPoint) OnConnectionEnded

func (pep *PRUDPEndPoint) OnConnectionEnded(handler func(connection *PRUDPConnection))

OnConnectionEnded adds an event handler which is fired when a connection is removed from the server

Fires both on a natural disconnect and from a timeout

func (*PRUDPEndPoint) OnData

func (pep *PRUDPEndPoint) OnData(handler func(packet PacketInterface))

OnData adds an event handler which is fired when a new DATA packet is received

func (*PRUDPEndPoint) OnDisconnect

func (pep *PRUDPEndPoint) OnDisconnect(handler func(packet PacketInterface))

OnDisconnect adds an event handler which is fired when a new DISCONNECT packet is received

To handle a connection being removed from the server, see OnConnectionEnded which fires on more cases

func (*PRUDPEndPoint) OnError

func (pep *PRUDPEndPoint) OnError(handler func(err *Error))

OnError adds an event handler which is fired when an error occurs on the endpoint

func (*PRUDPEndPoint) RegisterCustomPacketHandler

func (pep *PRUDPEndPoint) RegisterCustomPacketHandler(packetType uint16, handler func(packet PRUDPPacketInterface))

RegisterCustomPacketHandler registers a custom handler for a given packet type. Used to override existing handlers or create new ones for custom packet types.

func (*PRUDPEndPoint) RegisterServiceProtocol

func (pep *PRUDPEndPoint) RegisterServiceProtocol(protocol ServiceProtocol)

RegisterServiceProtocol registers a NEX service with the endpoint

func (*PRUDPEndPoint) Send

func (pep *PRUDPEndPoint) Send(packet PacketInterface)

Send sends the packet to the packets sender

func (*PRUDPEndPoint) SetAccessKey

func (pep *PRUDPEndPoint) SetAccessKey(accessKey string)

SetAccessKey sets the servers sandbox access key

func (*PRUDPEndPoint) SetByteStreamSettings

func (pep *PRUDPEndPoint) SetByteStreamSettings(byteStreamSettings *ByteStreamSettings)

SetByteStreamSettings sets the settings to be used for ByteStreams

func (*PRUDPEndPoint) UseVerboseRMC

func (pep *PRUDPEndPoint) UseVerboseRMC() bool

UseVerboseRMC checks whether or not the endpoint uses verbose RMC

type PRUDPPacket

type PRUDPPacket struct {
	// contains filtered or unexported fields
}

PRUDPPacket holds all the fields each packet should have in all PRUDP versions

func (*PRUDPPacket) AddFlag

func (p *PRUDPPacket) AddFlag(flag uint16)

AddFlag adds the given flag to the packet flag bitmask

func (*PRUDPPacket) DestinationVirtualPortStreamID

func (p *PRUDPPacket) DestinationVirtualPortStreamID() uint8

DestinationVirtualPortStreamID returns the packets destination VirtualPort port number

func (*PRUDPPacket) DestinationVirtualPortStreamType

func (p *PRUDPPacket) DestinationVirtualPortStreamType() constants.StreamType

DestinationVirtualPortStreamType returns the packets destination VirtualPort StreamType

func (*PRUDPPacket) Flags

func (p *PRUDPPacket) Flags() uint16

Flags returns the packet flags

func (*PRUDPPacket) HasFlag

func (p *PRUDPPacket) HasFlag(flag uint16) bool

HasFlag checks if the packet has the given flag

func (*PRUDPPacket) Payload

func (p *PRUDPPacket) Payload() []byte

Payload returns the packets payload

func (*PRUDPPacket) RMCMessage

func (p *PRUDPPacket) RMCMessage() *RMCMessage

RMCMessage returns the packets RMC Message

func (*PRUDPPacket) SendCount added in v2.0.3

func (p *PRUDPPacket) SendCount() uint32

SendCount returns the number of times this packet has been sent

func (*PRUDPPacket) Sender

func (p *PRUDPPacket) Sender() ConnectionInterface

Sender returns the Client who sent the packet

func (*PRUDPPacket) SentAt added in v2.0.3

func (p *PRUDPPacket) SentAt() time.Time

SentAt returns the latest time that this packet has been sent

func (*PRUDPPacket) SequenceID

func (p *PRUDPPacket) SequenceID() uint16

SequenceID returns the packets sequenc ID

func (*PRUDPPacket) SessionID

func (p *PRUDPPacket) SessionID() uint8

SessionID returns the packets session ID

func (*PRUDPPacket) SetDestinationVirtualPortStreamID

func (p *PRUDPPacket) SetDestinationVirtualPortStreamID(port uint8)

SetDestinationVirtualPortStreamID sets the packets destination VirtualPort port number

func (*PRUDPPacket) SetDestinationVirtualPortStreamType

func (p *PRUDPPacket) SetDestinationVirtualPortStreamType(streamType constants.StreamType)

SetDestinationVirtualPortStreamType sets the packets destination VirtualPort StreamType

func (*PRUDPPacket) SetPayload

func (p *PRUDPPacket) SetPayload(payload []byte)

SetPayload sets the packets payload

func (*PRUDPPacket) SetRMCMessage

func (p *PRUDPPacket) SetRMCMessage(message *RMCMessage)

SetRMCMessage sets the packets RMC Message

func (*PRUDPPacket) SetSender

func (p *PRUDPPacket) SetSender(sender ConnectionInterface)

SetSender sets the Client who sent the packet

func (*PRUDPPacket) SetSequenceID

func (p *PRUDPPacket) SetSequenceID(sequenceID uint16)

SetSequenceID sets the packets sequenc ID

func (*PRUDPPacket) SetSessionID

func (p *PRUDPPacket) SetSessionID(sessionID uint8)

SetSessionID sets the packets session ID

func (*PRUDPPacket) SetSourceVirtualPortStreamID

func (p *PRUDPPacket) SetSourceVirtualPortStreamID(port uint8)

SetSourceVirtualPortStreamID sets the packets source VirtualPort port number

func (*PRUDPPacket) SetSourceVirtualPortStreamType

func (p *PRUDPPacket) SetSourceVirtualPortStreamType(streamType constants.StreamType)

SetSourceVirtualPortStreamType sets the packets source VirtualPort StreamType

func (*PRUDPPacket) SetSubstreamID

func (p *PRUDPPacket) SetSubstreamID(substreamID uint8)

SetSubstreamID sets the packets substream ID

func (*PRUDPPacket) SetType

func (p *PRUDPPacket) SetType(packetType uint16)

SetType sets the packets type

func (*PRUDPPacket) SourceVirtualPortStreamID

func (p *PRUDPPacket) SourceVirtualPortStreamID() uint8

SourceVirtualPortStreamID returns the packets source VirtualPort port number

func (*PRUDPPacket) SourceVirtualPortStreamType

func (p *PRUDPPacket) SourceVirtualPortStreamType() constants.StreamType

SourceVirtualPortStreamType returns the packets source VirtualPort StreamType

func (*PRUDPPacket) SubstreamID

func (p *PRUDPPacket) SubstreamID() uint8

SubstreamID returns the packets substream ID

func (*PRUDPPacket) Type

func (p *PRUDPPacket) Type() uint16

Type returns the packets type

type PRUDPPacketInterface

type PRUDPPacketInterface interface {
	Copy() PRUDPPacketInterface
	Version() int
	Bytes() []byte
	SetSender(sender ConnectionInterface)
	Sender() ConnectionInterface
	Flags() uint16
	HasFlag(flag uint16) bool
	AddFlag(flag uint16)
	SetType(packetType uint16)
	Type() uint16
	SetSourceVirtualPortStreamType(streamType constants.StreamType)
	SourceVirtualPortStreamType() constants.StreamType
	SetSourceVirtualPortStreamID(port uint8)
	SourceVirtualPortStreamID() uint8
	SetDestinationVirtualPortStreamType(streamType constants.StreamType)
	DestinationVirtualPortStreamType() constants.StreamType
	SetDestinationVirtualPortStreamID(port uint8)
	DestinationVirtualPortStreamID() uint8
	SessionID() uint8
	SetSessionID(sessionID uint8)
	SubstreamID() uint8
	SetSubstreamID(substreamID uint8)
	SequenceID() uint16
	SetSequenceID(sequenceID uint16)
	Payload() []byte
	SetPayload(payload []byte)
	RMCMessage() *RMCMessage
	SetRMCMessage(message *RMCMessage)
	SendCount() uint32

	SentAt() time.Time
	// contains filtered or unexported methods
}

PRUDPPacketInterface defines all the methods a PRUDP packet should have

func NewPRUDPPacketsLite

func NewPRUDPPacketsLite(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) ([]PRUDPPacketInterface, error)

NewPRUDPPacketsLite reads all possible PRUDPLite packets from the stream

func NewPRUDPPacketsV0

func NewPRUDPPacketsV0(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) ([]PRUDPPacketInterface, error)

NewPRUDPPacketsV0 reads all possible PRUDPv0 packets from the stream

func NewPRUDPPacketsV1

func NewPRUDPPacketsV1(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) ([]PRUDPPacketInterface, error)

NewPRUDPPacketsV1 reads all possible PRUDPv1 packets from the stream

type PRUDPPacketLite

type PRUDPPacketLite struct {
	PRUDPPacket
	// contains filtered or unexported fields
}

PRUDPPacketLite represents a PRUDPLite packet

func NewPRUDPPacketLite

func NewPRUDPPacketLite(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) (*PRUDPPacketLite, error)

NewPRUDPPacketLite creates and returns a new PacketLite using the provided Client and stream

func (*PRUDPPacketLite) Bytes

func (p *PRUDPPacketLite) Bytes() []byte

Bytes encodes a PRUDPLite packet into a byte slice

func (*PRUDPPacketLite) Copy

Copy copies the packet into a new PRUDPPacketLite

Retains the same PRUDPConnection pointer

func (*PRUDPPacketLite) DestinationVirtualPortStreamID

func (p *PRUDPPacketLite) DestinationVirtualPortStreamID() uint8

DestinationVirtualPortStreamID returns the packets destination VirtualPort port number

func (*PRUDPPacketLite) DestinationVirtualPortStreamType

func (p *PRUDPPacketLite) DestinationVirtualPortStreamType() constants.StreamType

DestinationVirtualPortStreamType returns the packets destination VirtualPort constants.StreamType

func (*PRUDPPacketLite) SetDestinationVirtualPortStreamID

func (p *PRUDPPacketLite) SetDestinationVirtualPortStreamID(port uint8)

SetDestinationVirtualPortStreamID sets the packets destination VirtualPort port number

func (*PRUDPPacketLite) SetDestinationVirtualPortStreamType

func (p *PRUDPPacketLite) SetDestinationVirtualPortStreamType(streamType constants.StreamType)

SetDestinationVirtualPortStreamType sets the packets destination VirtualPort constants.StreamType

func (*PRUDPPacketLite) SetSourceVirtualPortStreamID

func (p *PRUDPPacketLite) SetSourceVirtualPortStreamID(port uint8)

SetSourceVirtualPortStreamID sets the packets source VirtualPort port number

func (*PRUDPPacketLite) SetSourceVirtualPortStreamType

func (p *PRUDPPacketLite) SetSourceVirtualPortStreamType(streamType constants.StreamType)

SetSourceVirtualPortStreamType sets the packets source VirtualPort StreamType

func (*PRUDPPacketLite) SourceVirtualPortStreamID

func (p *PRUDPPacketLite) SourceVirtualPortStreamID() uint8

SourceVirtualPortStreamID returns the packets source VirtualPort port number

func (*PRUDPPacketLite) SourceVirtualPortStreamType

func (p *PRUDPPacketLite) SourceVirtualPortStreamType() constants.StreamType

SourceVirtualPortStreamType returns the packets source VirtualPort StreamType

func (*PRUDPPacketLite) Version

func (p *PRUDPPacketLite) Version() int

Version returns the packets PRUDP version

type PRUDPPacketV0

type PRUDPPacketV0 struct {
	PRUDPPacket
}

PRUDPPacketV0 represents a PRUDPv0 packet

func NewPRUDPPacketV0

func NewPRUDPPacketV0(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) (*PRUDPPacketV0, error)

NewPRUDPPacketV0 creates and returns a new PacketV0 using the provided Client and stream

func (*PRUDPPacketV0) Bytes

func (p *PRUDPPacketV0) Bytes() []byte

Bytes encodes a PRUDPv0 packet into a byte slice

func (*PRUDPPacketV0) Copy

Copy copies the packet into a new PRUDPPacketV0

Retains the same PRUDPConnection pointer

func (*PRUDPPacketV0) Version

func (p *PRUDPPacketV0) Version() int

Version returns the packets PRUDP version

type PRUDPPacketV1

type PRUDPPacketV1 struct {
	PRUDPPacket
	// contains filtered or unexported fields
}

PRUDPPacketV1 represents a PRUDPv1 packet

func NewPRUDPPacketV1

func NewPRUDPPacketV1(server *PRUDPServer, connection *PRUDPConnection, readStream *ByteStreamIn) (*PRUDPPacketV1, error)

NewPRUDPPacketV1 creates and returns a new PacketV1 using the provided Client and stream

func (*PRUDPPacketV1) Bytes

func (p *PRUDPPacketV1) Bytes() []byte

Bytes encodes a PRUDPv1 packet into a byte slice

func (*PRUDPPacketV1) Copy

Copy copies the packet into a new PRUDPPacketV1

Retains the same PRUDPConnection pointer

func (*PRUDPPacketV1) Version

func (p *PRUDPPacketV1) Version() int

Version returns the packets PRUDP version

type PRUDPServer

type PRUDPServer struct {
	Endpoints                     *MutexMap[uint8, *PRUDPEndPoint]
	Connections                   *MutexMap[string, *SocketConnection]
	SupportedFunctions            uint32
	AccessKey                     string
	KerberosTicketVersion         int
	SessionKeyLength              int
	FragmentSize                  int
	PRUDPv1ConnectionSignatureKey []byte
	LibraryVersions               *LibraryVersions
	ByteStreamSettings            *ByteStreamSettings
	PRUDPV0Settings               *PRUDPV0Settings
	PRUDPV1Settings               *PRUDPV1Settings
	UseVerboseRMC                 bool
	// contains filtered or unexported fields
}

PRUDPServer represents a bare-bones PRUDP server

func NewPRUDPServer

func NewPRUDPServer() *PRUDPServer

NewPRUDPServer will return a new PRUDP server

func (*PRUDPServer) BindPRUDPEndPoint

func (ps *PRUDPServer) BindPRUDPEndPoint(endpoint *PRUDPEndPoint)

BindPRUDPEndPoint binds a provided PRUDPEndPoint to the server

func (*PRUDPServer) Listen

func (ps *PRUDPServer) Listen(port int)

Listen is an alias of ListenUDP. Implemented to conform to the EndpointInterface

func (*PRUDPServer) ListenUDP

func (ps *PRUDPServer) ListenUDP(port int)

ListenUDP starts a PRUDP server on a given port using a UDP server

func (*PRUDPServer) ListenWebSocket

func (ps *PRUDPServer) ListenWebSocket(port int)

ListenWebSocket starts a PRUDP server on a given port using a WebSocket server

func (*PRUDPServer) ListenWebSocketSecure

func (ps *PRUDPServer) ListenWebSocketSecure(port int, certFile, keyFile string)

ListenWebSocketSecure starts a PRUDP server on a given port using a secure (TLS) WebSocket server

func (*PRUDPServer) Send

func (ps *PRUDPServer) Send(packet PacketInterface)

Send sends the packet to the packets sender

func (*PRUDPServer) SetFragmentSize

func (ps *PRUDPServer) SetFragmentSize(fragmentSize int)

SetFragmentSize sets the max size for a packets payload

type PRUDPV0Settings

type PRUDPV0Settings struct {
	IsQuazalMode                  bool
	EncryptedConnect              bool
	LegacyConnectionSignature     bool
	UseEnhancedChecksum           bool
	ConnectionSignatureCalculator func(packet *PRUDPPacketV0, addr net.Addr) ([]byte, error)
	SignatureCalculator           func(packet *PRUDPPacketV0, sessionKey, connectionSignature []byte) []byte
	DataSignatureCalculator       func(packet *PRUDPPacketV0, sessionKey []byte) []byte
	ChecksumCalculator            func(packet *PRUDPPacketV0, data []byte) uint32
}

PRUDPV0Settings defines settings for how to handle aspects of PRUDPv0 packets

func NewPRUDPV0Settings

func NewPRUDPV0Settings() *PRUDPV0Settings

NewPRUDPV0Settings returns a new PRUDPV0Settings

type PRUDPV1Settings

type PRUDPV1Settings struct {
	LegacyConnectionSignature     bool
	ConnectionSignatureCalculator func(packet *PRUDPPacketV1, addr net.Addr) ([]byte, error)
	SignatureCalculator           func(packet *PRUDPPacketV1, sessionKey, connectionSignature []byte) []byte
}

PRUDPV1Settings defines settings for how to handle aspects of PRUDPv1 packets

func NewPRUDPV1Settings

func NewPRUDPV1Settings() *PRUDPV1Settings

NewPRUDPV1Settings returns a new PRUDPV1Settings

type PacketDispatchQueue added in v2.0.3

type PacketDispatchQueue struct {
	// contains filtered or unexported fields
}

PacketDispatchQueue is an implementation of rdv::PacketDispatchQueue. PacketDispatchQueue is used to sequence incoming packets. In the original library each virtual connection stream only uses a single PacketDispatchQueue, but starting in PRUDPv1 NEX virtual connections may have multiple reliable substreams and thus multiple PacketDispatchQueues.

func NewPacketDispatchQueue added in v2.0.3

func NewPacketDispatchQueue() *PacketDispatchQueue

NewPacketDispatchQueue initializes a new PacketDispatchQueue with a starting counter value.

func (*PacketDispatchQueue) Dispatched added in v2.0.3

func (pdq *PacketDispatchQueue) Dispatched(packet PRUDPPacketInterface)

Dispatched removes a packet from the queue to be dispatched.

func (*PacketDispatchQueue) GetNextToDispatch added in v2.0.3

func (pdq *PacketDispatchQueue) GetNextToDispatch() (PRUDPPacketInterface, bool)

GetNextToDispatch returns the next packet to be dispatched, nil if there are no packets and a boolean indicating whether anything was returned.

func (*PacketDispatchQueue) Purge added in v2.0.3

func (pdq *PacketDispatchQueue) Purge()

Purge clears the queue of all pending packets.

func (*PacketDispatchQueue) Queue added in v2.0.3

func (pdq *PacketDispatchQueue) Queue(packet PRUDPPacketInterface)

Queue adds a packet to the queue to be dispatched

type PacketInterface

type PacketInterface interface {
	Sender() ConnectionInterface
	Payload() []byte
	SetPayload(payload []byte)
	RMCMessage() *RMCMessage
	SetRMCMessage(message *RMCMessage)
}

PacketInterface defines all the methods a packet for both PRUDP and HPP should have

type RMCMessage

type RMCMessage struct {
	Endpoint              EndpointInterface
	IsRequest             bool                         // * Indicates if the message is a request message (true) or response message (false)
	IsSuccess             bool                         // * Indicates if the message is a success message (true) for a response message
	IsHPP                 bool                         // * Indicates if the message is an HPP message
	ProtocolID            uint16                       // * Protocol ID of the message. Only present in "packed" variations
	ProtocolName          *types.String                // * Protocol name of the message. Only present in "verbose" variations
	CallID                uint32                       // * Call ID associated with the message
	MethodID              uint32                       // * Method ID in the requested protocol. Only present in "packed" variations
	MethodName            *types.String                // * Method name in the requested protocol. Only present in "verbose" variations
	ErrorCode             uint32                       // * Error code for a response message
	ClassVersionContainer *types.ClassVersionContainer // * Contains version info for Structures in the request. Only present in "verbose" variations
	Parameters            []byte                       // * Input for the method

}

RMCMessage represents a message in the RMC (Remote Method Call) protocol

func NewRMCError

func NewRMCError(endpoint EndpointInterface, errorCode uint32) *RMCMessage

NewRMCError returns a new RMC Message configured as a error response

func NewRMCMessage

func NewRMCMessage(endpoint EndpointInterface) *RMCMessage

NewRMCMessage returns a new generic RMC Message

func NewRMCRequest

func NewRMCRequest(endpoint EndpointInterface) *RMCMessage

NewRMCRequest returns a new blank RMCRequest

func NewRMCSuccess

func NewRMCSuccess(endpoint EndpointInterface, parameters []byte) *RMCMessage

NewRMCSuccess returns a new RMC Message configured as a success response

func (*RMCMessage) Bytes

func (rmc *RMCMessage) Bytes() []byte

Bytes serializes the RMCMessage to a byte slice.

func (*RMCMessage) Copy

func (rmc *RMCMessage) Copy() *RMCMessage

Copy copies the message into a new RMCMessage

func (*RMCMessage) FromBytes

func (rmc *RMCMessage) FromBytes(data []byte) error

FromBytes decodes an RMCMessage from the given byte slice.

type RTT added in v2.0.3

type RTT struct {
	sync.Mutex
	// contains filtered or unexported fields
}

RTT is an implementation of rdv::RTT. Used to calculate the average round trip time of reliable packets

func NewRTT added in v2.0.3

func NewRTT() *RTT

NewRTT returns a new RTT based on the first value

func (*RTT) Adjust added in v2.0.3

func (rtt *RTT) Adjust(next time.Duration)

Adjust updates the average RTT with the new value

func (*RTT) Average added in v2.0.3

func (rtt *RTT) Average() time.Duration

GetRTO returns the current average

func (*RTT) GetRTTSmoothedAvg added in v2.0.3

func (rtt *RTT) GetRTTSmoothedAvg() float64

GetRTTSmoothedAvg returns the smoothed average of this RTT, it is used in calls to the custom RTO calculation function set on `PRUDPEndpoint::SetCalcRetransmissionTimeoutCallback`

func (*RTT) GetRTTSmoothedDev added in v2.0.3

func (rtt *RTT) GetRTTSmoothedDev() float64

GetRTTSmoothedDev returns the smoothed standard deviation of this RTT, it is used in calls to the custom RTO calculation function set on `PRUDPEndpoint::SetCalcRetransmissionTimeoutCallback`

func (*RTT) Initialized added in v2.0.3

func (rtt *RTT) Initialized() bool

Initialized returns a bool indicating whether this RTT has been initialized

type ServiceProtocol

type ServiceProtocol interface {
	HandlePacket(packet PacketInterface)
	Endpoint() EndpointInterface
	SetEndpoint(endpoint EndpointInterface)
}

ServiceProtocol represents a NEX service capable of handling PRUDP/HPP packets

type SlidingWindow

type SlidingWindow struct {
	TimeoutManager *TimeoutManager
	// contains filtered or unexported fields
}

SlidingWindow is an implementation of rdv::SlidingWindow. Currently this is a stub and does not reflect the interface and usage of rdv:SlidingWindow. In the original library this is used to manage sequencing of outgoing packets. each virtual connection stream only uses a single SlidingWindow, but starting in PRUDPv1 with NEX virtual connections may have multiple reliable substreams and thus multiple SlidingWindows.

func NewSlidingWindow

func NewSlidingWindow() *SlidingWindow

NewSlidingWindow initializes a new SlidingWindow with a starting counter value.

func (*SlidingWindow) Decrypt

func (sw *SlidingWindow) Decrypt(data []byte) ([]byte, error)

Decrypt decrypts the provided data with the substreams decipher

func (*SlidingWindow) Encrypt

func (sw *SlidingWindow) Encrypt(data []byte) ([]byte, error)

Encrypt encrypts the provided data with the substreams cipher

func (*SlidingWindow) NextOutgoingSequenceID

func (sw *SlidingWindow) NextOutgoingSequenceID() uint16

NextOutgoingSequenceID sets the reliable substreams RC4 cipher keys

func (*SlidingWindow) SetCipherKey

func (sw *SlidingWindow) SetCipherKey(key []byte)

SetCipherKey sets the reliable substreams RC4 cipher keys

type SocketConnection

type SocketConnection struct {
	Server              *PRUDPServer                       // * PRUDP server the socket is connected to
	Address             net.Addr                           // * Sockets address
	WebSocketConnection *gws.Conn                          // * Only used in PRUDPLite
	Connections         *MutexMap[uint8, *PRUDPConnection] // * Open PRUDP connections separated by rdv::Stream ID, also called "port number"
}

SocketConnection represents a single open socket. A single socket may have many PRUDP connections open on it.

func NewSocketConnection

func NewSocketConnection(server *PRUDPServer, address net.Addr, webSocketConnection *gws.Conn) *SocketConnection

NewSocketConnection creates a new SocketConnection

type StreamSettings

type StreamSettings struct {
	ExtraRetransmitTimeoutTrigger    uint32                // * The number of times a packet can be retransmitted before ExtraRetransmitTimeoutMultiplier is used
	MaxPacketRetransmissions         uint32                // * The number of times a packet can be retransmitted before the timeout time is checked
	KeepAliveTimeout                 uint32                // * Presumably the time a packet can be alive for without acknowledgement? Milliseconds?
	ChecksumBase                     uint32                // * Unused. The base value for PRUDPv0 checksum calculations
	FaultDetectionEnabled            bool                  // * Unused. Presumably used to detect PIA faults?
	InitialRTT                       uint32                // * The initial connection RTT used for all non-SYN packets
	SynInitialRTT                    uint32                // * The initial connection RTT used for all SYN packets
	EncryptionAlgorithm              encryption.Algorithm  // * The encryption algorithm used for packet payloads
	ExtraRetransmitTimeoutMultiplier float32               // * Used as part of the RTO calculations when retransmitting a packet. Only used if ExtraRestransmitTimeoutTrigger has been reached
	WindowSize                       uint32                // * Unused. The max number of (reliable?) packets allowed in a SlidingWindow
	CompressionAlgorithm             compression.Algorithm // * The compression algorithm used for packet payloads
	RTTRetransmit                    uint32                // * This is the number of times that a retried packet will be included in RTT calculations if we receive an ACK packet for it
	RetransmitTimeoutMultiplier      float32               // * Used as part of the RTO calculations when retransmitting a packet. Only used if ExtraRestransmitTimeoutTrigger has not been reached
	MaxSilenceTime                   uint32                // * Presumably the time a connection can go without any packets from the other side? Milliseconds?
}

StreamSettings is an implementation of rdv::StreamSettings. StreamSettings holds the state and settings for a PRUDP virtual connection stream. Each virtual connection is composed of a virtual port and stream type. In the original library this would be tied to a rdv::Stream class, but here it is not. The original library has more settings which are not present here as their use is unknown. Not all values are used at this time, and only exist to future-proof for a later time.

func NewStreamSettings

func NewStreamSettings() *StreamSettings

NewStreamSettings returns a new instance of StreamSettings with default params

func (*StreamSettings) Copy

func (ss *StreamSettings) Copy() *StreamSettings

Copy returns a new copy of the settings

type Timeout added in v2.0.3

type Timeout struct {
	// contains filtered or unexported fields
}

Timeout is an implementation of rdv::Timeout. Used to hold state related to resend timeouts on a packet

func NewTimeout added in v2.0.3

func NewTimeout() *Timeout

NewTimeout creates a new Timeout

func (*Timeout) RTO added in v2.0.3

func (t *Timeout) RTO() time.Duration

GetRTO gets the timeout field of this instance

func (*Timeout) SetRTO added in v2.0.3

func (t *Timeout) SetRTO(timeout time.Duration)

SetRTO sets the timeout field on this instance

type TimeoutManager added in v2.0.3

type TimeoutManager struct {
	// contains filtered or unexported fields
}

TimeoutManager is an implementation of rdv::TimeoutManager and manages the resending of reliable PRUDP packets

func NewTimeoutManager added in v2.0.3

func NewTimeoutManager() *TimeoutManager

NewTimeoutManager creates a new TimeoutManager

func (*TimeoutManager) AcknowledgePacket added in v2.0.3

func (tm *TimeoutManager) AcknowledgePacket(sequenceID uint16)

AcknowledgePacket marks a pending packet as acknowledged. It will be ignored at the next resend attempt

func (*TimeoutManager) SchedulePacketTimeout added in v2.0.3

func (tm *TimeoutManager) SchedulePacketTimeout(packet PRUDPPacketInterface)

SchedulePacketTimeout adds a packet to the scheduler and begins it's timer

func (*TimeoutManager) Stop added in v2.0.3

func (tm *TimeoutManager) Stop()

Stop kills the resend scheduler and stops all pending packets

type VirtualPort

type VirtualPort byte

VirtualPort in an implementation of rdv::VirtualPort. PRUDP will reuse a single physical socket connection for many virtual PRUDP connections. VirtualPorts are a byte which represents a stream for a virtual PRUDP connection. This byte is two 4-bit fields. The upper 4 bits are the stream type, the lower 4 bits are the stream ID. The client starts with stream ID 15, decrementing by one with each new virtual connection.

func (*VirtualPort) SetStreamID

func (vp *VirtualPort) SetStreamID(streamID uint8)

SetStreamID sets the VirtualPort stream ID

func (*VirtualPort) SetStreamType

func (vp *VirtualPort) SetStreamType(streamType constants.StreamType)

SetStreamType sets the VirtualPort stream type

func (VirtualPort) StreamID

func (vp VirtualPort) StreamID() uint8

StreamID returns the VirtualPort stream ID

func (VirtualPort) StreamType

func (vp VirtualPort) StreamType() constants.StreamType

StreamType returns the VirtualPort stream type

type WebSocketServer

type WebSocketServer struct {
	// contains filtered or unexported fields
}

WebSocketServer wraps a WebSocket server to create an easier API to consume

Directories

Path Synopsis
Package compression provides a set of compression algorithms found in several versions of Rendez-Vous for compressing large payloads
Package compression provides a set of compression algorithms found in several versions of Rendez-Vous for compressing large payloads
Package encryption provides a set of encryption algorithms found in several versions of Rendez-Vous for encrypting payloads
Package encryption provides a set of encryption algorithms found in several versions of Rendez-Vous for encrypting payloads
Package main implements a test server
Package main implements a test server
Package types provides types used in Quazal Rendez-Vous/NEX
Package types provides types used in Quazal Rendez-Vous/NEX

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL