Hello tease creators,
I have come up with a solution to go around the storage limitations of EOS. The idea is to use a text or word file to store the data. So the user has to save the data himself on his computer.
The data is not easily editable so it is not easy for the average user to manipulate the savegame, but of course it is far from impossible. There are improvements possible to prevent more experienced user from cheating like adding a CRC check or a hash, but if you can manipulate the current system the chances are very high that you could also do that if there is a hash present. I created a small test so you can try it and tell me any bugfixes or improvements I should make.
ETS - EOS Text Storage Test
I could create multiple megabytes of data with it. But depending on your hardware it will take some time to export a lot of data. 10.000 values works fine without a noticeable delay for me. 100.000 will take some time though.
I published the code below if you want to use it in your own tease. Just paste it into your init script to use it.
I also added the EOS test as attachment so you can import this into EOS and see with examples on how to use it.
Documentation
etsSaveValue(key, value)
Saves a key with a value. The value can also be an object.
Example: etsSaveValue("name", "alex")
etsLoadValue(key, defaultValue)
Loads the value of a given key and returns it. If the key does not exists the key is created with the default value and the default value is returned.
Example 1: etsLoadValue("teaseDurationSec", 120);
Example 2: etsLoadValue("name", null);
etsExport()
Returns the string to be saved by the user.
etsImport(importString)
Imports the previously exported string and initializes the etsJsonObject.
Warning: This will delete the current saved data!
Returns null on success. On error a message of the error is returned.
Example: etsImport("##01D6D0==")
ETS version 1 - 24.05.2020 :
- Spoiler: show
Code: Select all
// === ETS - EOS Text Storage === BEGIN
var etsJsonObject = JSON.constructor();
var etsDebug = false; // change to true for debugging
var etsPrefix = "##";
var etsSuffix = "=="; // should be different from prefix for better error checking
var etsXorValue = 0xAD; // change to something else if you want. Changing this corrupts current existing savedata from other users.
var etsVersion = 1;
/**
* @brief Saves the value of the given key
*/
function etsSaveValue(key, value)
{
etsJsonObject[key] = value;
if(etsDebug)
console.log("ETS: Saved " + key + " = " + value);
}
/**
* @brief Loads the value of the given key and returns it.
* If the loaded value is undefined the value of the given key will be set to the given default value.
*
* @return the value of the key or defaultValue if no set value exists.
*/
function etsLoadValue(key, defaultValue)
{
var etsValue = etsJsonObject[key];
if(etsValue === undefined)
etsValue = defaultValue;
etsJsonObject[key] = etsValue;
if(etsDebug)
console.log("ETS: Loaded " + key + " = " + etsJsonObject[key]);
return etsJsonObject[key];
}
/**
* @brief Exports the save data as a string
*
* @return The exported string
*/
function etsExport()
{
var etsJsonString = JSON.stringify(etsJsonObject);
var etsByte;
var etsByteString;
var etsHexString = etsPrefix;
// add version byte
etsByteString = etsVersion.toString(16).toUpperCase();
if(etsByteString.length < 2)
etsByteString = "0".concat(etsByteString);
etsHexString = etsHexString.concat(etsByteString);
// json -> byte -> XOR -> hexString
for(var i = 0; i < etsJsonString.length; i++)
{
etsByte = etsJsonString[i].charCodeAt();
etsByte ^= etsXorValue;
etsByteString = etsByte.toString(16).toUpperCase();
if(etsByteString.length < 2)
etsByteString = "0".concat(etsByteString);
etsHexString = etsHexString.concat(etsByteString);
}
// add suffix
etsHexString = etsHexString.concat(etsSuffix);
if(etsDebug)
console.log("ETS: Exported \n[" + etsHexString + "]");
return etsHexString;
}
/**
* @brief Imports the save data from the given string
*
* @return null on success, or a string describing the error
*/
function etsImport(importString)
{
// remove whitespaces
importString = importString.split(" ").join("");
importString = importString.split("\t").join(""); // tabs
importString = importString.split("\n").join(""); // new line - should be filtered by eos
importString = importString.split("\r").join(""); // carriage return - should be filtered by eos
// check string length
var etsMinLength = 6 + etsPrefix.length + etsSuffix.length; // 6 = version(2) + '{' + '}'
if(importString.length < etsMinLength)
return "Text storage must contain at least " +
etsMinLength + " characters. Received: " + importString.length +".";
// Check for prefix and suffix
var etsIndexBegin = importString.indexOf(etsPrefix);
var etsIndexEnd = importString.lastIndexOf(etsSuffix);
if(etsIndexBegin == -1)
return "Missing prefix \"" + etsPrefix + "\".";
if(etsIndexEnd == -1)
return "Missing suffix \"" + etsSuffix + "\".";
// remove prefix and suffix from string
var etsHexString = importString.substring(etsIndexBegin+etsPrefix.length, etsIndexEnd);
// check for valid hex string
if(etsHexString.length % 2 !== 0)
return "Text storage must contain an even amount of characters.";
if(etsHexString.length < 6)
return "Text inside prefix and suffix must be at least 6 characters long.";
// check for matching version - later adding backwards compatibility here
var etsParsedVersion = parseInt(etsHexString.substring(0, 2), 16);
if(etsParsedVersion != etsVersion)
return "Version " + etsParsedVersion + " not supported. Active ETS version: " + etsVersion;
// convert hex string to a json string
var etsByte;
var etsJsonString = "";
for(var i = 2; i < etsHexString.length; i+=2)
{
var etsSingleByteString = etsHexString.substring(i, i+2);
etsByte = parseInt(etsSingleByteString, 16);
etsByte ^= etsXorValue;
etsJsonString = etsJsonString.concat(String.fromCharCode(etsByte));
}
// parse string into json object
try
{
etsJsonObject = JSON.parse(etsJsonString);
}
catch(err)
{
if(etsDebug)
{
console.log("ETS: Invalid JSON \n[" + etsJsonString + "]");
console.log(err.toString())
}
return "Invalid data";
}
if(etsDebug)
console.log("ETS: Imported \n[" + JSON.stringify(etsJsonObject) + "]");
return null; // success
}
// === ETS - EOS Text Storage === END