Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
20f9a01
feat(doppelganger): add server-to-client packets 0xBF 0x0E-0x14
apraxico Sep 23, 2026
9bbdaf2
feat(doppelganger): add event view plugin
apraxico Sep 23, 2026
4276037
feat(doppelganger): add the event context skeleton
apraxico Sep 23, 2026
fcc7866
feat(doppelganger): enter the event through the NPC Lugard
apraxico Sep 23, 2026
ed85872
feat(doppelganger): monsters walk along the path to the magic circle
apraxico Sep 23, 2026
953eb6b
fix(doppelganger): place entering players on walkable coordinates
apraxico Sep 23, 2026
ab41925
feat(doppelganger): add the interim and final reward chests
apraxico Sep 23, 2026
fa91d96
fix(doppelganger): open the reward chests by talking to them
apraxico Sep 23, 2026
dff9b02
feat(doppelganger): scale the monsters by the level and number of pla…
apraxico Sep 23, 2026
bc75796
feat(doppelganger): announce the ice walker mission
apraxico Sep 23, 2026
911becc
feat(doppelganger): accept the free ticket and transform signs into m…
apraxico Sep 23, 2026
8cee2bd
fix(doppelganger): address review findings
apraxico Sep 24, 2026
36627f3
feat(doppelganger): configure the event in the admin panel
apraxico Sep 24, 2026
937e12e
test(doppelganger): cover the packets, the path progress and the tickets
apraxico Sep 24, 2026
e905d29
docs(doppelganger): describe values as configurable defaults
apraxico Sep 24, 2026
edfd4c6
style(doppelganger): order the members of the OpenNpcWindowPlugIn
apraxico Sep 24, 2026
af8546d
style(doppelganger): address static code analysis findings
apraxico Sep 24, 2026
f8d2e9d
style(doppelganger): discard the task of the timer callback
apraxico Sep 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/Packets/C1-92-UpdateMiniGameState_by-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ The state of the mini games.
| 10 | ChaosCastleClosed | The chaos castle game is closed. "Chaos Castle Closing (in x seconds)". |
| 11 | ChaosCastleOpened | The chaos castle game is opened for entrance. "Chaos Castle Penetration (in x seconds)". |
| 12 | ChaosCastleEnding | The chaos castle game is ending. "Chaos Castle Event ends (in x seconds)". |
| 13 | ChaosCastleFinished | The chaos castle game is finished. Chaos Castle Event shuts down (in x seconds)". |
| 13 | ChaosCastleFinished | The chaos castle game is finished. Chaos Castle Event shuts down (in x seconds)". |
| 16 | DoppelgangerEntranceClosing | The entrance of the doppelganger event closes in 30 seconds. The client shows the countdown only on the doppelganger maps. |
| 17 | DoppelgangerStarting | The doppelganger event starts in 30 seconds. The client shows the countdown only on the doppelganger maps. |
| 18 | DoppelgangerIceWalkerCountdown | The ice walker has to be killed within 30 seconds. The client shows the countdown only on the doppelganger maps. |
| 19 | DoppelgangerEnding | The doppelganger event ends in 30 seconds. The client shows the countdown only on the doppelganger maps. |
31 changes: 31 additions & 0 deletions docs/Packets/C1-BF-0E-DoppelgangerEnterResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# C1 BF 0E - DoppelgangerEnterResult (by server)

## Is sent when

The player requested to enter the doppelganger event through the NPC Lugard.

## Causes the following actions on the client side

On failure, the client locks the enter button of the doppelganger entry dialog and may show a message.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 5 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x0E | Packet header - sub packet type identifier |
| 4 | 1 | EnterResult | | Result |

### EnterResult Enum

Result of the doppelganger enter request.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Success | The player entered the event. |
| 1 | Failed | The player could not enter, e.g. because of a missing ticket item. The client locks the enter button without showing a message. |
| 2 | AlreadyStarted | The event is already running or occupied by another party. The client shows "Battle has already commenced. You cannot enter.". |
| 3 | PlayerKiller | Player killers are not allowed to enter. The client shows "You cannot enter if you are a 1st Stage Outlaw.". |
| 4 | EntranceAvailable | The client unlocks the enter button of the doppelganger entry dialog. |
19 changes: 19 additions & 0 deletions docs/Packets/C1-BF-0F-DoppelgangerMonsterPosition_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# C1 BF 0F - DoppelgangerMonsterPosition (by server)

## Is sent when

The position of the most advanced monster on the path to the magic circle changed during the doppelganger event.

## Causes the following actions on the client side

The client updates the monster progress bar of the doppelganger frame.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 5 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x0F | Packet header - sub packet type identifier |
| 4 | 1 | Byte | | Position; The position index on the path, between 0 (start) and 22 (magic circle). |
30 changes: 30 additions & 0 deletions docs/Packets/C1-BF-10-DoppelgangerStateUpdate_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# C1 BF 10 - DoppelgangerStateUpdate (by server)

## Is sent when

The state of the doppelganger event changed.

## Causes the following actions on the client side

When the event starts (state Playing), the client shows the doppelganger frame and a message box with the failure conditions.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 5 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x10 | Packet header - sub packet type identifier |
| 4 | 1 | DoppelgangerState | | State |

### DoppelgangerState Enum

The state of the doppelganger event.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Waiting | The event is waiting for the party members to enter. |
| 1 | Ready | The entrance is closed and the event is about to start. |
| 2 | Playing | The event is running. |
| 3 | Ended | The event has ended. |
29 changes: 29 additions & 0 deletions docs/Packets/C1-BF-11-DoppelgangerIceWalkerState_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# C1 BF 11 - DoppelgangerIceWalkerState (by server)

## Is sent when

The ice walker appeared on or disappeared from the path during the doppelganger event.

## Causes the following actions on the client side

The client shows or hides the ice walker icon on the progress bar of the doppelganger frame.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 6 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x11 | Packet header - sub packet type identifier |
| 4 | 1 | IceWalkerState | | State |
| 5 | 1 | Byte | | Position; The position index of the ice walker on the path, between 0 (start) and 22 (magic circle). |

### IceWalkerState Enum

The state of the ice walker.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Appeared | The ice walker is present at the given position. |
| 1 | Disappeared | The ice walker was killed or disappeared. |
33 changes: 33 additions & 0 deletions docs/Packets/C1-BF-12-DoppelgangerPlayInfo_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# C1 BF 12 - DoppelgangerPlayInfo (by server)

## Is sent when

Periodically (every second) while the doppelganger event is running.

## Causes the following actions on the client side

The client updates the remaining time and the positions of the party members on the progress bar of the doppelganger frame. Players which are not included are no longer shown.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x12 | Packet header - sub packet type identifier |
| 4 | 2 | ShortLittleEndian | | RemainingSeconds |
| 6 | 1 | Byte | | PlayerCount |
| 8 | PlayerPosition.Length * PlayerCount | Array of PlayerPosition | | PlayerPositions |

### PlayerPosition Structure

The position of a player on the path.

Length: 4 Bytes

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 2 | ShortLittleEndian | | PlayerId |
| 2 | 1 | Byte | | MapNumber; The map number of the player. It is ignored by the client. |
| 3 | 1 | Byte | | Position; The position index of the player on the path, between 0 (start) and 22 (magic circle). |
30 changes: 30 additions & 0 deletions docs/Packets/C1-BF-13-DoppelgangerResult_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# C1 BF 13 - DoppelgangerResult (by server)

## Is sent when

The doppelganger event ended for the player.

## Causes the following actions on the client side

The client stops the timer and the event music, and shows a message box with the result.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 12 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x13 | Packet header - sub packet type identifier |
| 4 | 1 | ResultType | | Result |
| 8 | 4 | IntegerLittleEndian | | RewardExperience; The experience which the player got as reward. It is not shown by the client. The field is aligned to 4 bytes, because the client structure is not packed. |

### ResultType Enum

The result of the doppelganger event.

| Value | Name | Description |
|-------|------|-------------|
| 0 | Success | The party successfully defended the magic circle. |
| 1 | Failed | The player failed, e.g. because the character died or left the event map. |
| 2 | MonstersReachedMagicCircle | The defense failed, because too many monsters reached the magic circle. |
20 changes: 20 additions & 0 deletions docs/Packets/C1-BF-14-DoppelgangerMonsterGoal_by-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# C1 BF 14 - DoppelgangerMonsterGoal (by server)

## Is sent when

A monster reached the magic circle during the doppelganger event.

## Causes the following actions on the client side

The client updates the counter of monsters which passed the magic circle.

## Structure

| Index | Length | Data Type | Value | Description |
|-------|--------|-----------|-------|-------------|
| 0 | 1 | Byte | 0xC1 | [Packet type](PacketTypes.md) |
| 1 | 1 | Byte | 6 | Packet header - length of the packet |
| 2 | 1 | Byte | 0xBF | Packet header - packet type identifier |
| 3 | 1 | Byte | 0x14 | Packet header - sub packet type identifier |
| 4 | 1 | Byte | | MaximumGoalCount; The number of monsters which may reach the magic circle until the event fails. |
| 5 | 1 | Byte | | GoalCount; The number of monsters which reached the magic circle. |
7 changes: 7 additions & 0 deletions docs/Packets/ServerToClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@
* [C1 BF 07 - IllusionTempleSkillEnd (by server)](C1-BF-07-IllusionTempleSkillEnd_by-server.md)
* [C1 BF 08 - IllusionTempleHolyItemRelics (by server)](C1-BF-08-IllusionTempleHolyItemRelics_by-server.md)
* [C1 BF 0A - ChainLightningHitInfo (by server)](C1-BF-0A-ChainLightningHitInfo_by-server.md)
* [C1 BF 0E - DoppelgangerEnterResult (by server)](C1-BF-0E-DoppelgangerEnterResult_by-server.md)
* [C1 BF 0F - DoppelgangerMonsterPosition (by server)](C1-BF-0F-DoppelgangerMonsterPosition_by-server.md)
* [C1 BF 10 - DoppelgangerStateUpdate (by server)](C1-BF-10-DoppelgangerStateUpdate_by-server.md)
* [C1 BF 11 - DoppelgangerIceWalkerState (by server)](C1-BF-11-DoppelgangerIceWalkerState_by-server.md)
* [C1 BF 12 - DoppelgangerPlayInfo (by server)](C1-BF-12-DoppelgangerPlayInfo_by-server.md)
* [C1 BF 13 - DoppelgangerResult (by server)](C1-BF-13-DoppelgangerResult_by-server.md)
* [C1 BF 14 - DoppelgangerMonsterGoal (by server)](C1-BF-14-DoppelgangerMonsterGoal_by-server.md)
* [C1 BF 51 - MuHelperStatusUpdate (by server)](C1-BF-51-MuHelperStatusUpdate_by-server.md)
* [C2 C0 - MessengerInitialization (by server)](C2-C0-MessengerInitialization_by-server.md)
* [C1 C1 01 - FriendAdded (by server)](C1-C1-01-FriendAdded_by-server.md)
Expand Down
Loading