Barebones PRUDP/NEX server library written in Go
Find a file
Jonathan Barrow 519e786544
Merge pull request #83 from DaniElectra/stationurl-custom-params
fix(types/station_url): Fix invalid checks for custom parameters
2025-03-15 17:10:12 -04:00
compression prudp: swap to native Go LZO lib 2024-02-27 18:34:16 -05:00
constants prudp: rename packet flags to distinguish them from other constants 2024-03-15 18:25:46 -04:00
encryption encryption: updated RC4 Godoc comment 2024-01-15 15:08:17 -05:00
test refactor: Replace AnyDataHolder with AnyObjectHolder 2025-01-09 23:21:11 +00:00
types fix(types/station_url): Fix invalid checks for custom parameters 2025-03-15 18:20:26 +00:00
.gitignore .gitignore: add IDEA 2025-01-03 17:54:55 +11:00
.golangci.yml Added golangci-lint config for aggregated linting 2022-12-31 13:16:55 -05:00
account.go refactor(types): remove reliance on pointers 2024-06-05 17:24:00 -04:00
byte_stream_in.go refactor: remove references to "Primitive" naming conventions 2024-06-16 11:52:39 -04:00
byte_stream_out.go refactor: remove references to "Primitive" naming conventions 2024-06-16 11:52:39 -04:00
byte_stream_settings.go streams: added ByteStreamSettings 2023-12-31 23:51:18 -05:00
connection_interface.go refactor(types): remove reliance on pointers 2024-06-05 17:24:00 -04:00
connection_state.go prudp: update enum godoc comments 2024-02-26 13:25:15 -05:00
counter.go total rewrite 2023-11-10 01:28:25 -05:00
endpoint_interface.go rmc: add a way to enable verbose RMC messages 2024-02-18 22:35:08 -05:00
error.go update: add Packet property to Error and OnError event hooks 2024-02-12 15:07:49 -05:00
go.mod chore: Update go modules 2025-01-12 20:15:30 +00:00
go.sum chore: Update go modules 2025-01-12 20:15:30 +00:00
hpp_client.go refactor(types): remove reliance on pointers 2024-06-05 17:24:00 -04:00
hpp_packet.go chore: rename ClientInterface to ConnectionInterface 2024-02-11 16:58:22 -05:00
hpp_server.go refactor(types): remove reliance on pointers 2024-06-05 17:24:00 -04:00
init.go refactor(types): make primitive types into type aliases 2024-06-02 15:20:20 -04:00
kerberos.go chore: fix kerberos.go indentation 2024-11-20 15:04:05 -05:00
kerberos_test.go fix: fix kerberos key derivation 2024-07-07 16:36:34 +01:00
library_version.go refactor: Update ServerInterface to EndpointInterface 2024-02-11 00:03:05 +00:00
LICENSE Create LICENSE 2022-08-13 20:16:23 -04:00
mutex_map.go feat: rework resending packets to be more accurate 2024-07-02 16:54:47 +01:00
mutex_slice.go mutex_slice: Fix typos 2024-03-23 19:24:36 +00:00
packet_dispatch_queue.go fix: added Purge method to PacketDispatchQueue 2024-06-12 23:03:41 +01:00
packet_dispatch_queue_test.go feat: use PacketDispatchQueue in PRUDPEndpoint 2024-05-27 21:59:51 +01:00
packet_interface.go chore: rename ClientInterface to ConnectionInterface 2024-02-11 16:58:22 -05:00
prudp_connection.go Merge branch 'master' into types-updates 2025-01-09 21:13:19 +00:00
prudp_endpoint.go fix(prudp): Check for matching user PID and ticket source PID 2025-02-13 21:50:11 +00:00
prudp_packet.go feat: rework resending packets to be more accurate 2024-07-02 16:54:47 +01:00
prudp_packet_interface.go feat: rework resending packets to be more accurate 2024-07-02 16:54:47 +01:00
prudp_packet_lite.go fix(prudp): Add missing size checks on PRUDP packets 2025-02-26 23:51:21 +00:00
prudp_packet_v0.go refactor: remove references to "Primitive" naming conventions 2024-06-16 11:52:39 -04:00
prudp_packet_v1.go fix(prudp): Add missing size checks on PRUDP packets 2025-02-26 23:51:21 +00:00
prudp_server.go fix(prudp): Add missing size checks on PRUDP packets 2025-02-26 23:51:21 +00:00
prudp_v0_settings.go prudp: Support legacy NEX 1 clients 2024-02-11 00:56:06 +00:00
prudp_v1_settings.go prudpv1: Add signature calculator functions settings 2024-02-24 11:22:50 +00:00
README.md chore: Update module version to v2 2024-04-07 23:40:51 +01:00
result_codes.go chore: rename errors to result codes 2024-01-24 13:19:23 -05:00
rmc_message.go feat: add CopyRef and Deref methods to RVType(Ptr) 2024-11-16 10:16:37 -05:00
rtt.go feat: rework resending packets to be more accurate 2024-07-02 16:54:47 +01:00
service_protocol.go chore: set protocols endpoint in RegisterServiceProtocol 2024-02-18 12:02:00 -05:00
sliding_window.go chore: rename ResendScheduler TimeoutManager 2024-07-02 17:29:28 +01:00
socket_connection.go chore: Remove Connections tracking from SocketConnection 2025-01-03 17:58:46 +11:00
stream_settings.go chore: updated documentation 2024-07-02 17:28:31 +01:00
sum.go total rewrite 2023-11-10 01:28:25 -05:00
timeout.go chore: renamed GetRTO to RTO to match style rules 2024-07-02 17:31:42 +01:00
timeout_manager.go feat(endpoint): Route connection closures via new cleanupConnection method 2025-01-04 17:33:33 +11:00
virtual_port.go chore: Update module version to v2 2024-04-07 23:40:51 +01:00
websocket_server.go feat(endpoint): Route connection closures via new cleanupConnection method 2025-01-04 17:33:33 +11:00

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)
}