Skip to content

Repository files navigation

libfirestorm

A Rust library and multi-platform shared library (.so / .dll / .dylib) providing SecondLife / OpenSim client functionality, derived from the Phoenix Firestorm viewer source code.

Includes .NET bindings, C# wrappers, and MIT-licensed modular example clients (Rust, C++, Unity) with plugin support.

Features

Core library (LGPL-2.1-or-later)

  • Math – 3D vectors, quaternions, 4×4 matrices (add, sub, dot, cross, normalize, slerp, rotate, transform)
  • UUID – 128-bit SecondLife UUID parsing, formatting, comparison
  • Image decoding – BMP, TGA (standalone); JPEG, PNG, JPEG2000 (with Firestorm backend)
  • Network host – IPv4 address + port representation for the UDP message system
  • Type enums – Asset types, inventory types, primitive codes (PCode)
  • LLSD – Linden Struct Data parser/serializer (the data format used for grids.xml, login responses, capabilities)
  • Grid management – Parses grids.xml, manages known grids (SecondLife, OpenSim, localhost), login URIs, helper URIs
  • XUI parsing – Parses Firestorm's XML UI definitions (floaters, panels, controls) into a node tree for rendering by any UI toolkit
  • C ABI – Stable extern "C" API consumable from C, C++, Python, C#, Go, and any language with FFI support
  • Multi-platform – Builds on Linux (.so), Windows (.dll), and macOS (.dylib)

.NET bindings (LGPL-2.1-or-later)

  • P/Invoke declarations for all C ABI functions
  • Safe managed wrappers: Vec3, Quat, Uuid, Host, ImageRaw, GridManager, Llsd, XuiNode
  • xUnit test suite

Example clients (MIT)

  • Rust client – Modular client with dynamic plugin loading (.so/.dll)
  • Rust GUI viewer – egui-based viewer with grid browser, math tools, LLSD/XUI parsers, image decoder
  • C++ client – Modular client with dlopen-based plugin loading
  • Unity client – C# component with reflection-based plugin discovery

License

  • Core library (src/, native/, include/): LGPL-2.1-or-later – GPL-compatible, does not restrict linking
  • .NET bindings (bindings/csharp/FsLib/): LGPL-2.1-or-later
  • Example clients (examples/): MIT – no restrictions

See LICENSE for the full LGPL text and individual files for MIT license text.

Quick start

Build the core library

cargo build --release

Produces:

  • target/release/libfslib.so / fslib.dll / libfslib.dylib – shared library
  • target/release/libfslib.a / fslib.lib – static library
  • target/release/libfslib.rlib – Rust crate

Test

cargo test --release

Build the .NET bindings

cd bindings/csharp
dotnet build
dotnet test  # requires xunit

Build and run the Rust example client

cd examples/rust-client
cargo run

# Build and load the example plugin
cd plugins/example_plugin
cargo build --release
cp target/release/libfslib_plugin_example.so ../
cd ../..
cargo run  # will load the plugin

Build and run the C++ example client

cd examples/cpp-client
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
cp libfslib_cpp_plugin_example.so plugins/
LD_LIBRARY_PATH=../../../target/release:. ./fslib_cpp_client

Build and run the Rust GUI viewer

cd examples/rust-gui-viewer
cargo run

Opens a window with 5 tabs: Grids, Math, LLSD, XUI Viewer, Image.

Use from Rust

use fslib;

fn main() {
    println!("{}", fslib::version_string());

    let a = fslib::Vec3::new(3.0, 4.0, 0.0);
    println!("length = {}", a.length()); // 5.0

    let uuid = fslib::Uuid::from_str("a1b2c3d4-e5f6-7890-abcd-ef1234567890").unwrap();
    println!("{}", uuid);

    // Grid management
    let mut gm = fslib::GridManager::new();
    let info = gm.get_info("util.agni.lindenlab.com").unwrap();
    println!("Grid: {} ({})", info.gridname, info.gridnick);

    // LLSD parsing
    let llsd = fslib::Llsd::parse("<llsd><string>hello</string></llsd>").unwrap();
    println!("LLSD: {}", llsd.as_str().unwrap());

    // XUI parsing
    let xui = fslib::XuiNode::parse("<floater name=\"test\" title=\"Test\"/>").unwrap();
    println!("UI: {} ({})", xui.tag(), xui.attr("title").unwrap());
}

Use from C#

using FsLib;

var v = new Vec3(3, 4, 0);
Console.WriteLine($"Length: {v.Length}"); // 5.0

using var gm = new GridManager();
var info = gm.GetInfo("util.agni.lindenlab.com");
Console.WriteLine($"Grid: {info.GridName}");

using var llsd = Llsd.Parse("<llsd><string>hello</string></llsd>");
Console.WriteLine($"LLSD: {llsd!.AsString}");

Use from C

#include "fslib.h"

fslib_grid_manager_t *gm = fslib_grid_manager_new();
fslib_grid_info_t info;
fslib_grid_manager_get_info(gm, "util.agni.lindenlab.com", &info);
printf("Grid: %s\n", info.gridname);
fslib_grid_manager_free(gm);

Project structure

fslib/
├── Cargo.toml                  # Rust crate manifest
├── build.rs                    # CMake build for C++ native code
├── LICENSE                     # LGPL-2.1
├── README.md
├── include/
│   ├── fslib.h                 # C API header (stable ABI)
│   └── fslib.hpp               # C++ RAII wrappers
├── src/                        # Rust library
│   ├── lib.rs                  # Library root
│   ├── ffi.rs                  # extern "C" FFI declarations
│   ├── export.rs               # #[no_mangle] re-exports for cdylib
│   ├── math.rs                 # Vec3, Quat, Mat4
│   ├── uuid.rs                 # Uuid
│   ├── image.rs                # ImageRaw, ImageCodec
│   ├── host.rs                 # Host
│   ├── types.rs                # AssetType, InventoryType, PCode
│   ├── llsd.rs                 # LLSD parser/serializer
│   ├── grid.rs                 # GridManager
│   └── xui.rs                  # XUI node parser
├── native/
│   ├── fslib_native/           # C++ C ABI implementation
│   │   ├── CMakeLists.txt
│   │   ├── fslib.cpp           # Core (math, UUID, image, host, types)
│   │   ├── fslib_llsd.cpp      # LLSD parser/serializer
│   │   ├── fslib_grid.cpp      # Grid manager
│   │   ├── fslib_xui.cpp       # XUI parser
│   │   └── fslib.ver           # Linker version script
│   └── indra/                  # Phoenix Firestorm C++ sources
├── data/                       # SecondLife/OpenSim data files
│   ├── app_settings/
│   │   └── grids.xml           # Grid definitions (LLSD)
│   └── skins/
│       ├── skins.xml           # Skin definitions
│       └── default/xui/en/     # Default skin UI XML (floaters, panels)
├── bindings/
│   └── csharp/                 # .NET bindings
│       ├── FsLib/              # P/Invoke + safe wrappers
│       │   ├── Native.cs       # P/Invoke declarations
│       │   └── Wrappers.cs     # Safe managed wrappers
│       └── FsLib.Tests/        # xUnit tests
├── examples/
│   ├── rust-client/            # MIT - Modular Rust client with plugins
│   │   ├── src/
│   │   │   ├── main.rs
│   │   │   └── plugin.rs       # Plugin system (dynamic loading)
│   │   └── plugins/
│   │       └── example_plugin/ # Example Rust plugin (cdylib)
│   ├── rust-gui-viewer/        # MIT - egui GUI viewer
│   │   ├── src/
│   │   │   ├── main.rs
│   │   │   └── tabs.rs         # Grid/Math/LLSD/XUI/Image tabs
│   │   └── README.md
│   ├── cpp-client/             # MIT - Modular C++ client with plugins
│   │   ├── src/
│   │   │   ├── main.cpp
│   │   │   ├── plugin_manager.h
│   │   │   └── plugin_manager.cpp
│   │   └── plugins/
│   │       └── example_plugin.cpp
│   └── unity-client/           # MIT - Unity C# client
│       └── Assets/FsLibClient/
│           ├── FsLibClient.cs  # Main client component
│           └── ExamplePlugin.cs
├── tests/
│   └── integration.rs          # 27 integration tests
└── .github/workflows/
    └── build.yml               # CI: Linux, Windows, macOS

Plugin system

All three example clients use the same plugin C ABI:

struct PluginVTable {
    const char* (*name)();
    const char* (*version)();
    const char* (*description)();
    void (*on_init)();
    void (*on_update)();
    void (*on_shutdown)();
};

extern const PluginVTable* fslib_plugin_entry(void);

Plugins are shared libraries (.so/.dll/.dylib) that export fslib_plugin_entry(). The client loads them at runtime and calls the lifecycle methods.

The Unity client uses a different approach (C# IPlugin interface discovered via reflection) since Unity plugins are managed assemblies.

Cargo features

Feature Default Description
native-build yes Build the bundled C++ code from source
system-native no Link against a pre-built fslib_native
opensim no Enable OpenSim / multi-grid support
verbose no Verbose CMake build output

Firestorm backend (optional)

By default, fslib builds with a lightweight standalone C++ implementation. To enable the full Phoenix Firestorm C++ backend:

FSLIB_FIRESTORM_BACKEND=ON cargo build --release

This requires the Firestorm 3rd-party dependency tree (Boost, APR, OpenSSL, GLM, etc.). See the Firestorm build instructions.

Acknowledgements

About

SecondLife/OpenSim client library (Rust + C++ + .NET) derived from Phoenix Firestorm. LGPL-2.1 core, MIT examples.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages