Skip to content

feat(gateway): handle guild petition turn-in at the gateway - #58

Closed
3kynox wants to merge 8 commits into
walkline:masterfrom
3kynox:feat/gateway-petition-turnin
Closed

feat(gateway): handle guild petition turn-in at the gateway#58
3kynox wants to merge 8 commits into
walkline:masterfrom
3kynox:feat/gateway-petition-turnin

Conversation

@3kynox

@3kynox 3kynox commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

This is the trigger part of the guild-creation rework we discussed on Discord: the gateway intercepts CMSG_TURN_IN_PETITION, asks the player's worldserver to validate the petition over gRPC (charter item, ownership, signatures — validation and MinPetitionSigns stay world-side), then creates the guild through the guild service with the signatories as members and answers SMSG_TURN_IN_PETITION_RESULTS. Arena charters are forwarded to the worldserver untouched, and if the worldserver doesn't implement the validation endpoint yet (mixed versions) the turn-in falls back to the in-process flow instead of being dropped.

The guild service maps CreateGuild business failures to gRPC status codes so the gateway renders the proper client errors (name taken, already in a guild, invalid name) without matching error strings. Sessions of online signatories are linked to the new guild through the guild.created event.

Stacked on #55 and #57: the net-new commits are the last two, the diff collapses once those merge. The AC-side counterpart (validation handler + guild.created consumer) walkline/azerothcore-wotlk#6.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Implements the gateway-driven guild petition turn-in flow for WotLK guild creation: the gateway validates a petition via a new worldserver gRPC endpoint, creates the guild via the guild service, and propagates membership linking via a new guild.created NATS event consumed by worldservers and gateways.

Changes:

  • Add CanTurnInGuildPetition gRPC endpoint (proto + Go/C++ libsidecar server/client plumbing) and gateway handler for CMSG_TURN_IN_PETITION.
  • Add CreateGuild RPC to the guild service + MySQL implementation, plus publish/consume the new guild.created event.
  • Wire guild.created consumption to update online sessions/worldserver state; add tests for guild creation and gateway petition turn-in.

Reviewed changes

Copilot reviewed 51 out of 53 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
shared/events/producer-guild.go Adds GuildCreated producer API for NATS publishing.
shared/events/mocks/GuildServiceProducer.go Updates mock to support GuildCreated.
shared/events/events-guild.go Defines guild.created subject and payload type.
gen/worldserver/pb/worldserver.pb.go Generated protobuf updates for CanTurnInGuildPetition messages/enums.
gen/worldserver/pb/worldserver_grpc.pb.go Generated gRPC stubs for CanTurnInGuildPetition.
gen/worldserver/pb/mocks/WorldServerServiceClient.go Updates mock client with CanTurnInGuildPetition.
gen/guilds/pb/guilds.pb.go Generated protobuf updates for CreateGuild params/response.
gen/guilds/pb/guilds_grpc.pb.go Generated gRPC stubs for CreateGuild.
game-server/libsidecar/petition-api.h New C ABI for petition validation handler binding.
game-server/libsidecar/petition-api.go cgo bridge for petition validation handler + data conversion/freeing.
game-server/libsidecar/petition-api.c C shim storing and invoking petition validation handler.
game-server/libsidecar/grpcapi/server-petitions.go Implements gRPC CanTurnInGuildPetition server handler (Go libsidecar).
game-server/libsidecar/grpcapi/petition-errors.go Defines ErrNoPetitionHandler.
game-server/libsidecar/grpcapi/cpp-bindings.go Adds Go-side bindings/types for petition validation results.
game-server/libsidecar/grpc-api.go Registers petition handler in Go libsidecar GRPC setup.
game-server/libsidecar/events-guilds.go Adds Go-side guild.created hook binding + handler implementation.
game-server/libsidecar/events-guild.h Adds C hook signature for guild.created.
game-server/libsidecar/events-guild.c Implements hook registration/call for guild.created.
game-server/libsidecar/consumer/handlers-fabric.go Extends handler factory interface with GuildCreatedHandler.
game-server/libsidecar/consumer/consumer.go Subscribes to guild.created and dispatches to handler queue (Go).
game-server/libsidecar-cpp/src/nats/handlers.h Declares C++ handler factory for guild.created.
game-server/libsidecar-cpp/src/nats/handlers.cpp Parses guild.created payload and dispatches hook (C++).
game-server/libsidecar-cpp/src/nats/consumer.cpp Subscribes/routes guild.created in the C++ consumer.
game-server/libsidecar-cpp/src/grpc/worldserver_service.h Adds C++ gRPC service method + binding pointer for petition validation.
game-server/libsidecar-cpp/src/grpc/worldserver_service.cpp Implements CanTurnInGuildPetition server method (C++).
game-server/libsidecar-cpp/src/events/event_hooks.h Adds registration/dispatch for guild.created hook (C++).
game-server/libsidecar-cpp/src/events/event_hooks.cpp Implements registration/dispatch for guild.created hook (C++).
game-server/libsidecar-cpp/src/api.cpp Exposes C API for petition handler + guild.created hook registration (C++).
game-server/libsidecar-cpp/include/petition-api.h Public C header for petition handler (C++ libsidecar).
game-server/libsidecar-cpp/include/libsidecar/tc9_types.h Adds petition validation types to exported ABI.
game-server/libsidecar-cpp/include/libsidecar/tc9_events.h Adds TC9EventGuildCreated event + hook type.
game-server/libsidecar-cpp/include/libsidecar.h Exposes new petition API + guild.created hook entrypoints.
game-server/libsidecar-cpp/include/events-guild.h Adds guild.created hook declaration in public header.
apps/guildserver/service/guilds.go Adds CreateGuild service method + publishes guild.created event.
apps/guildserver/service/guilds-create_test.go Adds unit tests for CreateGuild behavior and event payload.
apps/guildserver/service/guilds-cache.go Extends cache interface with source-of-truth membership lookup.
apps/guildserver/service/guilds-cache_inmem.go Implements membership source recheck + CreateGuild cache hydration.
apps/guildserver/service/guilds-cache_inmem_test.go Adds tests for source recheck eviction and leader-online marking.
apps/guildserver/server/guilds.go Adds gRPC CreateGuild handler with status-code mapping.
apps/guildserver/server/guilds-logger_debug.go Adds debug logging wrapper for CreateGuild.
apps/guildserver/repo/mocks/guilds-repo.go Extends repo mock with CreateGuild.
apps/guildserver/repo/guilds.go Adds CreateGuild repo API + ErrGuildNameTaken.
apps/guildserver/repo/guilds_mysql.go Implements GuildByRealmAndID + transactional CreateGuild (MySQL).
apps/gateway/session/petition.go Adds CMSG_TURN_IN_PETITION handling via gRPC validate + guild create.
apps/gateway/session/petition_test.go Adds tests for petition turn-in success/fallback/error mappings.
apps/gateway/session/handler.go Routes CMsgTurnInPetition to the new handler.
apps/gateway/session/handler-events.go Registers session handler for EventTypeGuildCreated.
apps/gateway/session/guild.go Adds guild command/result sender + handles GuildCreated event to link sessions.
apps/gateway/service/listener-guild.go Subscribes to guild.created and broadcasts to sessions.
apps/gateway/events-broadcaster/mocks/Broadcaster.go Adds broadcaster mock method for NewGuildCreatedEvent.
apps/gateway/events-broadcaster/broadcaster.go Adds EventTypeGuildCreated broadcasting to leader + signatories.
api/proto/v1/worldserver/worldserver.proto Adds CanTurnInGuildPetition RPC and messages.
api/proto/v1/guilds/guilds.proto Adds CreateGuild RPC and messages.
Files not reviewed (2)
  • apps/gateway/events-broadcaster/mocks/Broadcaster.go: Generated file
  • apps/guildserver/repo/mocks/guilds-repo.go: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +36 to +38
if resp.err != nil {
return nil, resp.err
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed: the Go libsidecar now maps the unbound-handler error to gRPC Unimplemented so the gateway fallback triggers (the native C++ implementation already returned Unimplemented).

@3kynox
3kynox force-pushed the feat/gateway-petition-turnin branch 2 times, most recently from 50dcee1 to 1bcd640 Compare July 17, 2026 20:22
3kynox added 8 commits July 23, 2026 09:13
Adds a CreateGuild RPC: the guild row, the five default 3.3.5 ranks and the
leader as guild master are inserted in one transaction, the guild id being
allocated as MAX(guildid)+1 with a retry on primary key conflicts (a
worldserver can still create guilds in-process concurrently). The created
guild is cached hydrated and a guild.created event is published.

Also implements the GuildByRealmAndID mysql repo method that was left as
panic("implement me") - the cache needs it to hydrate the new guild.

(cherry picked from commit 3608d5a3f14348c31ca54faafb07f27948919bfc)
…ild creation

The world can disband guilds without going through the guild service
(e.g. GM .guild delete handled in-process), leaving a stale positive
membership in the in-memory cache. CreateGuild now rechecks a positive
answer against the database and evicts the stale cache entry, instead
of rejecting with 'already in guild' until the service restarts.

Also treats a missing guild_member row as 'not in a guild' in the MySQL
repo instead of surfacing sql.ErrNoRows.

(cherry picked from commit 2c779169db1722cb20bfa58faf8674a482af09f1)
Guild creation is always driven by a live session of the leader, but in
cluster mode the world doesn't flush the online flag to the characters
table, so the hydration read the leader back as offline. This left the
fresh guild with an empty online-members list: the roster showed the
leader disconnected and guild events (e.g. MOTD updates) were broadcast
to nobody until the leader relogged.

(cherry picked from commit 7000ccaa6c9f19ce89c1f3884f355243a74628d9)
…ity)

The core's CreateDefaultGuildRanks gives both Guild Master and Officer
GR_RIGHT_ALL; the service only gave the Officer chat rights, so a freshly
promoted officer had every guild action greyed out client-side (invite,
promote, etc.). Match the core layout and assert it in the create test.
- CreateGuildParams gains signatoryGUIDs; members are inserted with the
  lowest rank in the same transaction, skipping characters that joined
  another guild since signing.
- guild.created event now carries the added member guids so worldservers
  can populate the state for the new guild.
- New worldserver RPC CanTurnInGuildPetition for the gateway to validate
  petitions on the worldserver side before calling CreateGuild.
…eated hook

Both implementations (Go and native C++) gain:
- CanTurnInGuildPetition gRPC method dispatched on the world update
  thread through a new TC9SetCanTurnInGuildPetitionHandler binding;
- a guild.created NATS consumer that calls the new TC9SetOnGuildCreatedHook
  so worldservers can populate state for guilds created by the guild service.
The gateway intercepts CMSG_TURN_IN_PETITION, asks the player's worldserver
to validate the petition over gRPC (charter item, ownership, signatures),
then creates the guild through the guild service with the signatories as
members. Arena charters are forwarded to the worldserver untouched.

The guild service maps business failures of CreateGuild to gRPC status
codes so the gateway can render the proper client errors (name taken,
already in guild, invalid name) without matching error strings.

Sessions of online signatories are linked to the new guild through the
guild.created event.
If the worldserver doesn't implement CanTurnInGuildPetition yet (mixed
versions in the cluster), the turn-in was silently dropped: the gRPC
call failed and the client never got an answer nor the packet. Fall
back to the in-process turn-in flow on Unimplemented.
@3kynox
3kynox force-pushed the feat/gateway-petition-turnin branch 2 times, most recently from 1bcd640 to 6d7a279 Compare July 23, 2026 07:16
@3kynox

3kynox commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #81, which regroups the guild creation work into a single PR as discussed. Same content, rebased on current master, with the review points from this PR already applied.

@3kynox 3kynox closed this Jul 26, 2026
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