Merge pull request #22 from josephbmanley/feature/match
Create Custom Match Plugin
This commit is contained in:
commit
b35208cbb0
8
.github/workflows/build_dev.yml
vendored
8
.github/workflows/build_dev.yml
vendored
@ -57,18 +57,16 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build Plugin
|
||||
- name: Build Nakma Plugin
|
||||
id: build_plugin
|
||||
uses: josephbmanley/build-nakama-plugin-action@v0.1.1
|
||||
with:
|
||||
nakamaVersion: "2.12.0"
|
||||
moduleDirectory: server/plugins/world_rpc
|
||||
moduleDirectory: server/plugin
|
||||
- name: Move Binary
|
||||
env:
|
||||
plugin: ${{ steps.build_plugin.outputs.binary }}
|
||||
run: |
|
||||
mkdir -p server/data/modules
|
||||
mv $plugin server/data/modules
|
||||
mv ${{ steps.build_plugin.outputs.binary }} server/data/modules
|
||||
- id: get_tag
|
||||
name: Get Tag
|
||||
env:
|
||||
|
8
.github/workflows/build_release.yml
vendored
8
.github/workflows/build_release.yml
vendored
@ -52,18 +52,16 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build Plugin
|
||||
- name: Build Nakma Plugin
|
||||
id: build_plugin
|
||||
uses: josephbmanley/build-nakama-plugin-action@v0.1.1
|
||||
with:
|
||||
nakamaVersion: "2.12.0"
|
||||
moduleDirectory: server/plugins/world_rpc
|
||||
moduleDirectory: server/plugin
|
||||
- name: Move Binary
|
||||
env:
|
||||
plugin: ${{ steps.build_plugin.outputs.binary }}
|
||||
run: |
|
||||
mkdir -p server/data/modules
|
||||
mv $plugin server/data/modules
|
||||
mv ${{ steps.build_plugin.outputs.binary }} server/data/modules
|
||||
- id: get_tag
|
||||
name: Get Tag
|
||||
env:
|
||||
|
8
.github/workflows/build_stage.yml
vendored
8
.github/workflows/build_stage.yml
vendored
@ -39,18 +39,16 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build Plugin
|
||||
- name: Build Nakma Plugin
|
||||
id: build_plugin
|
||||
uses: josephbmanley/build-nakama-plugin-action@v0.1.1
|
||||
with:
|
||||
nakamaVersion: "2.12.0"
|
||||
moduleDirectory: server/plugins/world_rpc
|
||||
moduleDirectory: server/plugin
|
||||
- name: Move Binary
|
||||
env:
|
||||
plugin: ${{ steps.build_plugin.outputs.binary }}
|
||||
run: |
|
||||
mkdir -p server/data/modules
|
||||
mv $plugin server/data/modules
|
||||
mv ${{ steps.build_plugin.outputs.binary }} server/data/modules
|
||||
- name: Get Docker Repo Name
|
||||
id: find_repo
|
||||
run: |
|
||||
|
@ -31,9 +31,18 @@ func login(_text=""):
|
||||
# Check for error
|
||||
if error:
|
||||
passwordEdit.text = ""
|
||||
errorLabel.add_color_override("font_color", Color.red)
|
||||
errorLabel.text = error.message
|
||||
display_message(error.message)
|
||||
else:
|
||||
errorLabel.add_color_override("font_color", Color.green)
|
||||
errorLabel.text = "Logged in successfully!"
|
||||
print("Logged in successfully!")
|
||||
display_message("Logged in successfully!", Color.green)
|
||||
display_message("Connecting to server...", Color.gray)
|
||||
error = yield(ServerConnection.connect_to_server_async(), "completed")
|
||||
if error:
|
||||
display_message(error.message)
|
||||
else:
|
||||
display_message("Connected to server!", Color.green)
|
||||
yield(ServerConnection.join_world_async(), "completed")
|
||||
|
||||
func display_message(message="", color=Color.red):
|
||||
errorLabel.add_color_override("font_color", color)
|
||||
errorLabel.text = message
|
||||
print(message)
|
||||
|
@ -5,6 +5,7 @@ const SERVER_ENDPOINT := "nakama.cloudsumu.com"
|
||||
|
||||
var _session : NakamaSession
|
||||
var _client : NakamaClient = Nakama.create_client(KEY, SERVER_ENDPOINT, 7350, "http")
|
||||
var _socket : NakamaSocket
|
||||
|
||||
func authenticate_async(email : String, password : String) -> NakamaException:
|
||||
var result : NakamaException = null
|
||||
@ -21,7 +22,7 @@ func authenticate_async(email : String, password : String) -> NakamaException:
|
||||
func signup_async(email : String, password : String) -> NakamaException:
|
||||
var result : NakamaException = null
|
||||
|
||||
var new_session : NakamaSession = yield(_client.authenticate_email_async(email, password, null, true), "completed")
|
||||
var new_session : NakamaSession = yield(_client.authenticate_email_async(email, password, email, true), "completed")
|
||||
|
||||
if not new_session.is_exception():
|
||||
_session = new_session
|
||||
@ -29,3 +30,23 @@ func signup_async(email : String, password : String) -> NakamaException:
|
||||
result = new_session.get_exception()
|
||||
|
||||
return result
|
||||
|
||||
func connect_to_server_async() -> NakamaException:
|
||||
_socket = Nakama.create_socket_from(_client)
|
||||
var result : NakamaAsyncResult = yield(_socket.connect_async(_session), "completed")
|
||||
if not result.is_exception():
|
||||
_socket.connect("closed", self, "_on_socket_closed")
|
||||
return null
|
||||
return result.exception
|
||||
|
||||
func join_world_async() -> Dictionary:
|
||||
var world : NakamaAPI.ApiRpc = yield(_client.rpc_async(_session, "get_world_id", ""), "completed")
|
||||
if world.is_exception():
|
||||
print("Join world error occured: %s" % world.exception.message)
|
||||
return {}
|
||||
var _world_id : String = world.payload
|
||||
print(_world_id)
|
||||
return {}
|
||||
|
||||
func _on_socket_closed():
|
||||
_socket = null
|
||||
|
73
server/plugin/control/control.go
Normal file
73
server/plugin/control/control.go
Normal file
@ -0,0 +1,73 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/heroiclabs/nakama-common/runtime"
|
||||
)
|
||||
|
||||
type Match struct{}
|
||||
|
||||
type MatchState struct {
|
||||
presences map[string]runtime.Presence
|
||||
inputs map[string]string
|
||||
positions map[string]string
|
||||
jumps map[string]string
|
||||
colors map[string]string
|
||||
names map[string]string
|
||||
}
|
||||
|
||||
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]string{},
|
||||
jumps: map[string]string{},
|
||||
colors: map[string]string{},
|
||||
names: map[string]string{},
|
||||
}
|
||||
tickRate := 10
|
||||
label := "{\"name\": \"Game World\"}"
|
||||
|
||||
return state, tickRate, label
|
||||
}
|
||||
|
||||
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) {
|
||||
mState, _ := state.(*MatchState)
|
||||
if _, ok := mState.presences[presence.GetUserId()]; ok {
|
||||
return mState, true, ""
|
||||
} else {
|
||||
return mState, false, "User already logged in."
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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{} {
|
||||
mState, _ := state.(*MatchState)
|
||||
for _, precense := range presences {
|
||||
mState.presences[precense.GetUserId()] = precense
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
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{} {
|
||||
mState, _ := state.(*MatchState)
|
||||
for _, presence := range presences {
|
||||
delete(mState.presences, presence.GetUserId())
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
24
server/plugin/family_plugin.go
Normal file
24
server/plugin/family_plugin.go
Normal file
@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/heroiclabs/nakama-common/runtime"
|
||||
"github.com/josephbmanley/family/server/plugin/control"
|
||||
"github.com/josephbmanley/family/server/plugin/rpc"
|
||||
)
|
||||
|
||||
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
|
||||
logger.Info("Loaded family plugin!")
|
||||
|
||||
if err := initializer.RegisterMatch("control", func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule) (runtime.Match, error) {
|
||||
return &control.Match{}, nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := initializer.RegisterRpc("get_world_id", rpc.GetWorldId); err != nil {
|
||||
logger.Error("Unable to register: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
module world_rpc
|
||||
module github.com/josephbmanley/family/server/plugin
|
||||
|
||||
go 1.13
|
||||
|
@ -13,8 +13,8 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/heroiclabs/nakama-common v1.5.1 h1:ViCm9AvYYdQOCSKEa34SuSQ80JyZOHl6ODawESWf2wk=
|
||||
github.com/heroiclabs/nakama-common v1.5.1/go.mod h1:nZAXHdeo4SyPlCyf7pU9rCVizxEhBF74gt7teDe/EaQ=
|
||||
github.com/heroiclabs/nakama-common v1.6.0 h1:2ZUNI3y8LnEpLEXUXYfERgWS1nm1l0TKPAwnyGMU96U=
|
||||
github.com/heroiclabs/nakama-common v1.6.1 h1:A2n8Jsr+wGuK8qQj5enMpu65NigChrcAMZYDLAJMY88=
|
||||
github.com/heroiclabs/nakama-common v1.7.2 h1:FQedePGCorBl3tXW4Ro8+XLGbEDQfGrT5Tb07j1UaLc=
|
||||
github.com/josephbmanley/family v0.0.0-20200815220504-0d9d05943cef h1:6oijVkew6eKI1fGE+YMaxmiNlp/hkN9wDpStoid9/ZI=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
52
server/plugin/rpc/rpc.go
Normal file
52
server/plugin/rpc/rpc.go
Normal file
@ -0,0 +1,52 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/heroiclabs/nakama-common/runtime"
|
||||
)
|
||||
|
||||
func getFirstWorld(ctx context.Context, logger runtime.Logger, nk runtime.NakamaModule) (string, error) {
|
||||
|
||||
// List existing matches
|
||||
// that have been 1 & 4 players
|
||||
minSize := 1
|
||||
maxSize := 4
|
||||
matches, listErr := nk.MatchList(ctx, 1, false, "", &minSize, &maxSize, "") //local matches = nakama.match_list()
|
||||
|
||||
// Return if listing error
|
||||
if listErr != nil {
|
||||
logger.Printf("Failed to list matches when grabing first world! Error: %v\n", listErr)
|
||||
return "", listErr
|
||||
}
|
||||
|
||||
// If no matches exist, create one
|
||||
if len(matches) <= 0 {
|
||||
|
||||
// Create match
|
||||
//params := map[string]interface{}{}
|
||||
matchID, createErr := nk.MatchCreate(ctx, "control", map[string]interface{}{})
|
||||
//return nakama.match_create("world_control", {})
|
||||
|
||||
// Return if creation error
|
||||
if createErr != nil {
|
||||
logger.Printf("Failed to create match when grabing first world! Error: %v\n", createErr)
|
||||
return "", createErr
|
||||
}
|
||||
logger.Info("Successfully created new match!")
|
||||
|
||||
// Return newly created match
|
||||
return matchID, nil
|
||||
|
||||
} else {
|
||||
|
||||
// Return first found match
|
||||
return matches[0].GetMatchId(), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetWorldId(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
|
||||
matchID, err := getFirstWorld(ctx, logger, nk)
|
||||
return matchID, err
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/heroiclabs/nakama-common/runtime"
|
||||
)
|
||||
|
||||
func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, initializer runtime.Initializer) error {
|
||||
logger.Info("Loaded World RPC plugin!")
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user