package CodeGenerator import BigNum constant string colorUpper = "|cffFF8000" constant string colorLower = "|cff0080C0" constant string colorNumber = "|cff008000" //function player_charset() returns string // return "0aku1eNbr2Pjg3fMtA4Fsvi5XloqI6SCmK7GLnx8EBOc9WpVhzQRdTDYyHwJUZ" // //function player_charsetlen() returns int // return StringLength(player_charset()) function charset() returns string return "0aUb1GLwR2kHvP3CQIM4npFs5iSW6tzAr7TNxo8JXVjy9OcdEfBKgqeuYDhmlZ" function charsetlen() returns int return StringLength(charset()) function base() returns int return charsetlen() function hashN() returns int return 5000 function maxInt() returns int return 2147483647 //function player_chartoi(string c) returns int // int i = 0 // string cs = player_charset() // int len = player_charsetlen() // while i < len and c != SubString(cs,i,i+1) // i = i + 1 // return i function chartoi(string c) returns int int i = 0 string cs = charset() int len = charsetlen() while i < len and c != SubString(cs,i,i+1) i = i + 1 return i function itochar(int i) returns string return SubString(charset(),i,i+1) public function fhash(string ps) returns int int hash = 7 for int i = 0 to ps.length()-1 hash = hash*31+chartoi(ps.charAt(i))+11 if hash < 0 hash = -hash return hash function modb( int x ) returns int if x >= base() return x - base() else if x < 0 return x + base() else return x public class Savecode real digits = 0. //logarithmic approximation BigNum bignum = new BigNum(base()) ondestroy destroy bignum function encode( int val, int max ) digits = digits + log(max+1.,base()+0.) bignum.mulSmall(max+1) bignum.addSmall(val) function decode( int max ) returns int return bignum.divSmall(max+1) function isEmpty() returns boolean return bignum.isZero() function length() returns real return digits function clean() bignum.clean() //These functions get too intimate with BigNum_l function pad() BigNum_l cur = bignum.list BigNum_l prev = null int maxlen = R2I(1.0 + length()) while cur != null prev = cur cur = cur.next maxlen-- while maxlen > 0 prev.next = new BigNum_l() prev = prev.next maxlen-- function toString() returns string BigNum_l cur = bignum.list string s = "" while cur != null s = itochar(cur.leaf) + s cur = cur.next return s function fromString( string s ) int i = s.length()-1 BigNum_l cur = new BigNum_l() bignum.list = cur while true cur.leaf = chartoi(SubString(s,i,i+1)) if i <= 0 break cur.next = new BigNum_l() cur = cur.next i-- function hash() returns int int hash = 0 int x BigNum_l cur = bignum.list while cur != null x = cur.leaf hash = ModuloInteger(hash+79*hash div (x+1) + 293*x div (1+hash - (hash div base())*base()) + 479,hashN()) cur = cur.next return hash //this is not cryptographic which is fine for this application //sign = 1 is forward //sign = -1 is backward function obfuscate(int key, int sign ) int seed = GetRandomInt(0,maxInt()) int advance = 0 int x = 0 BigNum_l cur = bignum.list if sign == -1 SetRandomSeed(bignum.lastDigit()) cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,base()-1)) x = cur.leaf SetRandomSeed(key) while cur != null if sign == -1 advance = cur.leaf cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,base()-1)) if sign == 1 advance = cur.leaf advance = advance + GetRandomInt(0,base()-1) SetRandomSeed(advance) x = cur.leaf cur = cur.next if sign == 1 SetRandomSeed(x) bignum.list.leaf = modb(bignum.list.leaf + sign*GetRandomInt(0,base()-1)) SetRandomSeed(seed) function save( player p, int loadtype ) returns string int key = fhash(GetPlayerName(p))+loadtype*73 int hash clean() hash = hash() encode(hash,hashN()) // print("key:"+ (scommhash(GetPlayerName(p))+loadtype*73).toString() + " : " + hash.toString()) clean() pad() obfuscate(key,1) return toString() function load( player p, string s, int loadtype ) returns boolean int ikey = fhash(GetPlayerName(p))+loadtype*73 int inputhash fromString(s) obfuscate(ikey,-1) inputhash = decode(hashN()) clean() let h = hash() return inputhash == h //function prop_Savecode() returns boolean // string s // Savecode loadcode ////--- Data you want to save --- // integer medal1 = 10 // integer medal2 = 3 // integer medalmax = 13 // integer XP = 1337 // integer xpmax = 1000000 // Savecode savecode = new Savecode() // // SetPlayerName(Player(0),"yomp") // SetPlayerName(Player(1),"fruitcup") // savecode.encode(medal1,medalmax) // savecode.encode(medal2,medalmax) // savecode.encode(XP,xpmax) ////--- Savecode_save generates the savecode for a specific player --- // s = savecode.save(Player(0),1) // destroy savecode // print("Savecode: " + s) ////--- User writes down code, inputs again --- // // loadcode = new Savecode() // if loadcode.load(Player(0),s,1) // BJDebugMsg("load ok") // else // BJDebugMsg("load failed") // return false // ////Must decode in reverse order of encodes // //// load object : max value that data can take // if XP != loadcode.decode(xpmax) // return false // else if medal2 != loadcode.decode(medalmax) // return false // else if medal1 != loadcode.decode(medalmax) // return false // destroy loadcode // return true // //// //init // getTimer().start(.2, function runTests) // //function runTests() // if prop_Savecode() // print("save1 OK") // else // print("save1 Failed")