Skip to main content

CLI & Packet System

CLI Architecture

The cli module is the user-facing entry point, built with picocli.

Command Structure

  • Main — creates a CommandLine instance and executes.
  • ExtractCommand — parent command (extract), defines --help and --version. No logic, just routes to subcommands.
  • ExtractResourceCommand — the primary subcommand (resource). Handles file/directory traversal, deserialization, and output.
  • ExtractPacketCommand — secondary subcommand (packet). Handles network packet file deserialization ( experimental).

Resource Extraction Arguments

ArgumentFlagTypeDefaultDescription
Client root folder(positional 0)PathrequiredDDON installation root (e.g., D:\DDON_03040008)
Translation file(positional 1)PathrequiredGMD translation CSV file
Input path(positional 2)PathrequiredFile or directory to process
Output format-f, --formatSerializationFormatjsonjson or yaml
Write to file-obooleanfalseOutput to file instead of console
Meta information-m, --meta-informationbooleanfalseEnrich output with resolved names/translations
Unpack archives-u, --unpack-archivesbooleanfalseDecompress and decrypt .arc files
Archives only-x, --unpack-archives-exclusivelybooleanfalseOnly process .arc files, skip others
Parallel-p, --parallelbooleantrueRun file processing in parallel
Export textures-t, --export-texturesbooleanfalseExport .tex files as .dds
Ignore extensions-i, --ignore-extensionsSet<String>emptyComma-separated extensions to skip

Version Detection Flow

File Processing Pipeline

Utility Classes

ClassPurpose
ArchiveUnpackerExtracts files from deserialized Archive objects to disk, creating the directory structure.
FileChangeDetectorTracks file checksums to detect changes and avoid redundant reprocessing.
ResourceFileFilterFilters files by supported extensions (ClientResourceFileExtension.getSupportedFileExtensions()), respects the ignore list.
TextureExporterConverts deserialized Texture objects to DDS format using DirectDrawSurfaceSerializer and writes them to disk.

Native Packaging

The cli module's build.gradle configures JLink + jpackage:

jlink options: --strip-debug, --compress zip-6, --no-header-files, --no-man-pages
jpackage: --win-console, skipInstaller = true
Application: mainModule = org.sehkah.ddon.tools.extractor.cli
mainClass = org.sehkah.ddon.tools.extractor.cli.Main

This produces a self-contained executable (ddon-extractor.exe on Windows) with an embedded JRE — no system Java installation required.


Packet System

The packet system mirrors the resource deserialization architecture but operates on captured network traffic instead of client files. It is experimental and currently only supports Season 3 with 2 packet types.

Architecture

Packet Naming Convention

DDON uses a directional naming convention:

PrefixDirectionMeaning
C2LClient → Login ServerLogin-phase packets
L2CLogin Server → ClientLogin-phase responses
C2SClient → Game ServerGameplay packets
S2CGame Server → ClientGameplay responses

Registered Packets (Season 3)

IdentifierGroupIDSubIDSourceDeserializer
C2L_LOGIN_REQ0110x00C2LLoginReqBufferDeserializer
L2C_LOGIN_RES0120x34L2CLoginResBufferDeserializer

Packet vs. Resource Differences

AspectResourcesPackets
Byte orderLittle-endianBig-endian
HeaderMagic string + versionGroup + ID + SubID + source
Lookup keyPair<Extension, FileHeader>PacketHeader
ManagerClientResourceFileManagerPacketManager
Base classResourcePacket
Season supportAll threeSeason 3 only
Deserializer instantiationDirect constructorReflection via Class.getConstructor(GamePacket.class).newInstance(this)

Packet Extraction Arguments

ArgumentFlagTypeDefaultDescription
Client root folder(positional 0)PathrequiredDDON client resource path
Input path(positional 1)PathrequiredPacket file or directory
Output format-f, --formatSerializationFormatjsonjson or yaml
Write to file-obooleanfalseOutput to file
Meta information-m, --meta-informationbooleanfalseEnrich output
Parallel-p, --parallelbooleantrueParallel processing

MetaInformation on Packets

The PacketHeader class uses @MetaInformation annotations on enriched fields:


@MetaInformation
private final PacketGroup packetGroup; // resolved group name
@MetaInformation
private final PacketSubType packetSubType; // resolved sub-type
@MetaInformation
private final PacketType packetType; // resolved type name
@MetaInformation
private PacketIdentifier identifier; // human-readable enum name

Similarly, Packet.size and Packet.dataSize are marked @MetaInformation as they are wire-level metadata not part of the logical packet payload.