Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
da6a906
fix: correct event invocation in ServerProtocol.HandleClose
AvinadavCoh Nov 3, 2025
aef29cc
fix: add null safety checks in server packet handlers
AvinadavCoh Nov 3, 2025
d789a27
feat: Implement multiplayer spawn system with position sync
AvinadavCoh Nov 4, 2025
b46832f
fix: add character selection validation in player spawn logic
AvinadavCoh Nov 4, 2025
f9ab43f
Implement enemy and map reveal synchronization in multiplayer
AvinadavCoh Nov 5, 2025
2feb374
feat: Implement chest and shrine interaction synchronization in multi…
AvinadavCoh Nov 6, 2025
a140466
feat: Implement player damage and death synchronization in multiplayer
AvinadavCoh Nov 6, 2025
fcf701c
feat: Add Player Health HUD and synchronize health and death events i…
AvinadavCoh Nov 6, 2025
84e5cc4
feat: Implement Steam integration for multiplayer invites and auto-jo…
AvinadavCoh Nov 6, 2025
dc12844
fix: Improve null and empty string checks for character selection and…
AvinadavCoh Nov 7, 2025
14aa734
idek
AvinadavCoh Nov 7, 2025
35b13e1
feat: Refactor enemy and player health synchronization patches for im…
AvinadavCoh Nov 7, 2025
d96ee06
feat: Update PlayerInventory initialization to ignore shop items duri…
AvinadavCoh Nov 7, 2025
96b6d18
feat: Enhance player spawning logic with error handling and inventory…
AvinadavCoh Nov 7, 2025
c8fe6b3
feat: Implement comprehensive error handling for player spawning and …
AvinadavCoh Nov 7, 2025
ec3f5d5
feat: Add network diagnostics utility for IP retrieval and connection…
AvinadavCoh Nov 7, 2025
62b8407
feat: Implement enemy data caching and mapping for improved client-si…
AvinadavCoh Nov 7, 2025
abad93c
feat: Implement enemy caching and synchronization, enhance network sp…
AvinadavCoh Nov 7, 2025
35bad9a
feat: Implement gold and wave synchronization features, including eve…
AvinadavCoh Nov 7, 2025
be9a4aa
feat: Implement boss spawner and stage transition event handling, inc…
AvinadavCoh Nov 7, 2025
c6eec19
feat: Update boss synchronization and stage transition handling, incl…
AvinadavCoh Nov 7, 2025
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
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@ desktop.ini
# NuGet
*.nupkg
packages/
.nuget/
.nuget/

# Local History (VS Code extension)
.lh/

# Machine-specific project files (users must configure their own paths)
*.csproj
215 changes: 215 additions & 0 deletions CHEST_SHRINE_SYNC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# Chest and Shrine Synchronization Implementation

## Overview
Added complete infrastructure for synchronizing chest openings and shrine/shop usage between players in multiplayer sessions.

## Implementation Date
November 6, 2025

## Components Created

### 1. Network Packets

#### ChestOpenPacket.cs
- **Purpose**: Broadcasts when any player opens a chest
- **Data**: ChestId (string), PlayerId (ushort)
- **Direction**: Server → All Clients
- **Packet ID**: 18 (CHEST_OPEN)

#### ShrineUsePacket.cs
- **Purpose**: Broadcasts when any player uses a shrine
- **Data**: ShrineId (string), PlayerId (ushort), ShrineType (int)
- **Direction**: Server → All Clients
- **Packet ID**: 19 (SHRINE_USE)

### 2. Client-Side Handlers

#### ChestOpenPacketHandler.cs
- Receives chest open broadcasts from server
- Queues chest opening on Unity main thread
- Ready to call game's chest opening method once discovered

#### ShrineUsePacketHandler.cs
- Receives shrine use broadcasts from server
- Queues shrine activation on Unity main thread
- Ready to call game's shrine method once discovered

### 3. Host-Side Event Handlers

#### ChestOpenEventHandler.cs
- Listens for `GameEvents.OpenChestEvent`
- Broadcasts chest openings to all connected clients
- Uses host's UUID as the player ID

#### ShrineUseEventHandler.cs
- Listens for `GameEvents.UseShrineEvent`
- Broadcasts shrine usage to all connected clients
- Generates shrine ID and type (placeholder until game structure discovered)

### 4. Game Patches

#### InteractableSyncPatches.cs
Contains two dynamic Harmony patches:

**ChestInteractPatch:**
- Attempts to find chest interaction methods at runtime
- Tries multiple possible class names:
- `Il2Cpp.InteractableChest`
- `Il2CppAssets.Scripts.Interactables.InteractableChest`
- `InteractableChest`, `Chest`, `Il2Cpp.Chest`
- Looks for `Open()` or `Interact()` methods
- On successful open: Triggers `GameEvents.TriggerOpenChest(chestId)`
- Host-only execution (checks `LobbyPatchFlags.IsHosting`)

**ShrineInteractPatch:**
- Attempts to find shrine interaction methods at runtime
- Tries multiple possible class names:
- `Il2Cpp.InteractableShrine`
- `Il2CppAssets.Scripts.Interactables.InteractableShrine`
- `InteractableShrine`, `Shrine`, `Il2Cpp.Shrine`
- Looks for `Use()` or `Interact()` methods
- On successful use: Triggers `GameEvents.TriggerUseShrine()`
- Host-only execution

### 5. Game Events

#### Added to GameEvents.cs:
```csharp
public static event Action<string> OpenChestEvent; // chestId
public static event Action UseShrineEvent;

public static void TriggerOpenChest(string chestId)
public static void TriggerUseShrine()
```

### 6. Registration

#### Updated Multibonk.cs:
- Registered `ChestOpenEventHandler` as `IGameEventHandler`
- Registered `ShrineUseEventHandler` as `IGameEventHandler`
- Registered `ChestOpenPacketHandler` as `IClientPacketHandler`
- Registered `ShrineUsePacketHandler` as `IClientPacketHandler`

## How It Works

### Chest Opening Flow:
1. **Host** interacts with a chest
2. `ChestInteractPatch.Postfix()` catches the interaction
3. Triggers `GameEvents.TriggerOpenChest(chestId)`
4. `ChestOpenEventHandler` receives the event
5. Creates `SendChestOpenPacket` and broadcasts to all clients
6. **Clients** receive packet via `ChestOpenPacketHandler`
7. Queues chest opening on main thread
8. *(TODO: Call game's method to open chest visually)*

### Shrine Usage Flow:
1. **Host** uses a shrine
2. `ShrineInteractPatch.Postfix()` catches the interaction
3. Triggers `GameEvents.TriggerUseShrine()`
4. `ShrineUseEventHandler` receives the event
5. Creates `SendShrineUsePacket` and broadcasts to all clients
6. **Clients** receive packet via `ShrineUsePacketHandler`
7. Queues shrine activation on main thread
8. *(TODO: Call game's method to activate shrine effect)*

## Current Status

### ✅ Completed:
- Network packet structure
- Client packet handlers
- Host event handlers
- Harmony patches with dynamic class discovery
- Event system integration
- Handler registration
- Documentation updates (README.md, INSTALL.txt)
- Build successful, DLL deployed to game

### ⚠️ Pending Testing:
- Patches need runtime testing to verify class names
- May need dnSpy inspection to find actual class/method names
- Client-side effect application needs game method discovery

### 🔧 Future Improvements:
1. **Discover actual game classes**:
- Use dnSpy on Assembly-CSharp.dll
- Search for: "Chest", "Shrine", "Interact"
- Update patch class names if needed

2. **Implement client-side effects**:
- Find chest opening animation method
- Find shrine effect application method
- Update packet handlers to call these methods

3. **Enhanced chest sync**:
- Sync loot contents
- Sync which items each player picks up
- Prevent double-looting

4. **Enhanced shrine sync**:
- Identify shrine type from game data
- Sync actual shrine effects to all players
- Handle different shrine types (health, damage, etc.)

## Architecture Notes

### Dynamic Patch Discovery
The patches use reflection to find classes at runtime because:
- IL2CPP class names can vary
- Namespace structure may differ across game versions
- Provides resilience against game updates

### Host Authority Model
- Only the host's interactions trigger broadcasts
- Prevents duplicate events
- Maintains consistent game state
- Clients receive and apply changes from host

### Thread Safety
- Game interactions queued via `GameDispatcher.Enqueue()`
- Ensures Unity API calls happen on main thread
- Prevents threading issues with Unity objects

## Testing Instructions

### When Testing:
1. **Host** starts server and enters game
2. **Client** connects to host
3. Navigate to an area with chests and shrines
4. **Host** opens a chest:
- Check host log for: `[Host] Chest opened: {id}`
- Check client log for: `[Client] Chest opened: {id} by player {id}`
5. **Host** uses a shrine:
- Check host log for: `[Host] Shrine used`
- Check client log for: `[Client] Shrine used: {id} (type {type}) by player {id}`

### Expected Behavior:
- Patches may log "Could not find" messages if class names don't match
- This is normal - patches gracefully disable if classes not found
- Infrastructure is ready and will work once correct classes discovered

### If Patches Don't Find Classes:
1. Open dnSpy
2. Load `D:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll`
3. Search for: "Chest", "Shrine", "Interact"
4. Find the actual class and method names
5. Update `InteractableSyncPatches.cs` with correct names
6. Rebuild and test again

## Related Files
- `Multibonk/Networking/Comms/Base/Packet/ChestOpenPacket.cs`
- `Multibonk/Networking/Comms/Base/Packet/ShrineUsePacket.cs`
- `Multibonk/Networking/Comms/Client/Handlers/ChestOpenPacketHandler.cs`
- `Multibonk/Networking/Comms/Client/Handlers/ShrineUsePacketHandler.cs`
- `Multibonk/Game/Handlers/NetworkNotify/ChestOpenEventHandler.cs`
- `Multibonk/Game/Handlers/NetworkNotify/ShrineUseEventHandler.cs`
- `Multibonk/Game/Patches/InteractableSyncPatches.cs`
- `Multibonk/Game/GameEvents.cs`
- `Multibonk/Networking/Comms/Base/PacketId.cs`
- `Multibonk/Multibonk.cs`

## Success Metrics
- ✅ Compiles without errors
- ✅ All handlers registered
- ✅ Patches can be applied (with or without finding classes)
- ⏳ Runtime testing needed
- ⏳ Actual game class discovery needed
Loading