Archived
1
0
Fork 0
This repository has been archived on 2026-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
Danmaku/server/game-modes/battle-royale/presence-management-hooks.go

96 lines
3.6 KiB
Go

package battleroyale
import (
"context"
"database/sql"
"github.com/heroiclabs/nakama-common/runtime"
)
// Run on match start, initializes game state and sets tick rate
func (m *Match) MatchInit(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, params map[string]any) (any, int, string) {
state := &MatchState{
tickRate: TICK_RATE,
presences: map[string]*PresenceState{},
emptyTicks: 0,
currentMatchPhase: MATCH_LOADING,
}
return state, TICK_RATE, ""
}
// Run when a user attempts to join or rejoin a match. Responsible for deciding whether or not to let them in.
func (m *Match) MatchJoinAttempt(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state any, presence runtime.Presence, metadata map[string]string) (any, bool, string) {
lobbyState, ok := state.(*MatchState)
if !ok {
logger.Error("State is not a valid lobby state object for MatchJoin.")
return nil, false, "Failed to join match: match does not exist."
}
accepted := true
rejectedMessage := ""
return lobbyState, accepted, rejectedMessage
}
// Run when a user successfully joins a match, registers their presence in the game state
func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state any, presences []runtime.Presence) any {
lobbyState, ok := state.(*MatchState)
if !ok {
logger.Error("State is not a valid lobby state object for MatchJoin.")
return nil
}
// Register every new presence associated with the new player
for i := range len(presences) {
lobbyState.presences[presences[i].GetSessionId()] = &PresenceState{
presence: &presences[i],
stageState: NewPlayerStage(),
}
}
return lobbyState
}
// Run when a user successfully leaves a match, de-registers their presence in the game state
func (m *Match) MatchLeave(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state any, presences []runtime.Presence) any {
lobbyState, ok := state.(*MatchState)
if !ok {
logger.Error("State is not a valid lobby state object for MatchLeave.")
return nil
}
// De-register every presence associated with the leaving player
for i := range len(presences) {
sessionID := presences[i].GetSessionId()
playerState, exists := lobbyState.presences[sessionID]
if exists {
playerState.stageState.Delete()
delete(lobbyState.presences, sessionID)
}
}
return lobbyState
}
// Run when a match gets an arbitrary signal from the Nakama runtime (probably from the matchmaker/match lister APIs)
func (m *Match) MatchSignal(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state any, data string) (any, string) {
lobbyState, ok := state.(*MatchState)
if !ok {
logger.Error("State is not a valid lobby state object for MatchSignal.")
return nil, "Failed to get valid state for return signal"
}
returnMessage := ""
return lobbyState, returnMessage
}
// Run when the server enters the graceful shutdown flow. Gives the match a chance to shutdown cleanly within graceSeconds.
func (m *Match) MatchTerminate(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state any, graceSeconds int) any {
lobbyState, ok := state.(*MatchState)
if !ok {
logger.Error("State is not a valid lobby state object for MatchTerminate.")
return nil
}
return lobbyState
}