Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.oxd.sh/llms.txt

Use this file to discover all available pages before exploring further.

Plain C++

Include the header and link the library. The SDK is pure C, so no extern "C" wrapper is needed — oxaccel.h handles it.
#include "oxaccel.h"
#include <cstdio>

int main() {
    OxAccelConfig config{};
    config.api_key    = "your-api-key";
    config.relay_host = "relay.oxd.sh";
    config.relay_port = 51820;
    config.enable_fec = true;
    config.enable_compression = true;

    OxAccel* ctx = ox_accel_create(&config);
    if (!ctx) return 1;

    if (ox_accel_connect(ctx) != OxAccelError_Ok) {
        ox_accel_destroy(ctx);
        return 1;
    }

    // Send
    uint8_t data[] = {0x01, 0x02, 0x03};
    ox_accel_send(ctx, data, sizeof(data));

    // Receive
    uint8_t buf[65536];
    size_t received = 0;
    ox_accel_recv(ctx, buf, sizeof(buf), &received);

    ox_accel_destroy(ctx);
    return 0;
}

RAII wrapper

#include "oxaccel.h"
#include <stdexcept>

class AccelContext {
    OxAccel* ctx_;
public:
    AccelContext(const OxAccelConfig& config)
        : ctx_(ox_accel_create(&config))
    {
        if (!ctx_) throw std::runtime_error("ox_accel_create failed");
    }

    ~AccelContext() { ox_accel_destroy(ctx_); }

    AccelContext(const AccelContext&) = delete;
    AccelContext& operator=(const AccelContext&) = delete;

    OxAccelError connect()                  { return ox_accel_connect(ctx_); }
    OxAccelError send(const uint8_t* d, size_t n) { return ox_accel_send(ctx_, d, n); }
    OxAccelError recv(uint8_t* b, size_t n, size_t* out) { return ox_accel_recv(ctx_, b, n, out); }
    OxAccelError stats(AccelStats* s)       { return ox_accel_stats(ctx_, s); }
};

Unreal Engine

Build module setup

// MyGame.Build.cs
using UnrealBuildTool;
using System.IO;

public class MyGame : ModuleRules
{
    public MyGame(ReadOnlyTargetRules Target) : base(Target)
    {
        string AccelDir = Path.Combine(ModuleDirectory, "ThirdParty", "oxaccel");

        PublicIncludePaths.Add(AccelDir);

        if (Target.Platform == UnrealTargetPlatform.Win64)
        {
            PublicAdditionalLibraries.Add(Path.Combine(AccelDir, "oxaccel.lib"));
            RuntimeDependencies.Add(Path.Combine(AccelDir, "oxaccel.dll"));
        }
        else if (Target.Platform == UnrealTargetPlatform.Linux)
        {
            PublicAdditionalLibraries.Add(Path.Combine(AccelDir, "liboxaccel.a"));
        }
        else if (Target.Platform == UnrealTargetPlatform.Mac)
        {
            PublicAdditionalLibraries.Add(Path.Combine(AccelDir, "liboxaccel.a"));
            PublicFrameworks.AddRange(new string[] { "Security", "CoreFoundation" });
        }
    }
}

Subsystem usage

// AccelSubsystem.h
#pragma once
#include "Subsystems/GameInstanceSubsystem.h"
#include "oxaccel.h"

UCLASS()
class UAccelSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()
    OxAccel* Ctx = nullptr;

public:
    virtual void Initialize(FSubsystemCollectionBase& Collection) override;
    virtual void Deinitialize() override;

    bool Send(const TArray<uint8>& Data);
    bool Recv(TArray<uint8>& OutData);
};
// AccelSubsystem.cpp
#include "AccelSubsystem.h"

void UAccelSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
    Super::Initialize(Collection);

    OxAccelConfig Config{};
    Config.relay_host = "relay.oxd.sh";
    Config.relay_port = 51820;
    Config.enable_fec = true;

    Ctx = ox_accel_create(&Config);
    if (Ctx) ox_accel_connect(Ctx);
}

void UAccelSubsystem::Deinitialize()
{
    if (Ctx) { ox_accel_destroy(Ctx); Ctx = nullptr; }
    Super::Deinitialize();
}

bool UAccelSubsystem::Send(const TArray<uint8>& Data)
{
    if (!Ctx) return false;
    return ox_accel_send(Ctx, Data.GetData(), Data.Num()) == OxAccelError_Ok;
}

bool UAccelSubsystem::Recv(TArray<uint8>& OutData)
{
    if (!Ctx) return false;
    OutData.SetNumUninitialized(65536);
    size_t Received = 0;
    auto Err = ox_accel_recv(Ctx, OutData.GetData(), OutData.Num(), &Received);
    if (Err != OxAccelError_Ok) return false;
    OutData.SetNum(Received);
    return true;
}