Skip to content

Dungeon Creation Adjustments, Dungeon Rewards WIP, and Mini Game Rewards - #375

Merged
AngeloTadeucci merged 9 commits into
MS2Community:masterfrom
Zintixx:dungeons
Mar 21, 2025
Merged

Dungeon Creation Adjustments, Dungeon Rewards WIP, and Mini Game Rewards#375
AngeloTadeucci merged 9 commits into
MS2Community:masterfrom
Zintixx:dungeons

Conversation

@Zintixx

@Zintixx Zintixx commented Mar 21, 2025

Copy link
Copy Markdown
Collaborator
  • Implements adjustments on dungeon creation
    • Now creates dungeons on first (aka instance channel)
    • Ability to reset dungeon
  • Ingest Reward data
  • Rudimentary dungeon rewards
    • Gives rewards upon completing dungeons (still needs tweaks on some rewards)
    • Weekly/mission rewards not implemented in this PR
  • Implemented most Mini Game reward triggers
  • Fixed Default plot on fields.
  • Updated trigger scripts for some changes on default value of parameters
  • Added missing values in FieldEnter packet
  • Adjusted check to disband party if all members are offline
  • Added GuildId and GuildName fetch on build player info to ensure it's set.

Summary by CodeRabbit

  • New Features

    • Player information now displays guild details for enhanced social connectivity.
    • Enhanced dungeon and mini-game systems with clearer state transitions, improved reward calculations, and streamlined party and field interactions.
    • New methods for creating and destroying dungeons have been added, enhancing dungeon management capabilities.
    • New properties for guild name and ID have been added to player information responses.
  • Bug Fixes

    • Updated banner notifications now show “GameOver” for accurate feedback.
    • Improved error messages for dungeon events offer more intuitive user guidance.

@coderabbitai

coderabbitai Bot commented Mar 21, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This pull request introduces a broad range of enhancements across the system. The changes extend the player information logic by incorporating guild details and update metadata storage with lazy-loaded tables for prestige and reward content. New parsing methods and enhanced error handling were added, along with numerous updates to dungeon and mini-game models and enums. The RPC and packet definitions now support field requests for creating and destroying dungeons, and dungeon management logic has been restructured throughout the server. Party, experience, and trigger systems have also been refined to accommodate the enhanced dungeon, field, and guild functionalities.

Changes

File(s) Change Summary
Maple2.Database/Storage/Game/GameStorage.User.cs
Maple2.Database/Storage/Game/GameStorage.cs
Enhanced GetPlayerInfo and BuildPlayerInfo methods to include guild ID and name.
Maple2.Database/Storage/Metadata/ServerTableMetadataStorage.cs
Maple2.Database/Storage/Metadata/TableMetadataStorage.cs
Added lazy-loaded fields for PrestigeIdExpTable and RewardContentTable in metadata storage.
Maple2.File.Ingest/Mapper/ServerTableMapper.cs
Maple2.File.Ingest/Mapper/TableMapper.cs
Introduced ParsePrestigeIdExpTable and ParseRewardContentTable methods; improved enum parsing using Enum.TryParse.
Maple2.File.Ingest/Utils/PyParameter.cs
Maple2.File.Ingest/Utils/TriggerDefinitionOverride.cs
Modified banner type mapping and updated default trigger values for dungeon_clear actions.
Maple2.Model/Enum/Dungeon.cs
Maple2.Model/Enum/FieldType.cs
Maple2.Model/Enum/InstanceType.cs
Added several new enums for dungeon mechanics and field types; reordered and renamed InstanceType members.
Maple2.Model/Error/DungeonRoomError.cs Updated error description for dungeon room errors.
Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs
Maple2.Model/Game/Dungeon/DungeonUserResult.cs
Maple2.Model/Game/Dungeon/IUserContentRecord.cs
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs
Introduced new models and interfaces for dungeon and mini-game records.
Maple2.Model/Game/FieldInstance.cs Removed the BlockChangeChannel parameter and updated default instance handling.
Maple2.Model/Game/RewardItem.cs Converted RewardItem to a record struct, added an implicit conversion operator, and introduced the new RewardRecord struct.
Maple2.Model/Game/User/PlotInfo.cs Removed the static default Plot instance from the Plot class.
Maple2.Model/Metadata/Constants.cs
Maple2.Model/Metadata/ServerTable/PrestigeIdExpTable.cs
Maple2.Model/Metadata/ServerTableMetadata.cs
Maple2.Model/Metadata/Table/RewardContentTable.cs
Maple2.Model/Metadata/TableMetadata.cs
Added new metadata structures for content rewards, prestige experience, and reward content with JSON type discriminators.
Maple2.Server.Core/proto/channel.proto
Maple2.Server.Core/proto/common.proto
Maple2.Server.Core/proto/world/world.proto
Introduced new RPC methods and messages for field requests, supporting dungeon creation and destruction.
Maple2.Server.Game/GameServer.cs Added CreateDungeon and DestroyDungeon methods to manage dungeon lifecycles.
Maple2.Server.Game/Manager/DungeonManager.cs
Maple2.Server.Game/Manager/ExperienceManager.cs
Maple2.Server.Game/Manager/Field/DungeonFieldManager.cs
Maple2.Server.Game/Manager/Field/FieldManager.Factory.cs
Maple2.Server.Game/Manager/Field/FieldManager.cs
Maple2.Server.Game/Manager/Field/IField.cs
Overhauled dungeon and field management with new properties (e.g., DungeonId, FieldType, Size) and methods, including LoadField, CompleteDungeon, ChangeState, and updated experience handling.
Maple2.Server.Game/Manager/PartyManager.cs
Maple2.Server.World/Containers/PartyManager.cs
Maple2.Server.World/Service/WorldService.Party.cs
Refined party disbanding and join logic; updated dungeon-related party properties and disband methods to consider the requestor’s ID.
Maple2.Server.Game/PacketHandlers/DungeonRoomHandler.cs
Maple2.Server.Game/Packets/DungeonRewardPacket.cs
Maple2.Server.Game/Packets/DungeonRoomPacket.cs
Maple2.Server.Game/Packets/DungeonWaitingPacket.cs
Maple2.Server.Game/Packets/FieldEnterPacket.cs
Maple2.Server.Game/Packets/PartyPacket.cs
Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs
Added new packet types and commands for dungeon rewards, room updates, waiting status, and field entry.
Maple2.Server.Game/Scripting/Scripts
Maple2.Server.Game/Service/ChannelService.Field.cs
Maple2.Server.Game/Service/ChannelService.cs
Maple2.Server.Game/Session/GameSession.State.cs
Maple2.Server.Game/Session/GameSession.cs
Maple2.Server.Game/Trigger/TriggerContext.*
Maple2.Server.Game/Util/Sync/PlayerInfoStorage.cs
Maple2.Server.World/Service/WorldService.Migrate.cs
Maple2.Server.World/Service/WorldService.Sync.cs
Expanded service methods, session state, triggers, and sync responses to support enhanced dungeon, mini-game, and guild functionalities, including adding guild data to player info.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ChannelService
    participant FieldManagerFactory as FieldManager.Factory
    participant DungeonManager

    Client->>ChannelService: Field(FieldRequest with CreateDungeon)
    ChannelService->>ChannelService: Validate request type
    ChannelService->>FieldManagerFactory: CreateDungeon(dungeonMetadata, ownerId, size, partyId)
    FieldManagerFactory-->>ChannelService: Return DungeonFieldManager or error
    ChannelService->>DungeonManager: Initialize dungeon lobby & set properties
    DungeonManager->>ChannelService: Return roomId in FieldResponse
    ChannelService->>Client: FieldResponse (roomId, error code)
Loading

Possibly related PRs

  • Bug fixes #329: The changes in the main PR, which enhance the GetPlayerInfo method by adding guild information, are related to the modifications in the retrieved PR that involve the GuildManager class, specifically the addition of a call to update the session's condition when setting a guild, indicating a connection through guild-related functionality.
  • FieldManager rework & Initial DungeonField implementation #341: The changes in the main PR, which enhance the GetPlayerInfo method to include guild information, are related to the modifications in the retrieved PR that introduce a new DungeonFieldManager class and various dungeon-related functionalities, as both involve updates to the data structures and methods that manage game state and player information.
  • Fix: Set Guild Id and Name for PlayerInfoUpdate #348: The changes in the main PR, which enhance the GetPlayerInfo method to include guild information, are directly related to the modifications in the retrieved PR that update the PlayerInfoUpdateExtensions class to handle guild ID and name updates, as both involve managing guild-related data for player information.

Suggested reviewers

  • AngeloTadeucci

Poem

I’m a rabbit hopping through code so fine,
With guilds and dungeons all in line.
New fields and methods make the system bright,
Enhancing quests from day to night.
Hop along—let’s debug and cheer,
For change and progress are finally here!
🐰🚀

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (17)
Maple2.Model/Enum/FieldType.cs (1)

4-6: Consider adding comments for all enum values for consistency.

While Random has a helpful explanatory comment, consider adding similar comments for Default and Dungeon values to maintain consistency and improve clarity for developers. Additionally, XML documentation for the enum itself would further enhance code documentation.

public enum FieldType : byte {
-    Default = 0,
+    Default = 0, // Standard field type
    Random = 1, // Random Rooms like Pocket Realms
-    Dungeon = 2
+    Dungeon = 2 // Dungeon instance fields
}
Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (2)

16-17: Consider documenting the purpose of the empty parameter writes.

The WriteInt() and WriteShort() methods are called without parameters, which differs from most other packet writers in the codebase. If this is intentional to write default values (0), consider adding a comment explaining why these fields are empty or what they represent in the packet structure.

  pWriter.WriteInt(dungeonId);
- pWriter.WriteInt();
- pWriter.WriteShort();
+ pWriter.WriteInt(); // Reserved field or unused parameter
+ pWriter.WriteShort(); // Reserved field or unused parameter

12-20: Consider adding method documentation.

It would be helpful to add a documentation comment that describes what this method does, what the dungeonId parameter represents, and when this packet is expected to be sent.

+ /// <summary>
+ /// Creates a packet to set the dungeon stage room information.
+ /// </summary>
+ /// <param name="dungeonId">The ID of the dungeon to set.</param>
+ /// <returns>A ByteWriter containing the packet data.</returns>
  public static ByteWriter Set (int dungeonId) {
      var pWriter = Packet.Of(SendOp.RoomStageDungeon);
      pWriter.Write<Command>(Command.Set);
      pWriter.WriteInt(dungeonId);
      pWriter.WriteInt();
      pWriter.WriteShort();

      return pWriter;
  }
Maple2.Server.Game/Model/Field/Widget/OxQuizWidget.cs (1)

54-54: Enhancement: Added debug formatting to quiz answers.

The change adds a newline and "[DebugMode]" prefix to quiz answers in development mode, making it more visually clear when debug information is being displayed during testing.

Consider using string interpolation for better readability:

-answer = question.IsTrue ? "\n[DebugMode] TRUE" : "\n[DebugMode] FALSE";
+answer = $"\n[DebugMode] {(question.IsTrue ? "TRUE" : "FALSE")}";
Maple2.Server.Game/Manager/Items/ItemDropManager.cs (1)

105-105: Using new C# 12 collection expression syntax

Good use of the modern C# 12 collection expression syntax to create an array literal [entry] instead of explicitly creating a new List. However, the GetAllGroups method signature on line 139 expects a List<IndividualDropItemTable.Entry>, which could potentially cause issues if the method internally uses List-specific operations.

Consider updating the GetAllGroups method signature to accept a more generic interface like IReadOnlyCollection<IndividualDropItemTable.Entry> or IEnumerable<IndividualDropItemTable.Entry> if it doesn't need to modify the collection:

-private IEnumerable<Item> GetAllGroups(GameSession session, int level, List<IndividualDropItemTable.Entry> entry, int index = -1) {
+private IEnumerable<Item> GetAllGroups(GameSession session, int level, IReadOnlyCollection<IndividualDropItemTable.Entry> entry, int index = -1) {
Maple2.Server.Game/Packets/DungeonWaitingPacket.cs (1)

1-15:

Details

❓ Verification inconclusive

Well-structured packet implementation

The DungeonWaitingPacket class follows the established pattern in the codebase for creating packets. The implementation is clean and focused on a single responsibility - creating a packet for dungeon waiting information.

One observation: Unlike other packet methods in the codebase (such as those in DungeonRoomPacket), this implementation doesn't include a Command enum after the operation code. If this is intentional based on the protocol specification, then it's fine. Otherwise, consider adding the appropriate command enum for consistency with other packet implementations.


🏁 Script executed:

#!/bin/bash
# Check if other simple packet classes follow similar pattern without Command enum
rg -A 10 "public static ByteWriter Set" --type cs | grep -v "Write<Command>"

Length of output: 14027


Action Required: Verify Consistency with Protocol Specification

After reviewing similar packet implementations in the codebase, the grep output indicates that many simple packet methods (including those in the RoomStageDungeonPacket and others) follow a pattern that does not include a command enum following the operation code. However, note that the original comment mentioned DungeonRoomPacket, which doesn’t seem to appear in our current repository context. Please confirm whether the omission of a Command enum in DungeonWaitingPacket is intentional per the protocol specification.

  • Verify if the protocol requires a Command enum that is missing.
  • Double-check if DungeonRoomPacket is still in use or has been renamed/replaced.

If the omission is by design, no changes are needed. Otherwise, consider adding the appropriate Command enum for consistency.

Maple2.Server.World/Service/WorldService.Migrate.cs (1)

114-132: Consider refactoring dungeon operation methods to reduce duplication.

Both CreateDungeon and DestroyDungeon methods contain nearly identical code for retrieving a client and forwarding the request. This could be refactored into a common helper method to improve maintainability.

- private FieldResponse CreateDungeon(FieldRequest request) {
-     if (!channelClients.TryGetClient(channelClients.FirstChannel(), out Channel.Service.Channel.ChannelClient? client)) {
-         return new FieldResponse {
-             Error = (int) MigrationError.s_move_err_no_server,
-         };
-     }
- 
-     return client.Field(request);
- }
- 
- private FieldResponse DestroyDungeon(FieldRequest request) {
-     if (!channelClients.TryGetClient(channelClients.FirstChannel(), out Channel.Service.Channel.ChannelClient? client)) {
-         return new FieldResponse {
-             Error = (int) MigrationError.s_move_err_no_server,
-         };
-     }
- 
-     return client.Field(request);
- }
+ private FieldResponse ProcessFieldRequest(FieldRequest request) {
+     if (!channelClients.TryGetClient(channelClients.FirstChannel(), out Channel.Service.Channel.ChannelClient? client)) {
+         return new FieldResponse {
+             Error = (int) MigrationError.s_move_err_no_server,
+         };
+     }
+ 
+     return client.Field(request);
+ }
+ 
+ private FieldResponse CreateDungeon(FieldRequest request) {
+     return ProcessFieldRequest(request);
+ }
+ 
+ private FieldResponse DestroyDungeon(FieldRequest request) {
+     return ProcessFieldRequest(request);
+ }

Additionally, consider whether using the first channel is always appropriate for dungeon operations, or if there are scenarios where a specific channel should be selected.

Maple2.Server.Game/Service/ChannelService.Field.cs (3)

9-18: Return a more descriptive error for unknown FieldRequest types.
Currently, the default case returns a blank FieldResponse. Consider returning an explicit error code or logging a warning to aid in troubleshooting unrecognized request types.


20-38: Consider logging successful dungeon creation.
After successfully creating a dungeon, generating a log entry or metric can help diagnose creation flow or track usage.


40-47: Add optional log message for destroyed dungeons.
Returning the MigrationError is correct. Including a debug log for successful or failed destruction could aid visibility into dungeon lifecycle operations.

Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (1)

280-280: Consider repetitive disposal attempts
Calling DisposeDungeon(dungeonField) each iteration when players remain could lead to frequent logs or overhead. You may wish to add a cooldown or check to limit repeated attempts.

Maple2.Server.Game/Manager/DungeonManager.cs (4)

28-31: Use consistent encapsulation for new fields
Lines 28, 30, 31 introduce new public fields/properties (Lobby, DungeonRoomRecord, UserRecord). Where possible, prefer private fields with public getters/setters or strongly consider using auto-properties to better control where the values can be mutated. This helps prevent unintentional modifications from external classes.


64-78: Clarify method naming or expand logic
The naming of Load() and LoadField() is slightly ambiguous, as LoadField() only sends a packet if it’s a dungeon lobby. Consider renaming them (e.g., InitializeDungeons() and CheckDungeonLobby()) or consolidating the logic if they are typically invoked together for initialization.


320-354: Ensure partition-based concurrency on dungeon completions
When multiple users finish at nearly the same time, concurrency might occur while awarding rewards or adding items. Ensure that awarding items and adding currency is thread-safe or that only one user triggers “completion” at a time. Otherwise, you risk race conditions or double awarding.


356-390: Check concurrency on dungeon reset
Similar to dungeon completion, resets triggered by multiple commands in quick succession could lead to concurrency issues (e.g., multiple attempts to destroy or reconfigure the same dungeon room). You may wish to guard against double resets or stale state to prevent undesired outcomes.

Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (2)

14-40: Allow custom logic upon mini-game end
The EndMiniGame method simply sends rewards (if applicable) and sets records to null. If you plan further expansions (e.g., a summary UI, stats tracking, logs, or secondary achievements), consider introducing event hooks or extension points here.


89-99: Check for external constraints during EXP awarding
MiniGameGiveExp adds mini-game EXP to every player in the box, ignoring potential level caps or EXP-block scenarios. If your game design includes maximum level or special conditions, ensure there are checks to avoid awarding unintended EXP.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e132cc and 480b69b.

📒 Files selected for processing (58)
  • Maple2.Database/Storage/Game/GameStorage.User.cs (1 hunks)
  • Maple2.Database/Storage/Game/GameStorage.cs (2 hunks)
  • Maple2.Database/Storage/Metadata/ServerTableMetadataStorage.cs (3 hunks)
  • Maple2.Database/Storage/Metadata/TableMetadataStorage.cs (3 hunks)
  • Maple2.File.Ingest/Mapper/ServerTableMapper.cs (3 hunks)
  • Maple2.File.Ingest/Mapper/TableMapper.cs (2 hunks)
  • Maple2.File.Ingest/Utils/PyParameter.cs (1 hunks)
  • Maple2.File.Ingest/Utils/TriggerDefinitionOverride.cs (1 hunks)
  • Maple2.Model/Enum/Dungeon.cs (1 hunks)
  • Maple2.Model/Enum/FieldType.cs (1 hunks)
  • Maple2.Model/Enum/InstanceType.cs (1 hunks)
  • Maple2.Model/Error/DungeonRoomError.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/DungeonUserResult.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/IUserContentRecord.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (1 hunks)
  • Maple2.Model/Game/FieldInstance.cs (1 hunks)
  • Maple2.Model/Game/RewardItem.cs (2 hunks)
  • Maple2.Model/Game/User/PlotInfo.cs (0 hunks)
  • Maple2.Model/Metadata/Constants.cs (2 hunks)
  • Maple2.Model/Metadata/ServerTable/PrestigeIdExpTable.cs (1 hunks)
  • Maple2.Model/Metadata/ServerTableMetadata.cs (1 hunks)
  • Maple2.Model/Metadata/Table/RewardContentTable.cs (1 hunks)
  • Maple2.Model/Metadata/TableMetadata.cs (1 hunks)
  • Maple2.Server.Core/proto/channel/channel.proto (1 hunks)
  • Maple2.Server.Core/proto/common.proto (1 hunks)
  • Maple2.Server.Core/proto/world/world.proto (1 hunks)
  • Maple2.Server.Game/GameServer.cs (2 hunks)
  • Maple2.Server.Game/Manager/DungeonManager.cs (6 hunks)
  • Maple2.Server.Game/Manager/ExperienceManager.cs (3 hunks)
  • Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (1 hunks)
  • Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (7 hunks)
  • Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (4 hunks)
  • Maple2.Server.Game/Manager/Field/FieldManager/IField.cs (2 hunks)
  • Maple2.Server.Game/Manager/Items/ItemDropManager.cs (1 hunks)
  • Maple2.Server.Game/Manager/PartyManager.cs (4 hunks)
  • Maple2.Server.Game/Model/Field/Widget/OxQuizWidget.cs (1 hunks)
  • Maple2.Server.Game/PacketHandlers/DungeonRoomHandler.cs (1 hunks)
  • Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1 hunks)
  • Maple2.Server.Game/Packets/DungeonRoomPacket.cs (2 hunks)
  • Maple2.Server.Game/Packets/DungeonWaitingPacket.cs (1 hunks)
  • Maple2.Server.Game/Packets/FieldEnterPacket.cs (2 hunks)
  • Maple2.Server.Game/Packets/PartyPacket.cs (2 hunks)
  • Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (1 hunks)
  • Maple2.Server.Game/Scripting/Scripts (1 hunks)
  • Maple2.Server.Game/Service/ChannelService.Field.cs (1 hunks)
  • Maple2.Server.Game/Service/ChannelService.cs (1 hunks)
  • Maple2.Server.Game/Session/GameSession.State.cs (2 hunks)
  • Maple2.Server.Game/Session/GameSession.cs (6 hunks)
  • Maple2.Server.Game/Trigger/TriggerContext.Dungeon.cs (3 hunks)
  • Maple2.Server.Game/Trigger/TriggerContext.Interface.cs (1 hunks)
  • Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (1 hunks)
  • Maple2.Server.Game/Util/Sync/PlayerInfoStorage.cs (1 hunks)
  • Maple2.Server.World/Containers/PartyManager.cs (5 hunks)
  • Maple2.Server.World/Service/WorldService.Migrate.cs (2 hunks)
  • Maple2.Server.World/Service/WorldService.Party.cs (2 hunks)
  • Maple2.Server.World/Service/WorldService.Sync.cs (1 hunks)
💤 Files with no reviewable changes (1)
  • Maple2.Model/Game/User/PlotInfo.cs
🧰 Additional context used
🧬 Code Definitions (27)
Maple2.Model/Metadata/ServerTableMetadata.cs (1)
Maple2.File.Ingest/Mapper/ServerTableMapper.cs (1) (1)
  • PrestigeIdExpTable (646-656)
Maple2.Server.Game/PacketHandlers/DungeonRoomHandler.cs (2)
Maple2.Server.Game/Manager/DungeonManager.cs (1) (1)
  • Reset (356-390)
Maple2.Server.Game/Manager/FishingManager.cs (1) (1)
  • Reset (39-52)
Maple2.Model/Game/RewardItem.cs (1)
Maple2.Server.Game/Session/GameSession.cs (1) (1)
  • RewardRecord (524-579)
Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (2)
Maple2.Server.Game/Packets/DungeonWaitingPacket.cs (1) (1)
  • ByteWriter (8-14)
Maple2.Server.Game/Packets/DungeonRoomPacket.cs (6) (6)
  • ByteWriter (21-31)
  • ByteWriter (33-39)
  • ByteWriter (41-48)
  • ByteWriter (50-63)
  • ByteWriter (65-72)
  • ByteWriter (74-84)
Maple2.Server.Game/Packets/FieldEnterPacket.cs (1)
Maple2.Model/Game/FieldInstance.cs (2) (2)
  • FieldInstance (7-22)
  • FieldInstance (13-16)
Maple2.Server.Game/Service/ChannelService.cs (5)
Maple2.Database/Storage/Metadata/TableMetadataStorage.cs (2) (2)
  • TableMetadataStorage (7-208)
  • TableMetadataStorage (130-188)
Maple2.Database/Storage/Metadata/ServerTableMetadataStorage.cs (2) (2)
  • ServerTableMetadataStorage (9-103)
  • ServerTableMetadataStorage (52-73)
Maple2.Server.Game/Service/ChannelService.Field.cs (1) (1)
  • ChannelService (8-47)
Maple2.Database/Storage/Game/GameStorage.User.cs (1) (1)
  • GameStorage (23-529)
Maple2.Database/Storage/Game/GameStorage.cs (2) (2)
  • GameStorage (10-71)
  • GameStorage (21-32)
Maple2.Database/Storage/Metadata/TableMetadataStorage.cs (2)
Maple2.Database/Storage/Metadata/ServerTableMetadataStorage.cs (1) (1)
  • Lazy (85-102)
Maple2.File.Ingest/Mapper/TableMapper.cs (1) (1)
  • RewardContentTable (1634-1686)
Maple2.Database/Storage/Game/GameStorage.cs (1)
Maple2.Database/Storage/Game/GameStorage.User.cs (4) (4)
  • PlayerInfo (100-140)
  • Character (74-92)
  • Character (455-465)
  • IList (312-358)
Maple2.Server.Game/GameServer.cs (1)
Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (3) (3)
  • DungeonFieldManager (146-201)
  • MigrationError (203-209)
  • MigrationError (292-308)
Maple2.Model/Metadata/ServerTable/PrestigeIdExpTable.cs (2)
Maple2.File.Ingest/Mapper/ServerTableMapper.cs (2) (2)
  • PrestigeIdExpTable (646-656)
  • ExpType (658-711)
Maple2.File.Ingest/Mapper/TableMapper.cs (1) (1)
  • ExpType (1235-1240)
Maple2.Server.Game/Service/ChannelService.Field.cs (4)
Maple2.Server.Game/Service/ChannelService.cs (2) (2)
  • ChannelService (7-23)
  • ChannelService (16-22)
Maple2.Server.Game/GameServer.cs (2) (2)
  • MigrationError (109-111)
  • DungeonFieldManager (105-107)
Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (3) (3)
  • MigrationError (203-209)
  • MigrationError (292-308)
  • DungeonFieldManager (146-201)
Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (2) (2)
  • DungeonFieldManager (11-69)
  • DungeonFieldManager (18-27)
Maple2.Server.Game/Session/GameSession.cs (3)
Maple2.Server.Game/Manager/PartyManager.cs (3) (3)
  • PartyManager (17-383)
  • PartyManager (28-39)
  • CheckDisband (203-214)
Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (2) (2)
  • DungeonFieldManager (11-69)
  • DungeonFieldManager (18-27)
Maple2.Server.Game/Manager/DungeonManager.cs (1) (1)
  • LoadField (70-78)
Maple2.Server.Game/Manager/PartyManager.cs (4)
Maple2.Server.Game/Manager/DungeonManager.cs (2) (2)
  • SetDungeon (207-214)
  • SetDungeon (305-318)
Maple2.Model/Game/Party/Party.cs (1) (1)
  • Party (11-63)
Maple2.Server.World/Containers/PartyManager.cs (1) (1)
  • Disband (241-250)
Maple2.Server.Game/Packets/PartyPacket.cs (1) (1)
  • PartyPacket (13-339)
Maple2.Server.World/Service/WorldService.Migrate.cs (2)
Maple2.Server.World/Containers/ChannelClientLookup.cs (4) (4)
  • TryGetClient (104-112)
  • FirstChannel (82-88)
  • Channel (25-48)
  • Channel (38-47)
Maple2.Server.Game/Service/ChannelService.Field.cs (2) (2)
  • FieldResponse (20-38)
  • FieldResponse (40-46)
Maple2.Server.World/Service/WorldService.Party.cs (2)
Maple2.Server.World/Containers/PartyManager.cs (12) (12)
  • Disband (241-250)
  • PartyManager (13-433)
  • PartyManager (19-22)
  • PartyError (94-130)
  • PartyError (132-156)
  • PartyError (158-185)
  • PartyError (187-209)
  • PartyError (211-239)
  • PartyError (269-305)
  • PartyError (307-338)
  • PartyError (372-412)
  • PartyError (414-432)
Maple2.Server.World/Containers/PartyLookup.cs (3) (3)
  • TryGet (36-38)
  • PartyError (51-70)
  • PartyError (72-84)
Maple2.Server.Game/Packets/DungeonRewardPacket.cs (2)
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (2) (2)
  • DungeonUserRecord (7-91)
  • DungeonUserRecord (23-35)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (2) (2)
  • MiniGameUserRecord (6-55)
  • MiniGameUserRecord (15-21)
Maple2.Model/Metadata/Table/RewardContentTable.cs (1)
Maple2.File.Ingest/Mapper/TableMapper.cs (3) (3)
  • RewardContentTable (1634-1686)
  • Dictionary (313-366)
  • Dictionary (1044-1091)
Maple2.Server.Game/Packets/DungeonWaitingPacket.cs (2)
Maple2.Server.Game/Packets/DungeonRoomPacket.cs (6) (6)
  • ByteWriter (21-31)
  • ByteWriter (33-39)
  • ByteWriter (41-48)
  • ByteWriter (50-63)
  • ByteWriter (65-72)
  • ByteWriter (74-84)
Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (1) (1)
  • ByteWriter (12-20)
Maple2.File.Ingest/Mapper/TableMapper.cs (4)
Maple2.Model/Metadata/TableMetadata.cs (1) (1)
  • TableMetadata (6-25)
Maple2.File.Ingest/MapperExtensions.cs (3) (3)
  • Dictionary (15-25)
  • Dictionary (27-37)
  • Dictionary (387-446)
Maple2.File.Ingest/Mapper/ServerTableMapper.cs (5) (5)
  • Dictionary (93-153)
  • Dictionary (155-215)
  • Dictionary (247-304)
  • Dictionary (306-363)
  • Dictionary (1459-1519)
Maple2.Model/Game/Item/Item.cs (4) (4)
  • Item (11-271)
  • Item (52-92)
  • Item (94-119)
  • Item (121-146)
Maple2.Server.Game/Manager/ExperienceManager.cs (3)
Maple2.Model/ModelExtensions.cs (2) (2)
  • ExpMessageCode (248-261)
  • ExpType (263-276)
Maple2.Server.Game/Packets/ExperienceUpPacket.cs (1) (1)
  • ExperienceUpPacket (8-34)
Maple2.Server.Game/Session/GameSession.cs (1) (1)
  • ConditionUpdate (510-513)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (1)
Maple2.Model/Game/RewardItem.cs (2) (2)
  • RewardRecord (34-39)
  • RewardRecord (41-46)
Maple2.Server.Game/Packets/PartyPacket.cs (1)
Maple2.Model/Game/Party/Party.cs (1) (1)
  • Party (11-63)
Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (3)
Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (2) (2)
  • DungeonFieldManager (11-69)
  • DungeonFieldManager (18-27)
Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (2) (2)
  • DungeonRoomRecord (7-17)
  • DungeonRoomRecord (14-16)
Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (2) (2)
  • Init (109-231)
  • Dispose (584-603)
Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (5)
Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (4) (4)
  • FieldManager (30-604)
  • FieldManager (81-106)
  • TryGetPlayerById (295-305)
  • Broadcast (573-582)
Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (2) (2)
  • DungeonRoomRecord (7-17)
  • DungeonRoomRecord (14-16)
Maple2.Model/Game/Dungeon/DungeonUserResult.cs (1) (1)
  • DungeonUserResult (13-17)
Maple2.Server.Game/Manager/Field/FieldManager/IField.cs (2) (2)
  • TryGetPlayerById (80-80)
  • Broadcast (68-68)
Maple2.Server.Game/Packets/DungeonRoomPacket.cs (1) (1)
  • DungeonRoomPacket (11-85)
Maple2.Server.Game/Manager/DungeonManager.cs (4)
Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (2) (2)
  • DungeonRoomRecord (7-17)
  • DungeonRoomRecord (14-16)
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (3) (3)
  • DungeonUserRecord (7-91)
  • DungeonUserRecord (23-35)
  • Add (37-45)
Maple2.Server.Game/Packets/DungeonRoomPacket.cs (1) (1)
  • DungeonRoomPacket (11-85)
Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1) (1)
  • DungeonRewardPacket (9-32)
Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (4)
Maple2.Server.Game/Trigger/TriggerContext.cs (2) (2)
  • TriggerContext (15-232)
  • TriggerContext (31-39)
Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1) (1)
  • DungeonRewardPacket (9-32)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (3) (3)
  • MiniGameUserRecord (6-55)
  • MiniGameUserRecord (15-21)
  • Add (23-33)
Maple2.Server.Game/Session/GameSession.cs (1) (1)
  • RewardRecord (524-579)
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (2)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (2) (2)
  • Add (23-33)
  • WriteTo (35-54)
Maple2.Model/Game/RewardItem.cs (2) (2)
  • RewardRecord (34-39)
  • RewardRecord (41-46)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: format
🔇 Additional comments (114)
Maple2.Server.Game/Scripting/Scripts (1)

1-1: Subproject Commit Update Verification

The updated subproject commit hash (a5694aea90d5ed1ee4c5f6e9ee06dcf6aab6810d) appears to be the only change in this file. Please verify that this new commit incorporates all the necessary changes for dungeon creation, rewards, and mini-game adjustments as described in the PR objectives. This update should have been tested against the overall integration to ensure that no unintended issues are introduced.

Maple2.Model/Metadata/Constants.cs (1)

114-119: Well-structured implementation of Content Rewards constants!

The addition of these reward constants is well-aligned with the PR objectives for implementing dungeon and mini-game rewards. The use of a read-only dictionary provides immutable access to these values, and the included comments clearly explain the purpose of each constant.

Maple2.Model/Enum/FieldType.cs (1)

3-7: Looks good! The enum is well-structured for the field type categorization.

The enum is correctly defined as a byte type for memory optimization and follows proper C# naming conventions. It provides a clear categorization for different field types which aligns with the PR objective of adjusting dungeon creation processes.

Maple2.File.Ingest/Utils/PyParameter.cs (1)

147-147: Banner type mapping updated correctly

The change from "BannerType.Fail" to "BannerType.GameOver" for value "5" appears to be a deliberate correction that aligns with the PR objectives of updating mini-game reward triggers. This mapping change will ensure the proper banner type is displayed when appropriate in-game events occur.

Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (1)

1-21: LGTM on the overall structure of this new packet handler.

The implementation follows the packet construction pattern used throughout the project. This new class correctly handles the RoomStageDungeon packet format, which appears to be part of the dungeon management enhancements mentioned in the PR objectives.

Maple2.File.Ingest/Mapper/TableMapper.cs (2)

82-82: Good addition of the reward content mapping

This line properly adds the mapping for reward content XML files, following the same pattern as other similar mappings in the Map() method.


1634-1686: Well-structured implementation of reward content parsing

The ParseRewardContentTable() method follows the same pattern as other parsing methods in the class, with clear separation between the different types of reward content data. The method handles base reward content, item rewards, meso rewards (both static and level-based), and experience rewards.

I particularly like the use of null-coalescing operators in lines 1667 and 1682 to handle potential null data.

Maple2.Server.Game/Packets/PartyPacket.cs (2)

129-129: Documentation improvement

Adding a clear comment to indicate that this boolean value is related to "Party Search" improves code readability and maintenance.


202-207: Enhanced parameter usage and clarity

Renaming the parameter from message2 to systemSoundKey makes its purpose much clearer. Additionally, you're now correctly using this parameter value in the packet (line 207) instead of an empty string, allowing sound effects to be sent with party notifications. The comment example "Field_Enterance_Reset_Dungeon" provides helpful context for developers.

Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (4)

74-76: New properties to support dungeon functionality

These new properties with init accessors enhance the FieldManager class to properly support dungeon management. DungeonId identifies associated dungeons, Size likely controls dungeon capacity, and FieldType categorizes the field type. These additions align with the PR objective of implementing dungeon creation adjustments.


105-105: Default initialization for FieldType property

The FieldType property is correctly initialized to FieldType.Default in the constructor, establishing proper default behavior for new field instances.


123-123: Simplified FieldInstance initialization

The constructor call for FieldInstance has been simplified by removing the blockChangeChannel: true parameter. This change supports the PR objective of allowing dungeon creation on the first instance channel.


134-139: Fixed default plot initialization

Replaced Plot.Default with a properly initialized Plot instance using a UgcMapGroup with appropriate nested objects. This addresses the PR objective of "fixing the default plot on fields."

Maple2.Server.Game/PacketHandlers/DungeonRoomHandler.cs (1)

45-47: Implementation of dungeon reset functionality looks good.

The added line now properly delegates the reset functionality to the Dungeon manager, aligning with the PR objectives of allowing dungeon resets. The DungeonManager.Reset() method contains appropriate validation and error handling, including checking if the session has a party and if the current character is the party leader.

Maple2.Server.Game/Session/GameSession.State.cs (2)

2-2: New import added for Dungeon functionality.

This import aligns with the PR objectives of implementing dungeon creation adjustments and rewards. The import is needed for the Dungeon-related models and types.


48-48:

Details

✅ Verification successful

New MiniGameRecord field added for tracking mini-game state.

This nullable field enables the GameSession to track information about mini-games for the current player session, which aligns with the PR objectives of implementing "mini-game reward triggers". As a nullable reference type, it properly indicates that a player may not always be participating in a mini-game.

Make sure that any code that uses this field properly checks for null before accessing it to avoid null reference exceptions. Also, confirm that this field is properly initialized when a player starts a mini-game and cleared when they exit one.


🏁 Script executed:

#!/bin/bash
# Search for places where MiniGameRecord is assigned or accessed
rg "MiniGameRecord\s*=" --type cs
rg "MiniGameRecord\s*\?" --type cs
rg "MiniGameRecord\s*\." --type cs

Length of output: 2222


Attention: Verified MiniGameRecord Implementation and Usage

The newly added nullable MiniGameRecord field in Maple2.Server.Game/Session/GameSession.State.cs is used consistently throughout the codebase. The shell script results confirm that:

  • The field is explicitly set to null when appropriate (e.g., in GameSession.cs).
  • Nullable checks (e.g., if (player.Session.MiniGameRecord == null)) are in place in TriggerContext.MiniGame.cs.
  • The field is correctly initialized—assigning a new MiniGameUserRecord when needed—and subsequently used safely (accessing properties like ShowResult, calling .Add, and manipulating Rewards).

There are no further concerns regarding potential null reference exceptions as long as these checks remain consistent. Please continue to ensure that any additional modifications uphold this pattern.

Maple2.File.Ingest/Utils/TriggerDefinitionOverride.cs (1)

264-264:

Details

❓ Verification inconclusive

Updated default parameter handling for dungeon_clear action.

The default value for the uiType parameter has been changed from a string value "None" to null. This change aligns with the dungeon creation adjustments mentioned in the PR objectives, likely affecting how UI behaves during dungeon clear events.

Since this change could affect trigger script behavior, verify that existing scripts using this action continue to work properly.


🏁 Script executed:

#!/bin/bash
# Search for any scripts using the dungeon_clear action to ensure they work with the new null default
rg -A 2 -B 2 "dungeon_clear" --type xml

Length of output: 188


Below is a revised review comment. Since the initial ripgrep command (using the XML file type filter) did not actually search any files—likely due to an overly restrictive filter—we need manual verification (or a broader search) to ensure that no trigger scripts using the dungeon_clear action are impacted by the updated default parameter. You might consider running the following broader command to search the entire repository:

#!/bin/bash
# Search the entire repository for references to "dungeon_clear" to verify that none of the associated scripts are adversely affected.
rg -A 2 -B 2 "dungeon_clear" .

Manual Verification Required – Verify dungeon_clear Script Behavior

  • The uiType default now being set to null (instead of "None") is consistent with the recent dungeon creation changes.
  • Because the previous search command (filtered to XML files) returned no results, please ensure that any scripts (regardless of file type) that might be using the dungeon_clear action are checked for compatibility with the new default.

Once you confirm that the trigger scripts behave as expected, we can consider this aspect of the PR as verified.

Maple2.Model/Metadata/ServerTableMetadata.cs (1)

37-37: Added support for prestige ID experience table serialization.

This addition registers the PrestigeIdExpTable class with the JSON serialization system, allowing it to be properly deserialized from JSON data with the discriminator "prestigeIdExpTable". This supports the parsing functionality seen in ServerTableMapper.ParsePrestigeIdExpTable().

Maple2.Model/Error/DungeonRoomError.cs (1)

33-33: Improved error message clarity.

The description for s_room_dungeon_AlreadyLapentaHall has been updated from a placeholder with a map ID to a more user-friendly message. This improves the player experience by providing a clearer explanation when this error occurs.

Maple2.Model/Metadata/TableMetadata.cs (1)

82-82: Added reward content table for JSON serialization.

This change registers the RewardContentTable class with the JSON serialization system, which supports the dungeon reward system implementation mentioned in the PR objectives. This allows for proper serialization and deserialization of reward content data.

Maple2.Server.Game/Manager/Field/FieldManager/IField.cs (2)

23-23: Clean addition of a DungeonId property.

The property is well-placed in the interface and aligns with the PR's goal of enhancing dungeon creation and management capabilities.


56-57: Good addition of FieldType and Size properties.

These properties will be valuable for distinguishing between different field types (especially dungeons) and defining their dimensions. The use of init accessor for Size ensures its immutability after initialization, which is a good practice.

Maple2.Database/Storage/Metadata/TableMetadataStorage.cs (3)

48-48: Clean addition of reward content table field.

The private field follows the established pattern used throughout this class, using lazy loading for efficient resource management.


109-109: Good implementation of RewardContentTable property.

The property provides a clean interface to access the lazy-loaded table value, consistent with other properties in this class.


171-171: Proper initialization of rewardContentTable.

The initialization follows the same pattern as other tables, using the Retrieve method with the appropriate XML pattern. This ensures consistency with the rest of the codebase.

Maple2.Server.Game/Packets/FieldEnterPacket.cs (3)

2-2: Appropriate addition of the FieldType enum namespace.

This import is necessary for the changes made to write the field type in the packet.


19-19: Good implementation of field type serialization.

The code now writes the field type to the packet, allowing clients to distinguish between different field types (like dungeons, default fields, etc.).


21-21: Proper serialization of dungeon ID.

This change ensures the dungeon ID is properly communicated to the client, which is essential for dungeon-related functionality.

Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (3)

1-6: Well-structured namespace and imports.

The imports and namespace are appropriately organized. The ConcurrentDictionary is a good choice for managing concurrent access to user results.


7-13: Clean implementation of DungeonRoomRecord properties.

The class design is appropriate for tracking dungeon room data:

  • Using a concurrent dictionary for thread-safe access to user results
  • Read-only metadata reference ensures it can't be changed after initialization
  • Start/end tick properties for timing
  • State property with a reasonable default value

14-17: Simple and effective constructor.

The constructor properly initializes the essential metadata property while leaving other properties to be set elsewhere as needed.

Maple2.Model/Enum/InstanceType.cs (1)

9-17: Enum values reordered for better organization and additional context added

The enum values have been reordered to keep a consistent numbering scheme, with GuildEvent now at 6, GuildPvp at 7, and DungeonLobby at 8. Comments have been added to indicate which values are not confirmed, providing clarity for future development.

This change supports the dungeon creation adjustments mentioned in the PR objectives by properly defining the DungeonLobby instance type.

Maple2.Model/Metadata/Table/RewardContentTable.cs (1)

1-32: Well-structured data model for reward content implemented

This new file creates a comprehensive data model for storing various types of reward content, including base entries, items, meso, and experience points. The structure uses immutable records with clear property names and appropriate data types.

The implementation aligns perfectly with the PR objectives of "ingesting reward data" and establishing "rudimentary dungeon rewards." The model supports all the necessary data types mentioned in the related reward processing code.

Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1)

9-32: Clean implementation of dungeon and mini-game reward packets

The new packet definitions follow a consistent pattern for both dungeon and mini-game rewards. The Command enum clearly defines the different packet types, and the methods properly serialize the corresponding user record classes.

This implementation directly supports the PR objectives related to implementing dungeon rewards and mini-game reward triggers.

Maple2.Model/Game/FieldInstance.cs (2)

7-9: Simplified FieldInstance initialization

The static Default instance has been updated to use the new constructor signature that no longer includes the BlockChangeChannel parameter.


13-16: Simplified FieldInstance constructor

The constructor has been streamlined by removing the BlockChangeChannel parameter, simplifying the API and reducing potential confusion.

This change aligns with the PR objectives of adjusting the dungeon creation process, suggesting that blocking channel changes is now handled differently or is no longer needed for the enhanced dungeon functionality.

Maple2.Model/Enum/Dungeon.cs (6)

79-100: Great implementation of DungeonAccumulationRecordType enum

The enum is well-defined with descriptive attributes that will be useful for UI display. The naming is consistent and the values cover a comprehensive range of metrics to track in dungeon gameplay.


102-108: LGTM: DungeonState enum implementation

The enum values are clearly defined with appropriate description attributes for user-facing messages.


110-118: LGTM: DungeonGrade enum implementation

Good implementation with a logical progression from F to SPlus grades, with None as a default state.


120-124: LGTM: DungeonRewardType enum implementation

Simple and concise definition of reward types that aligns well with the PR objectives for implementing dungeon rewards.


126-136: LGTM: DungeonBonusFlag enum implementation

Good use of [Flags] attribute for bit flags that can be combined. The values follow the binary pattern as expected for flags (0, 2, 4, 8, 16, etc.).


138-143: LGTM: DungeonBonusFlag2 enum implementation

Properly implemented as flags enum with appropriate naming for the specific bonus flags.

Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (4)

6-13: Well-structured MiniGameUserRecord class with appropriate properties

The class has all the necessary properties to track user records in mini-games, implemented with proper initialization of collections.


15-21: LGTM: Constructor properly initializes rewards dictionary

The constructor correctly initializes the character ID and populates the Rewards dictionary with all enum values, setting their initial values to 0.


23-33: LGTM: Add method with appropriate null check

The Add method correctly updates reward values and includes a proper null check before iterating through items.


35-54: LGTM: Complete WriteTo implementation

The WriteTo method correctly serializes all record data to the byte writer in a logical order.

Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (4)

7-22: Well-structured DungeonUserRecord class with appropriate properties

The class has a comprehensive set of properties to track user performance and rewards in dungeons. The use of ConcurrentDictionary for AccumulationRecords is a good choice for thread safety.


23-35: LGTM: Constructor properly initializes collections

The constructor correctly sets up the necessary dictionaries for accumulation records and rewards.


47-64: LGTM: First part of WriteTo implementation

This section properly serializes the dungeon success state, IDs, and other metadata.


66-90: LGTM: Item and bonus reward serialization in WriteTo

These sections correctly serialize the reward items and bonus rewards.

Maple2.Server.Core/proto/world/world.proto (1)

15-16: LGTM: New Field RPC method

This addition aligns with the PR objective of implementing dungeon creation adjustments. It follows the existing pattern in the file and is well-commented.

Maple2.Server.Core/proto/channel/channel.proto (1)

10-11: Well-implemented RPC addition for field management!

The new Field RPC method is a clean addition to the Channel service, following the established pattern of other RPC methods in this service. This aligns with the PR objectives for implementing dungeon creation adjustments.

Maple2.Server.Game/Trigger/TriggerContext.Interface.cs (1)

78-80: Good optimization to prevent unnecessary broadcasts

This conditional check prevents broadcasting round events when minimum and maximum round values are identical, which is a sensible optimization.

Maple2.Model/Game/Dungeon/IUserContentRecord.cs (1)

6-10: Well-designed interface for user content records

This interface establishes a clean contract for classes that handle dungeon and mini-game rewards, aligning perfectly with the PR objectives. The properties are clearly defined and the extension of IByteSerializable ensures implementations will handle serialization correctly.

Maple2.Model/Game/Dungeon/DungeonUserResult.cs (1)

6-18: Well-structured result object for dungeon performance

The struct is well-designed with appropriate memory layout attributes and a clear separation between immutable and mutable fields. This is perfect for efficiently representing user performance in dungeons and will work well with the reward system being implemented.

Maple2.Server.Game/Util/Sync/PlayerInfoStorage.cs (1)

46-47: Guild information enhancement looks good.

The addition of GuildName and GuildId properties to the CharacterInfo object completes the player information by including guild-related data, which aligns with the PR objective of fetching GuildId and GuildName during player info construction.

Maple2.Model/Metadata/ServerTable/PrestigeIdExpTable.cs (1)

5-12: Well-structured record definition for prestige experience data.

This new PrestigeIdExpTable record provides a clean structure for storing prestige ID experience mapping data, supporting the dungeon rewards implementation mentioned in the PR objectives. The record pattern is appropriate for this type of immutable metadata.

Maple2.Server.World/Service/WorldService.Sync.cs (1)

39-40: Properly extends PlayerInfoResponse with guild information.

The addition of GuildName and GuildId to the PlayerInfoResponse ensures that the guild data is properly propagated from the World service to the Game service, consistent with the earlier changes in PlayerInfoStorage.

Maple2.Server.Game/Packets/DungeonRoomPacket.cs (2)

16-16: New command enum for dungeon results.

Adding the DungeonResult command allows for packet communication of dungeon completion results, supporting the "Dungeon Rewards WIP" objective mentioned in the PR.


50-63: Comprehensive packet creation for dungeon results.

The implementation follows the established pattern in the class and properly serializes all necessary information for dungeon results, including player statistics and reward information. This supports the dungeon rewards implementation mentioned in the PR objectives.

A few observations:

  1. The method handles a variable number of player results appropriately
  2. All required fields (character ID, grade, record type, and value) are included in the packet
  3. The implementation is consistent with other packet construction methods in the class
Maple2.Server.Game/GameServer.cs (3)

7-7: Added necessary import for error handling.

The addition of Maple2.Model.Error import supports the new dungeon management functionality while maintaining clean code organization.


105-107: Well-structured facade method for dungeon creation.

This method provides a clean interface to the dungeon creation functionality by delegating to the field factory. Good separation of concerns.


109-111: Well-structured facade method for dungeon destruction.

The method provides a clear interface for destroying dungeons while properly returning MigrationError to inform callers about the outcome of the operation.

Maple2.Server.Core/proto/common.proto (2)

5-19: Well-structured protocol definition for field operations.

The FieldRequest message with its nested messages provides a clean way to handle different field operations (creating and destroying dungeons) while maintaining a single entry point. The oneof construct ensures type safety and clear request structure.


21-24: Clear response structure for field operations.

The FieldResponse includes both an error code and room ID, which provides sufficient information for the client to handle the response appropriately.

Maple2.Database/Storage/Metadata/ServerTableMetadataStorage.cs (1)

19-19: Added support for new prestige ID experience table.

The additions properly follow the established pattern of lazy-loaded metadata tables in the class. This supports the new reward functionality while maintaining consistency with the existing code structure.

Also applies to: 40-40, 62-62

Maple2.Server.Game/Session/GameSession.cs (5)

303-303: Moved PartyManager initialization to EnterField.

Moving the PartyManager initialization from EnterServer to EnterField ensures that party-related functionality is only available after the player has successfully entered a field, which can prevent potential issues with party management during the initialization phase.


332-332: Reset MiniGameRecord when leaving field.

Adding MiniGameRecord = null ensures proper cleanup of mini-game state when leaving a field, preventing potential state leakage between different game sessions.


354-363: Improved dungeon field navigation logic.

The enhanced logic properly checks if the target map is either a room in the current dungeon or the dungeon lobby, with a fallback to migrate out of the instance if neither condition is met. This provides clearer handling of dungeon navigation.


558-579: Well-implemented item reward handling with appropriate fallback.

The implementation properly handles item creation, level restrictions, and inventory management. The fallback to mail items when inventory is full is a good design decision that ensures players receive all rewards.


698-698: Added party cleanup on session disconnect.

The call to Party.CheckDisband() ensures that party resources are properly cleaned up when a player disconnects, preventing orphaned party instances and helping to maintain system integrity.

Maple2.Server.Game/Trigger/TriggerContext.Dungeon.cs (5)

8-15: Good defensive coding added to prevent errors.

The addition of early return checks ensures that the dungeon clear logic only executes under appropriate conditions. First validating that the field is a dungeon field manager, then checking if the UI should be displayed based on the uiType parameter helps prevent potential errors and improves control flow.


17-17: Improved dungeon state management.

Using the ChangeState method on the dungeon field manager provides a cleaner way to handle state transitions, making the code more maintainable and easier to understand than direct state assignments.


120-120: Helpful debug logging added.

Adding debug logging at the beginning of this check provides valuable information for troubleshooting dungeon lobby user count issues.


125-125: Simplified size check logic.

The player count check has been simplified to directly compare against the dungeon field's size property, making the code more readable and maintainable.


135-135: Simplified dungeon room check.

The IsDungeonRoom method has been simplified to use type checking rather than property validation, which is cleaner and more efficient.

Maple2.Model/Game/RewardItem.cs (4)

7-7: Good usage of record struct.

Converting RewardItem to a record struct provides value-based equality and immutability features, which is ideal for data transfer objects like this reward representation.


23-25: Useful implicit conversion operator.

Adding an implicit conversion from Item to RewardItem simplifies code that needs to work with both types, reducing the need for manual conversion and making the API more user-friendly.


28-39: Well-designed RewardRecord structure.

The new RewardRecord struct provides a clean way to encapsulate multiple reward items along with currency and experience values, which aligns perfectly with the PR objective of implementing dungeon rewards.


41-46: Convenient constructor overload.

This constructor overload that accepts Item objects and converts them to RewardItems demonstrates good API design by allowing flexibility in how rewards are created.

Maple2.Server.Game/Service/ChannelService.cs (2)

11-11: Adding TableMetadataStorage dependency.

Adding the TableMetadataStorage field will allow access to dungeon and reward metadata, which is necessary for the dungeon creation adjustments mentioned in the PR objectives.


16-22: Updated constructor with new dependency.

The constructor has been properly updated to accept and initialize the new TableMetadataStorage dependency, maintaining proper dependency injection practices.

Maple2.Database/Storage/Game/GameStorage.User.cs (2)

131-136: Added guild information retrieval.

The new code effectively retrieves guild information by joining the GuildMember and Guild tables. The use of a Tuple to store both the guild ID and name is a clean approach, and the null coalescing operator handles the case when a player is not in a guild.


139-139: Updated BuildPlayerInfo call with guild data.

The BuildPlayerInfo method call now includes guild information as parameters, fulfilling the PR objective of "fetching of GuildId and GuildName during player info construction."

Maple2.Database/Storage/Game/GameStorage.cs (1)

49-68: Guild information is now properly incorporated into PlayerInfo.

The method signature has been updated to include guild-related parameters, and these parameters are now used in both branches of the conditional logic to ensure guild information is consistently available in the PlayerInfo object.

Maple2.Server.Game/Manager/PartyManager.cs (3)

93-95: Properly initializing dungeon properties from PartyInfo.

These property initializations ensure that when a party is set, the dungeon-related properties are correctly maintained, supporting the dungeon creation functionality mentioned in the PR objectives.


203-214: Simplified party disbanding logic.

The CheckDisband method has been refactored to always send a disband request to the world service without first checking for online members. This moves the responsibility of checking online members to the world service, centralizing the party-related logic.


299-301: Added notification for dungeon reset.

This enhancement provides better user feedback when dungeons are reset by sending a party notice when Party.DungeonId is set to zero.

Maple2.File.Ingest/Mapper/ServerTableMapper.cs (3)

46-46: Added support for processing adventureIdExpTable.xml.

This addition enables the system to parse and utilize data from the adventureIdExpTable.xml file, enhancing the mapping capabilities. This aligns with the PR objectives related to ingesting reward data.


67-67: Improved error handling in instance field type parsing.

Replaced direct casting with Enum.TryParse to safely convert instance types, preventing potential runtime exceptions if invalid values are encountered. The code now defaults to InstanceType.none if parsing fails.


646-656: Added method to parse prestige ID experience table.

The new ParsePrestigeIdExpTable method properly constructs a PrestigeIdExpTable from parsed adventure ID experience data, following the established pattern of other parsing methods in the class.

Maple2.Server.World/Service/WorldService.Migrate.cs (1)

103-112: Added Field request handling to support dungeon operations.

The new Field method routes requests to appropriate handlers based on the FieldCase, enabling support for dungeon creation and destruction operations. This aligns with the PR objectives related to dungeon creation adjustments.

Maple2.Server.World/Service/WorldService.Party.cs (2)

25-25: Confirm all DisbandParty method invocations follow new signature.
The updated call, now passing request.RequestorId and request.Disband, properly aligns with the revised DisbandParty signature.


63-70: Ensure robust handling of requestor privileges within the disband workflow.
The updated method references manager.Disband(requestorId), relying on PartyManager to handle leadership or permission checks. This approach is valid so long as PartyManager consistently enforces authority requirements.

Maple2.Server.Game/Manager/ExperienceManager.cs (2)

99-109: Good improvement returning gained experience.
Converting from void to long return type helps track how many points were actually awarded. The early return of 0 when expGained <= 0 also promotes clarity.


111-151: Consistent return usage for experience addition by type.
This method properly returns 0 when the experience type is invalid or the table lookups fail, and delegates to AddExp(...) otherwise. The approach aligns with the first AddExp method's new return conventions.

Maple2.Server.World/Containers/PartyManager.cs (3)

86-87: Confirm disband conditions for edge cases
Disbanding if fewer than 2 members are online or the total member count is ≤ 2 may be intentional. However, if you plan to keep 2-member parties when both are online, you might need to revise this logic.


142-142: Validate direct assignment of player info
Assigning Info = info stores the reference directly rather than creating a copy. Verify if this is intentional, as changes to info outside this scope could affect the stored PartyMember.


419-419: No immediate concerns
Assigning Party.DungeonSet = set; appears straightforward. Ensure other parts of the code consistently reference this property.

Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.Factory.cs (5)

8-8: Import changes
No issues with adding using Maple2.Model.Error; to handle migration/error codes.


10-10: Import of dungeon-related classes
Including using Maple2.Model.Game.Dungeon; aligns with the new dungeon handling methods below.


146-168: Check concurrency in dungeon creation
Creating a lobby field and subfields is a multi-step process involving metadata loading, record creation, and initialization. Confirm thread-safety if multiple calls to CreateDungeon use the same metadata concurrently.


203-209: Destroy method return flow
The method correctly returns an error if the dungeon is absent or proceeds to dispose it. Ensure concurrency safety if multiple actors request destruction at the same time.


292-308: Verify multi-threaded disposal correctness
Ensure that no players can join while the dungeon is being disposed. The concurrency checks on RoomFields and dungeons look correct, but concurrency across multiple threads could still pose issues.

Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (6)

3-4: New imports for enums and dungeon classes
The imports for Maple2.Model.Enum and Maple2.Model.Game.Dungeon correctly support the new dungeon features.


6-7: Additional references for model and packet logic
These imports (Maple2.Server.Game.Model and Maple2.Server.Game.Packets) integrate with the methods handling dungeon state changes and packet broadcasting.


12-12: Dungeon metadata as a read-only field
Declaring DungeonMetadata as readonly ensures consistency with other immutable definitions, preventing accidental reassignment.


15-16: Examining data flow for DungeonRoomRecord and PartyId
Exposing these properties is fine, but confirm that external code uses them correctly, especially for merging party and dungeon logic.


18-27: Constructor parameter alignment
Setting DungeonMetadata, DungeonId, Size, and PartyId in one place is clean. However, ensure Lobby = this; only applies when the metadata truly matches the current mapMetadata.Id.


29-67: Ensure stability in ChangeState
The state transition logic compiles user records, broadcasts results, and calls CompleteDungeon if cleared. Confirm that player data is updated or saved appropriately before disposal.

Maple2.Server.Game/Manager/DungeonManager.cs (1)

218-255: Validate party size for large groups
When creating a dungeon with a party (lines 229–237), the number of members is used directly as size. Depending on the constraints of the dungeon, you might want to ensure the party size does not exceed the maximum allowable. Failing to do so could result in a mismatch between the requested dungeon size and actual capacity.

Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (3)

42-80: Handle partial round completions more clearly
EndMiniGameRound increments ClearedRounds for winners while awarding loser bonuses if isGainLoserBonus is true. This logic is sound, but be mindful of partial round completions or tie scenarios. You may want to track a “no winners found” edge case or handle special draw conditions where no one is in the “winning” box.


82-87: Camera direction logic is straightforward
Sending CameraPacket.Local(...) to all players in the specified box is clear and minimal. Ensure that cameraId values correspond to valid cameras or handle invalid IDs gracefully to avoid confusion in the player's client.


117-127: Initialize MiniGameUserRecord carefully
The StartMiniGame method sets each MiniGameRecord with MinRound = 1; if you need more nuanced behaviors (e.g., some mini-games start from round 0 or might skip rounds), ensure these fields are dynamically set or validated.

Comment thread Maple2.Model/Game/Dungeon/DungeonUserRecord.cs
Comment thread Maple2.Model/Game/Dungeon/DungeonUserRecord.cs Outdated
Comment thread Maple2.Server.Game/Session/GameSession.cs
Comment thread Maple2.Server.World/Containers/PartyManager.cs
Comment thread Maple2.Server.Game/Manager/DungeonManager.cs
Comment thread Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs
Comment thread Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs
Comment thread Maple2.Server.Game/Trigger/TriggerContext.Dungeon.cs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (1)

137-139: ⚠️ Potential issue

Avoid returning prematurely inside a multi-player loop.

If one player in the loop has reached the TotalRounds == MinRound, the method StartMiniGameRound returns immediately, bypassing the round start for other players. This may lead to inconsistent states among participants.

Apply this diff to fix the issue:

-if (player.Session.MiniGameRecord.TotalRounds == player.Session.MiniGameRecord.MinRound) {
-    return;
-}
+if (player.Session.MiniGameRecord.TotalRounds == player.Session.MiniGameRecord.MinRound) {
+    continue;
+}
Maple2.Server.Game/Manager/DungeonManager.cs (1)

287-300: ⚠️ Potential issue

Guard for invalid indexes in field IDs

The code accesses Metadata.FieldIds[0] without verifying that FieldIds is non-empty. This could lead to an IndexOutOfRangeException if the array is empty.

Apply this change to add a guard clause:

if (Lobby == null || Metadata == null || Lobby.RoomFields.IsEmpty) {
    logger.Error("Field is null, cannot enter dungeon");
    return;
}

+if (Metadata.FieldIds.Length == 0) {
+    logger.Error("Dungeon has no field IDs, cannot enter dungeon");
+    return;
+}

if (!Lobby.RoomFields.TryGetValue(Metadata.FieldIds[0], out DungeonFieldManager? firstField)) {
    logger.Error("First field is null, cannot enter dungeon");
    return;
}
🧹 Nitpick comments (2)
Maple2.Model/Game/RewardItem.cs (1)

28-46: Well-designed RewardRecord structure.

The new RewardRecord struct effectively encapsulates all reward components (items, experience, prestige experience, and meso) in a single immutable package. The dual constructors provide flexibility, allowing creation from either RewardItem collections or Item collections. This aligns well with the PR objectives for implementing dungeon and mini-game rewards.

Two minor observations:

  1. The Items property initializes with = [] which uses C# 12 collection expressions - ensure your target framework supports this.
  2. Consider adding a parameterless constructor to create empty rewards (similar to what's used in GetRewardContent when metadata isn't found).
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (1)

7-21: Consider encapsulating fields with properties for better maintainability.

Exposing multiple public fields directly can quickly lead to maintenance issues and unintended modifications. Using properties or private fields with public getters and setters fosters better encapsulation and helps maintain consistent usage across the codebase.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 480b69b and 8596629.

📒 Files selected for processing (10)
  • Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (1 hunks)
  • Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (1 hunks)
  • Maple2.Model/Game/RewardItem.cs (2 hunks)
  • Maple2.Model/Metadata/Constants.cs (1 hunks)
  • Maple2.Server.Game/Manager/DungeonManager.cs (6 hunks)
  • Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (4 hunks)
  • Maple2.Server.Game/Packets/DungeonWaitingPacket.cs (1 hunks)
  • Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs (1 hunks)
  • Maple2.Server.Game/Trigger/TriggerContext.Dungeon.cs (3 hunks)
  • Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • Maple2.Server.Game/Packets/RoomStageDungeonPacket.cs
  • Maple2.Server.Game/Packets/DungeonWaitingPacket.cs
  • Maple2.Model/Metadata/Constants.cs
  • Maple2.Server.Game/Trigger/TriggerContext.Dungeon.cs
  • Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs
🧰 Additional context used
🧬 Code Definitions (4)
Maple2.Model/Game/RewardItem.cs (1)
Maple2.Server.Game/Session/GameSession.cs (1) (1)
  • RewardRecord (524-579)
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (2)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (2) (2)
  • Add (23-31)
  • WriteTo (33-52)
Maple2.Model/Game/RewardItem.cs (2) (2)
  • RewardRecord (34-39)
  • RewardRecord (41-46)
Maple2.Server.Game/Manager/DungeonManager.cs (5)
Maple2.Server.Game/Manager/Field/FieldManager/DungeonFieldManager.cs (2) (2)
  • DungeonFieldManager (11-69)
  • DungeonFieldManager (18-27)
Maple2.Model/Game/Dungeon/DungeonRoomRecord.cs (2) (2)
  • DungeonRoomRecord (7-17)
  • DungeonRoomRecord (14-16)
Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (3) (3)
  • DungeonUserRecord (7-91)
  • DungeonUserRecord (23-35)
  • Add (37-45)
Maple2.Server.Game/Packets/DungeonRoomPacket.cs (1) (1)
  • DungeonRoomPacket (11-85)
Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1) (1)
  • DungeonRewardPacket (9-32)
Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (3)
Maple2.Server.Game/Trigger/TriggerContext.cs (2) (2)
  • TriggerContext (15-232)
  • TriggerContext (31-39)
Maple2.Server.Game/Packets/DungeonRewardPacket.cs (1) (1)
  • DungeonRewardPacket (9-32)
Maple2.Model/Game/Dungeon/MiniGameUserRecord.cs (3) (3)
  • MiniGameUserRecord (6-53)
  • MiniGameUserRecord (15-21)
  • Add (23-31)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (22)
Maple2.Model/Game/RewardItem.cs (2)

7-7: Good change to record struct for RewardItem.

Changing to a record struct provides value-based equality, better toString implementation, and reinforces the immutability semantics of this read-only data structure. This is a good practice for data objects, especially those used for reward representation.


23-25: Nice addition of implicit conversion operator.

This operator elegantly simplifies the conversion from Item to RewardItem, making the codebase more readable by eliminating explicit conversions when working with rewards. The implementation correctly maps properties from the source to the target type.

Maple2.Server.Game/Trigger/TriggerContext.MiniGame.cs (6)

14-40: Good implementation of end-game rewards.

The code properly handles both winners and losers, with appropriate null checks and conditional logic for showing results. Setting the MiniGameRecord to null after processing ensures clean state management.


42-80: Well-structured reward system with type differentiation.

The implementation correctly differentiates between experience types based on game name, and handles rewards for both winners and losers appropriately. The meso reward is only added when the value is positive, and round tracking is properly maintained.


82-87: Camera direction function is correctly implemented.

The method properly sends camera packets to all players in the specified box.


89-99: Experience reward handling is well-implemented.

The code correctly checks for null records before adding experience, and properly updates the player's reward records.


101-114: Reward distribution includes proper error handling.

The implementation now includes checking if the content type exists and logs warnings appropriately if it doesn't.


118-128: Clean initialization of mini-game records.

The code correctly initializes the mini-game record for each player with appropriate default values.

Maple2.Model/Game/Dungeon/DungeonUserRecord.cs (3)

23-35: Constructor logic looks good.

These initializations align well with the defined enumerations, ensuring default values and preventing missing dictionary keys.


37-45: Add a null check for record.Items to prevent potential NullReferenceException.

This issue is identical to a past review comment in a similar method. If record.Items is null, iterating over it will throw at runtime.
[flag_critical_issue, duplicate_comment]

 public void Add(RewardRecord record) {
     Rewards[DungeonRewardType.Exp] += (int) record.Exp;
     Rewards[DungeonRewardType.Meso] += (int) record.Meso;
     Rewards[DungeonRewardType.Prestige] += (int) record.PrestigeExp;

-    foreach (RewardItem item in record.Items) {
-        RewardItems.Add(item);
-    }
+    if (record.Items != null) {
+        foreach (RewardItem item in record.Items) {
+            RewardItems.Add(item);
+        }
+    }
 }

47-90: Serialization logic appears properly structured and consistent.

The partitioned writing of rewards, items, and bonus items matches the enumerated types and avoids the common pitfalls of collection size mismatches.

Maple2.Server.Game/Manager/Field/FieldManager/FieldManager.cs (4)

74-76: Good addition of dungeon-related properties.

Adding these properties with the init accessor is a good practice for immutability after initialization, providing better structure for dungeon field management.


105-105: Default initialization for FieldType is appropriate.

Setting the default field type during initialization ensures consistent behavior for all fields.


134-139: Fixed the default plot initialization.

Replacing the Plot.Default with a proper instance of Plot including UgcMapGroup parameters fixes the issue with default plots mentioned in the PR objectives.


123-123:

Details

✅ Verification successful

Verify the implications of removing blockChangeChannel parameter.

The blockChangeChannel: true parameter has been removed from the FieldInstance constructor. This change appears intentional to allow dungeon creation on the first instance channel as mentioned in the PR objectives, but ensure this doesn't unintentionally allow channel changes in other contexts.


🏁 Script executed:

#!/bin/bash
# Check for other usages of blockChangeChannel in the codebase
echo "Searching for other usages of blockChangeChannel parameter..."
rg "blockChangeChannel" -A 5 -B 5

Length of output: 166


Let's gather a bit more context on how the FieldInstance constructor is defined to ensure that removing the blockChangeChannel parameter won't have unexpected side effects. It’s important to verify that the constructor no longer expects this parameter (or that it has a safe default), and that its removal here doesn’t leave any gaps elsewhere in the codebase.

Please run the following shell script to search for the FieldInstance constructor definition and check for any mentions of blockChangeChannel:

Once we have this output, we can determine if the removal was safe or if further adjustments are needed.


🏁 Script executed:

#!/bin/bash
echo "Searching for FieldInstance constructor for usage of blockChangeChannel..."
rg "public FieldInstance\s*\(" -A 20 -B 20

Length of output: 1577


FieldInstance Constructor: Removal of blockChangeChannel Confirmed

I verified that the FieldInstance constructor now accepts only the instanceType and instanceId parameters (see Maple2.Model/Game/FieldInstance.cs), and there are no remaining usages of blockChangeChannel in the codebase. This aligns with the PR objectives, and no unintended side effects regarding channel changes appear to be present.

Maple2.Server.Game/Manager/DungeonManager.cs (7)

28-31: Good renaming and property enhancements.

Renaming Field to Lobby with a private setter improves encapsulation, and the added properties provide convenient access to dungeon state and user records.


64-68: Well-structured Load method.

This new method sends all necessary dungeon-related packets to the client in a clear and organized way.


70-78: Good field loading implementation.

The LoadField method properly checks for null values and sends the appropriate packet based on the instance type.


207-214: Enhanced SetDungeon method with user record handling.

The updated method now properly initializes the user record and adds it to the dungeon room record, which is essential for tracking player progress in dungeons.


240-257: Improved dungeon creation with RPC and error handling.

The implementation now uses proper RPC calls to the field service with good error handling, which is critical for a reliable dungeon creation process.


320-354: Well-implemented dungeon completion logic.

The CompleteDungeon method properly:

  1. Validates required objects are not null
  2. Calculates and awards experience and meso rewards
  3. Handles item rewards from drop boxes
  4. Adds items to inventory or mails them if inventory is full
  5. Sends appropriate packets to update the client

This implementation aligns well with the PR objective of implementing rudimentary dungeon rewards.


356-390: Good dungeon reset implementation.

The Reset method properly:

  1. Verifies the player is the party leader
  2. Makes a field request to destroy the dungeon
  3. Handles RPC errors
  4. Updates the party state via the party service

This effectively supports the PR objective of providing the ability to reset dungeons.

@AngeloTadeucci
AngeloTadeucci merged commit f82310f into MS2Community:master Mar 21, 2025
@Zintixx
Zintixx deleted the dungeons branch March 21, 2025 07:12
@AngeloTadeucci AngeloTadeucci added this to the Dungeons milestone Apr 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants