mm201 / pkmn-classic-framework

Pokémon application logic for Generation IV and V, including servers
http://pkmnclassic.net/
Other
219 stars 43 forks source link

Implement Game Sync #8

Open mm201 opened 10 years ago

mm201 commented 10 years ago

@polaris- already did some amazing work reverse engineering this; I should be able to do the rest myself.

Note that I have no plans of replicating the original dream world, since that would be a major violation of copyright.

zurgeg commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values.

I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.)

image image

I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

Ooh! We would definitely love to know how savedata.download works. Currently, we're stuck on Pokemon data. All it gives us is a Blaziken, and I've been stuck trying to bruteforce due to GS's cool down.

If you need help with RT Debugging, use No$GBA.

kuroppoi commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values. I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.) image image I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

Ooh! We would definitely love to know how savedata.download works. Currently, we're stuck on Pokemon data. All it gives us is a Blaziken, and I've been stuck trying to bruteforce due to GS's cool down.

If you need help with RT Debugging, use No$GBA.

Hi! I've tinkered with No$GBA before, but I was unable to get WiFi to work on it. I currently use MelonDS and use save states to skip the whole Game Sync recharge thing. As for savedata.download; The Pokémon data that I currently send starts at index 0x84 (132) in the response packet, is 10 entries long and each entry contains 8 bytes of data. The entry data format is as follows:

0x00 - 2 bytes - Species/Dex Number
0x02 - 2 bytes - Move ID, matches with numbers here: https://bulbapedia.bulbagarden.net/wiki/List_of_moves
0x04 - 1 byte  - Unknown
0x05 - 1 byte  - Unknown
0x06 - 1 byte  - Animation
0x07 - 1 byte  - Unknown

Here is how I currently write the Pokémon data to the response buffer:

// 10 entries starting at index 132 and incrementing by 8 with each subsequent entry
for(int i = 0; i < 10; i++) {
    // Currently #1 aka Bulbasaur
    response[i * 8 + 132] = 1; // 0x00 - 2 bytes - Species/Dex Number
    response[i * 8 + 133] = 0; // ^

    // Currently #1 aka Pound
    response[i * 8 + 134] = 1; // 0x02 - 2 bytes - Move ID
    response[i * 8 + 135] = 0; // ^

    response[i * 8 + 136] = 0  // 0x04 - 1 byte  - Unknown
    response[i * 8 + 137] = 0; // 0x05 - 1 byte  - Unknown

    response[i * 8 + 138] = 5; // 0x06 - 1 byte  - Animation
    response[i * 8 + 139] = 0; // 0x07 - 1 byte  - Unknown
}

I'm currently trying to figure out how to make the Pokémon appear in different parts of the forest. Hope this helps!

zurgeg commented 1 year ago

Ahh, I figured out why it wasn't working. I forgot to catch my Blazikens I've been holding hostage keeping in the entree.

kuroppoi commented 1 year ago

image Items work a little interestingly; starting at index 0xDC (220), up to 20 item IDs (2 bytes) may be sent. Then, starting at index 0x104 (260) the item amounts are sent (1 byte) in respective order.

// Items obtained
// First, starting at index 220, send up to 20 item IDs.
for(int i = 0; i < 20; i++) {
    // This will send items Water Stone through Old Amber
    response[i * 2 + 220] = i + 84; // Item ID
    response[i * 2 + 221] = 0;
}

// Then, starting at index 260, send the item counts in the same order.
for(int i = 0; i < 20; i++) {
    response[i * 1 + 260] = i + 1) // Item Count
}
zurgeg commented 1 year ago

image Items work a little interestingly; starting at index 0xDC (220), up to 20 item IDs (2 bytes) may be sent. Then, starting at index 0x104 (260) the item amounts are sent (1 byte) in respective order.

// Items obtained
// First, starting at index 220, send up to 20 item IDs.
for(int i = 0; i < 20; i++) {
    // This will send items Water Stone through Old Amber
    response[i * 2 + 220] = i + 84; // Item ID
    response[i * 2 + 221] = 0;
}

// Then, starting at index 260, send the item counts in the same order.
for(int i = 0; i < 20; i++) {
    response[i * 1 + 260] = i + 1) // Item Count
}

Yep, that's what we found too

Pyrochrome commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values.

I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.)

image image

I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

You wouldn't mind opening your own repo for this, would you? I'm curious about replicating the same thing on my own computer.

kuroppoi commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values. I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.) image image I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

You wouldn't mind opening your own repo for this, would you? I'm curious about replicating the same thing on my own computer.

If nobody beats me to it, I might make a simple open-source tool that allows you to download any Pokémon, item and (custom) C-Gear/Pokédex skin you want.

mm201 commented 1 year ago

I would be delighted to take a pull request that gets Game Sync working! If you want to talk more, you should hop on Discord. There should be a current link on https://pkmnclassic.net/

zurgeg commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values. I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.) image image I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

You wouldn't mind opening your own repo for this, would you? I'm curious about replicating the same thing on my own computer.

If nobody beats me to it, I might make a simple open-source tool that allows you to download any Pokémon, item and (custom) C-Gear/Pokédex skin you want.

atm, DSLink has repos for it. https://github.com/NDSLink/dream-server

zurgeg commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values. I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.) image image I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

Ooh! We would definitely love to know how savedata.download works. Currently, we're stuck on Pokemon data. All it gives us is a Blaziken, and I've been stuck trying to bruteforce due to GS's cool down. If you need help with RT Debugging, use No$GBA.

Hi! I've tinkered with No$GBA before, but I was unable to get WiFi to work on it. I currently use MelonDS and use save states to skip the whole Game Sync recharge thing. As for savedata.download; The Pokémon data that I currently send starts at index 0x84 (132) in the response packet, is 10 entries long and each entry contains 8 bytes of data. The entry data format is as follows:

0x00 - 2 bytes - Species/Dex Number
0x02 - 2 bytes - Move ID, matches with numbers here: https://bulbapedia.bulbagarden.net/wiki/List_of_moves
0x04 - 1 byte  - Unknown
0x05 - 1 byte  - Unknown
0x06 - 1 byte  - Animation
0x07 - 1 byte  - Unknown

Here is how I currently write the Pokémon data to the response buffer:

// 10 entries starting at index 132 and incrementing by 8 with each subsequent entry
for(int i = 0; i < 10; i++) {
    // Currently #1 aka Bulbasaur
    response[i * 8 + 132] = 1; // 0x00 - 2 bytes - Species/Dex Number
    response[i * 8 + 133] = 0; // ^

    // Currently #1 aka Pound
    response[i * 8 + 134] = 1; // 0x02 - 2 bytes - Move ID
    response[i * 8 + 135] = 0; // ^

    response[i * 8 + 136] = 0  // 0x04 - 1 byte  - Unknown
    response[i * 8 + 137] = 0; // 0x05 - 1 byte  - Unknown

    response[i * 8 + 138] = 5; // 0x06 - 1 byte  - Animation
    response[i * 8 + 139] = 0; // 0x07 - 1 byte  - Unknown
}

I'm currently trying to figure out how to make the Pokémon appear in different parts of the forest. Hope this helps!

@kuroppoi do you happen to know if this is in big endian or little? I'm p sure that DS uses little but just checking before I use my GS energy for today :P

kuroppoi commented 1 year ago

Has there been any cool & notable progress that I missed out on? I came across this a while back and it piqued my interest, so I decided to have a go at figuring this out for fun and experience. It seems that the hardest part has already been done, so admittedly all I have really done so far was write a local DNS server and some very simple server emulators based on the groundwork that has been laid down until now & messed with some of the values. I'm currently at the point where I am able to tuck in and wake up a Pokémon, as well as catch downloaded Pokémon in the Entralink/Dream World. (Although the provided data is far from complete.) image image I'm currently not very experienced when it comes to reverse engineering DS games (couldn't for the life of me figure out how to debug them in realtime..), but I'd love to share any of my findings with you, should you find them interesting!

Ooh! We would definitely love to know how savedata.download works. Currently, we're stuck on Pokemon data. All it gives us is a Blaziken, and I've been stuck trying to bruteforce due to GS's cool down. If you need help with RT Debugging, use No$GBA.

Hi! I've tinkered with No$GBA before, but I was unable to get WiFi to work on it. I currently use MelonDS and use save states to skip the whole Game Sync recharge thing. As for savedata.download; The Pokémon data that I currently send starts at index 0x84 (132) in the response packet, is 10 entries long and each entry contains 8 bytes of data. The entry data format is as follows:

0x00 - 2 bytes - Species/Dex Number
0x02 - 2 bytes - Move ID, matches with numbers here: https://bulbapedia.bulbagarden.net/wiki/List_of_moves
0x04 - 1 byte  - Unknown
0x05 - 1 byte  - Unknown
0x06 - 1 byte  - Animation
0x07 - 1 byte  - Unknown

Here is how I currently write the Pokémon data to the response buffer:

// 10 entries starting at index 132 and incrementing by 8 with each subsequent entry
for(int i = 0; i < 10; i++) {
    // Currently #1 aka Bulbasaur
    response[i * 8 + 132] = 1; // 0x00 - 2 bytes - Species/Dex Number
    response[i * 8 + 133] = 0; // ^

    // Currently #1 aka Pound
    response[i * 8 + 134] = 1; // 0x02 - 2 bytes - Move ID
    response[i * 8 + 135] = 0; // ^

    response[i * 8 + 136] = 0  // 0x04 - 1 byte  - Unknown
    response[i * 8 + 137] = 0; // 0x05 - 1 byte  - Unknown

    response[i * 8 + 138] = 5; // 0x06 - 1 byte  - Animation
    response[i * 8 + 139] = 0; // 0x07 - 1 byte  - Unknown
}

I'm currently trying to figure out how to make the Pokémon appear in different parts of the forest. Hope this helps!

@kuroppoi do you happen to know if this is in big endian or little? I'm p sure that DS uses little but just checking before I use my GS energy for today :P

Little endian

kuroppoi commented 1 year ago

Alright, I published all of my findings in a separate repository, so feel free to do with that what you will.