feat: add rpc_find_match for basic 2-player matchmaking
- Implement rpc_find_match Nakama RPC function - Search for existing authoritative TicTacToe matches via MatchList - Return first match with available slot (size < 2) - Create new match using MatchCreate when none available - Add request/response structs for future extensibility - Log match search, selection, and creation flow - Gracefully handle optional JSON payload and invalid input
This commit is contained in:
@@ -34,6 +34,10 @@ func InitModule(
|
||||
logger.Error("Failed to register RPC: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := initializer.RegisterRpc("rpc_find_match", rpcFindMatch); err != nil {
|
||||
logger.Error("RegisterRpc rpc_find_match failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info("Go module loaded successfully!")
|
||||
return nil
|
||||
|
||||
70
plugins/matchmaking.go
Normal file
70
plugins/matchmaking.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/heroiclabs/nakama-common/runtime"
|
||||
)
|
||||
|
||||
type FindMatchRequest struct{}
|
||||
|
||||
type FindMatchResponse struct {
|
||||
MatchID string `json:"match_id"`
|
||||
}
|
||||
|
||||
func rpcFindMatch(
|
||||
ctx context.Context,
|
||||
logger runtime.Logger,
|
||||
db *sql.DB,
|
||||
nk runtime.NakamaModule,
|
||||
payload string,
|
||||
) (string, error) {
|
||||
|
||||
logger.Info("rpc_find_match called")
|
||||
|
||||
var req FindMatchRequest
|
||||
if payload != "" {
|
||||
if err := json.Unmarshal([]byte(payload), &req); err != nil {
|
||||
logger.Warn("rpc_find_match: invalid request payload: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
const limit = 10
|
||||
authoritative := true
|
||||
labelFilter := "tictactoe" // must match MatchInit label
|
||||
var minSize, maxSize *int // nil = no constraint
|
||||
|
||||
matches, err := nk.MatchList(
|
||||
ctx,
|
||||
limit,
|
||||
authoritative,
|
||||
labelFilter,
|
||||
minSize,
|
||||
maxSize,
|
||||
"", // query
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("rpc_find_match: MatchList failed: %v", err)
|
||||
return "", runtime.NewError("internal error", 13)
|
||||
}
|
||||
|
||||
for _, m := range matches {
|
||||
if m.Size < 2 {
|
||||
logger.Info("rpc_find_match: found match %s with size=%d", m.MatchId, m.Size)
|
||||
out, _ := json.Marshal(FindMatchResponse{MatchID: m.MatchId})
|
||||
return string(out), nil
|
||||
}
|
||||
}
|
||||
|
||||
matchID, err := nk.MatchCreate(ctx, "tictactoe", map[string]interface{}{})
|
||||
if err != nil {
|
||||
logger.Error("rpc_find_match: MatchCreate failed: %v", err)
|
||||
return "", runtime.NewError("internal error", 13)
|
||||
}
|
||||
|
||||
logger.Info("rpc_find_match: created new match %s", matchID)
|
||||
out, _ := json.Marshal(FindMatchResponse{MatchID: matchID})
|
||||
return string(out), nil
|
||||
}
|
||||
Reference in New Issue
Block a user