Introduction

Note

This is a read-the-docs port of the original google docs lu_packet_structs, written by humanoid, lcdr and others, ported by @Xiphoseer. This is currently a proof of concept and is not guaranteed to reflect the latest changes.

Quick notes to get started

Client

  • This documentation is targeted towards the latest publicly released client (1.10.64)
  • To redirect the client to a different server simply change the AUTHSERVERIP host info in the boot.cfg file to a new host.
  • The client stores an additional config and a log file from the last session in the SystemDrive:\Users{User}\AppData\Local\LEGO Software\LEGO Universe\ folder.

Server

  • The client uses the RakNet network library (v3.25) to communicate with the server, therefore it is recommended to use it in the server if you want to work on one and are new to this project.
  • You can download it here (documentation and sample projects are included), note that later versions of the library won’t work due to changes in the network protocol. Alternatively lcdr wrote a python version with the minimum features needed to run a server for the game implemented, available here (no documentation yet so not recommended for inexperienced users)
  • The listening port for the Authentication Server is hardcoded to 1001 (UDP), the ports for the following instances (char, world) depend on what the Authentication Server sends to the client but the port range used for the original servers was 2001-2200 (UDP)
  • In order for the server to establish a working connection with the client it is required to set up a pre-set password in RakNet by calling SetIncomingPassword("3.25 ND1", 8); for the RakPeerInterface instance before listening for packets
  • It seems that the server used the SYSTEM_PRIORITY and RELIABLE_ORDERED options for all outgoing packets to the client (though that’s probably not a requirement)

Packet Captures

Thanks to pwjones we have access to quite a lot of (partial) traffic sessions of the original server which serve as a basis for this documentation, if you want to dig into them yourself, here is a download link.

Since the original captures (*.pcap files) were encrypted by RakNet it was required to decrypt them again (*.bin files stored in *.zip archives where each archive represents a session) which was only possible using a piece of information that RakNet exchanges at the beginning of a traffic.

However since more than half of the captured traffics only consist of a fraction of the entire session this information is missing for those captures (marked as *_unresolved.pcap), making them undecryptable at this point (they’re still included in the archives though, so all available captures are in one place).

There are a few exceptions where it was possible to decrypt them using the same information from other traffic sessions but the remaining ones can’t be decrypted with this method so they’ll remain unreadable for the time being.

The naming format used is: [packet number]_[source port]-[destination port]_[packet header]_[optional].bin where [optional] is used to display game message ids or network ids and LOTs in round brackets for the according packet types.

Extracting the entire .zip capture(s) is not recommended, since this many files (several ten thousand) will have a huge overhead on the file system (because of things like last modified info, which isn’t applicable here anyways), resulting in a much larger file space consumption and slower access times when trying to list the files in the explorer. If you want to search multiple captures for specific files, use this script: https://github.com/lcdr/utils/ find_packets.py

(The script also yields the binary content of the packets, which can be useful for further filtering or logging) If you want to look at the raw data of a packet yourself (not recommended for inexperienced users) you can of course extract single files from the .zip archive using an archive extractor of your choice (I recommend 7-Zip). Then you can open the extracted *.bin file(s) using a hex editor of your choice (for some packet types it might be useful to have an editor that can shift the bits in the data, no recommendation here). Alternatively a graphical viewer for capture files is available at https://github.com/lcdr/utils/tree/master/utils/captureviewer.py (takes the entire .zip archive of a traffic as input, no need to extract anything)

Appendix A: LEGO data format and data type IDs

LDF is used in boot.cfg, client xml settings, .luz and .lvl files, and the binary part of the chardata packet.

This binary data format is used in various packets, for example the chardata packet.

[u32] - number of keys
[u8] - key length in bytes
[wchar] - key
[u8] - data type (see below)
[according to data type] - data

The text format has the format: key=type:value

  • 0: String (variable wstring?)
  • 1: s32
  • 2: ??? (haven’t found an occurrence of this type so far)
  • 3: Float (32bit, signed)
  • 4: ??? (Location&Size, appeared on lwo_override.xml)
  • 5: u32
  • 6: ??? (haven’t found an occurrence of this type so far)
  • 7: Boolean (8bit, 0 or 1)
  • 8: s64
  • 9: s64, Used only for (object?) IDs?
  • 10: ??? (haven’t found an occurrence of this type so far)
  • 11: ??? (haven’t found an occurrence of this type so far)
  • 12: ??? (haven’t found an occurrence of this type so far)
  • 13: in chardata this was XML data, in client settings checksum, in lvl files strings/GUIDs (maybe it’s for bytes)

Appendix B: Maps info and checksum

Here are the checksums I found. Probably need to go back through and find the different map instances if I can.

Map Name Zone ID Checksum
Venture Explorer 1000 7c 08 b8 20
Return to Venture Explorer 1001 3c 0a 68 26
Avant Gardens 1100 11 55 52 49
Avant Gardens Survival 1101 e2 14 82 53
Spider Queen Battle 1102 da 03 d4 0f
Block Yard 1150 da 03 d4 0f
Avant Grove 1151 03 03 89 0a
Nimbus Station 1200 30 6b 1e da
Pet Cove 1201 30 13 6e 47
Vertigo Loop Racetrack 1203 02 05 fc 10
Battle of Nimbus Station 1204 58 02 d4 07
Nimbus Rock 1250 91 01 8d 05
Nimbus Isle 1251 5d 04 4f 09
Frostburgh 1260 currently disabled in the client
Gnarled Forest 1300 90 c2 ea 12
Canyon Cove 1302 ef 02 77 0b
Keelhaul Canyon 1303 todo
Chantey Shantey 1350 5c 01 b6 04
Forbidden Valley 1400 0d 76 19 85
Forbidden Valley Dragon 1402 87 01 f5 02
Dragonmaw Chasm 1403 4e 0f 85 81
Raven Bluff 1450 26 01 f0 03
Starbase 3001 1600 ee 02 c2 07
Deep Freeze 1601 06 01 32 02
Robot City 1602 7f 03 93 07
Moon Base 1603 ad 01 3b 04
Portabello 1604 dd 07 15 18
LEGO Club 1700 38 01 04 02
Crux Prime 1800 99 a3 17 4b
Nexus Tower 1900 3c f4 4a 9e
Ninjago 2000 74 2c 69 4d
Frakjaw Battle 2001 ef 00 eb 09