Skip to main content
The Application.Network namespace handles all network communication between the game client and servers.

NetworkModule

Central network management module. Struct Layout:
// Application::Network::NetworkModule
[StructLayout(LayoutKind.Explicit, Size = 0xC50)]
public unsafe partial struct NetworkModule {
    // Lobby servers
    [FieldOffset(0x028)] public byte LobbyCount;
    [FieldOffset(0x02C)] internal FixedSizeArray14<uint> _lobbyPorts;
    [FieldOffset(0x068)] internal FixedSizeArray14<Utf8String> _lobbyHosts;
    
    // Save data
    [FieldOffset(0x620)] public uint SaveDataBankPort;
    [FieldOffset(0x628)] public Utf8String SaveDataBankHost;
    [FieldOffset(0x690)] public uint SaveDataBankMode;
    
    // DC Travel
    [FieldOffset(0x694)] public uint DktWebPort;
    [FieldOffset(0x698)] public Utf8String DktWebHost;
    
    // Active lobby
    [FieldOffset(0x700)] public uint ActiveLobbyPort;
    [FieldOffset(0x708)] public Utf8String ActiveLobbyHost;
    [FieldOffset(0x770)] public uint AlternateLobbyPort;
    [FieldOffset(0x778)] public Utf8String AlternateLobbyHost;
    [FieldOffset(0x7E0)] public uint LobbyRetryCount;
    [FieldOffset(0x7E4)] public uint LobbyRetryInterval;
    [FieldOffset(0x7E8)] public uint LobbyPing;
    
    // Frontend
    [FieldOffset(0x7EC)] public uint FrontPort;
    [FieldOffset(0x7F0)] public Utf8String FrontHost;
    [FieldOffset(0x858)] public Utf8String FrontProtocol;
    [FieldOffset(0x8C0)] public bool UseCfgFrontend;
    
    // Authentication
    [FieldOffset(0x8C8)] public Utf8String Ticket;
    [FieldOffset(0x930)] public Utf8String World;
    [FieldOffset(0x998)] public Utf8String ZoneName;
    
    // Clients
    [FieldOffset(0xA70)] private ZoneClient* ZoneClient;
    [FieldOffset(0xA78)] private ChatClient* ChatClient;
    
    // Callbacks
    [FieldOffset(0xAB0)] public ZoneLoginCallbackInterface* ZoneLoginCallback;
    [FieldOffset(0xAB8)] public LogoutCallbackInterface* LogoutCallback;
    [FieldOffset(0xAA8)] public NetworkModulePacketReceiverCallback* PacketReceiverCallback;
    
    // State
    [FieldOffset(0xAA1)] public bool WinSockInitialized;
    [FieldOffset(0xC06)] public short CurrentInstance;
    [FieldOffset(0xC38)] public bool IsInCrossWorldDuty;
    
    // Keep-alive
    [FieldOffset(0xC10)] public int KeepAliveZone;
    [FieldOffset(0xC14)] public int KeepAliveIntervalZone;
    [FieldOffset(0xC18)] public int KeepAliveChat;
    [FieldOffset(0xC1C)] public int KeepAliveIntervalChat;
    
    // Timing
    [FieldOffset(0xB54)] public int CurrentDeviceTime;
    [FieldOffset(0xB58)] public int CurrentDeviceTimeMillis;
}
Access:
var framework = Framework.Instance();
var networkProxy = framework->NetworkModuleProxy;
if (networkProxy != null) {
    var networkModule = /* access from proxy */;
}
Usage Example:
var netModule = /* get NetworkModule */;

// Check connection state
if (netModule->WinSockInitialized) {
    Console.WriteLine($"World: {netModule->World.ToString()}");
    Console.WriteLine($"Instance: {netModule->CurrentInstance}");
    Console.WriteLine($"Cross-world duty: {netModule->IsInCrossWorldDuty}");
}

// Check lobby info
var lobbyHost = netModule->ActiveLobbyHost.ToString();
var lobbyPort = netModule->ActiveLobbyPort;
Console.WriteLine($"Lobby: {lobbyHost}:{lobbyPort}");

ZoneClient

Handles zone/game server communication. Struct Layout:
// Application::Network::ZoneClient
[Inherits<ClientBase>]
[StructLayout(LayoutKind.Explicit, Size = 0xA0)]
public unsafe partial struct ZoneClient {
    // Inherits from ClientBase
}
Key Methods:
  • SendPacket(nint, uint, uint, bool) - Send packet to zone server
Usage Example:
var netModule = /* get NetworkModule */;
var zoneClient = netModule->ZoneClient;

if (zoneClient != null) {
    // Send packet
    var packet = stackalloc byte[128];
    // ... fill packet ...
    zoneClient->SendPacket((nint)packet, 0, 0, false);
}
Warning: Sending arbitrary packets can corrupt game state or cause disconnection. Only use for debugging or with complete understanding of the protocol.

ChatClient

Handles chat server communication. Struct Layout:
// Application::Network::ChatClient
[Inherits<ClientBase>]
[StructLayout(LayoutKind.Explicit, Size = 0xA8)]
public unsafe partial struct ChatClient {
    // Inherits from ClientBase
}
Usage:
var netModule = /* get NetworkModule */;
var chatClient = netModule->ChatClient;

if (chatClient != null) {
    // Chat client is active
}

ClientBase

Base class for network clients.
// Application::Network::ClientBase
public unsafe partial struct ClientBase {
    // Connection management
}
Both ZoneClient and ChatClient inherit from this.

Network Callbacks

ZoneLoginCallbackInterface

Handles zone login events.
var netModule = /* get NetworkModule */;
var loginCallback = netModule->ZoneLoginCallback;

if (loginCallback != null) {
    // Handle login events
}

LogoutCallbackInterface

Handles logout events.
var netModule = /* get NetworkModule */;
var logoutCallback = netModule->LogoutCallback;

if (logoutCallback != null) {
    // Handle logout events
}

PacketReceiverCallback

Handles incoming packets.
var netModule = /* get NetworkModule */;
var packetCallback = netModule->PacketReceiverCallback;

if (packetCallback != null) {
    // Process packets
}
Modifying packet callbacks can break game functionality. Use extreme caution.

Common Patterns

Checking Connection State

var netModule = /* get NetworkModule */;

if (netModule->WinSockInitialized) {
    Console.WriteLine("Network initialized");
    
    // Check which world
    var world = netModule->World.ToString();
    var zone = netModule->ZoneName.ToString();
    
    Console.WriteLine($"Connected to {world} - {zone}");
    
    // Check instance
    if (netModule->CurrentInstance > 0) {
        Console.WriteLine($"Instance: {netModule->CurrentInstance}");
    }
    
    // Check duty status
    if (netModule->IsInCrossWorldDuty) {
        Console.WriteLine("In cross-world duty");
    }
}

Monitoring Keep-Alive

var netModule = /* get NetworkModule */;

// Zone keep-alive
var zoneKeepAlive = netModule->KeepAliveZone;
var zoneInterval = netModule->KeepAliveIntervalZone;
Console.WriteLine($"Zone keep-alive: {zoneKeepAlive} (interval: {zoneInterval})");

// Chat keep-alive
var chatKeepAlive = netModule->KeepAliveChat;
var chatInterval = netModule->KeepAliveIntervalChat;
Console.WriteLine($"Chat keep-alive: {chatKeepAlive} (interval: {chatInterval})");

Getting Server Information

var netModule = /* get NetworkModule */;

// Lobby servers
for (int i = 0; i < netModule->LobbyCount; i++) {
    var host = netModule->LobbyHosts[i].ToString();
    var port = netModule->LobbyPorts[i];
    Console.WriteLine($"Lobby {i}: {host}:{port}");
}

// Active lobby
var activeHost = netModule->ActiveLobbyHost.ToString();
var activePort = netModule->ActiveLobbyPort;
Console.WriteLine($"Active: {activeHost}:{activePort}");

// Alternate lobby (for failover)
var altHost = netModule->AlternateLobbyHost.ToString();
var altPort = netModule->AlternateLobbyPort;
Console.WriteLine($"Alternate: {altHost}:{altPort}");

Authentication Info

var netModule = /* get NetworkModule */;

// Session ticket (sensitive!)
var ticket = netModule->Ticket.ToString();

// Frontend server
var frontHost = netModule->FrontHost.ToString();
var frontPort = netModule->FrontPort;
var frontProto = netModule->FrontProtocol.ToString();

Console.WriteLine($"Frontend: {frontProto}://{frontHost}:{frontPort}");
Never log or expose the session ticket. It contains sensitive authentication data.

Data Center Travel

var netModule = /* get NetworkModule */;

// DC Travel endpoint
var dktHost = netModule->DktWebHost.ToString();
var dktPort = netModule->DktWebPort;

Console.WriteLine($"DC Travel: {dktHost}:{dktPort}");

Save Data Server

var netModule = /* get NetworkModule */;

// Save data (config) server
var saveHost = netModule->SaveDataBankHost.ToString();
var savePort = netModule->SaveDataBankPort;
var saveMode = netModule->SaveDataBankMode;

Console.WriteLine($"Save Data: {saveHost}:{savePort} (mode: {saveMode})");

Network Timing

Device Time

var netModule = /* get NetworkModule */;

var deviceTime = netModule->CurrentDeviceTime;
var deviceTimeMs = netModule->CurrentDeviceTimeMillis;

var totalMs = deviceTime * 1000 + deviceTimeMs;
Console.WriteLine($"Device time: {totalMs}ms");

Integration with Framework

Accessing from Framework

var framework = Framework.Instance();

// Check if network is initialized
if (framework->IsNetworkModuleInitialized) {
    var networkProxy = framework->NetworkModuleProxy;
    if (networkProxy != null) {
        // Access network module through proxy
    }
}

if (framework->EnableNetworking) {
    Console.WriteLine("Networking enabled");
}

See Also

Build docs developers (and LLMs) love