Closed urothis closed 5 years ago
Paging @niv who spent some time thinking about this.
For the sake of completeness and cleanup, you can just do this on mysql:
string GetUUID() {
NWNX_SQL_ExecuteQuery("SELECT UUID();");
NWNX_SQL_ReadNextRow();
return NWNX_SQL_ReadDataInActiveRow();
}
For PgSQL, it's similar, you just need to create an extension first:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
And the function name is uuid_generate_v4()
.
@Urothis think we can close this?
IMO, the time to trip out to the database and back would be an order of magnitude longer than just generating it in native C++.
Also, that requires you to use the SQL plugin where the user may not have been using it before.
With BD talking about implementing SQLite for persistent storage, the SQL plugin may be a thing of the past in six months.
I would have to agree with @ELadner,
While being able to use SQL for the uuid generation is a good placeholder.
Something attached to the utils plugin and in "native" c++ will probably be much faster than using SQL in the long run.
The idea behind having in-game UUID functionality was to make it a first-level item on all gff structures. Generate on creation, write on save, re-generate on duplication and conflict.
That way, you can re-identify items, creatures, placeables, etc even if they make a round trip to the vault, save game, or any other database. You could even do this for localvault characters, assuming you trust your players.
The background for wanting this was to fix effect assignment for players re-entering the game world with the same character name, but different character. Expanding it into scripting and making it available to all objects seems the best course of action.
I have a proof of concept written, but it's untested and thus not ready to go into dev; and has been super low priority, as you can see from the initial usecase ..
As to sqlite for the base game, I thought it would be best fitting for a replacement to the CodeBase DB. That way we can store the sqlite3 blob inside the save game too (as opposed to USERDIR/databases/). Adding raw sqlite commands for the advanced user is possible too, with a big fat warning label of course that error recovery will be a pain.
For serverside use cases, the sqlite db would have to live elsewhere. Maybe database/ again .. .. sigh. I can see why it should be in the base game, but for now, Nixie has a good hold on the sql crown w.r.t. persistent worlds.
For now, I'd suggest not worrying too much about UUIDs taking longer in sqlite/mysql than in native. How many thousands per second do you really need?
Edit: From my POC:
// Returns a v4 UUID. This UUID will not be associated with any object.
string GetRandomUUID();
// Returns the given objects' UUID. This UUID is persisted across save states;
// like Save/RestoreCampaignObject.
//
// Thus, reidentification is only guaranteed in scenarios where players cannot introduce
// new objects (i.e. servervault servers).
//
// UUIDs are guaranteed to be unique on any single running server instance.
//
// For normal items, collision conflicts are handled on a first-come-first-serve basis:
//
// Any loaded object that would collide with a existing UUID in the object space
// will receive a new, randomly-generated one and a notice will be emitted to
// the log file (except when done so explicitly through CopyObject).
//
// For servervault characters, the character will fail to load if a object with that
// UUID is already present.
//
// This UUID is useful to, for example:
// - Safely identify servervault characters
// - Track serialisable objects (like items or creatures) as they are saved to the
// campaign DB - i.e. persistent storage chests or dropped items.
// - Track objects across multiple servers (in trusted scenarios).
//
// Will return "" (empty string) when the given object cannot carry a UUID.
string GetObjectUUID(object oObject);
Happy to discuss the proposed feature!
Could we maybe get a small plugin to generate GUID/UUID, it would be insanely helpful.
It would remove the current way of generating a random string via nwscript, and then having to confirm that random string isn't being used elsewhere for a unique id.
I found this https://github.com/graeme-hill/crossguid It might work for this situation but I'm not sure on dependencies. But cross platform seemed good.