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.
- 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)
- P/Invoke declarations for all C ABI functions
- Safe managed wrappers:
Vec3,Quat,Uuid,Host,ImageRaw,GridManager,Llsd,XuiNode - xUnit test suite
- 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
- 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.
cargo build --releaseProduces:
target/release/libfslib.so/fslib.dll/libfslib.dylib– shared librarytarget/release/libfslib.a/fslib.lib– static librarytarget/release/libfslib.rlib– Rust crate
cargo test --releasecd bindings/csharp
dotnet build
dotnet test # requires xunitcd 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 plugincd 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_clientcd examples/rust-gui-viewer
cargo runOpens a window with 5 tabs: Grids, Math, LLSD, XUI Viewer, Image.
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());
}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}");#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);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
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.
| 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 |
By default, fslib builds with a lightweight standalone C++ implementation.
To enable the full Phoenix Firestorm C++ backend:
FSLIB_FIRESTORM_BACKEND=ON cargo build --releaseThis requires the Firestorm 3rd-party dependency tree (Boost, APR, OpenSSL, GLM, etc.). See the Firestorm build instructions.
- Phoenix Firestorm – the original C++ viewer source code
- Linden Lab – the SecondLife viewer code that Firestorm is built upon