This repository has been archived on 2023-04-11. You can view files and clone it, but cannot push or open issues or pull requests.

126 lines
4.1 KiB
Go
Raw Normal View History

package control
import (
"context"
"database/sql"
"github.com/heroiclabs/nakama-common/runtime"
"github.com/josephbmanley/family/server/plugin/gamemap"
)
2020-08-16 22:11:52 -04:00
// OpCode represents a enum for valid OpCodes
// used by the match logic
type OpCode int64
const (
2020-08-16 22:11:52 -04:00
// OpCodeTileUpdate is used for tile updates
OpCodeTileUpdate = 1
)
2020-08-16 22:11:52 -04:00
// Match is the object registered
// as a runtime.Match interface
type Match struct{}
2020-08-16 22:11:52 -04:00
// MatchState holds information that is passed between
// Nakama match methods
type MatchState struct {
presences map[string]runtime.Presence
inputs map[string]string
positions map[string]map[string]int
names map[string]string
worldMap *gamemap.WorldMap
}
2020-08-16 22:11:52 -04:00
// MatchInit is called when a new match is created
func (m *Match) MatchInit(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, params map[string]interface{}) (interface{}, int, string) {
state := &MatchState{
presences: map[string]runtime.Presence{},
inputs: map[string]string{},
positions: map[string]map[string]int{},
names: map[string]string{},
worldMap: gamemap.IntializeMap(),
}
tickRate := 10
label := "{\"name\": \"Game World\"}"
return state, tickRate, label
}
2020-08-16 22:11:52 -04:00
// MatchJoinAttempt is called when a player tried to join a match
// and validates their attempt
func (m *Match) MatchJoinAttempt(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state interface{}, presence runtime.Presence, metadata map[string]string) (interface{}, bool, string) {
2020-08-16 20:35:58 -04:00
mState, ok := state.(*MatchState)
if !ok {
logger.Error("Invalid match state on join attempt!")
return state, false, "Invalid match state!"
}
2020-08-16 22:11:52 -04:00
// Validate user is not already connected
if _, ok := mState.presences[presence.GetUserId()]; ok {
return mState, false, "User already logged in."
} else {
return mState, true, ""
}
}
2020-08-16 22:11:52 -04:00
// MatchJoin is called when a player successfully joins the match
func (m *Match) MatchJoin(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state interface{}, presences []runtime.Presence) interface{} {
2020-08-16 20:35:58 -04:00
mState, ok := state.(*MatchState)
if !ok {
logger.Error("Invalid match state on join!")
2020-08-16 22:11:52 -04:00
return state
2020-08-16 20:35:58 -04:00
}
2020-08-16 22:11:52 -04:00
for _, precense := range presences {
2020-08-16 22:11:52 -04:00
// Add presence to map
mState.presences[precense.GetUserId()] = precense
2020-08-16 22:11:52 -04:00
// Set player spawn pos
mState.positions[precense.GetUserId()] = map[string]int{"x": 16, "y": 16}
mState.names[precense.GetUserId()] = "User"
2020-08-16 22:11:52 -04:00
// Get intial tile data around player
if regionData, err := mState.worldMap.GetJSONRegionAround(16, 16, 8); err != nil {
logger.Error(err.Error())
} else {
2020-08-16 22:11:52 -04:00
// Broadcast tile data to client
if sendErr := dispatcher.BroadcastMessage(OpCodeTileUpdate, regionData, []runtime.Presence{precense}, precense, true); sendErr != nil {
logger.Error(sendErr.Error())
}
}
}
return mState
}
2020-08-16 22:11:52 -04:00
// MatchLeave is called when a player leaves the match
func (m *Match) MatchLeave(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state interface{}, presences []runtime.Presence) interface{} {
2020-08-16 20:35:58 -04:00
mState, ok := state.(*MatchState)
if !ok {
logger.Error("Invalid match state on leave!")
return state
}
for _, presence := range presences {
delete(mState.presences, presence.GetUserId())
}
return mState
}
2020-08-16 22:11:52 -04:00
// MatchLoop is code that is executed every tick
func (m *Match) MatchLoop(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state interface{}, messages []runtime.MatchData) interface{} {
// Custom code to:
// - Process the messages received.
// - Update the match state based on the messages and time elapsed.
// - Broadcast new data messages to match participants.
return state
}
2020-08-16 22:11:52 -04:00
// MatchTerminate is code that is executed when the match ends
func (m *Match) MatchTerminate(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, dispatcher runtime.MatchDispatcher, tick int64, state interface{}, graceSeconds int) interface{} {
return state
}