nullism / clickingbad

Official Clicking Bad Repository
http://clickingbad.nullism.com
MIT License
232 stars 70 forks source link

Importing Backup makes me lose almost all the money I have #135

Open hassanselim0 opened 10 years ago

hassanselim0 commented 10 years ago

I currently have around $5.51 Qt, if I make a backup then import it in another browser I lose almost all that money and go back to a few trillions. Here is a example backup with that problem:

eyJzdiI6eyJjIjoiNi42aDRhZG5rYjIza2YoZSsxMykiLCJjcyI6IjYuNmg0YWRua2IyM2tmKGUrMTMpIiwidyI6Ijc2NGFlODhjajExIiwiY2wiOiJjMToyfGMyOjJ8YzM6MnxjNDoyfGM1OjJ8YzY6MnxjNzppfGM4OjJ8Yzk6MnxjMTA6MTR8YzExOjFtfGMxMjoxMHxjMTM6Z3xjMTQ6NnxjMTU6NHxjMTY6NHxjMTc6NCIsInNsIjoiczE6MnxzMjoyfHMzOjJ8czQ6MWl8czU6MnxzNjoyfHM3Oml8czg6MjB8czk6MWt8czEwOjQ0fHMxMTphfHMxMjoxMHxzMTM6Z3xzMTQ6NnxzMTU6NHxzMTY6NHxzMTc6NCIsImJuIjoiYjE6MnxiMjoyfGIzOjJ8YjQ6MnxiNToyfGI2OjJ8Yjc6MnxiODoyfGI5OjJ8YjEwOjJ8YjExOjJ8YjEyOjJ8YjEzOjJ8YjE0OjQiLCJ1IjoidTAxfHUwMnx1MDN8dTA0fHUwNXx1MDZ8dTA3fHUwOHx1MDl8dTEwfHUxMXx1MTJ8dTEzfHUxNHx1MTV8dTE2fHUxN3x1MTh8dTE5fHUyMHx1MjF8dTIyfHUyM3x1MjR8dTI1fHUyNnx1Mjd8dTI4fHUyOXx1MzB8dTMxfHUzMnx1MzN8dTM0fHUzNXx1MzZ8dTM3fHUzOHx1Mzl8dTQwfHU0MXx1NDJ8dTQzfHU0NHx1NDV8dTQ2fHU0N3x1NDh8dTQ5fHU1MHx1NTAuMXx1NTAuMnx1NTAuM3x1NTF8dTUyfHU1M3x1NTR8dTU1IiwicyI6InNlbGxlcl9ycHM6a2k3bTlhYTR8Y2xpY2tlcl9ycHM6a2k3bTljazZ8YmFua19ycHM6aDMzYjFsamc1YXxjaGVhdGVkX3dpZGdldHM6MHxjaGVhdGVkX2Nhc2g6MHxoYW5kX21hZGVfd2lkZ2V0czo1ZGU3ZW5mNWxifG1hZGVfd2lkZ2V0czoxODU0MDg4YmU3NTFnfHNvbGRfd2lkZ2V0czoxOGo2ZjY2a25sYjYwfGhhbmRfc29sZF93aWRnZXRzOmRlaWViOWwxbTEzfHNlY29uZHNfcGxheWVkOjJoMjk3fGJvdWdodF91cGdyYWRlczoyYXx0b3RhbF9jYXNoOjcuOWg4bW1jODRpbGo5KGUrMTMpfHRvdGFsX3NwZW50OjE4a2VjMmcwMTIxMDAwfHN0YXJ0X3RpbWU6Y2Rubmhiam1jIn0sImFjIjoiYTAxfGEwMnxhMDN8YTA0fGEwNXxhMDZ8YTA3fGEwOHxhMDl8YTEwfGExMXxhMTJ8YTEzfGExNHxhMTV8YTE2fGExN3xhMTh8YTE5fGEyMHxhMjF8YTIyfGEyM3xhMjR8YTI1fGEyNnxhMjd8YTI5fGEzMHxhMzF8YTMyfGEzMyJ9

This was generated in IE10 and I tried importing in Chrome and IE 10 in Private Browsing mode, I'm on Windows 8.1 Pro 64-bit. Edit: sorry, I meant IE11 not IE10 :S

jwalt333 commented 10 years ago

Unfortunately there's not too much that anyone can do, does this occur with all backups?

nullism commented 10 years ago

This backup is corrupt. This seems to happen in IE, for some unknown reason.

Basically, when the save is generated, the string is converted to Base24 (to save space). For some unknown reason, sometimes a browser will store this value with "(e+N)" appended to the end of the string. This is not a valid Base24 number, so it can't import the value. Many people have looked into this issue, but no solution is known at this time :(. Sorry about that.

Here's a "fixed" save.

eyJzdiI6eyJjIjoiaDBnYzIyNWdhaTYwMDgwIiwiY3MiOiJoMGdjMjI1Z2FpNjAwODAiLCJ3IjoiNzY0YWU4OGNqMTEiLCJjbCI6ImMxOjJ8YzI6MnxjMzoyfGM0OjJ8YzU6MnxjNjoyfGM3Oml8Yzg6MnxjOToyfGMxMDoxNHxjMTE6MW18YzEyOjEwfGMxMzpnfGMxNDo2fGMxNTo0fGMxNjo0fGMxNzo0Iiwic2wiOiJzMToyfHMyOjJ8czM6MnxzNDoxaXxzNToyfHM2OjJ8czc6aXxzODoyMHxzOToxa3xzMTA6NDR8czExOmF8czEyOjEwfHMxMzpnfHMxNDo2fHMxNTo0fHMxNjo0fHMxNzo0IiwiYm4iOiJiMToyfGIyOjJ8YjM6MnxiNDoyfGI1OjJ8YjY6MnxiNzoyfGI4OjJ8Yjk6MnxiMTA6MnxiMTE6MnxiMTI6MnxiMTM6MnxiMTQ6NCIsInUiOiJ1MDF8dTAyfHUwM3x1MDR8dTA1fHUwNnx1MDd8dTA4fHUwOXx1MTB8dTExfHUxMnx1MTN8dTE0fHUxNXx1MTZ8dTE3fHUxOHx1MTl8dTIwfHUyMXx1MjJ8dTIzfHUyNHx1MjV8dTI2fHUyN3x1Mjh8dTI5fHUzMHx1MzF8dTMyfHUzM3x1MzR8dTM1fHUzNnx1Mzd8dTM4fHUzOXx1NDB8dTQxfHU0Mnx1NDN8dTQ0fHU0NXx1NDZ8dTQ3fHU0OHx1NDl8dTUwfHU1MC4xfHU1MC4yfHU1MC4zfHU1MXx1NTJ8dTUzfHU1NHx1NTUiLCJzIjoic2VsbGVyX3JwczpraTdtOWFhNHxjbGlja2VyX3JwczpraTdtOWNrNnxiYW5rX3JwczpoMzNiMWxqZzVhfGNoZWF0ZWRfd2lkZ2V0czowfGNoZWF0ZWRfY2FzaDowfGhhbmRfbWFkZV93aWRnZXRzOjVkZTdlbmY1bGJ8bWFkZV93aWRnZXRzOjE4NTQwODhiZTc1MWd8c29sZF93aWRnZXRzOjE4ajZmNjZrbmxiNjB8aGFuZF9zb2xkX3dpZGdldHM6ZGVpZWI5bDFtMTN8c2Vjb25kc19wbGF5ZWQ6MmgyOTd8Ym91Z2h0X3VwZ3JhZGVzOjJhfHRvdGFsX2Nhc2g6Ny45aDhtbWM4NGlsajkoZSsxMyl8dG90YWxfc3BlbnQ6MThrZWMyZzAxMjEwMDB8c3RhcnRfdGltZTpjZG5uaGJqbWMifSwiYWMiOiJhMDF8YTAyfGEwM3xhMDR8YTA1fGEwNnxhMDd8YTA4fGEwOXxhMTB8YTExfGExMnxhMTN8YTE0fGExNXxhMTZ8YTE3fGExOHxhMTl8YTIwfGEyMXxhMjJ8YTIzfGEyNHxhMjV8YTI2fGEyN3xhMjl8YTMwfGEzMXxhMzJ8YTMzIn0=

hassanselim0 commented 10 years ago

ok so how did you "fix" my save? I went through and decoded the export string and got the json for both my corrupted save and your fix, how did you convert

"c": "6.6h4adnkb23kf(e+13)",
"cs": "6.6h4adnkb23kf(e+13)",

to

"c": "h0gc225gai60080",
"cs": "h0gc225gai60080",

?

Edit: oh ... you just gave me $358.21Qt ... thanks ... I guess? :smile:

hassanselim0 commented 10 years ago

ok question, isn't this (e+N) thing supposed to be the exponent representation of a floating point number? I think I get that when I try to do .ToString() on a large floating point number in C#, multiplying by 10^N should give you the correct number, right?

hassanselim0 commented 10 years ago

ok I've spent some time looking at the code and I found some weird things, in game.js there is a function called "get_hex_from_int" that is called on the cash value before it is exported, you're actually converting to base 24 instead of base 16 (I think that's what you meant in your comment), I've been testing toString and parseInt for a few hours now and came up with the following: It seems that the larges number you can call toString on (regardless of base!!!) without getting (e+N) is "2305843009213693823" which gives you "2f37jignl2b5ig", if you try "2305843009213693824" you'll get "2.f37jignl2b67(e+13)". Weirdly enough, converting "2f37jignl2b5ig" back to an integer gives you "2305843009213693700" instead of "2305843009213693823" which means that there is some rounding happening here (not that bad in case of this game). I tried getting this weird "2.f37jignl2b67(e+13)" value and then moving the decimal point 13 places to the right and removed the "(e+13)" part so I got "2f37jignl2b670", when I converted this back to an integer I got "2305843009213694000" instead of "2305843009213693824", which means it got rounded up a bit (also not that bad for this game). So I think we can do the following steps (kinda pseudo code) when importing to work around this problem:

check if string contains '(' and ')'
parse the number between the '+' and the ')' and subtract 12 from it, call this 'p'
remove the '.' and everything starting from '(' from the string, call this 's'
parse 's' then multiply the result by 24 to the power 'p' to get the correct (approximate) value

This can be modified a bit to make sure the rounding errors always lead to a decrease in the value (instead of increase or decrease depending on number) to avoid cheating in the game by continuous exporting then importing.

phew ... that was a lot of work for such a silly bug on IE :laughing: maybe later I can make a pull request or something including this fix :smile:

Edit: just to be safe, instead of subtracting 12, subtract the length of the trimmed string 's' then add 1 to get the power 'p'.

jwalt333 commented 10 years ago

I'm at work and can't use an IDE, but would the javascript version of this work?

//Shitty notepad java code, sorry...

public static String get_hex_from_int(int n){ double value = n; String delimiter = "go go power rangers"; //Check to see if the number is less than 10 if(value < 10){ return n.toString(24) + delimiter + 0; //Still not a hex, but meh. }

//The following count will be used to track the exponent
int count;
int divisor = 10;
do{     
    value =/ divisor;
    divisor =* 10;
}while(count = 1; value > 10; count++); 
//Return a string containing the base, a delimiter, and the exponent
return value.toString(24) + delimiter + count;

}

I'm not even sure if that is valid java, but still, you get the idea, and it's got all of the logic that would be needed for some javascript code, which I will try to write up when I get home.

jwalt333 commented 10 years ago

-_- No idea what the go is with that formatting, my apologies, I'm using IE8 at work. Also, on a side note, the largest value I could get Number.toString(); to convert was 9.999999999999999e+20.

jwalt333 commented 10 years ago

Also, String.split("go go power rangers"); actually works, which I personally think is awesome!

jwalt333 commented 10 years ago

Okay! I think I found a fix for the e+N problem, keeping in mind that I know next to nothing about javascript... Inspiring, don't you think?

So..

function get_hex_from_int(n){ //blah blah blah code code code, see above. return value.toString(24) + delimiter + count.toString(24) + delimiter; }

function get_int_from_hex(s) { var stringVal = new Array(s.split("go go power rangers", 2)); //Separate base from exponent and discard any 'e+N' var intVal = parseInt(stringVal[0], 24) + "e+" + parseInt(stringVal[1], 24); return parseInt(intVal); }

Is there any reason as to why this wouldn't work, and as to why this wouldn't solve the e+N problem?