-
Notifications
You must be signed in to change notification settings - Fork 44
Description
While the documentation suggests it is enough to switch out the EntityLoader to implement your custom data source, this is currently not entirely true for accounts. You can load them from any alternate source, but the only proper method for creating/saving them is calling save() on the Account object (as done by the example bundles). Save() on Account.js in turn calles the save() function on Data.js, which currently looks like this:
/**
* Save data file (player/account) data to disk
* @param {string} type
* @param {string} id
* @param {*} data
* @param {function} callback
*/
static save(type, id, data, callback) {
fs.writeFileSync(this.getDataFilePath(type, id), JSON.stringify(data, null, 2), 'utf8');
if (callback) {
callback();
}
}
... regardless of the user implementation for the data source.
Work Around
To implement custom sources for accounts there are currently two ways--switching out Account.js with one imlementing a custom save() function (and consequently AccountManager which depends on it)--or to access the loader stored in AccountManager directly in your code via Accountmanager.loader.custom_loader_save_function(). The first is somewhat overkill if you have no intention of changing the fields/pw encryption Account provides while the later leaves it to the developer to make sure the loader they access from the Accountmanager is the one they hooked up and feels unintuitive.
Proposed Solution:
- Add a create/save function to the EntityLoader (similar to the already existing update and replace functions), surrendering full CRUD control to the loader and consequently user implementation.
- Add a save() function to AccountManager which takes an Account object, serializes it and passes the data on to the loader for handling--similar to save(player) on the PlayerManager.
- Update Account.js to remove all calls to this.save() which currently happens in all functions changing account data. Instead call save explicitely outside of account, bringing it inline with how player requires explicit saving.
- Update example bundles to do AccountManager.save(account) rather than account.save().
- Deprecate/dissuade use of account.save(), but leave it in for backwards compatibility?
Optional Consideration:
EntityLoader currently has implementations for update/replace which are not used by AccountManager and inaccessible unless using the loader directly. There is also no delete function for cases when you do want to delete an account properly rather than just setting account.delete to true. It may be an interesting feature to add the full set of CRUD functions to the AccountManager so it can serve as a gateway to accessing all loader functions for usecases where people really only want to change how data is saved/loaded, but don't need custom implementations for accounts.