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)
|
logger.Error("Failed to register RPC: %v", err)
|
||||||
return 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!")
|
logger.Info("Go module loaded successfully!")
|
||||||
return nil
|
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