From 12ea66e4fccb8cdbf5218569f3618745cc541136 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Sat, 15 Aug 2020 19:26:02 -0400 Subject: [PATCH] Create custom match plugin Rename world_control Fix package name Attempt with main package Go world_control debug Go world_control debug Added get world RPC method Remove '_' from module Nakama plugin testing Nakama plugin testing Nakama plugin testing Try updated pipeline Nakama plugin testing Update pipeline Rework plugin dir Fix path Fix imports Fix imports Load match Load match work Server changes Server changes Server changes Changes basic upon helpful suggestions Client side get match --- .github/workflows/build_dev.yml | 8 +- .github/workflows/build_release.yml | 15 ++-- .github/workflows/build_stage.yml | 15 ++-- client/scripts/menus/login_form.gd | 19 +++-- client/scripts/singletons/ServerConnection.gd | 23 +++++- server/plugin/control/control.go | 73 +++++++++++++++++++ server/plugin/family_plugin.go | 24 ++++++ server/{plugins/world_rpc => plugin}/go.mod | 2 +- server/{plugins/world_rpc => plugin}/go.sum | 4 +- server/plugin/rpc/rpc.go | 52 +++++++++++++ server/plugins/world_rpc/world_rpc.go | 14 ---- 11 files changed, 211 insertions(+), 38 deletions(-) create mode 100644 server/plugin/control/control.go create mode 100644 server/plugin/family_plugin.go rename server/{plugins/world_rpc => plugin}/go.mod (53%) rename server/{plugins/world_rpc => plugin}/go.sum (95%) create mode 100644 server/plugin/rpc/rpc.go delete mode 100644 server/plugins/world_rpc/world_rpc.go diff --git a/.github/workflows/build_dev.yml b/.github/workflows/build_dev.yml index f6b5efa..e5f9026 100644 --- a/.github/workflows/build_dev.yml +++ b/.github/workflows/build_dev.yml @@ -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: diff --git a/.github/workflows/build_release.yml b/.github/workflows/build_release.yml index 12bde47..da1fd22 100644 --- a/.github/workflows/build_release.yml +++ b/.github/workflows/build_release.yml @@ -52,18 +52,23 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Build Plugin - id: build_plugin + - name: Build RPC Plugin + id: build_rpc_plugin uses: josephbmanley/build-nakama-plugin-action@v0.1.1 with: nakamaVersion: "2.12.0" moduleDirectory: server/plugins/world_rpc + - name: Build Control Plugin + id: build_control_plugin + uses: josephbmanley/build-nakama-plugin-action@v0.1.1 + with: + nakamaVersion: "2.12.0" + moduleDirectory: server/plugins/control - name: Move Binary - env: - plugin: ${{ steps.build_plugin.outputs.binary }} run: | mkdir -p server/data/modules - mv $plugin server/data/modules + mv ${{ steps.build_rpc_plugin.outputs.binary }} server/data/modules + mv ${{ steps.build_control_plugin.outputs.binary }} server/data/modules - id: get_tag name: Get Tag env: diff --git a/.github/workflows/build_stage.yml b/.github/workflows/build_stage.yml index 74cf3bb..2e24b75 100644 --- a/.github/workflows/build_stage.yml +++ b/.github/workflows/build_stage.yml @@ -39,18 +39,23 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Build Plugin - id: build_plugin + - name: Build RPC Plugin + id: build_rpc_plugin uses: josephbmanley/build-nakama-plugin-action@v0.1.1 with: nakamaVersion: "2.12.0" moduleDirectory: server/plugins/world_rpc + - name: Build Control Plugin + id: build_control_plugin + uses: josephbmanley/build-nakama-plugin-action@v0.1.1 + with: + nakamaVersion: "2.12.0" + moduleDirectory: server/plugins/control - name: Move Binary - env: - plugin: ${{ steps.build_plugin.outputs.binary }} run: | mkdir -p server/data/modules - mv $plugin server/data/modules + mv ${{ steps.build_rpc_plugin.outputs.binary }} server/data/modules + mv ${{ steps.build_control_plugin.outputs.binary }} server/data/modules - name: Get Docker Repo Name id: find_repo run: | diff --git a/client/scripts/menus/login_form.gd b/client/scripts/menus/login_form.gd index b1eaf0e..06a3b83 100644 --- a/client/scripts/menus/login_form.gd +++ b/client/scripts/menus/login_form.gd @@ -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) diff --git a/client/scripts/singletons/ServerConnection.gd b/client/scripts/singletons/ServerConnection.gd index ae27970..fe4da27 100644 --- a/client/scripts/singletons/ServerConnection.gd +++ b/client/scripts/singletons/ServerConnection.gd @@ -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 diff --git a/server/plugin/control/control.go b/server/plugin/control/control.go new file mode 100644 index 0000000..6aeb31e --- /dev/null +++ b/server/plugin/control/control.go @@ -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 +} diff --git a/server/plugin/family_plugin.go b/server/plugin/family_plugin.go new file mode 100644 index 0000000..a4ddf6a --- /dev/null +++ b/server/plugin/family_plugin.go @@ -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 +} diff --git a/server/plugins/world_rpc/go.mod b/server/plugin/go.mod similarity index 53% rename from server/plugins/world_rpc/go.mod rename to server/plugin/go.mod index 4887533..509bb99 100644 --- a/server/plugins/world_rpc/go.mod +++ b/server/plugin/go.mod @@ -1,4 +1,4 @@ -module world_rpc +module github.com/josephbmanley/family/server/plugin go 1.13 diff --git a/server/plugins/world_rpc/go.sum b/server/plugin/go.sum similarity index 95% rename from server/plugins/world_rpc/go.sum rename to server/plugin/go.sum index 30c51d5..2015c67 100644 --- a/server/plugins/world_rpc/go.sum +++ b/server/plugin/go.sum @@ -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= diff --git a/server/plugin/rpc/rpc.go b/server/plugin/rpc/rpc.go new file mode 100644 index 0000000..c4c42eb --- /dev/null +++ b/server/plugin/rpc/rpc.go @@ -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 +} diff --git a/server/plugins/world_rpc/world_rpc.go b/server/plugins/world_rpc/world_rpc.go deleted file mode 100644 index ea2d70a..0000000 --- a/server/plugins/world_rpc/world_rpc.go +++ /dev/null @@ -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 -}