ZHelper 4 Protocol v4.44
--------------------------------------------------------------------------------
If you're looking to make your own tracker interact with ZHelper 4 over the Internet or LAN, this is all the info
you should need to get your tracker working with mine.

This is pretty much like it was before, except enhanced to support all the new stuff in ZHelper 4.

This will probably get an overhaul at some point to dump everything onto the server so a client won't lose any
of their clientside data if they crash or lose connection. For now we'll stick with only shared things until the
bugs with what's here get ironed out.

I'm using GM Studio's raw socket functions, so what's here is the exact format for packet data.

When a client first connects, its sends its player name in packet 0 and then receives its player id in packet 1.
The client will do a full reset of its data (except the stored player id) upon receiving packet 1 as well.
Once the reset happens, the client will send packet 3, which requests a full sync from the server.
It will receive a series of packets containing all the data on the server.
After that, everything works as it normally would. Packets with an invalid packet type are ignored, while
those with incorrect/invalid/corrupted payloads will produce undefined results, or may even cause a crash.
Any string length values sent do not include the null terminator in the length, but are padded to a given size
with $00 bytes to be safe and to avoid GM:S networking crashes from reading outside buffers.

The server will periodically send ping packets (#254) to all clients. Clients should respond with a #254 as well
just to make sure the connection doesn't time out.

Incoming pseudocode as before; shouldn't be too hard to figure out, but i'll explain the buffer_ stuff just in case:
buffer_u##: unsigned integers of given size in bits.
buffer_s##: signed integers of given size in bits.
buffer_f##: floats of given size in bits.
buffer_bool: boolean (1 byte).
buffer_string: null-terminated string.

A (C) indicates the packet is sent by clients, and (S) by the server.
Every packet has the following header at the start:
buffer_u8 packetID; //packet type (from the list below)
buffer_s8 playerID; //packets sent only from the server have this set to -1 so it never interferes with client ids.
              //the client also starts with -1 until it receives its own id from the server. afterwards, the
              //client then sets this value to its assigned player id in every packet it sends. When the server
              //relays these packets, they keep the player id of the original player that sent the packet.

Screen/cell numbers are always referenced from left to right, top to bottom, just like before.
See the lists at the end for the cell types for everything like overworld, dungeon, itembox, and door cells.

If anything isn't clear here, just refer to the code in GM to see how it works.

These are the packet types:
--------------------------------------------------------------------------------
Packet 0 (C): Handshake made by client immediately after connecting. Will receive packet 1 as a response.

buffer_u32 playerColor; //the player's selected color. A typical RGBA8888 color value.
buffer_u8 nameLength; //length of the player name string. Not needed for GM, but provided anyway for compatibility.
buffer_string playerName; //max 16 characters, plus the null term. (padded to a total of 17 bytes with $00)
================================================================================

Packet 1 (S): Handshake response from server upon connection. Gives a client its player ID (from 0 - 7).

buffer_u8 playerID; //the player id assigned to the player.
================================================================================

Packet 2 (S): Instructs client to fully reset its data to an empty state. No payload, just a header.
Sent when clicking on the reset all data button on the server.
================================================================================

Packet 3 (C): Full sync request. Sent by the client after the initial full reset, and upon clicking the sync button
on the client. No payload, just a header. Will get all these packets in response to sync everything:
    4 (x1): Player data.
    5 (x1): Starting screen markers, item box items, dungeon numbers, dungeon colors, hint icons.
    6 (x1): Overworld data.
    7 (x1): Overworld markers.
    8 (x1): Dungeon icons.
    9 (x9): Dungeon markers, 1 for each new map.
    10 (x1): Dungeon doors.
    11 (x1): Classic dungeon icons.
    12 (x4): Classic dungeon markers, 1 for each map.
    14 (x1): Player location info.
    15 (x1) Auto dungeon palette info.
    16 (x1) Auto dungeon level number info.

This means a full sync may take several seconds now depending on how fast connections are, especially the server's
upload speed.
================================================================================

Packet 4 (S): Syncs all player info on the client. 8 player info sets in total.

for(i = 0; i < 8; i += 1){
    buffer_u32 playerColor[i]; //the player's selected color. A typical RGBA8888 color value.
    buffer_u8 nameLength[i]; //length of the player name string.
    buffer_string playerName[i]; //max 16 characters, plus the null term. (padded to a total of 17 bytes with $00)
}
================================================================================

Packet 5 (S): Syncs starting screen markers, item box items, dungeon numbers, and dungeon colors.
Dungeon colors are typical RGB888 color values. i is the seed index, j is the position.
For starting screens, 0 is overworld, 1-9 are dungeons.

//starting screens
for(j = 0; j < 10; j += 1){
    buffer_u8 startingPos[j];
}

//item boxes
for(j = 0; j < 24; j += 1){
    buffer_u8 itemBox[j];
}

//dungeon numbers (used to identify which dungeon a map is, like the automatic tracker)
for(j = 0; j < 9; j += 1){
    buffer_s8 dungeonNum[j];
}

//dungeon colors (used to identify the overall color of a dungeon.) typical RGBA8888 value.
for(j = 0; j < 9; j += 1){
    buffer_u32 dungeonColor[j];
}

//dungeon location hints
for(j = 0; j < 9; j += 1){
    buffer_u8 dungeonLocHint[i, j];
}
================================================================================

Packet 6 (S): Syncs overworld icon data. j is screen number

for(j = 0; j < 128; j += 1){
    buffer_u8 overworldIcon[j];
}
================================================================================

Packet 7 (S): Syncs overworld player markers. Inefficient, but will change once I get GM:S
to stop being dumb with binary math.

for(i = 0; i < 1024; i += 1){
    buffer_bool overworldMarker[i];
}
================================================================================

Packet 8 (S): Syncs dungeon screen icons.

for(i = 0; i < 576; i += 1){
    buffer_u8 dungeonIcon[i];
}
================================================================================

Packet 9 (S): Syncs dungeon player markers for the specified dungeon number. Inefficient, but will change
once I get GM:S to stop being dumb with binary math.

buffer_u8 dungeonIndex; //specifies the dungeon being synced.
for(i = 0; i < 512; i += 1){
    buffer_bool dungeonMarker[dungeonIndex, i];
}
================================================================================

Packet 10 (S): Syncs dungeon door icons.

for(i = 0; i < 504; i += 1){
    buffer_bool dungeonDoorIconH[i]; //left/right sides of rooms, 56 per dungeon.
}

for(i = 0; i < 504; i += 1){
    buffer_bool dungeonDoorIconV[i]; //top/bottom of rooms. 56 per dungeon.
}
================================================================================

Packet 11 (S): Syncs classic (ZHelper 3 style) dungeon map icons.
Each map is 128 icons:
0-127: 1st 1-6
128-255: 1st 7-9
256-383: 2nd 1-6
384-511: 2nd 7-9

See the classic maps (C1-C4 on the view button) inside the program for the layout of these maps.

for(i = 0; i < 512; i += 1){
    buffer_bool classicDungeonIcon[i];
}
================================================================================

Packet 12 (S): Syncs classic dungeon player markers for the specified map number
(as mentioned in packet 11). Inefficient, but will change once I get GM:S to stop being dumb with binary math.

buffer_u8 mapIndex; //specifies the map being synced.
for(i = 0; i < 1024; i += 1){
    buffer_bool classicDungeonMarker[mapIndex, i];
}
================================================================================

Packet 13 (S): Syncs all player info (names/colors). There is no method to only sync one.
This is sent when a player connects or disconnects.

for(i = 0; i < 8; i += 1){
    buffer_u32 playerColor[i]; //the player's selected color. A typical RGBA8888 color value.
    buffer_u8 nameLength[i]; //length of the player name string.
    buffer_string playerName[i]; //max 16 characters, plus the null term. (padded to a total of 17 bytes with $00)
}
================================================================================

Packet 14 (S): Syncs all player positions. 
This is sent to all clients a couple times a second to update the position indicators on their maps.

for(i = 0; i < 8; i += 1){
    buffer_u8 playerOWPos[i]; //the player's last known overworld position. 255 if not in a valid state.
    buffer_u8 playerMapType[i]; //the player's last known map type. 1 is OW, 2 DGN, any other value is invalid state.
    buffer_u8 playerDGNMap; //player's current dungeon map number. 255 if unknown or invalid.
    buffer_u8 playerDGNPos; //player's current dungeon screen. 255 if not in a dungeon room or invalid.
}
================================================================================

Packet 15 (S): Syncs all auto dungeon palette info. There is no method to sync only one. This helps ensure that
clients always have the correct map order, since it may not be in numerical order according to dungeon numbers.
Each seed is 9 sets of 4 colors as NES palette indexes. The values are 255 if unknown or invalid. The order of
entries is as follows: light wall, med. wall, dark wall, statue/liquid
Compute a dungeon color by taking the average of the 3 wall colors and forcing the luminance/value to at least 128.

for(j = 0; j < 36; j += 1){
    buffer_u8 autoDGNPal[i, j];
}
================================================================================

Packet 16 (S): Syncs all auto dungeon level info. This helps ensure that clients always have the most up-to-date
numbers for all dungeons from all players.
This is the level number found from reading the LEVEL-# text from the screen.
1-9 for levels 1-9, 0 for unknown.
DO NOT WRITE THIS DATA UNLESS IT COMES FROM READING THE SCREEN OR IT WILL MESS THINGS UP HORRIBLY!

for(j = 0; j < 9; j += 1){
    buffer_u8 autoDGNLevel[i, j];
}
--------------------------------------------------------------------------------
That's it for the handshake and sync packets. Below are all the packets sent between clients
and the server to update specific items:
--------------------------------------------------------------------------------

Packet 101 (CS): Syncs one start marker.

buffer_u8 mapNum; //map number (ow = 0, dgn = 1-9)
buffer_u8 screenNum; //screen number
================================================================================

Packet 102 (CS): Syncs one itembox item.

buffer_u8 boxNum; //itembox number (0-12=dungeon items, 13/14/15 are ladder/armos/white sword)
buffer_u8 itemID; //item id (see end of document for this and other ids)
================================================================================

Packet 103 (CS): Syncs one overworld icon.

buffer_u8 screenNum; //screen number
buffer_u8 icon; //cell icon
================================================================================

Packet 104 (CS): Syncs one overworld marker.

buffer_u8 screenNum; //screen number
buffer_u8 playerID; //player id
buffer_bool isSet; //whether to set or unset marker
================================================================================

Packet 105 (CS): Syncs one dungeon icon.

buffer_u8 mapNum; //map number
buffer_u8 screenNum; //screen number
buffer_u8 icon; //cell icon
================================================================================

Packet 106 (CS): Syncs one dungeon marker.

buffer_u8 mapNum; //map number
buffer_u8 screenNum; //screen number
buffer_u8 playerID; //player id
buffer_bool isSet; //whether to set or unset marker
================================================================================

Packet 107 (CS): Syncs one dungeon number.

buffer_u8 mapNum; //map number
buffer_s8 dgnNum; //dungeon number
================================================================================

Packet 108 (CS): Syncs one dungeon color.

buffer_u8 mapNum; //map number
buffer_u32 dgnColor; //color (RGBA8888 value)
================================================================================

Packet 109 (CS): Syncs one horizontal dungeon door.

buffer_u8 mapNum; //map number
buffer_u8 doorNum; //door number
buffer_u8 icon; //cell icon
================================================================================

Packet 110 (CS): Syncs one vertical dungeon door.

buffer_u8 mapNum; //map number
buffer_u8 doorNum; //door number
buffer_u8 icon; //cell icon
================================================================================

Packet 111 (CS): Syncs one classic dungeon icon.

buffer_u8 mapNum; //map number (0=1st 1-6, 1=1st 7-9, 2=2nd 1-6, 3=2nd 7-9)
buffer_u8 screenNum; //screen number (see zhelper classic dungeon maps C1-C4 for the layout)
buffer_u8 icon; //cell icon
================================================================================

Packet 112 (CS): Syncs one classic dungeon marker.

buffer_u8 mapNum; //map number (0=1st 1-6, 1=1st 7-9, 2=2nd 1-6, 3=2nd 7-9)
buffer_u8 screenNum; //screen number
buffer_u8 playerID; //player id
buffer_bool isSet; //whether to set or unset marker
================================================================================

Packet 113 (CS): Syncs one dungeon location hint.

buffer_u8 hintNum; //hint number
buffer_u8 hintLoc; //hint location (icon number)
================================================================================

Packet 114 (C): Syncs one player location.

buffer_u8 screenOW; //last known overworld screen number
buffer_u8 mapType; //last known map type. see packet 14 for values.
buffer_u8 mapDGN; //player's current dungeon map number. 255 if unknown or invalid.
buffer_u8 screenDGN; //player's current dungeon screen. 255 if not in a dungeon room or invalid.
================================================================================

Packet 115 (C): Syncs one auto dungeon level number. The server will always respond with packet 16, updating ALL listings on the client
to help keep everything in sync better.

buffer_u8 mapNum; //map number to update (NOT the level number, but the map index in ZHelper)
buffer_u8 levelNum; //level number read from the screen. DO NOT SET UNLESS READ FROM SCREEN!!!
--------------------------------------------------------------------------------
That's it for the single sync packets. Next up is the special request packets for
getting specific info from the server:
--------------------------------------------------------------------------------

Packet 200 (C): Requests the server's dungeon number for a given set of NES palette indexes and start position.
The server will check this info with its own, creating a new map if the dungeon hasn't been encountered yet.
The client will receive packet 201 as a response, containing the assigned dungeon number. This is used for
creating auto-track dungeons on the server and for finding which map to switch to when entering one on a server.

buffer_u8 DGNPal[0]; //player's tracked light wall color
buffer_u8 DGNPal[1]; //player's tracked medium wall color
buffer_u8 DGNPal[2]; //player's tracked dark wall color
buffer_u8 DGNPal[3]; //player's tracked liquid/statue color
buffer_u8 autoDGNStart; //player's tracked start screen for the requested dungeon
================================================================================

Packet 201 (S): Tells the client the dungeon map number that matches the request info.
buffer_u8 mapNum; //map number from 0-8 or 255 if invalid.
--------------------------------------------------------------------------------
That's it for the special request packets. Last up is the special packets for things
like kicking, etc.:
--------------------------------------------------------------------------------

Packet 254 (CS): Keep-alive ping packet. No payload. Clients are recommended to respond with a #254 packet as well
just to make sure the connection doesn't time out.
================================================================================

Packet 255 (S): Tells the client to disconnect forcefully. No payload.

--------------------------------------------------------------------------------
I think that's about it for packets for now. I'll add more if needed.
Below is the ID listings (subject to change):
--------------------------------------------------------------------------------
Itembox icons:
0-blank
1-book
2-boomerang (wood)
3-bow
4-power bracelet
5-ladder
6-boomerang (magic)
7-magic key
8-raft
9-recorder
10-red candle
11-red ring
12-shield
13-silver arrow
14-wand
15-white sword
16-heart container
17-X (manually disabled itembox)


Overworld icons:
0-blank
1-unknown level
2-L1
3-L2
4-L3
5-L4
6-L5
7-L6
8-L7
9-L8
10-L9
11-warp 1
12-warp 2
13-warp 3
14-warp 4
15-heart/potion take any one cave
16-money making game
17-letter cave
18-armos item screen
19-magic sword cave
20-white sword cave
21-wood sword cave
22-pay for info
23-shield shop
24-ring shop
25-meat shop
26-key shop
27-heart shop
28-candle shop
29-book shop
30-bomb shop
31-arrow shop
32-potion shop
33-door repair
34-unknown rupee secret
35-100 secret
36-30 secret
37-10 secret
38-X (cleared screen, junk screen)

Dungeon icons:
0-blank
1-X (cleared/useless room
2-? (unknown room contents)
3-key drop room
4-triforce drop room
5-heart container drop room
6-map drop room
7-compass drop room
8-stair item room
9-floor/drop item room
10-bomb drop room
11-more bombs guy
12-leave money or life
13-5 rupee drop room
14-10 rupee enemy room
15-grumble grumble
16-gannon
17-gannon roar
18-zelda
19-boss roar
20-ladder block
21-recorder block
22-bow/arrow block
23-sword/wand block
24-stair 9
25-stair 8
26-stair 7
27-stair 6
28-stair 5
29-stair 4
30-stair 3
31-stair 2
32-stair 1
33-unknown stair

Horizontal door icons:
0-? (unknown)
1-no door, bomb checked
2-passage
3-shutter
4-one way shutter right
5-one way shutter left
6-walkthrough wall
7-attempted but failed walkthrough wall
8-one-way walkthrough right
9-one-way walkthrough left
10-key door
11-bombable wall

Vertical door icons are the same but up-down instead of left-right.

Location hint icons:
0-unknown/unset/???
1-coast
2-death mountain
3-desert
4-forest (green trees)
5-graveyard
6-lost hills
7-lake
8-river
9-near start
10-dead woods (brown trees)

I think that's everything you'll need to know about the networking at the moment. Let me know if you think anything else needs to be added.