Since I can't exactly edit my top post anymore for whatever reason.. just a slight update to the DB NPC. Instead of using extractfilebase I decided to use the identity variable which is a slight efficieny boost so.. woot.
Basicly overlapping filenames shouldn't be a problem if someone decides to put this to extensive use, also I added a little check to prevent overlapping identities, it causes the file using the identity to save and unload, and then the new file can load which is a scenario that would be caused by a server crash.
If someone could update my main post with this, that would be appreciated.
The Database NPC
PHP Code:
/*
Main Idea: Alternative to clientr. values
- Loads a Variable File into Memory
- Allows Option to Sync Data with Client
- Unloads and Saves on PlayerLogout
*/
function onCreated() {
// For Calling Scratch instead of using findnpc()
const Scratch = this;
// The Clientside Weapon used with Scratch
this.db = "+Scratch";
}
/*
Loads Scratch Data into Database
@param file Absolute Path to File
@param identity The ID you're going to give your file
@param clientsync Sync Data with Client? True or False
*/
public function onLoadScratch(file, identity, clientsync) {
// Content Overlap Prevention
// Example: Server Crashes, this will save the File and Reload It.
if (identity in this.identifiers.(@player.account)) onUnloadScratch(player.account, identity);
// Add Files to Memory
this.identifiers.(@player.account).add(identity);
this.files.(@player.account).add(file);
// Load Scratch Memory
this.scratch.(@player.account).(@identity).loadvars(file);
// Sync with Client?
if (clientsync) {
temp.lines.loadlines(file);
player.triggerclient(this.db, "load", identity, temp.lines);
this.clientsync.(@player.account).add(identity);
}
}
/*
Unloads all Scratch data associated with account
@param acc Player's Account Name
*/
public function onUnloadScratch(acc, identity) {
// Remove Specific Scratch
if (identity) {
// Determine File
temp.file = onGetFile(identity);
// Save File
this.scratch.(@acc).(@identity).savevars(file, 0);
// Remove from Memory
this.scratch.(@acc).(@identity).clearvars();
// Remove from Player Variables
this.identifiers.(@acc).remove(identity);
this.files.(@acc).remove(file);
if (identity in this.clientsync.(@acc))
this.clientsync.(@acc).remove(identity);
return;
}
// Save Files and Remove from Memory
for (temp.file: this.files.(@acc)) {
temp.identity = this.identifiers.(@acc)[0+temp.i];
this.scratch.(@acc).(@identity).savevars(file, 0);
this.scratch.(@acc).(@identity).clearvars();
temp.i++;
}
// Remove Player Variables from Memory
this.identifiers.(@acc) = "";
this.files.(@acc) = "";
this.clientsync.(@acc) = "";
}
/*
Sets variable to value in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's New Value
*/
public function onSetScratch(identity, variable, value) {
// Adjust Scratch
this.scratch.(@player.account).(@identity).(@variable) = value;
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, value);
}
// Forces DB to Save
this.trigger("update", "");
}
/*
Adds value to variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onAddScratch(identity, variable, value) {
// Adjust Scratch
this.scratch.(@player.account).(@identity).(@variable).add(value);
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, onGetScratch(identity, variable));
}
// Forces DB to Save
this.trigger("update", "");
}
/*
Removes value from variable's array in identity's scratch data
@param identity Scratch's Identity Value
@param variable Variable Name
@param value Variable's Value to Add
*/
public function onRemScratch(identity, variable, value) {
// Adjust Scratch
this.scratch.(@player.account).(@identity).(@variable).remove(value);
// Sync with Client?
if (identity in this.clientsync.(@player.account)) {
player.triggerclient(this.db, "sync", identity, variable, onGetScratch(identity, variable));
}
// Forces DB to Save
this.trigger("update", "");
}
/*
Accesses identity's Scratch and returns Variable's Value
@param identity Scratch's Identity Value
@param variable Variable Name
@return Value of Variable
*/
public function onGetScratch(identity, variable) {
return this.scratch.(@player.account).(@identity).(@variable);
}
/*
getstringkeys for your Scratch data
@param identity Scratch's Identity Value
@param prefix Variable Name
@return String Keys from identity's Scratch
*/
public function onGetScratchKeys(identity, prefix) {
return getstringkeys("this.scratch." @ player.account @ "." @ identity @ "." @ prefix);
}
/*
Gets the Scratch's associated file
@param identity Scratch's Identity Value
@return Files Absolute Location
*/
public function onGetFile(identity) {
return this.files.(@player.account)[this.identifiers.(@player.account).index(identity)];
}