Repository navigation
Fix/announcements messages field hidden - #995
OviedoMarcelo wants to merge 30 commits into
Conversation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Weekly quests are configured in the custom configuration of the new WeeklyQuestsPlugIn (admin panel -> Plugins). Supported objectives: kill a specific or any monster (optionally per map), gain levels / master levels, do resets, finish a mini game and kill players. Rewards: items, zen, experience and master experience. - Progress is stored per character and weekly period in its own "weekly" schema (WeeklyQuestContext with own migrations), so the generated game data model stays untouched. A new week starts with fresh rows, no reset job is needed. - Rewards are handed out completely or not at all. When the inventory is full they stay pending and are retried at the next login or /weekly. - New plugin points ICharacterResetPlugIn and IMiniGameEndedPlugIn. - New /weekly chat command which shows the progress.
Introduce weekly-quests support: adds C2 F5 02 WeeklyQuestEntry packet and XML definition, IWeeklyQuestListViewPlugIn interface, and RemoteView implementation WeeklyQuestListViewPlugIn to send quest lists/updates. Integrates into WeeklyQuestsPlugIn (overview creation, change notifications, SendList) and triggers on chat-command list request. Adds reward text helpers (WeeklyQuestReward/GetDisplayText, WeeklyQuestDefinition/GetRewardsText), localization resources, Mapster configuration tweaks, and unit tests for packet and view behaviour. Also includes docs for the packet and updates ServerToClient packet refs.
Feature/weekly quests
This patch adds a weekly quest system with period rotation, class/level gating, item pickup objectives, account-wide reward locking, and all-completed bonus tracking. It also introduces the item pickup plugin hook and persistence support for account-scoped quest progress. On the UI side, modal dialogs now stack correctly instead of cancelling the underlying one, and the related tests cover quest selection, progress rules, and modal behavior.
This change adds multi-step quest tracking across weekly, daily, and once-only periods, including prerequisite locking and per-period reset handling. It also introduces objective checklist packets for the client, NPC/map-based objective detection, and progress persistence for additional objective counts. The quest UI and overview logic were updated to show current steps, remaining resets, and category-specific details.
Feature/weekly quests
The merge left an extra </data> before </root>, so the resx wasn't valid XML and the build failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ith tooltips and a quick help page Labels stay in English. The info popup of each field now shows a Spanish explanation and its impact above the original description. Help texts live in SpanishHelp.*.cs (new files). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e current page empty After a filter reduced the results (e.g. plugins on page 7), the table showed nothing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ster Feature/admin panel es on master
The client had its own copy of the skill requirements in its data files, which drifted from the server's configuration: e.g. Summon Goblin needed 30 energy on the client and 90 on the server, so the client cast it and the server silently rejected it. After a successful login, the server now sends the requirements and costs of all skills (C2 F5 04) and what it takes to learn the skill of each item (C2 F5 05), once per session and only to clients which support it. Learning a skill with an item now also requires the requirements of the skill, so that a skill can't be learned when it couldn't be used afterwards. The Orb of Summoning takes the requirements of the skill of its item level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ments feat: Send skill requirements to the client after the login
…stered before a cutoff Disabled by default. No account flag needed: Founder = Account.RegistrationDate before the configured cutoff (default matches the beta opening, 2026-10-12 10:00 ART = 13:00 UTC). Adds Spanish admin-panel help for its two fields. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…onus Add Founder Experience Bonus plugin: small XP bonus for accounts regi…
…client The client already scrolls 0x0D notices of type 10 to 15 in its slide help band, but OpenMU only sent the types 0 to 2. Add MessageType.SlideNotice, which ShowMessagePlugIn sends as type 14 (bold notice band) with the loop count, delay, color and speed fields the client reads. Clients before season 1 get it as a golden notice instead. It can be sent with the new GM command '/slidenotice <text>' and from the admin panel, whose global message now has a message type selector. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fet: Add slide notices: server messages that scroll across the top of the …
The client's data files only have the name of each monster, so it can't show their level. After a successful login, the server now sends the level of all monsters (C2 F5 06), once per session and only to clients which support it, right after the skill requirements. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat: Send the level of the monsters to the client after the login
…c-2026-09-27 # Conflicts: # src/GameLogic/Properties/PlugInResources.resx # src/GameServer/Properties/PlugInResources.resx # src/Web/AdminPanel/Components/Layout/ConfigNavMenu.razor
This fork doesn't use CI, releases or notifications, so no workflow should run on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test/upstream sync 2026 09 27
… global messages Shows one message from a configured list every N minutes, cycling through them, so they never overlap each other. Reuses the same message styles as /post, /goldnotice and /slidenotice. Disabled by default. Adds Spanish admin-panel help for its fields. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Alpine base image ships without /usr/share/zoneinfo, so .NET only knew UTC and the server time zone setting rejected ids like America/Argentina/Buenos_Aires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add Server Announcements plugin: a configurable rotation of automatic…
build: Install tzdata in the Docker image so IANA server time zones resolve
…y code check always failed) Account.SecurityCode defaults to "" (not null), so 'SecurityCode != null' was always true and the check always ran against an empty string that no player input could match - there's no in-game or web flow to set a security code either. Now mirrors DeleteCharacterAction's fallback: with no security code configured, the account password is checked instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…code Fix: guilds could never be disbanded or have a member kicked (securit…
The admin panel's ObjectCollectionFieldBuilder only recognizes a property declared exactly as ICollection<T> with a reference-type T; IList<T> doesn't match that check even though it implements ICollection<T>, so the Messages list silently disappeared from the generated config form. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
sven-n
left a comment
There was a problem hiding this comment.
Thanks for sharing this work. Some of it is useful, but this PR can't be merged in its current form.
Scope doesn't match the title
The title ("Fix/announcements messages field hidden") describes a one-line change (IList<T> → ICollection<T> in ServerAnnouncementsConfiguration). The PR is actually the fork's whole master branch: 30 commits, 115 files, +9952/−329, including merge commits of the fork's own PRs #1–#11 and an upstream sync. Nobody can properly review that as one unit, and reverting any single part of it later wouldn't be practical.
Blockers
- It removes all GitHub Actions workflows (
dotnetcore.yml,publish.yml,docs-website.yml,claude.yml,discord-merge-notification.yml). The commit message says it outright: "This fork doesn't use CI, releases or notifications, so no workflow should run on it." That's fine for your fork, but it can't go upstream. It would turn off the build, the releases and the docs site for this project. - Fork-specific customizations that don't belong upstream:
FounderExperienceBonusPlugIn: its default cutoff is hardcoded to your beta launch (2026-10-12 13:00 UTC, "Argentina time"), and its docs point to your website (lib/beta.ts,BETA_OPENS_AT).WebsiteController(api/web/...): a custom API for your community website. Its culture is hardcoded to"es", it can disconnect accounts, and it isn't generic.- The admin panel is partly localized to Spanish in a way that bypasses the resource system:
SpanishHelp.*.cs, theHelp.razorpage (/ayuda), hardcoded Spanishtitle=tooltips and section headers inNavMenu.razor, the hardcoded"Impacto:"inFieldLabel.razor, and SpanishDisplaydescriptions and default messages in the new plugin configs. Upstream localizes through.resxresources, not hardcoded strings or a language-specific class.
- Protocol extensions for a custom client. The new
C2 F5 02..06packets (weekly quests, quest details, skill requirements, learnable item requirements, monster levels) are sent to every106.3 Invariantclient after login or map entry. They need a matching, agreed client implementation. Protocol additions like these should go in their own PR, together with the client-side change (e.g. in MuMain), so we can check that stock clients handle them safely. - CI is red. The Azure
MUnique.OpenMUbuild failed on the head commit, and Codacy reportsaction_required.
Parts that could be upstreamed as separate, focused PRs
Some changes look useful. I'd happily review them one at a time, each with its own tests:
- Guild kick/disband security code fix (
GuildKickPlayerAction): falls back to the password check likeDeleteCharacterAction. It also stops logging the security code in plain text. This looks like a real bug fix. - Slide notice (
MessageType.SlideNotice,/slidenotice, and the message type selector in the admin panel's global message). DataTablerefresh jumping back to page 1 when the current page becomes empty.- Stacked modal dialogs (
ModalService/ModalContainer). tzdatain the Docker image.- Learnable-skill requirement check (
LearnableSkillRequirements, the Summoning Orb refactor). Please send it separately from the new packets. - Server Announcements plugin, with English defaults and resource-based texts.
- Weekly quests. This is a large feature with its own DB context/schema, migrations, new plugin points (
ICharacterResetPlugIn,IMiniGameEndedPlugIn,IItemPickedUpPlugIn,INpcTalkStartedPlugIn) and a static service locator (WeeklyQuestProgressRepositoryRegistry.Current). Please open an issue or discussion about the design first, then send it as a dedicated PR.
Suggestion
Please close this PR. Then open separate PRs from branches based on upstream master (not on your fork's master), and leave out the workflow removal and the server-specific customizations.
Generated by Claude Code
|
Closing this as discussed in the review. The useful parts are split into focused pull requests against the current
Not split out:
Thanks for the contribution! Generated by Claude Code |
Account.SecurityCode defaults to "" (not null), so 'SecurityCode != null' was always true and the check always ran against an empty string that no player input could match - there's no in-game or web flow to set a security code either. Now mirrors DeleteCharacterAction's fallback: with no security code configured, the account password is checked instead. The entered and the stored code are no longer written to the debug log. Split out of MUnique#995. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Alpine base image ships without /usr/share/zoneinfo, so .NET only knew UTC and the server time zone setting rejected ids like America/Argentina/Buenos_Aires. Split out of MUnique#995. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s its page empty After a filter reduced the results (e.g. plugins on page 7), the table showed nothing. Split out of MUnique#995. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…screen Since season 1, the client scrolls 0x0D notices of the types 10 to 15 through the help and notice bands at the top of the screen, but OpenMU only sent the types 0 to 2. The new SlideNotice packet defines the fields the client reads for them (loop count, loop delay, color, speed). MessageType.SlideNotice is sent as SlideNotice packet of type 14 (queued in the notice band, shown once). Clients before season 1 get a golden notice instead. It can be sent with the new GM command '/slidenotice <text>' and from the admin panel, whose global message now has a message type selector. Split out of MUnique#995; the packet is now defined in the XML instead of being written by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uz47mrsSwm3hxZc7gCMxd9
Shows a configured list of announcements to all players of a game server, one after another in a fixed interval, so that a game master doesn't have to type recurring ones. Disabled by default. Split out of MUnique#995 and reworked: the texts are LocalizedStrings which are shown in the language of each player, the plugin and its configuration use PlugInResources (with German translations), the rotation state lives in the plugin instance per game context instead of a static dictionary, the interval has a lower bound, and ForceStart shows the next announcement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uz47mrsSwm3hxZc7gCMxd9
A player could learn a skill with a scroll, orb or crystal without complying with the requirements of the skill itself, and then couldn't use it. E.g. the Orb of Summoning has no energy requirement, but Summon Goblin needs 90 energy and Summon Soldier (orb +6) 280. Learning a skill with an item now also requires the requirements of the skill. The requirement check of Player.TryConsumeForSkillAsync is extracted to Player.CompliesRequirements(Skill) and reused for it. Split out of MUnique#995, without the client data packets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uz47mrsSwm3hxZc7gCMxd9
No description provided.