Skip to content

Client freeze on character select / loading screen fix#404

Merged
Mosch0512 merged 5 commits into
sven-n:mainfrom
nolt:pragma-freeze-fix
May 22, 2026
Merged

Client freeze on character select / loading screen fix#404
Mosch0512 merged 5 commits into
sven-n:mainfrom
nolt:pragma-freeze-fix

Conversation

@nolt
Copy link
Copy Markdown
Contributor

@nolt nolt commented May 21, 2026

Root Cause: Missing #pragma pack(push, 1) around PRECEIVE_JOIN_MAP_SERVER_EXTENDED

Commit: b46d2cc1 ("fix pragma and DWORD to WORD")
File: src/source/Network/Server/WSclient.h (line ~344)

What happened

The commit removed #pragma pack(push, 1) and #pragma pack(pop) around the PRECEIVE_JOIN_MAP_SERVER_EXTENDED struct and changed DWORD Resets to BYTE Spare; WORD Resets:

- #pragma pack(push, 1)
  typedef struct
  {
      PBMSG_HEADER Header;
      ...
      BYTE         InventoryExtensions;
-     DWORD        Resets;
+     BYTE         Spare;
+     WORD         Resets;
  } PRECEIVE_JOIN_MAP_SERVER_EXTENDED, * LPPRECEIVE_JOIN_MAP_SERVER_EXTENDED;
- #pragma pack(pop)

Effect

Without #pragma pack(push, 1), the struct uses default alignment (8-byte for uint64_t). This increases sizeof(PRECEIVE_JOIN_MAP_SERVER_EXTENDED) from 92 to ~96 bytes (tail padding to the next multiple of 8).

Root cause chain

  1. Server sends a packed packet (92 bytes)
  2. safe_cast<> in ReceiveJoinMapServer() (WSclient.cpp:944) checks span.size() < sizeof(T)92 < 96 = true
  3. safe_cast returns nullptr
  4. Function returns false, error is silently swallowed (line 13207-13210)
  5. CurrentProtocolState stays REQUEST_JOIN_MAP_SERVER
  6. EnableMainRender never becomes true
  7. SwapBuffers is never called
  8. Client freezes on the last frame of the loading screen — user sees a hang

Fix

Restore #pragma pack(push, 1) / #pragma pack(pop) around the struct in WSclient.h. Since adjacent structs (PRECEIVE_CREATE_CHARACTER, PRECEIVE_REVIVAL_EXTENDED) also use raw casts with network data, it is safest to wrap all three in one packed block:

// Add before PRECEIVE_CREATE_CHARACTER:
#pragma pack(push, 1)

// ... PRECEIVE_CREATE_CHARACTER ...
// ... PRECEIVE_JOIN_MAP_SERVER_EXTENDED ...
// ... PRECEIVE_REVIVAL_EXTENDED ...

// Add after PRECEIVE_REVIVAL_EXTENDED:
#pragma pack(pop)

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where the client would hang during the loading screen due to incorrect memory alignment of network packets. By explicitly enforcing packing on specific data structures, the client can now correctly interpret the data sent by the server, preventing silent failures in the protocol state machine and allowing the rendering process to resume as expected.

Highlights

  • Memory Alignment Fix: Restored #pragma pack(push, 1) and #pragma pack(pop) directives around critical network structures to ensure correct memory alignment.
  • Client Stability: Resolved a client freeze issue occurring during the character selection loading screen caused by struct size mismatches.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@nolt nolt changed the title Client freeze on character select fix Client freeze on character select / loading screen fix May 21, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces memory alignment packing using #pragma pack(push, 1) and #pragma pack(pop) for network-related structs in WSclient.h. Feedback indicates that the packing block is incorrectly scoped: it should be expanded to include PRECEIVE_CHARACTER_LIST_EXTENDED to prevent buffer offset drift during data parsing, and it should also encompass later structs like PCREATE_CHARACTER_EXTENDED to ensure correct sizeof calculations for safe_cast operations, which are critical for player rendering.

Comment thread src/source/Network/Server/WSclient.h
Comment thread src/source/Network/Server/WSclient.h Outdated
@Mosch0512 Mosch0512 self-assigned this May 21, 2026
@Mosch0512 Mosch0512 merged commit 3d9eb4d into sven-n:main May 22, 2026
2 checks passed
@nolt nolt deleted the pragma-freeze-fix branch May 22, 2026 14:28
Mosch0512 added a commit to Mosch0512/MuMain that referenced this pull request May 23, 2026
Adds two defenses for the bug class behind PR sven-n#402 / fixed by sven-n#404:

1. static_assert(sizeof == N) on PRECEIVE_CREATE_CHARACTER (19),
   PRECEIVE_JOIN_MAP_SERVER_EXTENDED (92), and PRECEIVE_REVIVAL_EXTENDED
   (36). If the #pragma pack(push, 1) ever gets dropped or a field is
   added/reordered, the build now breaks at the offending struct with a
   pointer to check the pragma. Wire sizes match OpenMU's XML schema
   (CharacterInformationExtended, RespawnAfterDeathExtended).

2. Named overload safe_cast<T>(span, "TYPE_NAME") that logs an MCD_ERROR
   with packet type + received vs expected size on failure. Used at the
   join-map receive site. The dispatcher also logs the user-visible
   symptom ("loading screen will appear frozen") so a future drift turns
   a silent freeze into a one-line console diagnostic.
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