MySQL plugin for SA-MP and Open Multiplayer, written in Rust — by NullSablex
mysql_samp is a modern MySQL plugin for SA-MP (San Andreas Multiplayer) and Open Multiplayer (open.mp), written entirely in Rust. It provides a complete API for database connectivity, non-blocking queries, prepared statements, transactions, a cache system, an ORM and Argon2id password hashing, with zero external runtime dependencies.
The same binary loads on SA-MP and on Open Multiplayer — natively as a component (recommended) or via legacy mode.
Not affiliated. This is an independent, community-maintained project. It is not affiliated with, endorsed by, sponsored by, or otherwise connected to SA-MP, the open.mp (Open Multiplayer) project, or the MySQL plugin by BlueG / maddinat0r that this one is compared against. It has no relationship with any of them. "SA-MP", "open.mp" and "MySQL" belong to their respective owners and are referenced here solely to describe what this plugin is compatible with.
- Zero external dependencies — no
libmysqlclient, no OpenSSL. The MySQL protocol and TLS (via rustls) are compiled directly into the binary. - All queries are non-blocking —
mysql_queryruns on background threads with FIFO ordering. The server never stalls. - Connection pool — automatic reuse through
mysql::Pool, thread-safe by design, with a configurable ceiling. - Credentials out of the source —
mysql_connect_filereads them from a config file your repository does not have to carry. - Schema scripts —
mysql_query_fileruns a.sqlfile's statements in order, non-blocking. - Built-in ORM — maps Pawn variables to columns with CRUD helpers.
- Cache system — results accessible through an automatic stack or persisted manually with
cache_save, including multi-result sets from stored procedures. - Prepared statements —
mysql_stmt_*binds values server-side over the binary protocol. Nothing to escape, so nothing to get wrong: the safe way to handle player input. - Transactions —
mysql_transaction_*runs a batch atomically on one connection and rolls it back if any step fails. - Argon2id password hashing —
mysql_hash_password/mysql_verify_password, off the server thread on a bounded worker pool. The plaintext never reaches SQL, so it never reaches your logs. - TLS — rustls compiled in, with CA pinning, mutual TLS and certificate verification on by default.
- Safe by default —
sql_mode-aware escaping, forced UTF-8, protection against SQL injection and memory exhaustion. - Universal binary — built on top of rust-samp v3.4.0; one
.so/.dllruns on SA-MP and on Open Multiplayer (native component or legacy). - Simple deploy — drop the
.soor.dllin and you are done. No system libraries to install.
- Download the latest release for your platform:
mysql_samp.so(Linux i686)mysql_samp.dll(Windows i686, MSVC ABI)mysql_samp.inc(Pawn include, shared between SA-MP and Open Multiplayer)
- Place the binary in the server's
plugins/directory. - Copy
mysql_samp.incto your compiler's include folder:- Windows:
pawno/include/orqawno/include/ - Linux:
include/(at the server root)
- Windows:
- Register the plugin:
- SA-MP — add to
server.cfg:(orplugins mysql_samp.somysql_samp.dllon Windows) - Open Multiplayer (native, recommended) — drop the binary into the
components/folder. open.mp auto-discovers it on start and loads it viaComponentEntryPoint, with access toICore,ITimersComponentand the other native APIs. Noconfig.jsonentry required. - Open Multiplayer (legacy) — same binary works as a legacy plugin. Drop it into
plugins/and add it tolegacy_pluginsinconfig.json(this one DOES need to be declared, otherwise open.mp skips legacy plugins).
- SA-MP — add to
Important
No libmysqlclient or other system library is required. The plugin is self-contained.
#include <a_samp>
#include <mysql_samp>
new gMysql;
public OnGameModeInit() {
gMysql = mysql_connect("127.0.0.1", "root", "password", "samp_db");
if (mysql_errno()) {
return 1;
}
// Non-blocking query with callback
mysql_query(gMysql, "SELECT * FROM players LIMIT 10", "OnPlayersLoaded");
return 1;
}
forward OnPlayersLoaded();
public OnPlayersLoaded() {
new rows = cache_get_row_count();
printf("Players found: %d", rows);
new name[MAX_PLAYER_NAME];
for (new i = 0; i < rows; i++) {
cache_get_value_name(i, "name", name);
printf(" - %s", name);
}
}
public OnGameModeExit() {
mysql_close(gMysql);
return 1;
}Browse the examples/ folder for self-contained .pwn scripts covering connection setup, threaded queries, ORM, TLS, error handling, prepared statements, transactions, password hashing, config files, .sql scripts and multi-result sets. For anything carrying player input, start with 08_prepared_statements.pwn. The plugin natives (mysql_*, cache_*, orm_*) and the OnQueryError forward are identical across SA-MP and Open Multiplayer, so every example builds and runs on both — the only thing that differs between servers is the installation path documented above.
The full plugin documentation lives in docs/:
| Document | Contents |
|---|---|
| Installation and setup | Setup, server.cfg / config.json, requirements |
| Connection | mysql_connect, mysql_connect_file, mysql_close, mysql_status, charset, pool size |
| Options | All MYSQL_OPT_* values, defaults, TLS, mutual TLS, pool size |
| Queries | mysql_query, mysql_pquery, mysql_format, mysql_escape_string, prepared statements, transactions, running a .sql file |
| Cache | All cache_* functions, save/restore, lifecycle, multiple result sets |
| ORM | Object-relational mapping, CRUD, bindings |
| Errors | mysql_errno, mysql_error, OnQueryError, error codes |
| Security | Prepared statements vs escaping, password storage, TLS, resource limits |
| API reference | Full table of every native and forward |
| Migration from R41-4 | Differences and migration steps from mysql R41-4 |
- Rust stable toolchain with the targets
i686-unknown-linux-gnuandi686-pc-windows-msvc cargo-xwinfor cross-compiling the Windows.dllfrom Linux (installed automatically by the script)- 32-bit C support, for the Linux target. The TLS backend (
ring) compiles C and 32-bit assembly, sogcc -m32must work:apt install gcc-multilib g++-multilibon Debian/Ubuntu (glibc-devel.i686on Fedora,lib32-glibcon Arch). Both build scripts check this up front and name the package, because the underlying error is an opaque missing-header message. - LLVM, only when cross-compiling the Windows
.dllfrom Linux. Archivingring's objects for MSVC needsllvm-lib, which cargo-xwin does not ship;scripts/build-linux.shfinds it under/usr/lib/llvm-*/binautomatically. Not needed when building on Windows — MSVC's ownlib.exehandles it, andringships pre-assembled objects so NASM is not required either. - No MySQL or TLS system libraries — no
libmysqlclient, no OpenSSL.
cargo build --target i686-unknown-linux-gnuFrom Linux:
./scripts/build-linux.shFrom Windows (Git Bash):
./scripts/build-windows.shBoth scripts produce dist/mysql_samp.so and dist/mysql_samp.dll, each with full SA-MP + Open Multiplayer native support.
Caution
This plugin is distributed under the GPL v3. Any derivative work must keep the source code open under the same license.
Copyright (c) 2026 NullSablex
This project is licensed under the GNU General Public License v3.0.