Loading server/runtime_javascript.go +8 −6 Original line number Diff line number Diff line Loading @@ -505,6 +505,8 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM Indent: jsonpbMarshaler.Indent, } localCache := NewRuntimeJavascriptLocalCache() runtimeProviderJS := &RuntimeProviderJS{ config: config, logger: logger, Loading Loading @@ -537,7 +539,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM var tournamentResetFunction RuntimeTournamentResetFunction var leaderboardResetFunction RuntimeLeaderboardResetFunction callbacks, matchCallbacks, err := evalRuntimeModules(runtimeProviderJS, modCache, matchProvider, leaderboardScheduler, func(mode RuntimeExecutionMode, id string) { callbacks, matchCallbacks, err := evalRuntimeModules(runtimeProviderJS, modCache, matchProvider, leaderboardScheduler, localCache, func(mode RuntimeExecutionMode, id string) { switch mode { case RuntimeExecutionModeRPC: rpcFunctions[id] = func(ctx context.Context, queryParams map[string][]string, userID, username string, vars map[string]string, expiry int64, sessionID, clientIP, clientPort, payload string) (string, error, codes.Code) { Loading Loading @@ -1385,7 +1387,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM return nil, nil } return NewRuntimeJavascriptMatchCore(logger, name, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, matchProvider.CreateMatch, eventFn, id, node, stopped, mc) return NewRuntimeJavascriptMatchCore(logger, name, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, matchProvider.CreateMatch, eventFn, id, node, stopped, mc) }) runtimeProviderJS.newFn = func() *RuntimeJS { Loading @@ -1398,7 +1400,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM logger.Fatal("Failed to initialize JavaScript runtime", zap.Error(err)) } nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchProvider.CreateMatch) nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchProvider.CreateMatch) nk := runtime.ToValue(nakamaModule.Constructor(runtime)) nkInst, err := runtime.New(nk) if err != nil { Loading Loading @@ -1441,7 +1443,7 @@ func CheckRuntimeProviderJavascript(logger *zap.Logger, config Config) error { logger: logger, config: config, } _, _, err = evalRuntimeModules(rp, modCache, nil, nil, func(RuntimeExecutionMode, string) {}, true) _, _, err = evalRuntimeModules(rp, modCache, nil, nil, nil, func(RuntimeExecutionMode, string) {}, true) if err != nil { logger.Error("Failed to load JavaScript module.", zap.Error(err)) } Loading Loading @@ -1704,7 +1706,7 @@ func (rp *RuntimeProviderJS) LeaderboardReset(ctx context.Context, leaderboard r return errors.New("Unexpected return type from runtime Leaderboard Reset hook, must be nil.") } func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, matchProvider *MatchProvider, leaderboardScheduler LeaderboardScheduler, announceCallbackFn func(RuntimeExecutionMode, string), dryRun bool) (*RuntimeJavascriptCallbacks, *RuntimeJavascriptMatchHandlers, error) { func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, matchProvider *MatchProvider, leaderboardScheduler LeaderboardScheduler, localCache *RuntimeJavascriptLocalCache, announceCallbackFn func(RuntimeExecutionMode, string), dryRun bool) (*RuntimeJavascriptCallbacks, *RuntimeJavascriptMatchHandlers, error) { logger := rp.logger r := goja.New() Loading @@ -1723,7 +1725,7 @@ func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, m return nil, nil, err } nakamaModule := NewRuntimeJavascriptNakamaModule(rp.logger, rp.db, rp.jsonpbMarshaler, rp.jsonpbUnmarshaler, rp.config, rp.socialClient, rp.leaderboardCache, rp.leaderboardRankCache, leaderboardScheduler, rp.sessionRegistry, rp.matchRegistry, rp.tracker, rp.streamManager, rp.router, rp.eventFn, matchProvider.CreateMatch) nakamaModule := NewRuntimeJavascriptNakamaModule(rp.logger, rp.db, rp.jsonpbMarshaler, rp.jsonpbUnmarshaler, rp.config, rp.socialClient, rp.leaderboardCache, rp.leaderboardRankCache, localCache, leaderboardScheduler, rp.sessionRegistry, rp.matchRegistry, rp.tracker, rp.streamManager, rp.router, rp.eventFn, matchProvider.CreateMatch) nk := r.ToValue(nakamaModule.Constructor(r)) nkInst, err := r.New(nk) if err != nil { Loading server/runtime_javascript_localcache.go 0 → 100644 +50 −0 Original line number Diff line number Diff line // Copyright 2021 The Nakama Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package server import ( "github.com/dop251/goja" "sync" ) type RuntimeJavascriptLocalCache struct { sync.RWMutex data map[string]goja.Value } func NewRuntimeJavascriptLocalCache() *RuntimeJavascriptLocalCache { return &RuntimeJavascriptLocalCache{ data: make(map[string]goja.Value), } } func (lc *RuntimeJavascriptLocalCache) Get(key string) (goja.Value, bool) { lc.RLock() value, found := lc.data[key] lc.RUnlock() return value, found } func (lc *RuntimeJavascriptLocalCache) Put(key string, value goja.Value) { lc.Lock() lc.data[key] = value lc.Unlock() } func (lc *RuntimeJavascriptLocalCache) Delete(key string) { lc.Lock() delete(lc.data, key) lc.Unlock() } server/runtime_javascript_match_core.go +2 −2 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ type RuntimeJavaScriptMatchCore struct { // ctxCancelFn context.CancelFunc } func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, matchCreateFn RuntimeMatchCreateFunction, eventFn RuntimeEventCustomFunction, id uuid.UUID, node string, stopped *atomic.Bool, matchHandlers *jsMatchHandlers) (RuntimeMatchCore, error) { func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, localCache *RuntimeJavascriptLocalCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, matchCreateFn RuntimeMatchCreateFunction, eventFn RuntimeEventCustomFunction, id uuid.UUID, node string, stopped *atomic.Bool, matchHandlers *jsMatchHandlers) (RuntimeMatchCore, error) { runtime := goja.New() jsLogger := NewJsLogger(logger) Loading @@ -72,7 +72,7 @@ func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB logger.Fatal("Failed to initialize JavaScript runtime", zap.Error(err)) } nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, rankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchCreateFn) nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, rankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchCreateFn) nk := runtime.ToValue(nakamaModule.Constructor(runtime)) nkInst, err := runtime.New(nk) if err != nil { Loading server/runtime_javascript_nakama.go +60 −3 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ type runtimeJavascriptNakamaModule struct { socialClient *social.Client leaderboardCache LeaderboardCache rankCache LeaderboardRankCache localCache *RuntimeJavascriptLocalCache leaderboardScheduler LeaderboardScheduler tracker Tracker sessionRegistry SessionRegistry Loading @@ -77,7 +78,7 @@ type runtimeJavascriptNakamaModule struct { eventFn RuntimeEventCustomFunction } func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, eventFn RuntimeEventCustomFunction, matchCreateFn RuntimeMatchCreateFunction) *runtimeJavascriptNakamaModule { func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, localCache *RuntimeJavascriptLocalCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, eventFn RuntimeEventCustomFunction, matchCreateFn RuntimeMatchCreateFunction) *runtimeJavascriptNakamaModule { return &runtimeJavascriptNakamaModule{ logger: logger, config: config, Loading @@ -92,6 +93,7 @@ func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMars socialClient: socialClient, leaderboardCache: leaderboardCache, rankCache: rankCache, localCache: localCache, leaderboardScheduler: leaderboardScheduler, httpClient: &http.Client{ Timeout: 5 * time.Second, Loading Loading @@ -225,6 +227,9 @@ func (n *runtimeJavascriptNakamaModule) mappings(r *goja.Runtime) map[string]fun "groupUsersPromote": n.groupUsersPromote(r), "groupUsersDemote": n.groupUsersDemote(r), "fileRead": n.fileRead(r), "localcacheGet": n.localcacheGet(r), "localcachePut": n.localcachePut(r), "localcacheDelete": n.localcacheDelete(r), } } Loading @@ -233,7 +238,7 @@ func (n *runtimeJavascriptNakamaModule) event(r *goja.Runtime) func(goja.Functio eventName := getJsString(r, f.Argument(0)) properties := getJsStringMap(r, f.Argument(1)) ts := ×tamp.Timestamp{} if f.Argument(2) != goja.Undefined() { if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() { ts.Seconds = getJsInt(r, f.Argument(2)) } else { ts.Seconds = time.Now().Unix() Loading Loading @@ -2105,7 +2110,7 @@ func (n *runtimeJavascriptNakamaModule) streamUserGet(r *goja.Runtime) func(goja stream := getStreamData(r, streamObj) meta := n.tracker.GetLocalBySessionIDStreamUserID(sessionID, stream, userID) if meta == nil { return nil return goja.Null() } return r.ToValue(map[string]interface{}{ Loading Loading @@ -5534,6 +5539,58 @@ func (n *runtimeJavascriptNakamaModule) fileRead(r *goja.Runtime) func(goja.Func } } func (n *runtimeJavascriptNakamaModule) localcacheGet(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } defVal := goja.Undefined() if f.Argument(1) != goja.Undefined() && f.Argument(1) != goja.Null() { defVal = f.Argument(1) } value, found := n.localCache.Get(key) if found { return value } return defVal } } func (n *runtimeJavascriptNakamaModule) localcachePut(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } value := f.Argument(1) if value == goja.Undefined() || value == goja.Null() { panic(r.NewTypeError("expects a non empty value")) } n.localCache.Put(key, value) return goja.Undefined() } } func (n *runtimeJavascriptNakamaModule) localcacheDelete(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } n.localCache.Delete(key) return goja.Undefined() } } func getJsString(r *goja.Runtime, v goja.Value) string { s, ok := v.Export().(string) if !ok { Loading Loading
server/runtime_javascript.go +8 −6 Original line number Diff line number Diff line Loading @@ -505,6 +505,8 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM Indent: jsonpbMarshaler.Indent, } localCache := NewRuntimeJavascriptLocalCache() runtimeProviderJS := &RuntimeProviderJS{ config: config, logger: logger, Loading Loading @@ -537,7 +539,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM var tournamentResetFunction RuntimeTournamentResetFunction var leaderboardResetFunction RuntimeLeaderboardResetFunction callbacks, matchCallbacks, err := evalRuntimeModules(runtimeProviderJS, modCache, matchProvider, leaderboardScheduler, func(mode RuntimeExecutionMode, id string) { callbacks, matchCallbacks, err := evalRuntimeModules(runtimeProviderJS, modCache, matchProvider, leaderboardScheduler, localCache, func(mode RuntimeExecutionMode, id string) { switch mode { case RuntimeExecutionModeRPC: rpcFunctions[id] = func(ctx context.Context, queryParams map[string][]string, userID, username string, vars map[string]string, expiry int64, sessionID, clientIP, clientPort, payload string) (string, error, codes.Code) { Loading Loading @@ -1385,7 +1387,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM return nil, nil } return NewRuntimeJavascriptMatchCore(logger, name, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, matchProvider.CreateMatch, eventFn, id, node, stopped, mc) return NewRuntimeJavascriptMatchCore(logger, name, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, matchProvider.CreateMatch, eventFn, id, node, stopped, mc) }) runtimeProviderJS.newFn = func() *RuntimeJS { Loading @@ -1398,7 +1400,7 @@ func NewRuntimeProviderJS(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbM logger.Fatal("Failed to initialize JavaScript runtime", zap.Error(err)) } nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchProvider.CreateMatch) nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, leaderboardRankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchProvider.CreateMatch) nk := runtime.ToValue(nakamaModule.Constructor(runtime)) nkInst, err := runtime.New(nk) if err != nil { Loading Loading @@ -1441,7 +1443,7 @@ func CheckRuntimeProviderJavascript(logger *zap.Logger, config Config) error { logger: logger, config: config, } _, _, err = evalRuntimeModules(rp, modCache, nil, nil, func(RuntimeExecutionMode, string) {}, true) _, _, err = evalRuntimeModules(rp, modCache, nil, nil, nil, func(RuntimeExecutionMode, string) {}, true) if err != nil { logger.Error("Failed to load JavaScript module.", zap.Error(err)) } Loading Loading @@ -1704,7 +1706,7 @@ func (rp *RuntimeProviderJS) LeaderboardReset(ctx context.Context, leaderboard r return errors.New("Unexpected return type from runtime Leaderboard Reset hook, must be nil.") } func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, matchProvider *MatchProvider, leaderboardScheduler LeaderboardScheduler, announceCallbackFn func(RuntimeExecutionMode, string), dryRun bool) (*RuntimeJavascriptCallbacks, *RuntimeJavascriptMatchHandlers, error) { func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, matchProvider *MatchProvider, leaderboardScheduler LeaderboardScheduler, localCache *RuntimeJavascriptLocalCache, announceCallbackFn func(RuntimeExecutionMode, string), dryRun bool) (*RuntimeJavascriptCallbacks, *RuntimeJavascriptMatchHandlers, error) { logger := rp.logger r := goja.New() Loading @@ -1723,7 +1725,7 @@ func evalRuntimeModules(rp *RuntimeProviderJS, modCache *RuntimeJSModuleCache, m return nil, nil, err } nakamaModule := NewRuntimeJavascriptNakamaModule(rp.logger, rp.db, rp.jsonpbMarshaler, rp.jsonpbUnmarshaler, rp.config, rp.socialClient, rp.leaderboardCache, rp.leaderboardRankCache, leaderboardScheduler, rp.sessionRegistry, rp.matchRegistry, rp.tracker, rp.streamManager, rp.router, rp.eventFn, matchProvider.CreateMatch) nakamaModule := NewRuntimeJavascriptNakamaModule(rp.logger, rp.db, rp.jsonpbMarshaler, rp.jsonpbUnmarshaler, rp.config, rp.socialClient, rp.leaderboardCache, rp.leaderboardRankCache, localCache, leaderboardScheduler, rp.sessionRegistry, rp.matchRegistry, rp.tracker, rp.streamManager, rp.router, rp.eventFn, matchProvider.CreateMatch) nk := r.ToValue(nakamaModule.Constructor(r)) nkInst, err := r.New(nk) if err != nil { Loading
server/runtime_javascript_localcache.go 0 → 100644 +50 −0 Original line number Diff line number Diff line // Copyright 2021 The Nakama Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package server import ( "github.com/dop251/goja" "sync" ) type RuntimeJavascriptLocalCache struct { sync.RWMutex data map[string]goja.Value } func NewRuntimeJavascriptLocalCache() *RuntimeJavascriptLocalCache { return &RuntimeJavascriptLocalCache{ data: make(map[string]goja.Value), } } func (lc *RuntimeJavascriptLocalCache) Get(key string) (goja.Value, bool) { lc.RLock() value, found := lc.data[key] lc.RUnlock() return value, found } func (lc *RuntimeJavascriptLocalCache) Put(key string, value goja.Value) { lc.Lock() lc.data[key] = value lc.Unlock() } func (lc *RuntimeJavascriptLocalCache) Delete(key string) { lc.Lock() delete(lc.data, key) lc.Unlock() }
server/runtime_javascript_match_core.go +2 −2 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ type RuntimeJavaScriptMatchCore struct { // ctxCancelFn context.CancelFunc } func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, matchCreateFn RuntimeMatchCreateFunction, eventFn RuntimeEventCustomFunction, id uuid.UUID, node string, stopped *atomic.Bool, matchHandlers *jsMatchHandlers) (RuntimeMatchCore, error) { func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, localCache *RuntimeJavascriptLocalCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, matchCreateFn RuntimeMatchCreateFunction, eventFn RuntimeEventCustomFunction, id uuid.UUID, node string, stopped *atomic.Bool, matchHandlers *jsMatchHandlers) (RuntimeMatchCore, error) { runtime := goja.New() jsLogger := NewJsLogger(logger) Loading @@ -72,7 +72,7 @@ func NewRuntimeJavascriptMatchCore(logger *zap.Logger, module string, db *sql.DB logger.Fatal("Failed to initialize JavaScript runtime", zap.Error(err)) } nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, rankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchCreateFn) nakamaModule := NewRuntimeJavascriptNakamaModule(logger, db, jsonpbMarshaler, jsonpbUnmarshaler, config, socialClient, leaderboardCache, rankCache, localCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, eventFn, matchCreateFn) nk := runtime.ToValue(nakamaModule.Constructor(runtime)) nkInst, err := runtime.New(nk) if err != nil { Loading
server/runtime_javascript_nakama.go +60 −3 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ type runtimeJavascriptNakamaModule struct { socialClient *social.Client leaderboardCache LeaderboardCache rankCache LeaderboardRankCache localCache *RuntimeJavascriptLocalCache leaderboardScheduler LeaderboardScheduler tracker Tracker sessionRegistry SessionRegistry Loading @@ -77,7 +78,7 @@ type runtimeJavascriptNakamaModule struct { eventFn RuntimeEventCustomFunction } func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, eventFn RuntimeEventCustomFunction, matchCreateFn RuntimeMatchCreateFunction) *runtimeJavascriptNakamaModule { func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, rankCache LeaderboardRankCache, localCache *RuntimeJavascriptLocalCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, eventFn RuntimeEventCustomFunction, matchCreateFn RuntimeMatchCreateFunction) *runtimeJavascriptNakamaModule { return &runtimeJavascriptNakamaModule{ logger: logger, config: config, Loading @@ -92,6 +93,7 @@ func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, jsonpbMars socialClient: socialClient, leaderboardCache: leaderboardCache, rankCache: rankCache, localCache: localCache, leaderboardScheduler: leaderboardScheduler, httpClient: &http.Client{ Timeout: 5 * time.Second, Loading Loading @@ -225,6 +227,9 @@ func (n *runtimeJavascriptNakamaModule) mappings(r *goja.Runtime) map[string]fun "groupUsersPromote": n.groupUsersPromote(r), "groupUsersDemote": n.groupUsersDemote(r), "fileRead": n.fileRead(r), "localcacheGet": n.localcacheGet(r), "localcachePut": n.localcachePut(r), "localcacheDelete": n.localcacheDelete(r), } } Loading @@ -233,7 +238,7 @@ func (n *runtimeJavascriptNakamaModule) event(r *goja.Runtime) func(goja.Functio eventName := getJsString(r, f.Argument(0)) properties := getJsStringMap(r, f.Argument(1)) ts := ×tamp.Timestamp{} if f.Argument(2) != goja.Undefined() { if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() { ts.Seconds = getJsInt(r, f.Argument(2)) } else { ts.Seconds = time.Now().Unix() Loading Loading @@ -2105,7 +2110,7 @@ func (n *runtimeJavascriptNakamaModule) streamUserGet(r *goja.Runtime) func(goja stream := getStreamData(r, streamObj) meta := n.tracker.GetLocalBySessionIDStreamUserID(sessionID, stream, userID) if meta == nil { return nil return goja.Null() } return r.ToValue(map[string]interface{}{ Loading Loading @@ -5534,6 +5539,58 @@ func (n *runtimeJavascriptNakamaModule) fileRead(r *goja.Runtime) func(goja.Func } } func (n *runtimeJavascriptNakamaModule) localcacheGet(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } defVal := goja.Undefined() if f.Argument(1) != goja.Undefined() && f.Argument(1) != goja.Null() { defVal = f.Argument(1) } value, found := n.localCache.Get(key) if found { return value } return defVal } } func (n *runtimeJavascriptNakamaModule) localcachePut(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } value := f.Argument(1) if value == goja.Undefined() || value == goja.Null() { panic(r.NewTypeError("expects a non empty value")) } n.localCache.Put(key, value) return goja.Undefined() } } func (n *runtimeJavascriptNakamaModule) localcacheDelete(r *goja.Runtime) func(goja.FunctionCall) goja.Value { return func(f goja.FunctionCall) goja.Value { key := getJsString(r, f.Argument(0)) if key == "" { panic(r.NewTypeError("expects non empty key string")) } n.localCache.Delete(key) return goja.Undefined() } } func getJsString(r *goja.Runtime, v goja.Value) string { s, ok := v.Export().(string) if !ok { Loading