96 lines
3.6 KiB
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
|
|
}
|