darkbeast887 Posted April 28, 2012 Posted April 28, 2012 Im working on a personal project for some colleagues and myself that allows our Android emulators to trade pokemon. It works by uploading the saves to my private server. From there the server handles the trades. I've already managed to unscramble the GBA save blocks and unencrypt the pokemon data, so I can read all the pokemon data, but I can't figure out how the checksum is equated so the server can't trade our pokemon yet. I've come close by taking the sum of 0xF80 bytes of data and modulus that with 0xFFFF, however this gets me off by 0x40-0x140. If someone could please tell me how Pokemon GBA games calculate their block checksums, it would be very helpful. Thanks! P.S. I accientally posted this in the saves section at first thinking it was the right section. If someone could tell me how to delete it , I would appreciate it.
Kaphotics Posted April 29, 2012 Posted April 29, 2012 check out Enciclopedia Pokemon and PokeBoxGBA there's also psavfix http://pastebin.com/UTeQNjsx read also http://projectpokemon.org/forums/archive/index.php/t-15666.html
darkbeast887 Posted April 29, 2012 Author Posted April 29, 2012 Thank you for your quick reply. I have already checked out those links and LoadingNOW's PSavFix, but unfortunately Im not very skilled at coding in C, so its a little hard to read. Also, the first time I got that code, parts were missing so when I showed some people I know they couldn't make sense of it either. This completed version should help me. Again, thanks for your help!
PedroLima Posted August 21, 2012 Posted August 21, 2012 darkbeast887 did you made that program? to be honest I want to do the same but i'm a little lazy jaja, so maybe you can share your code with me, or maybe give me some helps. In your program is necessary to upload the save, the android device can't do that?? sorry for my bad english i'm a spanish speaker
darkbeast887 Posted August 24, 2012 Author Posted August 24, 2012 If you know some C then you can take loadingNOW's PSavFix code and adapt it to suit your needs. The code can be found at http://projectpokemon.org/forums/showthread.php?15666-Some-questions-about-save-files In the end, I decided to change course and made a personal online Pokemon GBA stat checker which someone can upload their save to and check all the stats of their pokemon. It was a lot easier than transfering my save from my android to my computer and running it through other programs. The site allows me to download other people's uploaded pokemon also. However, I am now making a shell script for Linux based machines (including android) that trades pokemon. It's not as polished as an app, but it's written to be run on pretty much any linux machine. If you don't know C or are having troubles understanding the checksum, then I might be able to help you depending on what you are coding your program in. Good luck.
PedroLima Posted August 25, 2012 Posted August 25, 2012 oh your idea of making 3th gen trade in andorid is what i was looking for. My first idea was that but i didn't know how i can do it but if you can please let me notice, i understand c (some parts but with your help i sure that i will do it). do you want to do an emulator or how will you trade pokemons? i want and hope your script will be quickly. thanks for everything!!!
PedroLima Posted August 25, 2012 Posted August 25, 2012 a little question more can you pass me the offset of the things in the save? like the ID OT Name, secret ID, party begin and end, and the others things please
darkbeast887 Posted August 27, 2012 Author Posted August 27, 2012 Here is my script to trade Pokemon with the android phones. It's pretty primitive and written in bash. Just a few notes about it: The android terminal can't handle many of the same things that other terminals can handle, such as arrays. Because of this, the script had to be written a bit more inefficient than what it could have been. However, a plus to this is that it is fairly portable, meaning that you can run this script on many other linux machines, such as latptops or computers. Also, to make rebuilding the save more efficient, it creates 32 seperate files of the GBA save's 32 blocks. It does it's best to remove these at the end of the script, but I've noticed that it doesn't work on all machines. To use this script you need to have a rooted android, busybox installed, and an Android terminal emulator installed. Save the script as something like PokemonTrade.sh Usage: sh PokemonTrade.sh [save file location] [kanto or hoenn] After you start the script, your six party pokemon will be shown to you; select one. Next, you will be asked if you want to be a server or a client; choose one and have your friend choose the opposite. The client should type the server's ip into their terminal. Both people should choose 'yes' when asked if they want to trade their pokemon for their offered pokemon. Finally, the script rebuilds the GBA save file, calculates the new checksum, and writes the new save to replace the old one. Now realize that I haven't really tested this script on many different machines, and there are most likely a few bugs in it. It also uses netcat as it's server and client which certain schools and businesses don't like you to use if you are on their wifi, so be aware. Also, because of the way the server and client communicate, if either the server or the client starts acting strange, just close both terminals running, on any droid run task killer, then try again. The server is inefficient and doesn't do a good job. Standard disclaimers apply: I'm not responsible for how you use this script or any trouble that you and this script get in to. I'm posting this on here for educational purposes to hopefully help others who would like to understand the GBA save structure. PokemonTrade.sh: #! /bin/bash if [ -z "${1+xxx}" ] || [ -f $1 ]; then if [ $2 != "kanto" ] && [ $2 != "hoenn" ]; then echo "Usage: $0 [save location] [region] Error: Invalid region (ie. kanto or hoenn)" else $(cp $1 $1.bak) clear letterconv(){ alphabet=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz echo $(echo $alphabet | cut -c $(expr $1 + 1)) } hexdec(){ printf "%d" "0x"$1 } dechex(){ printf "%X" $1 } bindec(){ ans="0" p="1" binary=$(echo $1 | sed -e :a -e 's/^.\{1,31\}$/0&/;ta') while [ $p -le "32" ] do binnum=$(echo $binary | cut -c $p) ans=$(($(($ans*2))+$binnum)) p=$(($p+1)) done echo $ans } hexbin(){ binArray=0000000100100011010001010110011110001001101010111100110111101111 hex=$1 p=1 bin="" while [ $p -le $(expr length $1) ] do hex2bin=$(hexdec $(echo $hex | cut -c $p)) bin=$bin$(echo $binArray | cut -c $(($(($hex2bin*4))+1))-$(($(($hex2bin*4))+4))) p=$(($p+1)) done echo $bin } xorEnc(){ keyStr=$(hexbin $1) stringStr=$(hexbin $2) enc="" o="1" while [ $o -le 32 ] do if [ $(echo $keyStr | cut -c $(($o))) -eq $(echo $stringStr | cut -c $(($o))) ]; then enc=$enc"0" else enc=$enc"1" fi o=$(($o+1)) done echo $(echo $(echo $(dechex $(bindec $enc)) | sed -e :a -e 's/^.\{1,15\}$/0&/;ta') | cut -c 9-16) } blockFind(){ if [ $2 -eq "1" ]; then if [ $1 -eq "1" ]; then partyBlock=$3 fi if [ $1 -eq "0" ]; then partyBlock=$((1+$3)) fi if [ $1 -ge "2" ]; then partyBlock=$((15-$1+$3)) fi fi if [ $2 -eq "0" ]; then if [ $1 -eq "0" ]; then partyBlock=$3 fi if [ $1 -gt "0" ]; then partyBlock=$((14-$1+$3)) fi fi if [ $2 -gt "1" ]; then if [ $1 -eq $2 ]; then partyBlock=$3 fi if [ $1 -ge $(($2+1)) ]; then partyBlock=$((14+$2-$1+$3)) fi if [ $1 -lt $(($2-1)) ]; then partyBlock=$(($2-$1+$3)) fi fi echo $partyBlock } dataForm(){ mod=$(expr $1 % 24) fromArray="GAEMGAMEGEAMGEMAGMAEGMEAAGEMAGMEAEGMAEMGAMGEAMEGEGAMEGMAEAGMEAMGEMGAEMAGMGAEMGEAMAGEMAEGMEGAMEAG" form=$(echo $fromArray | cut -c $(($(($mod*4))+1))-$(($(($mod*4))+4))) if [ $(echo $form | cut -c 1) = $2 ]; then growth=$(($3+32)) elif [ $(echo $form | cut -c 2) = $2 ]; then growth=$(($3+44)) elif [ $(echo $form | cut -c 3) = $2 ]; then growth=$(($3+56)) elif [ $(echo $form | cut -c 4) = $2 ]; then growth=$(($3+68)) fi echo $growth } pokeName(){ pokeNameArray="None----------------Bulbasaur-----------Ivysaur-------------Venusaur------------Charmander----------Charmeleon----------Charizard-----------Squirtle------------Wartortle-----------Blastoise-----------Caterpie------------Metapod-------------Butterfree----------Weedle--------------Kakuna--------------Beedrill------------Pidgey--------------Pidgeotto-----------Pidgeot-------------Rattata-------------Raticate------------Spearow-------------Fearow--------------Ekans---------------Arbok---------------Pikachu-------------Raichu--------------Sandshrew-----------Sandslash-----------NidoranF------------Nidorina------------Nidoqueen-----------NidoranM------------Nidorino------------Nidoking------------Clefairy------------Clefable------------Vulpix--------------Ninetales-----------Jigglypuff----------Wigglytuff----------Zubat---------------Golbat--------------Oddish--------------Gloom---------------Vileplume-----------Paras---------------Parasect------------Venonat-------------Venomoth------------Diglett-------------Dugtrio-------------Meowth--------------Persian-------------Psyduck-------------Golduck-------------Mankey--------------Primeape------------Growlithe-----------Arcanine------------Poliwag-------------Poliwhirl-----------Poliwrath-----------Abra----------------Kadabra-------------Alakazam------------Machop--------------Machoke-------------Machamp-------------Bellsprout----------Weepinbell----------Victreebel----------Tentacool-----------Tentacruel----------Geodude-------------Graveler------------Golem---------------Pnyta---------------Rapidash------------Slowpoke------------Slowbro-------------Magnemite-----------Magneton------------Farfetchd-----------Doduo---------------Dodrio--------------Seel----------------Dewgong-------------Grimer--------------Muk-----------------Shellder------------cloyster------------Gastly--------------Haunter-------------Gengar--------------Onix----------------Drowzee-------------Hypno---------------Krabby--------------Kingler-------------Voltorb-------------Electrode-----------Exeggcute-----------Exeggutor-----------Cubone--------------Marowak-------------Hitmonlee-----------Hitmonchan----------Lickitung-----------Koffing-------------Weezing-------------Rhyhorn-------------Rhydon--------------Chansey-------------Tangela-------------Kangaskhan----------Horsea--------------Seadra--------------Goldeen-------------Seaking-------------Staryu--------------Starmie-------------Mr.Mime-------------Scyther-------------Jynx----------------Electabuzz----------Magmar--------------Pinsir--------------Tauros--------------Magikarp------------Gyarados------------Lapras--------------Ditto---------------Eevee---------------Vaporeon------------Jolteon-------------Flareon-------------Porygon-------------Omanyte-------------Omastar-------------Kabuto--------------Kabutops------------Aerodactyl----------Snorlax-------------Articuno------------Zapdos--------------Moltres-------------Dratini-------------Dragonair-----------Dragonite-----------Mewtwo--------------Mew-----------------Chikorita-----------Bayleef-------------Meganium------------cyndaquil-----------Quilava-------------Typhlosion----------Totodile------------Croconaw------------Feraligatr----------Sentret-------------Furret--------------Hoothoot------------Noctowl-------------Ledyba--------------Ledian--------------Spinarak------------Ariados-------------Crobat--------------Chinchou------------Lanturn-------------Pichu---------------Cleffa--------------Igglybuff-----------Togepi--------------Togetic-------------Natu----------------Xatu----------------Mareep--------------Flaaffy-------------Ampharos------------Bellossom-----------Marill--------------Azumarill-----------Sudowoodo-----------Politoed------------Hoppip--------------Skiploom------------Jumpluff------------Aipom---------------Sunkern-------------Sunflora------------Yanma---------------Wooper--------------Quagsire------------Espeon--------------Umbreon-------------Murkrow-------------Slowking------------Misdreavus----------Unown-A-------------Wobbuffet-----------Girafarig-----------Pineco--------------Forretress----------Dunsparce-----------Gligar--------------Steelix-------------Snubbull------------Granbull------------Qwilfish------------Scizor--------------Shuckle-------------Heracross-----------Sneasel-------------Teddiursa-----------Ursaring------------Slugma--------------Magcargo------------Swinub--------------Piloswine-----------Corsola-------------Remoraid------------Octillery-----------Delibird------------Mantine-------------Skarmory------------Houndour------------Houndoom------------Kingdra-------------Phanpy--------------Donphan-------------Porygon2------------Stantler------------Smeargle------------Tyrogue-------------Hitmontop-----------Smoochum------------Elekid--------------Magby---------------Miltank-------------Blissey-------------Raikou--------------Entei---------------Suicune-------------Larvitar------------Pupitar-------------Tyranitar-----------Lugia---------------Ho-Oh---------------Celebi--------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------?-------------------Treecko-------------Grovyle-------------Sceptile------------Torchic-------------Combusken-----------Blaziken------------Mudkip--------------Marshtomp-----------Swampert------------Poochyena-----------Mightyena-----------Zigzagoon-----------Linoone-------------Wurmple-------------Silcoon-------------Beautifly-----------Cascoon-------------Dustox--------------Lotad---------------Lombre--------------Ludicolo------------Seedot--------------Nuzleaf-------------Shiftry-------------Nincada-------------Ninjask-------------Shedinja------------Taillow-------------Swellow-------------Shroomish-----------Breloom-------------Spinda--------------Wingull-------------Pelipper------------Surskit-------------Masquerain----------Wailmer-------------Wailord-------------Skitty--------------Delcatty------------Kecleon-------------Baltoy--------------Claydol-------------Nosepass------------Torkoal-------------Sableye-------------Barboach------------Whiscash------------Luvdisc-------------Corphish------------Crawdaunt-----------Feebas--------------Milotic-------------Carvanha------------Sharpedo------------Trapinch------------Vibrava-------------Flygon--------------Makuhita------------Hariyama------------Electrike-----------Manectric-----------Numel---------------Camerupt------------Spheal--------------Sealeo--------------Walrein-------------Cacnea--------------Cacturne------------Snorunt-------------Glalie--------------Lunatone------------Solrock-------------Azurill-------------Spoink--------------Grumpig-------------Plusle--------------Minun---------------Mawile--------------Meditite------------Medicham------------Swablu--------------Altaria-------------Wynaut--------------Duskull-------------Dusclops------------Roselia-------------Slakoth-------------Vigoroth------------Slaking-------------Gulpin--------------Swalot--------------Tropius-------------Whismur-------------Loudred-------------Exploud-------------Clamperl------------Huntail-------------Gorebyss------------Absol---------------Shuppet-------------Banette-------------Seviper-------------Zangoose------------Relicanth-----------Aron----------------Lairon--------------Aggron--------------Castform------------Volbeat-------------Illumise------------Lileep--------------Cradily-------------Anorith-------------Armaldo-------------Ralts---------------Kirlia--------------Gardevoir-----------Bagon---------------Shelgon-------------Salamence-----------Beldum--------------Metang--------------Metagross-----------Regirock------------Regice--------------Registeel-----------Kyogre--------------Groudon-------------Rayquaza------------Latias--------------Latios--------------Jirachi-------------Deoxys--------------Chimecho------------Egg-----------------Unown-B-------------Unown-C-------------Unown-D-------------Unown-E-------------Unown-F-------------Unown-G-------------Unown-H-------------Unown-I-------------Unown-J-------------Unown-K-------------Unown-L-------------Unown-M-------------Unown-N-------------Unown-O-------------Unown-P-------------Unown-Q-------------Unown-R-------------Unown-S-------------Unown-T-------------Unown-U-------------Unown-V-------------Unown-W-------------Unown-X-------------Unown-Y-------------Unown-Z-------------Unown-EM------------Unown-QM------------" species=$(echo $pokeNameArray | cut -c $(($(($1*20))+1))-$(($(($1*20))+20))) echo $species } Chksum() { i=0 Chk=0 while [ $i -lt 3968 ] do dataNum=$(hexdec $(echo $1 | cut -c $(($(($i*2))+7))-$(($(($i*2))+8)))$(echo $1 | cut -c $(($(($i*2))+5))-$(($(($i*2))+6)))$(echo $1 | cut -c $(($(($i*2))+3))-$(($(($i*2))+4)))$(echo $1 | cut -c $(($(($i*2))+1))-$(($(($i*2))+2)))) Chk=$(expr $Chk + $dataNum) i=$(($i+4)) done hexChk=$(dechex $Chk) tmp=$(hexdec $(echo $hexChk | cut -c 1-$(($(expr length $hexChk)-4)))) tmp=$(dechex $(expr $tmp + $Chk)) Chk=$(echo $tmp | cut -c $(($(expr length $tmp)-3))-$(expr length $tmp)) echo $(echo $Chk | cut -c 3-4)$(echo $Chk | cut -c 1-2) } hex=$(hexdump -ve '1/1 "%.2X"' $1) snum=$(echo $hex | cut -c 8185-8186) snum2=$(echo $hex | cut -c 122873-122874) saveNum=$(hexdec $snum) saveNum2=$(hexdec $snum2) if [ $saveNum -ge $saveNum2 ]; then extra="0" hex1=$(echo $hex | cut -c 8169-8170) $(split -b 4096 $1 PokeSave) else extra="14" hex1=$(echo $hex | cut -c 122857-122858) $(split -b 4096 $1 PokeSave) fi hexVar=$(hexdec $hex1) partyBlock=$(blockFind $hexVar 1 $extra) if [ $2 = "kanto" ]; then more="038" else more="238" fi partyStart=$(hexdec $(dechex $partyBlock)$more) partyStartHex=$(dechex $partyBlock)$more pokeNum1=$(($(($partyStart))*2)) poke1=$(echo $hex | cut -c $(($pokeNum1+1))-$(($pokeNum1+200))) pokeNum2=$(($(($partyStart+100))*2)) poke2=$(echo $hex | cut -c $(($pokeNum2+1))-$(($pokeNum2+200))) pokeNum3=$(($(($partyStart+200))*2)) poke3=$(echo $hex | cut -c $(($pokeNum3+1))-$(($pokeNum3+200))) pokeNum4=$(($(($partyStart+300))*2)) poke4=$(echo $hex | cut -c $(($pokeNum4+1))-$(($pokeNum4+200))) pokeNum5=$(($(($partyStart+400))*2)) poke5=$(echo $hex | cut -c $(($pokeNum5+1))-$(($pokeNum5+200))) pokeNum6=$(($(($partyStart+500))*2)) poke6=$(echo $hex | cut -c $(($pokeNum6+1))-$(($pokeNum6+200))) pidHex1=$(echo $poke1 | cut -c 7-8)$(echo $poke1 | cut -c 5-6)$(echo $poke1 | cut -c 3-4)$(echo $poke1 | cut -c 1-2) pid1=$(hexdec $pidHex1) pid2=$(hexdec $(echo $poke2 | cut -c 7-8)$(echo $poke2 | cut -c 5-6)$(echo $poke2 | cut -c 3-4)$(echo $poke2 | cut -c 1-2)) pid3=$(hexdec $(echo $poke3 | cut -c 7-8)$(echo $poke3 | cut -c 5-6)$(echo $poke3 | cut -c 3-4)$(echo $poke3 | cut -c 1-2)) pid4=$(hexdec $(echo $poke4 | cut -c 7-8)$(echo $poke4 | cut -c 5-6)$(echo $poke4 | cut -c 3-4)$(echo $poke4 | cut -c 1-2)) pid5=$(hexdec $(echo $poke5 | cut -c 7-8)$(echo $poke5 | cut -c 5-6)$(echo $poke5 | cut -c 3-4)$(echo $poke5 | cut -c 1-2)) pid6=$(hexdec $(echo $poke6 | cut -c 7-8)$(echo $poke6 | cut -c 5-6)$(echo $poke6 | cut -c 3-4)$(echo $poke6 | cut -c 1-2)) g1=$(dataForm $pid1 "G" "0") g2=$(dataForm $pid2 "G" "0") g3=$(dataForm $pid3 "G" "0") g4=$(dataForm $pid4 "G" "0") g5=$(dataForm $pid5 "G" "0") g6=$(dataForm $pid6 "G" "0") #First Pokemon's Things RevPID1=$(echo $poke1 | cut -c 1-8) OTID1=$(echo $poke1 | cut -c 9-16) key1=$(xorEnc $RevPID1 $OTID1) growthStr1=$(echo $(xorEnc $key1 $(echo $poke1 | cut -c $(($(($g1*2))+1))-$(($(($g1*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec1=$(hexdec $(echo $growthStr1 | cut -c 3-4)$(echo $growthStr1 | cut -c 1-2)) #Second Pokemon's Things RevPID2=$(echo $poke2 | cut -c 1-8) OTID2=$(echo $poke2 | cut -c 9-16) key2=$(xorEnc $RevPID2 $OTID2) growthStr2=$(echo $(xorEnc $key2 $(echo $poke2 | cut -c $(($(($g2*2))+1))-$(($(($g2*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec2=$(hexdec $(echo $growthStr2 | cut -c 3-4)$(echo $growthStr2 | cut -c 1-2)) #Third Pokemon's Things RevPID3=$(echo $poke3 | cut -c 1-8) OTID3=$(echo $poke3 | cut -c 9-16) key3=$(xorEnc $RevPID3 $OTID3) growthStr3=$(echo $(xorEnc $key3 $(echo $poke3 | cut -c $(($(($g3*2))+1))-$(($(($g3*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec3=$(hexdec $(echo $growthStr3 | cut -c 3-4)$(echo $growthStr3 | cut -c 1-2)) #Fourth Pokemon's Things RevPID4=$(echo $poke4 | cut -c 1-8) OTID4=$(echo $poke4 | cut -c 9-16) key4=$(xorEnc $RevPID4 $OTID4) growthStr4=$(echo $(xorEnc $key4 $(echo $poke4 | cut -c $(($(($g4*2))+1))-$(($(($g4*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec4=$(hexdec $(echo $growthStr4 | cut -c 3-4)$(echo $growthStr4 | cut -c 1-2)) #Five Pokemon's Things RevPID5=$(echo $poke5 | cut -c 1-8) OTID5=$(echo $poke5 | cut -c 9-16) key5=$(xorEnc $RevPID5 $OTID5) growthStr5=$(echo $(xorEnc $key5 $(echo $poke5 | cut -c $(($(($g5*2))+1))-$(($(($g5*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec5=$(hexdec $(echo $growthStr5 | cut -c 3-4)$(echo $growthStr5 | cut -c 1-2)) #Sixth Pokemon's Things RevPID6=$(echo $poke6 | cut -c 1-8) OTID6=$(echo $poke6 | cut -c 9-16) key6=$(xorEnc $RevPID6 $OTID6) growthStr6=$(echo $(xorEnc $key6 $(echo $poke6 | cut -c $(($(($g6*2))+1))-$(($(($g6*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDec6=$(hexdec $(echo $growthStr6 | cut -c 3-4)$(echo $growthStr6 | cut -c 1-2)) clear pokeName1=$(echo $(pokeName $speciesDec1) | tr -d '-') pokeName2=$(echo $(pokeName $speciesDec2) | tr -d '-') pokeName3=$(echo $(pokeName $speciesDec3) | tr -d '-') pokeName4=$(echo $(pokeName $speciesDec4) | tr -d '-') pokeName5=$(echo $(pokeName $speciesDec5) | tr -d '-') pokeName6=$(echo $(pokeName $speciesDec6) | tr -d '-') specdec1=$(echo $speciesDec1 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') specdec2=$(echo $speciesDec2 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') specdec3=$(echo $speciesDec3 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') specdec4=$(echo $speciesDec4 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') specdec5=$(echo $speciesDec5 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') specdec6=$(echo $speciesDec6 | sed -e :a -e 's/^.\{1,2\}$/0&/;ta') echo " Pick the pokemon you want to trade: 1) $pokeName1 2) $pokeName2 3) $pokeName3 4) $pokeName4 5) $pokeName5 6) $pokeName6" read pokeChoice if [ $pokeChoice != 1 ] && [ $pokeChoice != 2 ] && [ $pokeChoice != 3 ] && [ $pokeChoice != 4 ] && [ $pokeChoice != 5 ] && [ $pokeChoice != 6 ]; then echo "Not a valid number" else if [ $pokeChoice -eq 1 ]; then pokeGive=$pokeName1 pokeGiveHex=$poke1 elif [ $pokeChoice -eq 2 ]; then pokeGive=$pokeName2 pokeGiveHex=$poke2 elif [ $pokeChoice -eq 3 ]; then pokeGive=$pokeName3 pokeGiveHex=$poke3 elif [ $pokeChoice -eq 4 ]; then pokeGive=$pokeName4 pokeGiveHex=$poke4 elif [ $pokeChoice -eq 5 ]; then pokeGive=$pokeName5 pokeGiveHex=$poke5 elif [ $pokeChoice -eq 6 ]; then pokeGive=$pokeName6 pokeGiveHex=$poke6 fi code="" rm pokeTrade.pkm for byte in $(echo $pokeGiveHex | sed 's/../& /g') do code=$code$(printf "\x$byte" >>pokeTrade.pkm) done clear $(echo $pokeGive | cat > pokeTrade.txt) echo "You chose to trade $pokeGive One person needs to be a Server, the other needs to be the client. Which do you wish to be? 1) Server 2) Client" read serverChoice if [ $(uname -m | cut -c 1-3) = "arm" ]; then port=" -p" else port="" fi if [ $serverChoice != 1 ] && [ $serverChoice != 2 ]; then echo "Not a valid choice!" else if [ $serverChoice -eq 1 ]; then echo "Started the server. Type the ip address "$(ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')" into the client" $(nc -l$port 8765 > pokeGet.txt) echo "Looking at trade" $(nc -l$port 8765 < pokeTrade.txt) clear echo "Your friend wants to trade you a "$(cat pokeGet.txt) $(nc -l$port 8765 > pokeGet.pkm) $(nc -l$port 8765 < pokeTrade.pkm) echo "Accept Trade? y/n" read yesno if [ $yesno = "n" ]; then word="Kept" $(cp pokeTrade.pkm pokeGet.pkm) else word="Got" fi else echo "You are the client! Type the ip address of the server:" read serverIP $(nc -w 10 $serverIP 8765 < pokeTrade.txt) echo "Looking at trade" $(nc $serverIP 8765 > pokeGet.txt) clear echo "Your friend wants to trade you a "$(cat pokeGet.txt) echo "Accept Trade? y/n" read yesno if [ $yesno = "y" ]; then word="Got" $(nc -w 10 $serverIP 8765 < pokeTrade.pkm) $(nc $serverIP 8765 > pokeGet.pkm) else word="Kept" $(cp pokeTrade.pkm pokeGet.pkm) fi fi fi pokeGetHex=$(hexdump -ve '1/1 "%.2X"' "pokeGet.pkm") pidGet=$(hexdec $(echo $pokeGetHex | cut -c 7-8)$(echo $pokeGetHex | cut -c 5-6)$(echo $pokeGetHex | cut -c 3-4)$(echo $pokeGetHex | cut -c 1-2)) gGet=$(dataForm $pidGet "G" "0") RevPIDGet=$(echo $pokeGetHex | cut -c 1-8) OTIDGet=$(echo $pokeGetHex | cut -c 9-16) keyGet=$(xorEnc $RevPIDGet $OTIDGet) growthStrGet=$(echo $(xorEnc $keyGet $(echo $pokeGetHex | cut -c $(($(($gGet*2))+1))-$(($(($gGet*2))+8)))) | sed -e :a -e 's/^.\{1,7\}$/0&/;ta') speciesDecGet=$(hexdec $(echo $growthStrGet | cut -c 3-4)$(echo $growthStrGet | cut -c 1-2)) pokeNameGet=$(echo $(pokeName $speciesDecGet) | tr -d '-') clear echo "$word a $pokeNameGet!" if [ $pokeChoice -eq 1 ]; then party=$poke2$poke3$poke4$poke5$poke6$pokeGetHex elif [ $pokeChoice -eq 2 ]; then party=$poke1$poke3$poke4$poke5$poke6$pokeGetHex elif [ $pokeChoice -eq 3 ]; then party=$poke1$poke2$poke4$poke5$poke6$pokeGetHex elif [ $pokeChoice -eq 4 ]; then party=$poke1$poke2$poke3$poke5$poke6$pokeGetHex elif [ $pokeChoice -eq 5 ]; then party=$poke1$poke2$poke3$poke4$poke6$pokeGetHex elif [ $pokeChoice -eq 6 ]; then party=$poke1$poke2$poke3$poke4$poke5$pokeGetHex fi echo "Adding pokemon to save" partyBlockStart=$(($(($(hexdec $partyBlock"000")*2))+1)) partyStartPos=$(($(($partyStart*2)))) partyEnd=$(($(($partyStart*2))+1201)) partyBlockStop=$(($(($(hexdec $partyBlock"FFF")*2))+2)) partyBlockHex=$(echo $hex | cut -c $partyBlockStart-$partyStartPos)$party$(echo $hex | cut -c $partyEnd-$partyBlockStop) $(echo $partyBlockHex | cat > partyBlockHex.txt) echo "Calculating new checksum" checksum=$(Chksum $partyBlockHex) echo "New checksum = $checksum!" partyBlockFinal=$(echo $partyBlockHex | cut -c 1-8172)$checksum$(echo $partyBlockHex | cut -c 8177-8200) echo "Compiling new save" for byte in $(echo $partyBlockFinal | sed 's/../& /g') do $(printf "\x$byte" >>partyBlock.sav.part) done $(echo $(echo $partyBlockFinal | sed 's/../& /g') | cat > partyBlockFinal.txt) echo "Writing new save" $(rm $1) i=0 while [ $i -lt 26 ] do if [ $i -eq $partyBlock ]; then $(cat partyBlock.sav.part >>$1) else $(cat PokeSavea$(letterconv $i) >>$1) fi i=$(expr $i + 1) done while [ $i -lt 32 ] do if [ $i -eq $partyBlock ]; then $(cat partyBlock.sav.part >>$1) else $(cat PokeSaveb$(letterconv $i) >>$1) fi i=$(expr $i + 1) done i=0 while [ $i -lt 26 ] do $(rm PokeSavea$(letterconv $i)) i=$(expr $i + 1) done while [ $i -lt 32 ] do $(rm PokeSaveb$(letterconv $i)) i=$(expr $i + 1) done $(rm partyBlock.sav.part) $(rm pokeGet.txt) $(rm pokeTrade.txt) $(rm pokeGet.pkm) $(rm pokeTrade.pkm) echo "Done!" fi fi else echo "Usage: $0 [save location] [region] Error: No such File" fi This couldn't have been done without LoadingNOW's PSavFix or Bulbapedia. I've only written this script during my free time in the past few days, so if anyone could improve on this, please do. I've done a couple projects involving the GBA save structure, so if you need any help with it, just ask, and I may be able to help!
PedroLima Posted August 27, 2012 Posted August 27, 2012 you are the best i'm going to check it if it works in my droid (xperia 10 mini pro) i'm gonna learn bash and if i have some free time i will make a apk, one more question i need a access point to trade the pokemon, i gess that is only needed 2 phones and that's it
darkbeast887 Posted August 27, 2012 Author Posted August 27, 2012 If you're just looking to test and debug the program, then you can open up two terminals on a linux distribution of some sort (ubuntu, fedora, debian, etc.) and run both the server and client on one machine. However, if you do this, make sure that the two saves that you are trading are in two separate folders. The bash script should have all you need to know as far as basic offsets and decryption of Pokemon files go, but if you need more help then I'll be glad to pass along information.
PedroLima Posted August 28, 2012 Posted August 28, 2012 thanks if i have some more questions i will let you know, but for now can you give the name of a program that can run your script line by line in order to understand better how it works? thanks again
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now