itk-protocol

Wire protocol definitions with serialization, validation, and integrity checking. Every IPC message uses a 20-byte binary header followed by a bitcode-serialized payload.

Header Format

Magic
4B · "ITKP"
Version
4B · u32 (2)
MsgType
4B · u32
PayloadLen
4B · u32
CRC32
4B · u32

Constants

pub const MAGIC: [u8; 4] = *b"ITKP";
pub const VERSION: u32 = 2;            // bumped for bitcode migration
pub const HEADER_SIZE: usize = 20;
pub const MAX_PAYLOAD_SIZE: usize = 1_048_576;  // 1 MB
pub const MAX_STRING_LENGTH: usize = 256;
pub const MAX_DATA_LENGTH: usize = 65_536;      // 64 KB

MessageType Enum

RangeVariantsPurpose
0-1Ping, PongHealth check / latency
10-12ScreenRect, WindowState, OverlayUpdateWindow geometry
20-23StateSnapshot, StateEvent, StateQuery, StateResponseGame state exchange
30-32SyncState, ClockPing, ClockPongClock and playback sync
40-46VideoLoad through VideoErrorVideo control and state
255ErrorError response

Validation

All payload structs implement the Validate trait. Validation rules:

  • Float fields reject NaN and Infinity
  • String fields capped at 256 bytes
  • Data fields capped at 64 KB
  • DPI scale must be in range 0.1–10.0
  • Playback rate must be positive

Encode / Decode

// Encode a message
let bytes = itk_protocol::encode(MessageType::Ping, &())?;

// Decode with validation
let (msg_type, payload): (MessageType, ScreenRect) =
    itk_protocol::decode_validated(&bytes)?;

// Decode header only (for routing)
let header = itk_protocol::decode_header(&bytes)?;

Error Types

pub enum ProtocolError {
    InvalidMagic,
    UnsupportedVersion,
    PayloadTooLarge,
    CrcMismatch,
    UnknownMessageType,
    Serialization(String),
    IncompleteHeader,
    IncompletePayload,
    ValidationFailed(String),
}

itk-shmem

Cross-platform shared memory with seqlock synchronization for lock-free single-writer, multi-reader frame transport.

SeqlockHeader

#[repr(C)]  // 64 bytes, cache-line aligned
pub struct SeqlockHeader {
    pub seq: AtomicU32,           // odd = writing, even = consistent
    pub read_idx: AtomicU32,      // current read buffer (0-2)
    pub pts_ms: AtomicU64,        // presentation timestamp
    pub frame_width: AtomicU32,
    pub frame_height: AtomicU32,
    pub is_playing: AtomicU32,
    pub content_id_hash: AtomicU64,
    pub duration_ms: AtomicU64,
    pub writer_count: AtomicU32,  // multi-writer detection
    _padding: [u8; 8],
}

FrameBuffer API

Triple-buffered RGBA frame transport. Layout: [Header: 64B][Buf0: W*H*4][Buf1: W*H*4][Buf2: W*H*4]

// Writer (daemon)
let fb = FrameBuffer::create("nms_video", 1280, 720)?;
fb.write_frame(&rgba_data, pts_ms, content_hash)?;

// Reader (injector or overlay)
let fb = FrameBuffer::open("nms_video", 1280, 720)?;
let mut buf = vec![0u8; 1280 * 720 * 4];
let (pts, changed) = fb.read_frame(last_pts, &mut buf)?;

SharedMemory API

// Create (owner)
let shmem = SharedMemory::create("itk_frames", size)?;

// Open (reader)
let shmem = SharedMemory::open("itk_frames", size)?;

// Raw access (unsafe)
unsafe { shmem.write(offset, &data)?; }
unsafe { shmem.read(offset, &mut buf)?; }

Seqlock Algorithm

Writer operations use Acquire/Release memory ordering. ARM-compatible with explicit fence(Acquire) on the reader side. The begin_write() method checks writer_count to detect multiple-writer violations at runtime.

Read Strategies

MethodBehaviorUse Case
try_read()Returns Option<SeqlockState>Non-blocking poll
read_blocking()Spins until consistent readGuaranteed latest state
read_with_timeout(n)Retries up to N timesBounded wait

Size Reference

ResolutionTotal Size
720p (1280×720)64 + 11,059,200 bytes (~11 MB)
1080p (1920×1080)64 + 24,883,200 bytes (~24 MB)
4K (3840×2160)64 + 99,532,800 bytes (~95 MB)

Maximum dimension: 8192×8192. Checked arithmetic prevents integer overflow in size calculations.

itk-ipc

Cross-platform IPC via trait abstractions. Named pipes on Windows, Unix domain sockets on Linux.

IpcChannel Trait

pub trait IpcChannel: Send + Sync {
    fn send(&self, data: &[u8]) -> Result<()>;
    fn recv(&self) -> Result<Vec<u8>>;        // blocking
    fn try_recv(&self) -> Result<Option<Vec<u8>>>; // non-blocking
    fn is_connected(&self) -> bool;
    fn close(&self);
}

IpcServer Trait

pub trait IpcServer: Send + Sync {
    type Channel: IpcChannel;
    fn accept(&self) -> Result<Self::Channel>; // blocking
    fn close(&self);
}

Factory Functions

// Connect as client
let channel = itk_ipc::connect("video_control")?;

// Listen as server
let server = itk_ipc::listen("video_control")?;
let client = server.accept()?;

// Channel naming
itk_ipc::make_channel_name("video_control")
// Windows: "\\.\pipe\itk_video_control"
// Linux:   "/tmp/itk_video_control.sock"

Message Helpers

// Read a length-prefixed message
let data = itk_ipc::read_message(&mut reader)?;

// Write a length-prefixed message
itk_ipc::write_message(&mut writer, &data)?;

Platform Implementations

PlatformClientServer
WindowsNamedPipeClientNamedPipeServer
UnixUnixSocketClientUnixSocketServer

itk-sync

Clock synchronization and playback drift correction for multiplayer video sync.

Sync Model

Position is calculated from a reference point rather than absolute timestamps:

current_pos = position_at_ref + (now - ref_wallclock) * playback_rate

ClockSync

NTP-lite algorithm that processes ping/pong exchanges to estimate clock offset between peers.

let mut clock = ClockSync::new();

// After receiving a pong:
clock.process_pong(send_time_ms, remote_time_ms, recv_time_ms);

// Convert timestamps between clocks:
let remote_ts = clock.local_to_remote(local_ms)?;
let local_ts = clock.remote_to_local(remote_ms)?;

Uses the median of the best-half (lowest RTT) of up to 10 samples for robustness against network jitter.

PlaybackSync

pub struct PlaybackSync {
    pub content_id: String,
    pub position_at_ref_ms: u64,
    pub ref_wallclock_ms: u64,
    pub is_playing: bool,
    pub playback_rate: f64,  // 0.95-1.05 for drift correction
}

let sync = PlaybackSync::new("video_123");
let pos = sync.current_position_ms();  // computed from ref point
sync.set_playing(true);                // captures position first
sync.seek(30_000);                     // seek to 30s

DriftCorrector

Combines a target PlaybackSync with a ClockSync to smoothly correct playback drift across peers.

Drift RangeCorrection RateAction
0 – 150 ms1.0xNo correction (within tolerance)
151 – 500 ms0.98x / 1.02xGentle speed adjustment
501 – 1500 ms0.95x / 1.05xModerate speed adjustment
> 1500 ms0.0x (pause)Recommend hard seek
let mut corrector = DriftCorrector::new(target_sync, clock_sync);

// Get corrected playback rate
let rate = corrector.calculate_rate(current_position_ms);

// Check if hard seek is needed
if let Some(target) = corrector.should_seek(current_position_ms) {
    player.seek(target);
}

// Get current drift
let drift = corrector.current_drift_ms(current_position_ms);

itk-video

Video decoding pipeline powered by ffmpeg-next with hardware acceleration and shared memory frame output.

Pipeline

StreamSource (file/URL)
  → VideoDecoder (ffmpeg-next)
  → FrameScaler (to 1280×720 RGBA)
  → FrameWriter (to shared memory)

Constants

pub const DEFAULT_WIDTH: u32 = 1280;
pub const DEFAULT_HEIGHT: u32 = 720;
pub const BYTES_PER_PIXEL: usize = 4;  // RGBA

pub const fn frame_size(width: u32, height: u32) -> usize {
    width as usize * height as usize * BYTES_PER_PIXEL
}

StreamSource

Supports local files and network URLs. YouTube support is gated behind the youtube feature flag and requires yt-dlp to be installed.

Hardware Acceleration

The decoder tries D3D11VA hardware acceleration first, with automatic fallback to software decoding. The hwaccel module handles device negotiation and format conversion.

Modules

ModulePurpose
decoderVideoDecoder wrapping ffmpeg-next
scalerFrameScaler for pixel format/resolution conversion
frame_writerFrameWriter to shared memory via itk-shmem
hwaccelHardware acceleration negotiation
streamStreamSource URL/file resolution
youtubeyt-dlp integration (feature-gated)

itk-net

P2P networking for multiplayer session management and playback synchronization via laminar.

Architecture

Session
  +-- Discovery (UDP broadcast on port 7332)
  +-- PeerManager (laminar connections on port 7331)
  +-- SyncManager (ClockSync + PlaybackSync per peer)

Constants

pub const DEFAULT_PORT: u16 = 7331;
pub const DISCOVERY_PORT: u16 = 7332;
pub const SYNC_INTERVAL_MS: u64 = 500;
pub const CLOCK_PING_INTERVAL_MS: u64 = 2000;

Sync Flow

  1. Leader broadcasts SyncState every 500ms (unreliable delivery)
  2. Followers use DriftCorrector for smooth catch-up
  3. ClockPing/ClockPong exchanges estimate clock offset every 2s
  4. Commands (play, pause, seek) sent via reliable delivery

Session Roles

One peer is elected leader (the host). The leader is the authoritative source for playback state. Discovery uses UDP broadcast to find peers on the local network.

Public API

pub use session::{Session, SessionConfig, SessionEvent, SessionRole};
pub use discovery::Discovery;
pub use peer::{Peer, PeerEvent, PeerManager};
pub use sync_manager::SyncManager;

Templates

Starter templates for building new game mod projects on the ITK framework.

itk-daemon

Central coordinator daemon template. Handles IPC server setup, shared memory creation, and event loop scaffolding.

daemon/

itk-overlay

wgpu-based transparent overlay window template. Includes egui integration, click-through setup, and shared memory reading.

overlay/

itk-native-dll

Windows DLL injection template using retour for function hooking. Includes DllMain entry point and hook setup scaffolding.

injectors/windows/native-dll/

itk-ld-preload

Linux LD_PRELOAD injection template. Intercepts library calls at the dynamic linker level for non-invasive hooking.

injectors/linux/ld-preload/

CI/CD Pipeline

All CI runs inside Docker containers via docker compose --profile ci on a self-hosted runner.

Pipeline Stages

StageCommandPurpose
1. Formatcargo fmt --all -- --checkConsistent code style
2. Lintcargo clippy --all-targets -- -D warningsStatic analysis (warnings = errors)
3. Testcargo test -- --test-threads=4Unit and integration tests
4. Buildcargo build --releaseRelease binary compilation
5. Auditcargo deny checkLicense and advisory checking

Workflows

  • main-ci.yml — Runs on push to main and version tags. Includes binary building and GitHub Release creation with auto-generated changelog.
  • pr-validation.yml — Runs on pull requests. Adds AI code review (Gemini primary) with automated fix iterations (up to 5 rounds). (Codex review has been disabled — OpenAI is phased out due to mass surveillance and autonomous weapons concerns. See README for details.)

Release Artifacts

On tagged releases, the pipeline builds Linux x64 binaries:

  • nms-video-daemon-linux-x64
  • nms-video-overlay-linux-x64
  • mem-scanner-linux-x64

Advisory Exemptions

Two advisories are currently exempted in deny.toml:

  • RUSTSEC-2025-0141 — bincode unmaintained (migration to bitcode in progress)
  • RUSTSEC-2026-0007 — bytes integer overflow (update pending)