Offline instant messages on SQLite
OpenSim's offline-message module for standalones and grids, "Offline Message Module V2"
(OpenSim/Addons/OfflineIM), keeps its messages through an IOfflineIMData storage plugin, and 0.9.3.0 ships that
plugin for MySQL and PostgreSQL only. On a SQLite standalone the module cannot run: with
StorageProvider = OpenSim.Data.SQLite.dll its service finds no storage class, throws "Could not find a storage
interface in the given module", and because the exception comes out of a shared region module's Initialise,
OpenSim stops at startup. The other module, OfflineMessageModule, needs an external web service
(OfflineMessageURL, a PHP script).
This adds SQLiteOfflineIMData, a port of MySQLOfflineIMData: the same im_offline table, created by
IM_Store.migrations the first time the handler opens the database, and the same generic-table access. The SQLite
generic handler has no GetCount, so it is written here; DeleteOld uses datetime('now', '-14 days') where
MySQL uses NOW() - INTERVAL 2 WEEK. Written 2026-09-27 for the ship plan's "offline IM on".
Apply to a fresh opensim-src
../sqlite-offlineim.diff creates both files (OpenSim/Data/SQLite/SQLiteOfflineIMData.cs and
OpenSim/Data/SQLite/Resources/IM_Store.migrations). build/build_server.py applies it before Prebuild. By hand:
- Apply the diff at the tree root (
patch -p1 < sqlite-offlineim.diff, orgit apply). - Re-run
runprebuild(from cmd on Windows).prebuild.xmlwildcards*.csandResources/*.migrationsfor this project, so the regeneratedOpenSim.Data.SQLite.csprojincludes both files. - Build
OpenSim.Data.SQLite.csproj. The DLL isbin/OpenSim.Data.SQLite.dll; swap it in during a restart.
Deploy order on a running server: the DLL first, the config second. With the config below and an unpatched
OpenSim.Data.SQLite.dll, OpenSim does not start.
Region config (bin/OpenSim.ini; config/paracosm.ini writes it)
[Messaging]
OfflineMessageModule = "Offline Message Module V2"
StorageProvider = OpenSim.Data.SQLite.dll
ConnectionString = "URI=file:offlineim.db,version=3"
OfflineMessageURL stays unset (the service runs inside the simulator). Optional keys the service reads:
MaxOfflineIMs (default 25 per recipient; the sender is told "Message not saved" past it), Realm (the table,
default im_offline), ForwardOfflineGroupMessages (default true: group notices and invitations are kept too).
Tested (2026-09-27, offline; no OpenSim process was started)
Built with the whole series by build/build_server.py into a scratch folder; a test program in that bin/ drove
the module and service through OpenSim's own classes:
OfflineIMRegionModule.Initialisewith the config above (the startup path): no exception.StoreMessagethree times for one recipient, then a fourth refused with "Number of offline IMs has maxed out" atMaxOfflineIMs = 3.GetMessagesreturns the three intact (text, sender, UTF-8) and deletes them; a second call returns none.DeleteOld: a message aged 15 days is removed, a fresh one kept.- The config as
tools/make_config.pywrites it, loaded by OpenSim's ownConfigurationLoader, starts the module and createsbin/offlineim.db.
Not tested: a message sent in a viewer to an avatar who is offline, and its delivery at that avatar's next login.