• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Integer Save Load

Status
Not open for further replies.
Level 8
Joined
Apr 26, 2011
Messages
403
it depend on what variable you want to save, so you can't just copy & paste.


Step 1: you can create a string character:
char_string = "abcdefg.....ABCDEFG...1234567890" // around 60-70 character wrong

Step 2: assign characters to information you want to save

if your save code have 5 character : 1234567
1st character = which race (pick 1 character from char_string, up to 60-70 difference race)
2nd character = level of hero (pick 1 character from 60-70 difference character
3rd character = first ability
4rd character = level of first ability
etc.....

Step 3: Improve Step 2 by shorten code
eg:
1st character = combine which race and level of hero in 1 character (because you have 60-70 character, long enough to cover all possibility of race+level)
2nd character = 1st ability's name & level
3rd character = 2nd ability's name & level
etc

Step 4: Code Protection, so player can't enter random code to guess

if your code is 8 character long, then you can add 2 more character as protection.

there are many way for protection, here is one example:

Remainder : (eg, 11/3 ==> remainder is 2 )
1, convert code string to number ( by index of char_string, eg, a = 1, b=2, Z=24 etc)
2, use JASS's math function to calculate remander (mudule)
3, if number is too big, you can cut them to smaller part ( need good math/logic )
4, a good example is get module from : divide by 5 & 7

so if your code is 8 character long, then
- 9th character can generate from divide by 5
- 10th character can generate from divide by 7

now, if player try enter random character, chance for enter right code is like winning lotto
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
http://www.hiveworkshop.com/forums/1993458-post521.html
http://www.hiveworkshop.com/forums/1993464-post522.html

Save
JASS:
local NumberStack c = NumberStack.create(Base["abcdefghijklmnopqrstuvwxyz"])
call c.push(variable,variableMax)
call DisplayTimedTextToPlayer(Player(0),0,0,60,EncryptNumber(c,1000000,3,0))
call c.destroy()

Load
JASS:
local NumberStack c = DecryptNumber(string,Base["abcdefghijklmnopqrstuvwxyz"],1000000,3,0)
if (0!=c) then
    set variable = c.pop(variableMax)
    call c.destroy()
endif

Easy no? : P
 
Last edited:
Level 8
Joined
Apr 26, 2011
Messages
403
you missunderstud me i dont want it to save heroes and items all i want it to save is a verable (number) sorry if i didnt make it clear

sigh, I think you still don't understand how SAVE-LOAD system work.

I use hero as example so it make it easier for you to understand. I should call it "things" and you can save anything you want.

and each character can only save 1 "thing", or more than 1 if you want to combine them (Step 2).
 
Level 8
Joined
Apr 26, 2011
Messages
403
http://www.hiveworkshop.com/forums/1993458-post521.html
http://www.hiveworkshop.com/forums/1993464-post522.html

Save
JASS:
local NumberStack c = NumberStack.create(Base["abcdefghijklmnopqrstuvwxyz"])
call c.push(variable,variableMax)
call DisplayTimedTextToPlayer(Player(0),0,0,60,EncryptNumber(c,1000000,3,0))
call c.destroy()

Load
JASS:
local NumberStack c = DecryptNumber(string,Base["abcdefghijklmnopqrstuvwxyz"],1000000,3,0)
if (0!=c) then
    set variable = c.pop(variableMax)
    call c.destroy()
endif

Easy no? : P

I havn't try, if my final code is 10 character long, what is the length of encrypted string after encrypt by your method ?


my Save/load will save follow information:
(1), how many race unlock, I put them in array, 0 = havn't unlock, 1=unlock. 15 race atm, more in future
(2), player name, include color name start with |.ffeeooName
3, 3 bit hash code (calculate from module)


for (1) : because 1 race = 1 bit of 0 or 1, total 15 equal to something like: 010101010101010) to number. so I create a binary function to convert them from binary to integer. (15 race = integer with 5 digit. 20 race = 8 digit)

for (2) : I use a long character string that cover all possible character, then convert user's name to integer

for (3), it calculate from : combine (1) + (2), save them in array (because integer is too big), then calculate remainder from them.

Final code : (1) + (3) , I don't really need 2 because it is too long.

It work so far and easy to understand/modified. (of course, there are more hash involve in (1) so people can't read (1) directly)

do you have any idea to make (1) shorter ?
eg:
15 race = 15 digit of 010101010101.. . if I convert to binary, it will be 5 digit

in near future, race will like 20, which result in 8 digit integer.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Just keep them as booleans with 1 being the max value. Have 15 booleans.


Now why are you saving the player's name? If it's for name specific codes, the encryption already does that (it's player specific encryption). For saving the player's name, you would need to retrieve each Ascii value and put it into a delimited array, meaning that you'd need Encoder for its tree based structure. If you were to save a specific max amount of letters, like 20, then you'd end up having larger codes than you need for small names.

I'd save the color as a hexadecimal value. Color for strings is 6 digits, so you can make room for it with FFFFFF+1, which is 16777217.
 
Level 8
Joined
Apr 26, 2011
Messages
403
Just keep them as booleans with 1 being the max value. Have 15 booleans.


Now why are you saving the player's name? If it's for name specific codes, the encryption already does that (it's player specific encryption). For saving the player's name, you would need to retrieve each Ascii value and put it into a delimited array, meaning that you'd need Encoder for its tree based structure. If you were to save a specific max amount of letters, like 20, then you'd end up having larger codes than you need for small names.

I'd save the color as a hexadecimal value. Color for strings is 6 digits, so you can make room for it with FFFFFF+1, which is 16777217.


the save/load code is unique to each player's name, so they can't share their code.

and I don't want to make code too long, so I will use player's name as a salt and create a 3 digit hash value.

so for my decrypt function, it cannot decrypt player's name, but it can verified player's name by compare the hash value.

anyway, I have better idea for shorter code:
15 booleans = 15 digit Binary number
15 digit binary --> convert to Base36 hexatridecimal = max 3 digit (rank from [A-Z,0-9]
3 digit hexatridecimal + 3 digit hash = 6 digit final code !!!

I am not sure if I need 3 digit for hash. I still need to read & understand your hash method.

can you write 2 JASS function that :
ConvertToBase36 ( take int[] num, return string)
ConvertToBase2 ( take string, return int[] num)

here is similar function in C# ( I can't take int num because number is out of range for JASS)

Code:
public String ConvertToBase(int num, int nbase)
{
    String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    // check if we can convert to another base
    if(nbase < 2 || nbase > chars.Length)
        return "";

    int r;
    String newNumber = "";

    // in r we have the offset of the char that was converted to the new base
    while(num >= nbase)
    {
        r = num % nbase;
        newNumber = chars[r] + newNumber;
        num = num / nbase;
    }
    // the last number to convert
    newNumber = chars[num] + newNumber;

    return newNumber;
}
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Ok listen... my encryption method is 100% unique to the players. The shuffling is based off of a modified hash from the player's nickname. This player uniqueness adds 0 data to the code. It's just a simple StringHash though and convert to base 8 and add 1 to all the digits of 0 ; P.

So no, you don't need 3 digits for the hash for the player's nick. You need 0 ; P.

The only thing you need are the 15 binary digits and you are done = ). Let the encryption do the checksum and yea, you're set ; P. Custom Hero Foots uses similar save/load techniques (although it's a bit more advanced in that map since they have player unique checksums and bases as well) and it has yet to be cracked (and believe me, there was a guy doing all he could to crack it).

For player unique bases
encryptionKey = BigInt that just converts the base into a string (flip 0 with 1 in front)
baseEncryptionKey = the encryption key as a base
JASS:
                    call Scramble(encryptionKey,playerId,3,baseEncryptionKey,true)
                    set bases[playerId]=Base[encryptionKey.toString()]

From here, you use a player unique base when generating your number, thus most players have a different base (numbers are totally different).

The next thing is player unique checksums, which uses variance in checksums between players that I won't go into = P.

The only thing that the encrypt function does is a checksum (not player unique) with scrambling (player unique). I could add the other 2 security features if you want though =).

This is the equation for player unique checksums where CHECKSUM_VARIANCE is some constant (suggested .85) and maxChecksum is the security value (6-7 digits). PLAYER_CHECKSUM_SALT is a constant string that just muddles the player name (different checksum).

Code:
checksum=StringHash(StringCase(GetPlayerName(player)+PLAYER_CHECKSUM_SALT,false))
if (0>checksum) then
    set checksum=-checksum
endif
minChecksum=R2I(maxChecksum*CHECKSUM_VARIANCE)
checksumRange=maxChecksum-minChecksum
checksum=checksum-checksum/checksumRange*checksumRange+minChecksum

Again, the only thing my encrypt function has is scrambling. The other 2 techniques mentioned in this post are not in it.


Oh and these are your 15 binary digits max in base 36
9ZLDR or 5 digits, meaning that with the checksum, you're looking at around 5Y3CGMWG0, or 8 digits (1000000 checksum).
100000 would be LEQG2AG0, still 8 digits.

edit
wrote a couple of other useful snippets
http://www.hiveworkshop.com/forums/1993499-post523.html
http://www.hiveworkshop.com/forums/1993669-post524.html

edit
My NumberEncrypter thing now does all 3 encryption techniques ^)^

player unique bases
player unique checksums
player unique scrambling

It still bases stuff on simple StringHash though
 
Last edited:
Status
Not open for further replies.
Top