Edit: I've finished this project. I'm going to keep the original thread in case anybody wanted to see the methodology behind the project. I'm a fan of open source, hence the release. However, in the future we may opt to release a version with a GUI component, which will be closed source (namely because the code will become convoluted with code not relevant to sending scores).
Download: http://logicalgamers.com/files/python/3.2/score_sender/
Credits go to Riddle for his urllib class.
Usage: run from the command line.
Tested on Python 3.2 and not on any others. If you have multiple versions of Python installed (as I do), and your python environment variable is set to use Python 2.x, you may want to set up another environment variable (for instance I use python3 for 3.2). In that case I would use python3 master.py.Code:cd /path/to/files/ python master.py
---
Using this thread to save important information/help anyone on the project. Matt mentioned he would be interested, so you may find some of this useful.
HTTP Packet sent when sending score:
edit: are you kidding me? Had a massive post, and none of it went through. What a waste of time. To summarise then:
HTTP Packet sent when sending score:
I've spaced it out.Code:POST /high_scores/process_flash_score.phtml? cn=114300& gd=59276& asp_fs_g=& r=0.58089142665267& gmd_g=381& mltpl_g=0& gmdt_g=125053080038077114122119051106084072078050051089052055078119120068115066095080064107067126051073112075067071054115119071078099111050071065087054077089054115105050087086038049066089077044036106083122081055089067068046117044070069049056116095098055069069104037122083105038066119044071040043037120064045048050& sh_g=90ee37e99d11540bda96& sk_g=f711621a64d77a582b5e& usrnm_g=artificial113& dc_g=0& cmgd_g=89198& ddNcChallenge=0 HTTP/1.1
Score sending swf:
edit: it's actually:Code:http://images.neopets.com/games/gaming_system/np6_include_v1.swf
You can find the latest URI by looking in the page source of the game page (i.e. http://www.neopets.com/games/play_fl...a=&game_id=381). Look for the value of the swf variable 'include_movie'.Code:http://images.neopets.com/games/gaming_system/np6_include_v16.swf
Function that generates the URL:
We'll no doubt have to mimic more than that single HTTP request. There's a bunch of TCP packets sent to the server when sending the score, and I haven't even looked at what's sent/received when starting the game. First step is to determine how they're generating the final request URL (may have to backtrack anyways, we'll see).Code:function ch() { var cn = 300 * _level0.game_id; var _loc3 = scripturl + "?cn=" + cn + "&gd=" + String(getTimer() - _level0.game_isLoaded); if (aAddParams.length > 0) { for (var _loc1 = 0; _loc1 < aAddParams.length; ++_loc1) { var _loc2 = "&asp_" + aAddParams[_loc1][0] + "=" + aAddParams[_loc1][1]; _loc3 = _loc3 + _loc2; } } _loc3 = _loc3 + ("&r=" + Math.random(999999999)); objIncString.initBin(); var sRaw = "ssnhsh=" + _level0.game_hash + "&ssnky=" + _level0.game_sk + "&gmd=" + _level0.game_id + "&scr=" + _SCORE.show() + "&frmrt=" + _level0.average_real_framerate + "&chllng=" + _level0.game_challenge + "&gmdrtn=" + String(getTimer() - _level0.game_isLoaded); var sSlashed = objIncString.addSlashes(sRaw); var sessionID = String(_level0.game_hash) + String(_level0.game_sk); _loc3 = _loc3 + ("&gmd_g=" + _level0.game_id + "&mltpl_g=" + _level0.game_multiple + "&gmdt_g=" + sSlashed + "&sh_g=" + _level0.game_hash + "&sk_g=" + _level0.game_sk + "&usrnm_g=" + _level0.game_username + "&dc_g=" + _level0.game_dailyChallenge); return (_loc3); }
---
edit: Dug around for another 20 minutes and prepared the following notes:
Description of each POST variable:
Code:cn = game id * 300 (i.e. 381 * 300 = 114300) gd = difference between when we started playing and when we sent score (current time - starting time). In milliseconds. asp_fs_g = additional paramaters. For game I played (kass whacker or something), there were none. Have to find games where there are some and look in to it. r = random number gmd_g = game id (i.e. 381) mtlpl_g = multiplayer game? (I'm assuming 0 = no, 1 = yes) sh_g = game hash (it looks like every game has a unique hash. We should be able to find it in the flash file for said game) sk_h = similar to game hash, a variable that looks unique to the game. We should be able to find it in each game. usrnm_g = username of neopets account (value stored in game) dc_g = daily challenge. Not sure what this is, though value stored in game. gmtd_g = the tricky one. See below.sSlashed is the value. From this, we can see that plaintext it is the following string:Code:objIncString.initBin(); var sRaw = "ssnhsh=" + _level0.game_hash + "&ssnky=" + _level0.game_sk + "&gmd=" + _level0.game_id + "&scr=" + _SCORE.show() + "&frmrt=" + _level0.average_real_framerate + "&chllng=" + _level0.game_challenge + "&gmdrtn=" + String(getTimer() - _level0.game_isLoaded); var sSlashed = objIncString.addSlashes(sRaw);
ssnhsh=GAMEHASH&ssnky=GAME_SK&gmd=GAMEID&scr=SCORE &frmrt=FRAMERATE&chllng=CHALLENGE&gmdrtn=PLAYING_T IME
Game hash, game_sk, challenge are values found in each game. Again, not too sure what these are at the moment, but it doesn't look too tricky.
The string is then encoded with a function called addSlashes from the object called objIncString.
Declaration:
We can locate that library file (decompile the .swf I provided above and look for AS file __Packages.np.projects.include.Strings)Code:objIncString = new np.projects.include.Strings();
From looking at it, we can see that upon initialisation:
The value of variable sBin is the Game Hash + Game SK value. (Game_Hash + Game_SK)
The value of variable iBinLen is the amount of chars of the sBin variable.
The add slashes function:
1. Converts the string to hex using a custom function in the library file.
2. Escape the string using a custom function in the library file.
3. Returns.
---
So, it looks quite easy. Either tonight or early tomorrow I'll have a crack of simulating it without the client to see if I run in to any problems. I'll also have to look at how the game variables are generated. They could be generated in the game (i.e. client side), or the server could pass variables through.
Either way, looks a lot easier then I would have originally though.
--
edit: it looks like the sh and sk code are in the page source of the loading page;
In the preloader:Code:swf.addVariable('sh', '6d9ee07097caf0e4ca3a'); swf.addVariable('sk', '36e93bf26a047e360648');
And those two variables are:Code:game_hash = aVars[12][0]; game_sk = aVars[13][0];
The reason those two values are hard coded in to the swf is in the result of a failure. If no variables are set (in the addVariable call on the page) it will default to those two values.)Code:[sh, "35ba379a5d920acb6f18"], [sk, "35ba379a5d920acb6f18"]
sh, sk. So those two variables definitely control it. In that case, the first step for sending the score for any game is to go to the game loading page (i.e. http://www.neopets.com/games/play_fl...a=&game_id=381) and retrieve those two values.
---
edit: successful return result:
[b]When loading, preloader sends the following HTTP request to a translator service. I doubt this is required (however, if we wanted to properly emulate it, we would send the same request):Code:eof=0&np=6,533&success=1&errcode=0&plays=1&sk=688a9616306e7dafefe2&sh=7c786ab4a734b0672c2a&call_external_function=score_callback&call_external_params=args%3D%5B%7B%22fn%22%3A%22flash_func_trigger%22%2C%22args%22%3A%7B%22func%22%3A%22nf_trigger%22%2C%22param%22%3A%5B%22negg-quest-pushdown%22%5D%7D%7D%2C%7B%22fn%22%3A%22setnp%22%2C%22args%22%3A%226%2C533%22%7D%5D
And returns the following result:Code:POST /transcontent/gettranslationxml.phtml lang=EN&randomNumber=4089343&onData=%5Btype%20Function%5D&onLoad=%5Btype%20Function%5D&translator=%5B%5Fglobal%2ENPTranslator%5D
Code:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd" > <xliff version="1.0" xml:lang="en"> <file datatype="plaintext" original="381" source-language="EN"> <header></header> <body> <trans-unit id="001" resname="TRANSLATION_TITLE"> <source>Preloader</source> </trans-unit> <trans-unit id="002" resname="IDS_PRELOADER_LOADING_GAME"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20face%20%3D%20%27jokerman_fnt%27%20size%20%3D%20%2770%27%3ELoading%20Game%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="003"resname="IDS_PRELOADER_LOADING_BAND"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20face%20%3D%20%27jokerman_fnt%27%20size%20%3D%20%2770%27%3ELoading%20Band%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="004" resname="IDS_PRELOADER_PLUGIN"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3EPlug-in%20Version%3A%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="005" resname="IDS_PRELOADER_LOADED"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3ELoaded%3A%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="006" resname="IDS_PRELOADER_ELAPSED"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3EElapsed%20Time%3A%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="007" resname="IDS_PRELOADER_ESTIMATED"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3EEstimated%20Time%3A%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="008" resname="IDS_PRELOADER_RATE"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3ERate%3A%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="009" resname="IDS_PRELOADER_PERCENT"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3E%25%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="010" resname="IDS_PRELOADER_K"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3Ek%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="011" resname="IDS_PRELOADER_SEC"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3Esec.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="012" resname="IDS_PRELOADER_KPS"> <source>%3Cfont%20face%20%3D%20%27customFSS_fnt%27%20size%20%3D%20%2740%27%3Ekps%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="013" resname="IDS_PRELOADER_ADVERT"> <source>%3Cp%20align%3D%27left%27%3E%3Cfont%20size%3D%2718%27%3EADVERTISEMENT%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="014" resname="IDS_PRELOADER_FEATURED"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%3D%2728%27%3EFeatured%20Game%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="015" resname="IDS_PRELOADER_SPONSORED"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%3D%2728%27%3ESPONSORED%20BY%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="016" resname="IDS_PRELOADER_FEATURED2"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%3D%2728%27%3EThis%20Featured%20Game%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="017" resname="IDS_PRELOADER_SPONSORED2"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%3D%2728%27%3EIS%20BROUGHT%20TO%20YOU%20BY%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="018" resname="IDS_PRELOADER_NOTLOGGEDIN"> <source>You%27re%20not%20logged%20in%21%20Choose%20an%20option%3A</source> </trans-unit> <trans-unitid="019" resname="IDS_PRELOADER_PLAYGAME"> <source>%3CA%20HREF%3D%27asfunction%3A_root.HTMLClick%2C1%27%3EPlay%20Game%3C%2FA%3E</source> </trans-unit> <trans-unit id="020" resname="IDS_PRELOADER_SIGNUP"> <source>%3CA%20HREF%3D%27asfunction%3A_root.HTMLClick%2C2%27%3ESign%20Up%3C%2FA%3E</source> </trans-unit> <trans-unit id="021" resname="IDS_PRELOADER_LOGIN"> <source>%3CA%20HREF%3D%27asfunction%3A_root.HTMLClick%2C3%27%3ELogin%3C%2FA%3E</source> </trans-unit> <trans-unit id="022" resname="IDS_PRELOADER_SIGNUP_ONLY"> <source>Sign%20Up</source> </trans-unit> <trans-unit id="023" resname="IDS_PRELOADER_LOGIN_ONLY"> <source>Login</source> </trans-unit> <trans-unit id="024" resname="IDS_SM_TAG1_OPEN"> <source>%3Cp%20align%3D%27center%27%3E</source> </trans-unit> <trans-unit id="025" resname="IDS_SM_TAG2_OPEN"> <source>%3Cp%20align%3D%27center%27%3E</source> </trans-unit> <trans-unit id="026" resname="IDS_SM_TAG3_OPEN"> <source>%3Cp%20align%3D%27center%27%3E</source> </trans-unit> <trans-unit id="027" resname="IDS_SM_TAG_CLOSE"> <source>%3C%2Fp%3E</source> </trans-unit> <trans-unit id="028" resname="IDS_SM_score"> <source>Score%3A</source> </trans-unit> <trans-unit id="029" resname="IDS_SM_npscore"> <source>NP%3A</source> </trans-unit> <trans-unit id="030" resname="IDS_SM_pending"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3E%3Cbr%3ESuccess%20Pending</source> </trans-unit> <trans-unit id="031" resname="IDS_SM_success"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ESuccess%21%20Your%20NP%3A</source> </trans-unit> <trans-unit id="032" resname="IDS_SM_bonus"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3Ex2%20Bonus%21%20Your%20NP%3A</source> </trans-unit> <trans-unitid="033" resname="IDS_SM_hiscore"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3EYour%20High%20Score%3A</source> </trans-unit> <trans-unit id="034" resname="IDS_SM_plays"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3EPlays%20Today%3A</source> </trans-unit> <trans-unit id="035" resname="IDS_SM_restart"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.restartGame%27%3E%3Cu%3ERestart%20Game%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="036" resname="IDS_SM_tryagain"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.resendScore%27%3E%3Cu%3ETry%20Again%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="037" resname="IDS_SM_restart_new"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.restartGame%27%3E%3Cu%3ERestart%20Game%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="038" resname="IDS_SM_challengecard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.showCard%27%3E%3Cu%3ESend%20a%20Challenge%20Card%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="039" resname="IDS_SM_anothercard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.showCard%27%3E%3Cu%3ESend%20another%20Card%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="040" resname="IDS_SM_sendacard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3ESend%20a%20Challenge%20Card%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="041" resname="IDS_SM_submitcard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.submitCard%27%3E%3Cu%3ESubmit%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="042" resname="IDS_SM_cancelcard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.cancelCard%27%3E%3Cu%3ECancel%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="043" resname="IDS_SM_cardreturn"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.backToCard%27%3E%3Cu%3EBack%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="044" resname="IDS_SM_mainreturn"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3CA%20HREF%3D%27asfunction%3A_parent._parent.cancelCard%27%3E%3Cu%3EI%27m%20done%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="045" resname="IDS_SM_preparecard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3Cbr%3EPreparing%20email%20form...%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="046" resname="IDS_SM_sendingcard"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffffff%27%3E%3Cbr%3ESending%20Card...%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="047" resname="IDS_SM_CCARD_NAME1"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2712%27%20color%3D%27%23ffff00%27%3EYour%20First%20Name%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="048" resname="IDS_SM_CCARD_EMAIL1"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2712%27%20color%3D%27%23ffff00%27%3EYour%20Email%20Address%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="049" resname="IDS_SM_CCARD_NAME2"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2712%27%20color%3D%27%23ffff00%27%3EFriend%27s%20First%20Name%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="050" resname="IDS_SM_CCARD_EMAIL2"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2712%27%20color%3D%27%23ffff00%27%3EFriend%27s%20Email%3A%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="051" resname="IDS_FGS_PRESS_ANY_KEY"> <source>Press%20Any%20Key%20To%20Continue</source> </trans-unit> <trans-unit id="052" resname="FGS_MAIN_MENU_START_GAME"> <source>Start%20Game</source> </trans-unit> <trans-unit id="053" resname="FGS_MAIN_MENU_VIEW_INSTRUCTIONS"> <source>View%20Instructions</source> </trans-unit> <trans-unit id="054" resname="FGS_MAIN_MENU_VISIT_WEBSITE"> <source>Visit%20Website</source> </trans-unit> <trans-unit id="055" resname="FGS_MAIN_MENU_VIEW_TRAILER"> <source>View%20Trailer</source> </trans-unit> <trans-unit id="056" resname="FGS_MAIN_MENU_TURN_MUSIC_OFF"> <source>Turn%20Music%20Off</source> </trans-unit> <trans-unit id="057"resname="FGS_MAIN_MENU_TURN_SOUND_OFF"> <source>Turn%20Sound%20Off</source> </trans-unit> <trans-unit id="058" resname="FGS_MAIN_MENU_TURN_MUSIC_ON"> <source>Turn%20Music%20On</source> </trans-unit> <trans-unit id="059" resname="FGS_MAIN_MENU_TURN_SOUND_ON"> <source>Turn%20Sound%20On</source> </trans-unit> <trans-unitid="060" resname="FGS_MAIN_MENU_SETUP"> <source>Setup</source> </trans-unit> <trans-unit id="061" resname="FGS_GAME_MENU_END_GAME"> <source>End%20Game</source> </trans-unit> <trans-unit id="062" resname="FGS_OTHER_MENU_GO_BACK"> <source>Go%20Back</source> </trans-unit> <trans-unit id="063" resname="FGS_OTHER_MENU_MORE"> <source>More</source> </trans-unit> <trans-unit id="064" resname="FGS_GAME_OVER_MENU_RESTART_GAME"> <source>Restart%20Game</source> </trans-unit> <trans-unitid="065" resname="FGS_GAME_OVER_MENU_SEND_SCORE"> <source>Send%20Score</source> </trans-unit> <trans-unit id="066" resname="IDS_SM_ERR_MAXPLAYS"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2712%27%20color%3D%27%23ff0000%27%3EYou%20have%20already%20reached%20the%20maximum%20number%20of%20times%20you%20can%20post%20your%20score%20for%20today%21%20Play%20again%20tomorrow%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="067" resname="IDS_SM_ERR_ZEROSCORE"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EYou%20didn%27t%20score%20any%20points%2C%20so%20your%20score%20cannot%20be%20posted%20-%20sorry%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="068" resname="IDS_SM_ERR_UNKNOWN"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20our%20servers%20are%20currently%20experiencing%20problems%20and%20we%20cannot%20accept%20your%20score%20right%20now%20%3A%28%3C%2Ffont%3E</source> </trans-unit> <trans-unitid="069" resname="IDS_SM_ERR_INVALID"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20but%20you%20cannot%20send%20scores%20if%20you%20have%20not%20%3CA%20HREF%3D%27asfunction%3A_parent._parent.validateEmail%27%3E%3Cu%3Evalidated%20your%20account%3C%2Fu%3E%3C%2Fa%3E%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="070" resname="IDS_SM_ERR_TIMEOUT"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20but%20there%20is%20no%20response%20from%20the%20server%20at%20this%20time%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="071" resname="IDS_SM_ERR_NOLOGIN"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EPlease%20%3CA%20HREF%3D%27asfunction%3A_parent._parent.showLogin%27%3E%3Cu%3ELog%20In%3C%2Fu%3E%3C%2Fa%3E%20to%20Neopets%20to%20submit%20your%20next%20score%20or%20%3CA%20HREF%3D%27asfunction%3A_parent._parent.showSignup%27%3E%3Cu%3ESign%20Up%20Today%3C%2Fu%3E%3C%2Fa%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="072" resname="IDS_SM_ERR_COOKIE"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EProblem%20reading%20your%20cookies.%20Please%20log%20out%20and%20log%20back%20in.%20Thanks.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="073" resname="IDS_SM_ERR_CHALLENGE"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EChallenged%20posted%2C%20however%2C%20max%20scores%20already%20posted%20for%20today.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="074" resname="IDS_SM_ERR_NOCHALL"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EYou%20have%20no%20outstanding%20challenges%20for%20this%20game%20and%20you%20have%20already%20posted%20your%20max%20scores%20for%20today.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="075" resname="IDS_SM_ERR_CHALLSLOW"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3E%28Scroll%20Down%29%20Sorry%2C%20but%20your%20computer%20is%20running%20too%20slow%20to%20be%20in%20a%20challenge.%20%20This%20would%20make%20the%20game%20unfair%20to%20other%20users%20that%20play%20the%20game%20at%20regular%20speed.%20%20To%20speed%20your%20computer%20up%2C%20play%20the%20game%20with%20the%20smallest%20window%20setting%20and%20close%20all%20other%20applications%20or%20browser%20windows%20while%20you%20play%20the%20game.%20%20If%20that%20does%20not%20work%2C%20you%20may%20withdraw%20from%20a%20challenge%20to%20avoid%20this%20message%20%3CA%20HREF%3D%27asfunction%3A_parent._parent.showChallenge%27%3E%3Cu%3Ehere%3C%2Fu%3E%3C%2Fa%3E.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="076" resname="IDS_SM_ERR_DC_COMP"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3E%28Scroll%20Down%29.%20Sorry%2C%20but%20your%20computer%20is%20running%20too%20slow%20for%20this%20score%20to%20be%20valid%20for%20the%20Daily%20Competition.%20%20This%20would%20make%20the%20game%20unfair%20to%20other%20users%20that%20play%20the%20game%20at%20regular%20speed.%20%20To%20speed%20your%20computer%20up%2C%20play%20the%20game%20with%20the%20smallest%20window%20setting%20and%20close%20all%20other%20applications%20or%20browser%20windows.%20%20Once%20you%20do%20that%2C%20you%20may%20re-enter%20the%20Daily%20Competition.%20%20You%20may%20also%20withdraw%20from%20the%20Daily%20Competition%20on%20the%20Daily%20Competition%20page.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="077" resname="IDS_SM_ERR_DC_TIME"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20but%20you%20did%20not%20get%20your%20score%20sent%20in%20in%20time%20to%20count%20towards%20the%20Daily%20Competition%21%3C%2Ffont%3E</source> </trans-unit> <trans-unitid="078" resname="IDS_SM_ERR_REVIEW"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3E%28Scroll%20Down%29%20Your%20score%20is%20being%20reviewed%20by%20staff.%20If%20it%20is%20deemed%20valid%2C%20you%20will%20receive%20your%20Neopoints%20and%20go%20into%20the%20hiscore%20table.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="079" resname="IDS_SM_ERR_QUICK_SESSION"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3E%28Scroll%20Down%29%20Your%20game%20play%20was%20too%20short%20to%20be%20counted.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="080" resname="IDS_SM_ERR_MISSING_HASH"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3EProblems%20processing%20your%20score.%20For%20best%20results%2C%20close%20the%20pop%20up%20window%20and%20re-open%20it%20to%20restart%20your%20game.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="081" resname="IDS_MESSAGE_1"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20but%20your%20score%20is%20too%20low%20to%20be%20entered%20into%20the%20World%20Challenge.%20%28Scroll%20down%29.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="082" resname="IDS_SM_ERR_WC_TOO_LOW"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ff0000%27%3ESorry%2C%20but%20your%20score%20is%20too%20low%20to%20be%20entered%20into%20the%20World%20Challenge%20and%20you%20have%20posted%20your%20max%20scores%20for%20the%20day.%20The%20minimum%20score%20required%20varies%20slightly%20from%20challenge%20to%20challenge%20and%20throughout%20the%20hour.%20%20To%20ensure%20your%20score%20is%20entered%2C%20play%20the%20best%20game%20you%20can.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="083" resname="IDS_SM_DD_MAX"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3EYou%27ve%20sent%20your%20score%20for%20Neopoints%20the%20maximum%20number%20of%20times%20today%20for%20this%20game.%20You%20may%2C%20however%2C%20keep%20submitting%20scores%20to%20try%20to%20beat%20AAA%20or%20Abigail%2C%20although%20you%20won%27t%20receive%20Neopoints%20for%20doing%20so.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="084" resname="IDS_SM_DD_BEAT_AAA"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ECongratulations%21%20%20You%27ve%20beaten%20AAA.%20%20Go%20get%20your%20prize%20and%20play%20more%20Daily%20Dare%20games.%20%20Don%27t%20forget%20to%20take%20the%20%3Ca%20href%3D%27%2Fgames%2Faaa%2Fnc_challenge.phtml%27%20target%3D%27_blank%27%3ENC%20Challenge%3C%2Fa%3E%20for%20a%20chance%20to%20win%20additional%20prizes%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="085" resname="IDS_SM_DD_BEAT_ABIGAIL"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ECongratulations%21%20%20You%27ve%20beaten%20Abigail.%20%20Go%20get%20your%20prize%20and%20play%20more%20Daily%20Dare%20games.%20%20Don%27t%20forget%20to%20take%20the%20%3Ca%20href%3D%27%2Fgames%2Faaa%2Fnc_challenge.phtml%27%20target%3D%27_blank%27%3ENC%20Challenge%3C%2Fa%3E%20for%20a%20chance%20to%20win%20additional%20prizes%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="086" resname="IDS_SM_DD_BEAT_DOUBLE"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ECongratulations%21%20%20You%27ve%20won%20the%20Double%20Dare.%20%20Go%20get%20your%20prize%20and%20play%20more%20Daily%20Dare%20games.%20%20Don%27t%20forget%20to%20take%20the%20%3Ca%20href%3D%27%2Fgames%2Faaa%2Fnc_challenge.phtml%27%20target%3D%27_blank%27%3ENC%20Challenge%3C%2Fa%3E%20for%20a%20chance%20to%20win%20additional%20prizes%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="087" resname="IDS_SM_DD_BEAT_LULU"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ECongratulations%21%20%20You%27ve%20beaten%20Lulu.%20%20Go%20get%20your%20prize%20and%20play%20more%20NC%20Challenge%20games.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="088" resname="IDS_SM_DD_NC_BEAT_LULU"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3ECongratulations%21%20You%20have%20beaten%20or%20matched%20Lulu%27s%20score%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="089"resname="IDS_SM_DD_NC_LOST_LULU"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3EYou%20have%20not%20beaten%20or%20matched%20Lulu%27s%20score%21%20Try%20again%21%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="090" resname="IDS_SM_AC_MAX_SCORE"> <source>%3Cfont%20face%3D%27customFSS_fnt%27%20size%3D%2714%27%20color%3D%27%23ffff00%27%3EYou%27ve%20sent%20your%20score%20for%20Neopoints%20the%20maximum%20number%20of%20times%20today%20for%20this%20game.%20%20You%20may%20keep%20submitting%20scores%20to%20advance%20your%20team%20and%20earn%20prize%20shop%20points.%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="091" resname="IDS_CARD_PREPARING_EMAIL_FORM"> <source>Preparing%20email%20form</source> </trans-unit> <trans-unit id="092" resname="IDS_CARD_PLEASE_COMPLETE_THE_FORM"> <source>Please%20complete%20the%20form</source> </trans-unit> <trans-unit id="093" resname="IDS_CARD_VALIDATING_FORM"> <source>Validating%20Form</source> </trans-unit> <trans-unit id="094" resname="IDS_CARD_SENDING_FORM"> <source>Sending%20Form</source> </trans-unit> <trans-unit id="095" resname="IDS_CARD_UNDERAGE_SENDER_NAME"> <source>A%20Neopets.com%20User</source> </trans-unit> <trans-unit id="096" resname="IDS_CARD_UNDERAGE_SENDER_EMAIL"> <source>support%40neopets.com</source> </trans-unit> <trans-unit id="097" resname="IDS_CARD_UNDERAGE_RECIPIENT_NAME"> <source>A%20Friend%20of%20Neopets.com</source> </trans-unit> <trans-unit id="098" resname="IDS_CARD_PLEASE_COMPLETE_AND_SUBMIT_FORM"> <source>Please%20complete%20and%20submit%20form</source> </trans-unit> <trans-unit id="099" resname="IDS_CARD_YOUR_FIRST_NAME"> <source>%3CP%20ALIGN%3D%22LEFT%22%3EYour%20First%20Name%3A%3C%2FP%3E</source> </trans-unit> <trans-unit id="100"resname="IDS_CARD_YOUR_EMAIL_ADDRESS"> <source>%3CP%20ALIGN%3D%22LEFT%22%3EYour%20Email%20Address%3A%3C%2FP%3E</source> </trans-unit> <trans-unit id="101" resname="IDS_CARD_FRIENDS_FIRST_NAME"> <source>%3CP%20ALIGN%3D%22LEFT%22%3EFriend%27s%20First%20Name%3A%3C%2FP%3E</source> </trans-unit> <trans-unitid="102" resname="IDS_CARD_FRIENDS_EMAIL_ADDRESS"> <source>%3CP%20ALIGN%3D%22LEFT%22%3EFriend%27s%20Email%3A%3C%2FP%3E</source> </trans-unit> <trans-unit id="103" resname="IDS_CARD_TITLE"> <source>Postcard%0APrinted%20in%20Neopia</source> </trans-unit> <trans-unit id="104" resname="IDS_CARD_SUBMIT"> <source>Send%20Card</source> </trans-unit> <trans-unit id="105" resname="IDS_CARD_I_AM_DONE"> <source>I%20am%20Done</source> </trans-unit> <trans-unit id="106" resname="IDS_CARD_CANCEL"> <source>Go%20Back</source> </trans-unit> <trans-unit id="107" resname="IDS_CARD_SEND_ANOTHER_CARD"> <source>Send%20Another%20Card</source> </trans-unit> <trans-unit id="108" resname="IDS_CARD_SEND_EXPLANATION"> <source>Earn%20Neopoints%2A%20and%20send%20a%20card%20to%20your%20friends.%20%20They%20will%20be%20so%20happy%20to%20hear%20from%20you%20after%20so%20long%21</source> </trans-unit> <trans-unit id="109" resname="IDS_CARD_SEND_MAX_THREE_TIMES"> <source>%2AMax%203%20times%20daily</source> </trans-unit> <trans-unit id="110" resname="IDS_PLAYEASY"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EPlay%20Game%20With%20BREAD%20%28Easy%29%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unitid="111" resname="IDS_PLAYMED"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EPlay%20Game%20With%20STICK%20%28Medium%29%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="112" resname="IDS_LOCKEDMED"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3ELOCKED%20need%20175m%20hit%21%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="113" resname="IDS_PLAYHARD"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EPlay%20Game%20With%20BAT%20%28Hard%29%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="114"resname="IDS_LOCKEDHARD"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3ELOCKED%20need%20450m%20hit%21%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="115" resname="IDS_VIEWINSTRUCTIONS"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EView%20Instructions%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="116" resname="IDS_CLEARMARKERS"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EClear%20Markers%2F%20Farthest%20Whack%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="117" resname="IDS_INSTRUCTIONS"> <source>%3Cp%20align%3D%27left%27%3E%3Cfont%20size%20%3D%20%2712%27%3EObjective%3A%3Cbr%3E%20-%20Whack%20the%20Kass%20as%20far%20as%20you%20can%21%3Cbr%3E%3Cbr%3EHow%20To%20Play%3A%3Cbr%3E%20-%20Select%20the%20level%20of%20difficulty%3Cbr%3E%20-%20Click%20Left%20Mouse%20Button%20to%20drop%20Kass%3Cbr%3E%20-%20Click%20Left%20Mouse%20Button%20again%20to%20swing%20bat%3Cbr%3E%20-%20Spacebar%20may%20be%20used%20instead%20of%20mouse%3Cbr%3E%3Cbr%3EClear%20Markers%2F%20Furthest%20Whack%3A%3Cbr%3E%20-%20The%20game%20marks%20the%20spots%20where%20the%20Kass%20%3Cbr%3E%20has%20landed%20before.%20To%20Clear%20these%20marked%20%3Cbr%3E%20spots%20click%20on%20the%20Clear%20Markers%20button%20in%3Cbr%3E%20the%20main%20menu.%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="118" resname="IDS_BACK"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EBack%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="119" resname="IDS_RESTARTGAME"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2717%27%3ERestart%20Game%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="120" resname="IDS_SENDSCORE"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2717%27%3ESend%20Score%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unitid="121" resname="IDS_HITAGAIN"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2715%27%3EClick%20anywhere%20to%20Whack%20Kass%20Again%21%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="122" resname="IDS_WIND"> <source>%3Cp%20align%3D%27left%27%3E%3Cfont%20size%20%3D%20%2714%27%20color%3D%27%23000000%27%3EWind</source> </trans-unit> <trans-unit id="123" resname="IDS_WINDMPH"> <source>meters%2Fsecond%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="124" resname="IDS_WINDNOHTML"> <source>Wind</source> </trans-unit> <trans-unit id="125" resname="IDS_TOPHIT"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20color%20%3D%20%27%23000000%27%20size%20%3D%20%2714%27%3EFarthest%20Whack%3A%20%3C%2Fp%3E%3C%2Ffont%3E</source> </trans-unit> <trans-unit id="126" resname="IDS_MARKERDISTANCE"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2712%27%3EDistance</source> </trans-unit> <trans-unit id="127" resname="IDS_MARKERMETERS"> <source>meters</source> </trans-unit> <trans-unit id="128" resname="IDS_MARKERDATE"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2712%27%3EDate</source> </trans-unit> <trans-unit id="129" resname="IDS_MARKERDAYOF"> <source>day%20of</source> </trans-unit> <trans-unit id="130" resname="IDS_NEWLEVEL"> <source>%3Cp%20align%3D%27center%27%3E%3Cfont%20size%20%3D%20%2724%27%3ENEW%20LEVEL%20UNLOCKED%21%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> <trans-unit id="131" resname="IDS_SLEEPING"> <source>Sleeping</source> </trans-unit> <trans-unit id="132" resname="IDS_AWAKENING"> <source>Awakening</source> </trans-unit> <trans-unit id="133" resname="IDS_RUNNING"> <source>Running</source> </trans-unit> <trans-unit id="134" resname="IDS_EATING"> <source>Eating</source> </trans-unit> <trans-unit id="135" resname="IDS_HUNTING"> <source>Hunting</source> </trans-unit> <trans-unit id="136" resname="IDS_RELAXING"> <source>Relaxing</source> </trans-unit> <trans-unit id="137" resname="IDS_SWIMMING"> <source>Swimming</source> </trans-unit> <trans-unit id="138" resname="IDS_HIDING"> <source>Hiding</source> </trans-unit> <trans-unit id="139" resname="IDS_GATHERING"> <source>Gathering</source> </trans-unit> <trans-unit id="140" resname="IDS_COLLECTING"> <source>Collecting</source> </trans-unit> <trans-unit id="141" resname="IDS_STORING"> <source>Storing</source> </trans-unit> <trans-unit id="142" resname="IDS_CELEBRATING"> <source>Celebrating</source> </trans-unit> <trans-unit id="143" resname="IDS_MAXHIT"> <source>%3Cp%20align%3D%27right%27%3E%3Cfont%20size%20%3D%20%2714%27%3EMaximum%20Hit%3C%2Ffont%3E%3C%2Fp%3E</source> </trans-unit> </body> <system> <langs> <lang> <name>English</name> <code>en</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Nederlands</name> <code>nl</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Portugu%C3%AAs</name> <code>pt</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Deutsch</name> <code>de</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Fran%C3%A7ais</name> <code>fr</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Italiano</name> <code>it</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>Espa%C3%B1ol</name> <code>es</code> <enabled>1</enabled> <langgroup>WE</langgroup> </lang> <lang> <name>%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87</name> <code>ch</code> <enabled>1</enabled> <langgroup>NW</langgroup> </lang> <lang> <name>%E7%B9%81%E9%AB%94%E4%B8%AD%E6%96%87</name> <code>zh</code> <enabled>1</enabled> <langgroup>NW</langgroup> </lang> <lang> <name>%E6%97%A5%E6%9C%AC%E8%AA%9E</name> <code>ja</code> <enabled>1</enabled> <langgroup>NW</langgroup> </lang> <lang> <name>%ED%95%9C%EA%B5%AD%EC%96%B4</name> <code>ko</code> <enabled>1</enabled> <langgroup>NW</langgroup> </lang> </langs> </system> </file> </xliff>
Results 1 to 23 of 23
- 15 Apr. 2011 05:20am #1
[Python] Neopets Score Sender Source
Last edited by Artificial; 22 Apr. 2011 at 11:10am.
- 15 Apr. 2011 05:51am #2
- 15 Apr. 2011 07:28am #3
I've built stuff for Neopets in the past and it's pretty boring. I'm only really doing this because it's not as straightforward as your stereotypical Neopet programs (i.e. go to this page, look for this text, retrieve this information, post).
Though I am a little disappointed to see it turning out this easily. The way Gaia Online handles flash games is a lot better.Last edited by Artificial; 17 Apr. 2011 at 11:28am.
- 16 Apr. 2011 05:59am #4
Good old neopets.
A well designed auto buyer can bring you a lot of users to the site.
Also, remember that Gaia flash games were created by experienced programmers... I think Neopets flash game framework was originally developed by one of the creators and then the site kept building upon that... So the design for Gaia is probably a lot better than Neopets. My theory anyways.
- 17 Apr. 2011 11:16am #5
I've coded the encryption module in Python. Matt, if you're trying to port this over to C#, this will help you:
Code:#!/usr/bin/env python import random import sys # Neomaster class. class Encryption: aDecimals = [] aHex = [] iHexLen = 0 def __init__( self ): # Let's initialise all of the decimals self.aDecimals.append([42, 75, 83, 53, 102, 74, 40, 43, 44, 61, 70, 79, 36, 86, 94, 101, 108, 67, 106, 112, 76, 98, 69, 95, 64, 81, 59, 126, 45, 57, 71, 125, 56, 122, 105, 66, 85, 103, 49, 99, 41, 109, 72, 107, 121, 80, 87, 100, 48, 65, 120, 110, 88, 55, 50, 73, 77, 113, 89, 52, 111, 119, 78, 63, 118, 33, 116, 46, 54, 117, 68, 123, 115, 104, 37, 97, 38, 84, 82, 58, 90, 114, 51]); self.aDecimals.append([78, 59, 122, 113, 101, 69, 50, 80, 115, 55, 48, 108, 86, 56, 106, 68, 45, 33, 53, 90, 103, 120, 66, 54, 75, 102, 118, 64, 87, 99, 61, 121, 41, 88, 100, 81, 98, 76, 77, 42, 67, 73, 119, 107, 111, 63, 116, 38, 82, 114, 46, 37, 95, 84, 74, 70, 79, 94, 105, 52, 123, 85, 65, 110, 43, 97, 126, 49, 44, 83, 104, 71, 72, 36, 125, 51, 40, 117, 57, 58, 112, 89, 109]); self.aDecimals.append([50, 73, 77, 72, 113, 98, 68, 61, 71, 88, 43, 105, 38, 53, 42, 81, 52, 111, 86, 121, 46, 74, 89, 115, 59, 112, 84, 58, 102, 41, 117, 120, 76, 123, 103, 107, 85, 57, 118, 67, 110, 109, 99, 114, 55, 66, 90, 64, 70, 87, 78, 100, 95, 125, 119, 75, 44, 51, 83, 104, 65, 101, 69, 79, 122, 97, 80, 33, 37, 54, 108, 56, 48, 106, 45, 82, 40, 126, 63, 49, 116, 94, 36]); self.aDecimals.append([109, 97, 54, 51, 118, 43, 81, 104, 57, 113, 74, 53, 100, 83, 42, 102, 103, 116, 48, 82, 117, 72, 36, 115, 71, 119, 41, 59, 87, 95, 122, 52, 108, 45, 98, 73, 86, 66, 111, 78, 126, 80, 69, 123, 40, 70, 120, 38, 121, 64, 58, 56, 37, 112, 110, 84, 107, 50, 90, 101, 125, 33, 89, 49, 55, 99, 67, 75, 114, 85, 105, 106, 79, 61, 94, 65, 77, 63, 44, 46, 88, 68, 76]); self.aDecimals.append([67, 119, 66, 37, 95, 80, 105, 64, 44, 63, 40, 49, 109, 107, 103, 120, 55, 110, 113, 97, 42, 99, 112, 85, 68, 106, 115, 50, 59, 71, 108, 76, 90, 75, 101, 94, 122, 43, 52, 61, 73, 116, 100, 118, 125, 88, 72, 54, 98, 78, 83, 86, 114, 48, 81, 53, 87, 77, 36, 58, 104, 111, 123, 70, 79, 102, 74, 89, 117, 41, 69, 84, 82, 126, 121, 57, 51, 56, 33, 46, 45, 65, 38]); self.aDecimals.append([119, 103, 48, 97, 37, 90, 80, 83, 74, 59, 85, 95, 36, 101, 49, 45, 109, 118, 112, 58, 113, 99, 120, 82, 108, 110, 126, 75, 84, 88, 69, 52, 40, 63, 117, 115, 79, 72, 64, 107, 61, 123, 106, 87, 42, 53, 89, 66, 111, 51, 78, 50, 54, 67, 81, 116, 38, 57, 55, 73, 71, 98, 68, 46, 65, 102, 122, 77, 121, 100, 114, 94, 44, 86, 104, 76, 41, 70, 105, 43, 56, 33, 125]); self.aDecimals.append([37, 106, 79, 117, 78, 99, 107, 44, 101, 109, 40, 81, 86, 122, 72, 45, 110, 68, 114, 56, 33, 98, 71, 63, 111, 102, 104, 75, 89, 100, 125, 65, 115, 50, 53, 66, 82, 36, 74, 38, 119, 84, 112, 126, 105, 70, 48, 85, 42, 57, 94, 59, 76, 118, 43, 46, 80, 87, 58, 95, 73, 108, 88, 103, 123, 90, 97, 41, 113, 64, 67, 69, 54, 83, 61, 116, 52, 49, 51, 55, 77, 120, 121]); self.aDecimals.append([53, 103, 114, 73, 59, 118, 58, 90, 48, 64, 74, 110, 102, 111, 46, 63, 108, 123, 126, 122, 72, 83, 36, 100, 37, 112, 89, 113, 70, 50, 41, 38, 85, 101, 55, 115, 33, 40, 106, 84, 125, 76, 117, 42, 49, 77, 81, 43, 65, 44, 86, 56, 67, 121, 109, 68, 80, 94, 57, 97, 95, 119, 120, 104, 105, 71, 87, 75, 82, 88, 99, 79, 116, 69, 52, 54, 66, 107, 61, 98, 78, 51, 45]); self.aDecimals.append([69, 33, 72, 64, 46, 119, 76, 112, 59, 88, 78, 87, 97, 79, 89, 40, 126, 122, 61, 54, 95, 66, 94, 80, 125, 106, 117, 48, 36, 74, 123, 51, 71, 103, 56, 121, 107, 44, 38, 110, 65, 111, 86, 84, 73, 53, 99, 43, 85, 77, 68, 100, 120, 41, 83, 81, 58, 50, 42, 67, 82, 101, 52, 116, 75, 49, 114, 37, 63, 115, 55, 104, 98, 57, 102, 90, 113, 105, 45, 108, 109, 70, 118]); self.aDecimals.append([68, 103, 43, 113, 80, 84, 76, 44, 63, 45, 71, 72, 59, 123, 106, 75, 56, 86, 105, 41, 126, 120, 37, 111, 54, 97, 102, 50, 58, 94, 117, 67, 73, 66, 74, 78, 119, 115, 99, 65, 85, 90, 40, 89, 107, 114, 101, 77, 64, 57, 118, 69, 82, 49, 110, 88, 36, 122, 98, 95, 121, 79, 109, 81, 51, 38, 52, 108, 87, 70, 100, 83, 53, 48, 33, 61, 104, 42, 112, 46, 55, 116, 125]); self.aDecimals.append([46, 101, 72, 108, 54, 58, 109, 107, 112, 120, 61, 81, 75, 86, 43, 126, 85, 77, 51, 67, 41, 90, 111, 69, 89, 105, 38, 53, 70, 125, 94, 59, 73, 95, 49, 76, 82, 110, 65, 103, 74, 63, 48, 104, 56, 113, 123, 68, 57, 44, 36, 87, 80, 122, 106, 79, 37, 102, 66, 88, 117, 40, 99, 118, 33, 97, 71, 55, 119, 100, 98, 64, 121, 116, 52, 50, 83, 45, 114, 78, 84, 42, 115]); self.aDecimals.append([57, 123, 110, 37, 65, 38, 42, 51, 97, 69, 76, 98, 44, 99, 113, 82, 66, 119, 90, 83, 49, 112, 85, 74, 40, 126, 111, 106, 122, 73, 72, 36, 84, 46, 100, 61, 48, 56, 52, 75, 95, 89, 68, 103, 94, 105, 116, 58, 78, 117, 33, 115, 120, 109, 81, 104, 114, 45, 67, 87, 108, 54, 125, 43, 79, 107, 77, 102, 121, 59, 86, 71, 55, 50, 101, 63, 53, 118, 41, 80, 64, 88, 70]); self.aDecimals.append([40, 43, 123, 125, 97, 109, 126, 56, 48, 113, 107, 121, 73, 102, 118, 94, 33, 106, 89, 50, 46, 88, 67, 63, 112, 75, 64, 51, 114, 95, 104, 68, 58, 100, 74, 72, 70, 111, 117, 87, 37, 78, 55, 71, 105, 54, 81, 59, 86, 41, 44, 57, 49, 69, 116, 80, 98, 110, 119, 82, 76, 101, 122, 42, 85, 79, 45, 77, 103, 61, 83, 108, 65, 120, 90, 115, 53, 66, 52, 84, 36, 38, 99]); self.aDecimals.append([67, 70, 72, 64, 75, 73, 89, 95, 48, 77, 37, 115, 87, 53, 74, 120, 110, 83, 84, 121, 101, 33, 116, 80, 104, 98, 45, 90, 119, 59, 125, 42, 38, 58, 126, 68, 94, 107, 86, 123, 108, 118, 46, 88, 51, 36, 117, 109, 97, 65, 112, 54, 85, 82, 43, 102, 105, 79, 81, 99, 50, 113, 61, 40, 100, 76, 57, 63, 56, 66, 55, 52, 69, 71, 44, 111, 122, 49, 41, 106, 78, 114, 103]); self.aDecimals.append([51, 40, 83, 87, 105, 94, 79, 69, 46, 114, 101, 63, 121, 103, 37, 65, 107, 115, 76, 88, 53, 119, 109, 57, 52, 71, 84, 125, 41, 113, 54, 50, 61, 98, 59, 55, 118, 45, 56, 42, 123, 85, 106, 38, 100, 78, 36, 116, 44, 82, 66, 97, 75, 86, 122, 126, 33, 48, 67, 99, 90, 49, 72, 64, 108, 77, 102, 80, 112, 95, 117, 120, 74, 89, 81, 58, 70, 110, 104, 73, 43, 68, 111]); self.aDecimals.append([99, 87, 114, 64, 77, 78, 115, 83, 111, 48, 72, 75, 73, 121, 112, 56, 105, 94, 76, 36, 42, 65, 85, 45, 116, 74, 61, 54, 103, 84, 89, 67, 57, 43, 80, 86, 113, 117, 120, 119, 95, 81, 55, 69, 125, 33, 107, 109, 41, 58, 70, 90, 106, 52, 118, 97, 102, 51, 79, 37, 101, 53, 104, 40, 82, 122, 126, 88, 110, 71, 66, 98, 108, 100, 49, 63, 44, 46, 68, 50, 59, 123, 38]); self.aDecimals.append([119, 103, 79, 101, 114, 81, 52, 53, 50, 55, 51, 106, 37, 111, 68, 117, 48, 73, 42, 58, 77, 65, 84, 86, 71, 88, 104, 83, 105, 94, 115, 74, 49, 112, 67, 76, 118, 95, 36, 38, 66, 46, 56, 100, 126, 33, 40, 109, 82, 123, 69, 85, 122, 44, 59, 99, 61, 45, 63, 107, 80, 41, 102, 89, 116, 113, 110, 57, 87, 98, 121, 70, 97, 54, 108, 64, 120, 43, 72, 78, 125, 75, 90]); self.aDecimals.append([118, 81, 69, 71, 103, 65, 90, 43, 64, 94, 111, 52, 61, 66, 116, 83, 54, 59, 102, 46, 100, 40, 36, 68, 114, 48, 79, 109, 84, 80, 78, 85, 122, 86, 101, 89, 95, 41, 112, 106, 126, 74, 77, 99, 72, 37, 50, 33, 38, 107, 73, 108, 51, 44, 110, 56, 87, 57, 58, 55, 42, 88, 49, 115, 125, 75, 97, 104, 123, 53, 45, 70, 113, 117, 63, 98, 76, 120, 82, 67, 119, 105, 121]); self.aDecimals.append([44, 87, 37, 57, 52, 120, 82, 36, 125, 115, 70, 105, 59, 86, 94, 111, 46, 117, 99, 42, 84, 68, 38, 102, 109, 121, 48, 55, 122, 78, 41, 112, 107, 101, 45, 58, 66, 74, 77, 116, 51, 119, 73, 126, 56, 64, 69, 81, 76, 106, 61, 110, 85, 33, 53, 118, 95, 114, 123, 90, 65, 40, 54, 113, 108, 97, 50, 104, 72, 98, 103, 88, 79, 43, 67, 63, 89, 100, 49, 75, 83, 80, 71]); self.aDecimals.append([49, 106, 73, 56, 70, 59, 119, 45, 115, 38, 64, 81, 86, 97, 114, 66, 102, 121, 98, 67, 78, 74, 104, 54, 80, 110, 52, 82, 37, 94, 68, 117, 84, 120, 63, 57, 105, 72, 61, 50, 85, 51, 71, 55, 46, 89, 79, 41, 101, 44, 36, 69, 87, 76, 90, 123, 125, 116, 112, 40, 108, 83, 99, 107, 53, 48, 65, 58, 118, 43, 111, 122, 126, 103, 33, 95, 100, 88, 77, 113, 75, 42, 109]); # Let's loop through and convert decimals to their hexidecimal values for eachDecimalList in self.aDecimals: sHex = "" if( isinstance( eachDecimalList, list ) ): for eachDecimal in eachDecimalList: sHex += chr( eachDecimal ) self.aHex.append( sHex ) self.iHexLen = len( self.aHex[0] ) def initBin( self, game_hash, game_sk ): self.sBin = game_hash + game_sk self.iBinLen = len( self.sBin ) def addSlashes( self, s ): hexString = self.string2Hex( s ); return self.escapeString( hexString ); def string2Hex( self, s ): ## Intialise the variables sReplace = "" ii = random.randint( 0, len( self.aDecimals ) - 1 ) sHex = self.aHex[ii]; _loc3 = 0 for _loc2 in range( len( s ) ): if _loc3 >= self.iBinLen: _loc3 = 0; _loc1 = sHex.find(s[_loc2:_loc2+1]) if _loc1 >= 0: _loc1 = (_loc1 + sHex.find( self.sBin[_loc3:_loc3+1])) % self.iHexLen sReplace = sReplace + sHex[_loc1:_loc1+1] else: sReplace = sReplace + s[_loc2:_loc2+1] _loc3 += 1 if ii >= 10: sReplace = sReplace + str( ii ) else: sReplace = sReplace + str( 0 ) + str( ii ) return sReplace def escapeString( self, s ): sReplace = "" for _loc3 in range( len( s ) ): _loc1 = str( ord( s[_loc3:_loc3+1] ) ) # Make sure the _loc1 variable is 3 digits in length (i.e. 9 => 009) while( len( _loc1 ) < 3 ): _loc1 = "0" + _loc1 sReplace = sReplace + _loc1 return sReplace
Code:# Initialise some variables gameHash = "6d9ee07097caf0e4ca3a" gameSk = "36e93bf26a047e360648" Raw = "ssnhsh=" + gameHash + "&ssnky=" + gameSk + "&gmd=381&scr=300&frmrt=15&chllng=1&gmdrtn=54252" # Let's perform the calculations encrypt = Encryption() encrypt.initBin( gameHash, gameSk ) Encrypted = encrypt.addSlashes( Raw ) #Output print( Encrypted )
- 17 Apr. 2011 01:09pm #6
- 18 Apr. 2011 01:26pm #7
On closer inspection, I'm fairly confident the encryption module is wrong. I'm able to decrypt strings I generate, but not those that are generated when I actually play the game.
I'll take a look at it tomorrow and see exactly what's wrong. Here's the new file, I added a decryptString function to verify it wasn't working.
Code:#!/usr/bin/env python import random import re # Neomaster class. class Encryption: aDecimals = [] aHex = [] iHexLen = 0 def __init__( self ): # Let's initialise all of the decimals self.aDecimals.append([42, 75, 83, 53, 102, 74, 40, 43, 44, 61, 70, 79, 36, 86, 94, 101, 108, 67, 106, 112, 76, 98, 69, 95, 64, 81, 59, 126, 45, 57, 71, 125, 56, 122, 105, 66, 85, 103, 49, 99, 41, 109, 72, 107, 121, 80, 87, 100, 48, 65, 120, 110, 88, 55, 50, 73, 77, 113, 89, 52, 111, 119, 78, 63, 118, 33, 116, 46, 54, 117, 68, 123, 115, 104, 37, 97, 38, 84, 82, 58, 90, 114, 51]); self.aDecimals.append([78, 59, 122, 113, 101, 69, 50, 80, 115, 55, 48, 108, 86, 56, 106, 68, 45, 33, 53, 90, 103, 120, 66, 54, 75, 102, 118, 64, 87, 99, 61, 121, 41, 88, 100, 81, 98, 76, 77, 42, 67, 73, 119, 107, 111, 63, 116, 38, 82, 114, 46, 37, 95, 84, 74, 70, 79, 94, 105, 52, 123, 85, 65, 110, 43, 97, 126, 49, 44, 83, 104, 71, 72, 36, 125, 51, 40, 117, 57, 58, 112, 89, 109]); self.aDecimals.append([50, 73, 77, 72, 113, 98, 68, 61, 71, 88, 43, 105, 38, 53, 42, 81, 52, 111, 86, 121, 46, 74, 89, 115, 59, 112, 84, 58, 102, 41, 117, 120, 76, 123, 103, 107, 85, 57, 118, 67, 110, 109, 99, 114, 55, 66, 90, 64, 70, 87, 78, 100, 95, 125, 119, 75, 44, 51, 83, 104, 65, 101, 69, 79, 122, 97, 80, 33, 37, 54, 108, 56, 48, 106, 45, 82, 40, 126, 63, 49, 116, 94, 36]); self.aDecimals.append([109, 97, 54, 51, 118, 43, 81, 104, 57, 113, 74, 53, 100, 83, 42, 102, 103, 116, 48, 82, 117, 72, 36, 115, 71, 119, 41, 59, 87, 95, 122, 52, 108, 45, 98, 73, 86, 66, 111, 78, 126, 80, 69, 123, 40, 70, 120, 38, 121, 64, 58, 56, 37, 112, 110, 84, 107, 50, 90, 101, 125, 33, 89, 49, 55, 99, 67, 75, 114, 85, 105, 106, 79, 61, 94, 65, 77, 63, 44, 46, 88, 68, 76]); self.aDecimals.append([67, 119, 66, 37, 95, 80, 105, 64, 44, 63, 40, 49, 109, 107, 103, 120, 55, 110, 113, 97, 42, 99, 112, 85, 68, 106, 115, 50, 59, 71, 108, 76, 90, 75, 101, 94, 122, 43, 52, 61, 73, 116, 100, 118, 125, 88, 72, 54, 98, 78, 83, 86, 114, 48, 81, 53, 87, 77, 36, 58, 104, 111, 123, 70, 79, 102, 74, 89, 117, 41, 69, 84, 82, 126, 121, 57, 51, 56, 33, 46, 45, 65, 38]); self.aDecimals.append([119, 103, 48, 97, 37, 90, 80, 83, 74, 59, 85, 95, 36, 101, 49, 45, 109, 118, 112, 58, 113, 99, 120, 82, 108, 110, 126, 75, 84, 88, 69, 52, 40, 63, 117, 115, 79, 72, 64, 107, 61, 123, 106, 87, 42, 53, 89, 66, 111, 51, 78, 50, 54, 67, 81, 116, 38, 57, 55, 73, 71, 98, 68, 46, 65, 102, 122, 77, 121, 100, 114, 94, 44, 86, 104, 76, 41, 70, 105, 43, 56, 33, 125]); self.aDecimals.append([37, 106, 79, 117, 78, 99, 107, 44, 101, 109, 40, 81, 86, 122, 72, 45, 110, 68, 114, 56, 33, 98, 71, 63, 111, 102, 104, 75, 89, 100, 125, 65, 115, 50, 53, 66, 82, 36, 74, 38, 119, 84, 112, 126, 105, 70, 48, 85, 42, 57, 94, 59, 76, 118, 43, 46, 80, 87, 58, 95, 73, 108, 88, 103, 123, 90, 97, 41, 113, 64, 67, 69, 54, 83, 61, 116, 52, 49, 51, 55, 77, 120, 121]); self.aDecimals.append([53, 103, 114, 73, 59, 118, 58, 90, 48, 64, 74, 110, 102, 111, 46, 63, 108, 123, 126, 122, 72, 83, 36, 100, 37, 112, 89, 113, 70, 50, 41, 38, 85, 101, 55, 115, 33, 40, 106, 84, 125, 76, 117, 42, 49, 77, 81, 43, 65, 44, 86, 56, 67, 121, 109, 68, 80, 94, 57, 97, 95, 119, 120, 104, 105, 71, 87, 75, 82, 88, 99, 79, 116, 69, 52, 54, 66, 107, 61, 98, 78, 51, 45]); self.aDecimals.append([69, 33, 72, 64, 46, 119, 76, 112, 59, 88, 78, 87, 97, 79, 89, 40, 126, 122, 61, 54, 95, 66, 94, 80, 125, 106, 117, 48, 36, 74, 123, 51, 71, 103, 56, 121, 107, 44, 38, 110, 65, 111, 86, 84, 73, 53, 99, 43, 85, 77, 68, 100, 120, 41, 83, 81, 58, 50, 42, 67, 82, 101, 52, 116, 75, 49, 114, 37, 63, 115, 55, 104, 98, 57, 102, 90, 113, 105, 45, 108, 109, 70, 118]); self.aDecimals.append([68, 103, 43, 113, 80, 84, 76, 44, 63, 45, 71, 72, 59, 123, 106, 75, 56, 86, 105, 41, 126, 120, 37, 111, 54, 97, 102, 50, 58, 94, 117, 67, 73, 66, 74, 78, 119, 115, 99, 65, 85, 90, 40, 89, 107, 114, 101, 77, 64, 57, 118, 69, 82, 49, 110, 88, 36, 122, 98, 95, 121, 79, 109, 81, 51, 38, 52, 108, 87, 70, 100, 83, 53, 48, 33, 61, 104, 42, 112, 46, 55, 116, 125]); self.aDecimals.append([46, 101, 72, 108, 54, 58, 109, 107, 112, 120, 61, 81, 75, 86, 43, 126, 85, 77, 51, 67, 41, 90, 111, 69, 89, 105, 38, 53, 70, 125, 94, 59, 73, 95, 49, 76, 82, 110, 65, 103, 74, 63, 48, 104, 56, 113, 123, 68, 57, 44, 36, 87, 80, 122, 106, 79, 37, 102, 66, 88, 117, 40, 99, 118, 33, 97, 71, 55, 119, 100, 98, 64, 121, 116, 52, 50, 83, 45, 114, 78, 84, 42, 115]); self.aDecimals.append([57, 123, 110, 37, 65, 38, 42, 51, 97, 69, 76, 98, 44, 99, 113, 82, 66, 119, 90, 83, 49, 112, 85, 74, 40, 126, 111, 106, 122, 73, 72, 36, 84, 46, 100, 61, 48, 56, 52, 75, 95, 89, 68, 103, 94, 105, 116, 58, 78, 117, 33, 115, 120, 109, 81, 104, 114, 45, 67, 87, 108, 54, 125, 43, 79, 107, 77, 102, 121, 59, 86, 71, 55, 50, 101, 63, 53, 118, 41, 80, 64, 88, 70]); self.aDecimals.append([40, 43, 123, 125, 97, 109, 126, 56, 48, 113, 107, 121, 73, 102, 118, 94, 33, 106, 89, 50, 46, 88, 67, 63, 112, 75, 64, 51, 114, 95, 104, 68, 58, 100, 74, 72, 70, 111, 117, 87, 37, 78, 55, 71, 105, 54, 81, 59, 86, 41, 44, 57, 49, 69, 116, 80, 98, 110, 119, 82, 76, 101, 122, 42, 85, 79, 45, 77, 103, 61, 83, 108, 65, 120, 90, 115, 53, 66, 52, 84, 36, 38, 99]); self.aDecimals.append([67, 70, 72, 64, 75, 73, 89, 95, 48, 77, 37, 115, 87, 53, 74, 120, 110, 83, 84, 121, 101, 33, 116, 80, 104, 98, 45, 90, 119, 59, 125, 42, 38, 58, 126, 68, 94, 107, 86, 123, 108, 118, 46, 88, 51, 36, 117, 109, 97, 65, 112, 54, 85, 82, 43, 102, 105, 79, 81, 99, 50, 113, 61, 40, 100, 76, 57, 63, 56, 66, 55, 52, 69, 71, 44, 111, 122, 49, 41, 106, 78, 114, 103]); self.aDecimals.append([51, 40, 83, 87, 105, 94, 79, 69, 46, 114, 101, 63, 121, 103, 37, 65, 107, 115, 76, 88, 53, 119, 109, 57, 52, 71, 84, 125, 41, 113, 54, 50, 61, 98, 59, 55, 118, 45, 56, 42, 123, 85, 106, 38, 100, 78, 36, 116, 44, 82, 66, 97, 75, 86, 122, 126, 33, 48, 67, 99, 90, 49, 72, 64, 108, 77, 102, 80, 112, 95, 117, 120, 74, 89, 81, 58, 70, 110, 104, 73, 43, 68, 111]); self.aDecimals.append([99, 87, 114, 64, 77, 78, 115, 83, 111, 48, 72, 75, 73, 121, 112, 56, 105, 94, 76, 36, 42, 65, 85, 45, 116, 74, 61, 54, 103, 84, 89, 67, 57, 43, 80, 86, 113, 117, 120, 119, 95, 81, 55, 69, 125, 33, 107, 109, 41, 58, 70, 90, 106, 52, 118, 97, 102, 51, 79, 37, 101, 53, 104, 40, 82, 122, 126, 88, 110, 71, 66, 98, 108, 100, 49, 63, 44, 46, 68, 50, 59, 123, 38]); self.aDecimals.append([119, 103, 79, 101, 114, 81, 52, 53, 50, 55, 51, 106, 37, 111, 68, 117, 48, 73, 42, 58, 77, 65, 84, 86, 71, 88, 104, 83, 105, 94, 115, 74, 49, 112, 67, 76, 118, 95, 36, 38, 66, 46, 56, 100, 126, 33, 40, 109, 82, 123, 69, 85, 122, 44, 59, 99, 61, 45, 63, 107, 80, 41, 102, 89, 116, 113, 110, 57, 87, 98, 121, 70, 97, 54, 108, 64, 120, 43, 72, 78, 125, 75, 90]); self.aDecimals.append([118, 81, 69, 71, 103, 65, 90, 43, 64, 94, 111, 52, 61, 66, 116, 83, 54, 59, 102, 46, 100, 40, 36, 68, 114, 48, 79, 109, 84, 80, 78, 85, 122, 86, 101, 89, 95, 41, 112, 106, 126, 74, 77, 99, 72, 37, 50, 33, 38, 107, 73, 108, 51, 44, 110, 56, 87, 57, 58, 55, 42, 88, 49, 115, 125, 75, 97, 104, 123, 53, 45, 70, 113, 117, 63, 98, 76, 120, 82, 67, 119, 105, 121]); self.aDecimals.append([44, 87, 37, 57, 52, 120, 82, 36, 125, 115, 70, 105, 59, 86, 94, 111, 46, 117, 99, 42, 84, 68, 38, 102, 109, 121, 48, 55, 122, 78, 41, 112, 107, 101, 45, 58, 66, 74, 77, 116, 51, 119, 73, 126, 56, 64, 69, 81, 76, 106, 61, 110, 85, 33, 53, 118, 95, 114, 123, 90, 65, 40, 54, 113, 108, 97, 50, 104, 72, 98, 103, 88, 79, 43, 67, 63, 89, 100, 49, 75, 83, 80, 71]); self.aDecimals.append([49, 106, 73, 56, 70, 59, 119, 45, 115, 38, 64, 81, 86, 97, 114, 66, 102, 121, 98, 67, 78, 74, 104, 54, 80, 110, 52, 82, 37, 94, 68, 117, 84, 120, 63, 57, 105, 72, 61, 50, 85, 51, 71, 55, 46, 89, 79, 41, 101, 44, 36, 69, 87, 76, 90, 123, 125, 116, 112, 40, 108, 83, 99, 107, 53, 48, 65, 58, 118, 43, 111, 122, 126, 103, 33, 95, 100, 88, 77, 113, 75, 42, 109]); # Let's loop through and convert decimals to their hexidecimal values for eachDecimalList in self.aDecimals: sHex = "" if( isinstance( eachDecimalList, list ) ): for eachDecimal in eachDecimalList: sHex += chr( eachDecimal ) self.aHex.append( sHex ) self.iHexLen = len( self.aHex[0] ) def initBin( self, game_hash, game_sk ): self.sBin = game_hash + game_sk self.iBinLen = len( self.sBin ) def addSlashes( self, s ): hexString = self.string2Hex( s ); return self.escapeString( hexString ); def string2Hex( self, s ): ## Intialise the variables sReplace = "" ii = random.randint( 0, len( self.aDecimals ) - 1 ) sHex = self.aHex[ii]; y = 0 for x in range( len( s ) ): if y >= self.iBinLen: y = 0; sHexChatAt = sHex.find(s[x:x+1]) if sHexChatAt >= 0: sHexChatAt = (sHexChatAt + sHex.find( self.sBin[y:y+1])) % self.iHexLen sReplace = sReplace + sHex[sHexChatAt:sHexChatAt+1] else: sReplace = sReplace + s[x:x+1] y += 1 if ii >= 10: sReplace = sReplace + str( ii ) else: sReplace = sReplace + str( 0 ) + str( ii ) return sReplace def escapeString( self, s ): sReplace = "" for y in range( len( s ) ): sHexChatAt = str( ord( s[y:y+1] ) ) # Make sure the sHexChatAt variable is 3 digits in length (i.e. 9 => 009) while( len( sHexChatAt ) < 3 ): sHexChatAt = "0" + sHexChatAt sReplace = sReplace + sHexChatAt return sReplace def decryptString( self, s ): # Let's fetch all of the decimals matches = re.findall( "(\d{3})", s ) # Find the string c = "" for eachDecimal in matches: c += chr( int( eachDecimal ) ) # What was the random integer we used? ii = int( c[ -2: ] ) # What hex value are we using? sHex = self.aHex[ ii ] # Initialise some variables y = 0 s = "" # Let's loop through to decrypt for x in range( len( c ) - 2 ): z = c[ x:x+1 ] # If we've exceeded the iBinLength let's just set it back to 0 if y >= self.iBinLen: y = 0 sHexChatAt = sHex.find( z ) r = sHex.find( self.sBin[ y:y+1 ] ) # What character are we using? x1 = sHexChatAt - r c1 = sHex[ x1 : x1 + 1 ] s += c1 y += 1 return s """ Generated myself through addSlashes function encrypt = Encryption() encrypt.initBin( "d9da5a9cd17122fc192e", "0487cb8e3a6d30ed4ba9" ) Raw = "057059064106113106033059083079115106076098119059043041040046115055054038068085100118106067041048097089090080076086044079077066045081101090126056055079112108076098064120042083101043103071050066066126105043102125087117094061036101053108066121059103123069038085033086046097110079051038067072106082106065120049056" s = encrypt.decryptString( Raw ) print( s ) Generated by Neopets game: encrypt = Encryption() encrypt.initBin( "2547b6356c154a1b7abb", "3b5610f57912b254d003" ) Raw = "113095106040075061109075121059042097044072057101116090097064072072097045090108110077109073056121081076049064058115052107059051077114072103041075121059095126123072067056049050037041097072077071097061083075077121067059107082105033081107071061061082049073084043109077043037095105033074078072042078090109049050" s = encrypt.decryptString( Raw ) print( s ) """
- 20 Apr. 2011 08:49am #8
I can't decrypt strings that are generated by the actual games on the server. I've looked through my code 4-5 times and compared with the AS library file, and can't see how it could be wrong. In fact, I even used the AS in flash to generate the encrypted string and was able to decrypt it. The only reason, as I can see it is there's something else going on with the encryption (either another block of code entirely handles it, or another block of code is interacting with it).
Will have to keep looking. I found this Java code somewhere online posted in 2008.
Code:import java.text.DecimalFormat; import java.util.ArrayList; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.io.BufferedReader; import java.io.FileReader; import java.io.File; //import java.io.BufferedWriter; //import java.io.FileWriter; /** * A class to encode and decode Neopets.com flash game scores. * @author unlimitedorb * @since 4/20/2008 */ public class Crypt { private static final String scoreBase = "http://www.neopets.com/high_scores/process_flash_score.phtml"; private String username; private String sessionHash; private String sessionKey; private int gameID; private int wait; private int modifiedGameID; private String bin; private int score; private int dailyChallenge; //Setting it isn't implemented yet. (Don't do Daily Challenges!) private int averageFrameRate = 24; //Isn't currently implemented. private int multiple; //Confirm later! Probably determines whether it was multiplayer or not. public Crypt(String username, String sh, String sk, int gameID, int wait, int score) { this.username = username; this.sessionHash = sh; this.sessionKey = sk; this.gameID = gameID; this.wait = wait; this.score = score; this.dailyChallenge = -1; this.bin = sh + sk; modifiedGameID = 300 * gameID; } /* * The class isn't meant to be used as a standalone, but this is provided just in case/for testing * purposes. It's true purpose is as a utility to be used in a bot. */ public static void main(String[] args) { //Crypt crypt = new Crypt("username", "4c82431c320b55797868", "fcb375decc3f7e1e83c7", 500, 500, 500); String request = crypt.encode(); System.out.println(request); } /** * Method to decode a Neopets.com flash game score. Useful for development. * Hungarian notation in the original swf variables is stripped out. * @param encryptedScore The score to be decoded. */ public static String decode(String encryptedScore, String hash, String key) { String res = reverseEscapeString(encryptedScore); String result = reverseStringToHex(res, hash, key); return result; } /** * A method to encode sensitive data. * @return An encoded String. */ public String encode() { //There might be extra parameters added, but that's game specific. StringBuilder data = new StringBuilder(scoreBase + "?cn=" + modifiedGameID + "&gd=" + wait); //Format the parameter r in the style of ActionScript's Math.random() DecimalFormat rFormat = new DecimalFormat("0.000000000000000000"); data.append("&r=" + rFormat.format(Math.random())); String toEncrypt = "ssnhsh=" + sessionHash + "&ssnky=" + sessionKey + "&gmd=" + gameID + "&scr=" + this.score + "&frmrt=" + averageFrameRate + "&chllng=" + (dailyChallenge == -1? "": dailyChallenge) + "&gmdrtn=" + wait; String eScore = addSlashes(toEncrypt); data.append("&gmd_g=" + this.gameID + "&mltpl_g=" + multiple + "&gmdt_g=" + eScore + "&sh_g=" + sessionHash + "&sk_g=" + sessionKey + "&usrnm_g=" + username + "&dc_g=" + (dailyChallenge == -1? 0: dailyChallenge)); String result = data.toString(); return result; } /** * Scrambles information. * @param data The information to be scrambled. * @return Scrambled information. */ public String addSlashes(String data) { return this.escapeString(this.stringToHex(data)); } public String stringToHex(String data){ ArrayList<String> keys = getKeys(new File("keys.txt")); String result = ""; int randomKey = (int) (Math.random() * keys.size()); int index = 0; int count = 0; String key = keys.get(randomKey); while(index < data.length()) { if (count >= this.bin.length()) { count = 0; } int current = key.indexOf(data.charAt(index)); if (current >= 0) { current = (current + key.indexOf(this.bin.charAt(count))) % key.length(); result += key.charAt(current); } else { result += data.charAt(index); } ++count; ++index; } if (randomKey >= 10) { result += String.valueOf(randomKey); return result; } result += String.valueOf(0) + String.valueOf(randomKey); return result; } public static String reverseStringToHex(String data, String sHash, String sKey) { int k = Integer.parseInt(data.substring(data.length() - 2)); ArrayList<String> keys = getKeys(new File("keys.txt")); String key = keys.get(k); data = data.substring(0, data.length() - 2); String bin = sHash + sKey; String result = ""; int count = 0; int current = 0; for(int i = 0; i < data.length(); i++) { if(count >= bin.length()) { count = 0; } current = bin.charAt(count); current = key.indexOf(data.charAt(i)) - key.indexOf(current); if(current < 0) { result += key.charAt(key.length() + current); } else { result += key.charAt(current); } count++; } return result; } /** * Generates a String of ASCII code points with leading 0's for decoding purposes. * @param data The String to escape. * @return An escaped String. */ public String escapeString(String data) { String result = ""; String current = ""; int index = 0; int count = 0; while(index < data.length()) { current = String.valueOf((int) data.charAt(index)); //None of the key lengths are <= 1 count = 3 - current.length(); while(count > 0) { current = "0" + current; --count; } result += current; ++index; } return result; } /** * Reverses the escapeString process. * @param data The string to reverse. * @return An unescaped String. */ public static String reverseEscapeString(String data) { String result = ""; for(int i = 0; i < data.length(); i += 3) { String current = data.substring(i, i + 3); if(current.startsWith("0")) { current = current.substring(1, current.length()); result += (char) Integer.parseInt(current); } else { result += (char) Integer.parseInt(current); } } return result; } /** * Retrieves keys from the text file "keys.txt" * @param file The File to read the keys from. * @return An ArrayList of Neopets.com flash game encryption keys. */ public static ArrayList<String> getKeys(File file) { ArrayList<String> keys = new ArrayList<String>(); keys.ensureCapacity(20); try { BufferedReader stream = new BufferedReader(new FileReader(file)); String line; //BufferedWriter out = new BufferedWriter(new FileWriter(new File("reversedkeys.txt"))); while((line = stream.readLine()) != null) { String expression = "\\d+"; Pattern pattern = Pattern.compile(expression); Matcher matcher = pattern.matcher(line); String eLine = new String(""); while(matcher.find()) { eLine += (char) Integer.parseInt(line.substring(matcher.start(), matcher.end())); } keys.add(eLine); //out.write(eLine + "\n"); //out.flush(); } stream.close(); //out.close(); } catch(Exception e) { e.printStackTrace(); } return keys; } /** * @return the score */ public int getScore() { return this.score; } public void setScore(int score) { this.score = score; } }
- 22 Apr. 2011 06:37am #9
Ok, I'm an idiot. I spent about an hour attempting to decrypt the actual packet sent to the server, and it appeared that the decimal keys I was using was wrong. I wrote a little bruteforce module and was able to decrypt small portions of it at a time. I concluded, therefore, that the keys I was using was wrong, but I grabbed them straight from the SWF.
Upon closer inspection, I noticed that there was a block of code to overwrite the URL to the include file. I was using the include file that's hard coded in to the SWF. It turns out that, on the game page there is the URL to the proper file:
Code:swf.addVariable('include_movie', 'games%2Fgaming_system%2Fnp6_include_v16.swf');
Code:eof=0&np=5,201&success=1&errcode=0&plays=1&sk=2d628cc3bc86bb49ce80&sh=ce3ba5694d224c9c4b82&call_external_function=score_callback&call_external_params=args%3D%5B%7B%22fn%22%3A%22setnp%22%2C%22args%22%3A%225%2C201%22%7D%5D
- 22 Apr. 2011 08:22pm #10
I think it's mostly luck that Gaia's games are done better.
Gaia's games were created by experienced programmers, I'm sure, but they built most of them with the "Sushi" server from RawFishSoftware. It's a terrible setup and extremely annoying. Various programmers added to the games over the years and it's resulted in some terrible code and some terrible patches. I've suggested to a developer I'm in contact with, from time to time, that he bring up the idea of open source towns. The result being that they could scrap Towns 2.0 and allow the users to submit changes for them to review and apply. This means they don't have to waste effort to patch unless server side junk is needed. The response I got was "I don't think Towns / Rallies will be open source, for two main reasons: a) it's a horrible body of code that should be taken out and shot; I'd hate to have it seen by the world at large as an example of our code. b) Any security changes which require a compliant client are inherently flawed."
While there are problems with client patches, 90% of their patches have been client side anyway. Realized I'm starting to rant. My bad. Okay, on to topic.
Right, I just want to express my interest at the challenge of a score sender. I did not expect it to be so complicated. It almost makes me want to get into Neopets, but you said this is a rare find. All the same, I thoroughly enjoyed reading through this thread.
- 22 Apr. 2011 08:38pm #11
That is quite interesting. Did you ask him why they don't just completely re-make it? It would most likely be better on so many levels plus it would most likely be more organized and easier to add patches/plugins when needed. I can understand it would take time to re-make something.
ON Topic: Didn't think you were going to put this in public Arti. You should try to make a gaia score sender for fishing.
- 22 Apr. 2011 09:40pm #12
They are working on a new version of Towns. My suggestion would have theoretically removed the need for it.
@Score sender for fishing, I don't believe that's possible.
From what I understand, though I haven't looked in years and I'm basing this on hearsay:
The grants are handled on the server side. You receive packets telling you what level of fish you have caught. e.g. trash, small, medium, large, rare. It may be more specific than that. I'm not sure. But you can "Filter" with fishing. Based on the pull of the fish on your pole, you can decide what the fish is and whether or not you want to let it go. A fishing tool would be fun. I could get behind a project like that. Preferably a text filled GUI rather than flash modification. I'm really kind of excited about the idea of doing that.
Games on Gaia don't have scores in that sense, as far as I know.
- 22 Apr. 2011 11:40pm #13
We have to remember that Gaia is a business, re-designing and re-coding the games would mean to invest a good amount of time and money on that... and they already got a working version that is possible to update and manage! From a business perspective, it'd be a waste of time to re-do all the work.
- 23 Apr. 2011 12:33am #14
- 23 Apr. 2011 02:52am #15
The actual fishing component of their Fishing Game is all for show. Even Terry's old Mulefarm simulated fishing (i.e. 2 minutes of casting, caught __x__, repeat x 20). The actual fact is, it isn't required. There are only two important stages:
1. Starting the game. Gaia Online returns a packet of available fish (i.e. [0, 9, 12, 48]). That would translate to 0 rare, 9 large, 12 medium, 48 small.
2. You send the final packet to the server with the fish in your bucket. It will error if: a) The fish you send weren't in the original list Gaia sent you (i.e. you try and send a rare without it being in the list of available fish), and b) You sent the packet in less than 120 seconds after that original packet (not sure if it's exactly 120 seconds, but it's close).
The amount of large fish decreases the longer you play and, contrary to popular belief amongst users, rares are actually random (though how random depends on what bait you're using). A grade = 1/10,000. Next best is 1/100,000 and it's impossible to catch a rare with F grade bade.
I've simplified this all a bit, because there's a lot of flags that detect whether or not your hacking and then log it, but provided we simulate it all properly, we could create a client that doesn't rely on the swf. Of course, because they use reCaptcha, it couldn't be 100% automatic. I think the best recaptcha OCRs I've seen only have a success rate of 10-30%. However, if you guys wanted trk on this project, I'd be happy to go along with it (the user would just have to input the captcha manually).
--
As for re-designing Towns, Riddle has a fair point. 99.99% of users would never look at the code. The only reason I can think for them re-writing from scratch is to either make the final product better for the end user, or to make future collaboration easier and hence more efficient. I've never really looked at Towns - I just thought it was a place for people to walk around and talk?
- 23 Apr. 2011 03:46am #16
Interesting. I'll definitely have to look into fishing and you now have me considering bots for Gaia. Is there any particular reason bots are so rare?
As for towns, it's all about show. Towns was the place to be for "scriptors," that is to say, kids using WPE, for years. Colored names, widespread vulnerabilities. Towns was like a playground for us. If not for towns, I wouldn't be a programmer. I would have never picked up WPE. I would have never met Lain and he would have never told me to pick up AutoIt. I would have never taken it past AutoIt.
It's a place for programmers to exploit, basically. It's that way for a large part of the community I used to know. Rally was the other place. The place where the rest were. Towns was considered the one that required skill and the one that got the patches. Rally was the rejects that couldn't touch towns. That was how we thought. "Towns Whores" and "Rally fags." We were arrogant, pretentious, and proud to be "better." The way it's so different from rally and a social hangout makes it perfect for this kind of thing.Last edited by Personoid; 23 Apr. 2011 at 03:57am.
- 23 Apr. 2011 04:06am #17
Quite interesting. I knew you and Lain were really active in towns, but personally I could never see the benefits, mainly because I thought it would be a waste of time. From the brief discussions I've had with Lain though, you were able to get in to people's accounts and whatnot? I've never been a fan of stealing, and taking accounts that don't belong to me, but each to their own :p
As for your first question; I mean really, you can create a client for any flash game that removes the dependency for the .swf file. At the heart of it, that's all the game is: you download it on to your computer, your flash player runs it, and it communicates to and fro with the server. There's absolutely no reason you can't recreate the client that mimics that communication without the .swf being there. The reason why there aren't more bots? Because it is comparatively a lot harder than your average Gaia Online program. A lot of the programmers on the sites are kids (LG programmers are exempt from this mini-rant because we're awesomecunts), and their ability extends as far as sending basic HTTP request and manipulating the .swf files. Because fishing doesn't rely solely on the HTTP protocol, they wouldn't have a clue what to do.
All this discussion on Gaia Fishing is really putting me in a mood to make a bot for it :p Next project?
- 23 Apr. 2011 04:11am #18yup this is really me gamersoul AVA
- 23 Apr. 2011 04:17am #19
There used to be an exploit in the past that meant that were possible, but alas, not any more. The best you could do these days is rapidly create new games until you detect a rare. Remembering it's a 1/10000 chance of having a rare in your pond with A grade bate, you would have to cycle through approximately 5,000 games before you receive one (you could receive one on the first game, but this is just simple math/statistics). A grade bait is 250g each: 5,000 * 250 = 1.25m on average. I'm not sure how much rares are worth, but they would have to be over 1.25m to turn a profit. Even then though, it would take one staff member to look at your fishing logs and it would be obvious you were cheating.
- 23 Apr. 2011 04:38am #20
Stealing Accounts: I didn't take accounts. I accessed accounts and used them to harvest information. I lived in the staff forums of Gaia for months. I left everything where I found it. I typically don't take accounts.
Rarity: I figured that was going to be your answer. That's unfortunate.
Fishing Bot: Yes. Do you have msn? I've got a few people interested, but they may prove to be liability rather than asset. I may be too, as far as that goes. How many people want in on this?
Edit: I'm thinking that having loads of people tagging along will prove to be a problem instead of a good thing. This also may not be something we want to make public. What do you think of a contest instead? Teams of 2-3 or even individuals debating about their projects (I want some sort of group going even if we aren't sharing code), and seeing who can write the best tool?Last edited by Personoid; 23 Apr. 2011 at 04:53am.
- 23 Apr. 2011 04:53am #21
artificial_xth [at] hotmail [dot] com
- 23 Apr. 2011 05:43am #22
Trailing off topic here. I started Scripting in Rally and in Towns, later on found LG, started programming, made a few un-released clients that didn't require flash for both towns and rally. Got bored.
On topic. I would like to help out in the flash-less fishing bot. I know it is still possible. I've sort of made one in the past but stopped working on it. I got it to join the game but that's as far as I went with fishing. I'll stop in every now and then.
- 24 Apr. 2011 09:33pm #23
If you guys want trk in teams, you better have a good working structure. I would suggest having a team leader design the application and create the abstract designs for the modules needed. He should make a preliminary documentation clearly stating function names and their input, purpose, and output. After that is done, each team member should be assigned trk on developing parts of those abstract models, and then finally tie it all together. As long as the purpose of each function is clear, then each programmer can call those functions even if they haven't been created yet.