Jump to content

darkbeast887

Member
  • Posts

    7
  • Joined

  • Last visited

Posts posted by darkbeast887

  1. 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.

  2. 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!

  3. 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.

  4. I don't know if you're still looking to do this, but I have designed a personal website for myself that acts as a pokecheck website for 3rd generation pokemon.

    I understand how the GBA saves work, and have programmed my site to tell me just about every single part of a 3rd generation's party pokemon's details and stats. All I need to do is upload any 3rd generation save file (the version doesn't matter), and all the stats will be recorded.

    I don't know very much about 4th and 5th generation pokemon, but if someone had the ability to take my site's recorded information such as species, attacks, held item, etc., and create a 4th or 5th generation .pkm from that information, then we could create a website that could convert 3rd gen pokemon to 4th or 5th generation!

    The only problem is...I don't know how many people actually have the ability to create a web program that creates 4th or 5th gen pokemon. Even if I did, I'm new to the forums and wouldn't know how to contact them.

    There may be a way to pass my site's information to pokegts.us...however that seems somewhat unefficient, and I would rather have someone help with rebuilding a 4th gen file. Although, the idea of passing the information onto pokegts.us is plausable!

    I'm not saying that I will do this (or even release my site publicly), but if I could get some help, it sounds like a pretty intruiging idea. This would solve many people's problems of converting mass 3rd gen pokemon to 4th and 5th gens!

  5. 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!

  6. 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.

  7. Hey,

    Im working on a personal project for my colleagues and myself that allows us to trade pokemon between our emulators via my third party app.

    The app works by uploading the save to my private server. From there my server handles the trades.

    Right now the server can unscramble the GBA save blocks and unencrypt the pokemon data, but I can't figure out how the checksum for GBA saves work. I've done much research but cant seem to find how the checksum is equated.

    The closest I've gotten is adding 0xF80 bytes of a block together, then modulus that with 0xFFFF. This generally gets me about 0x40-0x150 bytes off of the actual checksum.

    Does anyone have any idea how the checksum equation works? Once I get this down my server will be able to exchange the pokemon and recalculate the checksums of my colleagues and my saves.

    Thank you very much for any help!

×
×
  • Create New...