Commit 6e878aba authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Add FriendsBlock function to all runtimes.

parent 26094fa6
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@ All notable changes to this project are documented below.
The format is based on [keep a changelog](http://keepachangelog.com) and this project uses [semantic versioning](http://semver.org).

## [Unreleased]
### Added
- Add "FriendsBlock" function to all runtimes.

### Changed
- Ensure storage write ops return acks in the same order as inputs.
- Adjust console path for delete all data operation.
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ require (
	github.com/gorilla/mux v1.8.0
	github.com/gorilla/websocket v1.4.2
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0
	github.com/heroiclabs/nakama-common v1.22.1-0.20220506145920-4c0b3c5a4a43
	github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d
	github.com/jackc/pgconn v1.10.0
	github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451
	github.com/jackc/pgtype v1.8.1
+2 −2
Original line number Diff line number Diff line
@@ -290,8 +290,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/heroiclabs/nakama-common v1.22.1-0.20220506145920-4c0b3c5a4a43 h1:aNV5cSox9Bby8wClFmxVL7YjgzzyO/cXDrRvM4R3424=
github.com/heroiclabs/nakama-common v1.22.1-0.20220506145920-4c0b3c5a4a43/go.mod h1:WF4YG46afwY3ibzsXnkt3zvhQ3tBY03IYeU7xSLr8HE=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d h1:2pdN0sSZmdTwCOKhep4F3OeW36ODuhW76mLnZUCKsNM=
github.com/heroiclabs/nakama-common v1.22.1-0.20220521150612-11ae5d0b3b0d/go.mod h1:WF4YG46afwY3ibzsXnkt3zvhQ3tBY03IYeU7xSLr8HE=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+58 −0
Original line number Diff line number Diff line
@@ -3568,6 +3568,64 @@ func (n *RuntimeGoNakamaModule) FriendsDelete(ctx context.Context, userID string
	return nil
}

// @group friends
// @summary Block friends for a user.
// @param ctx(type=context.Context) The context object represents information about the server and requester.
// @param userId(type=string) The ID of the user for whom you want to block friends.
// @param username(type=string) The name of the user for whom you want to block friends.
// @param ids(type=[]string) The IDs of the users you want to block as friends.
// @param usernames(type=[]string) The usernames of the users you want to block as friends.
// @return error(error) An optional error value if an error occurred.
func (n *RuntimeGoNakamaModule) FriendsBlock(ctx context.Context, userID string, username string, ids []string, usernames []string) error {
	userUUID, err := uuid.FromString(userID)
	if err != nil {
		return errors.New("expects user ID to be a valid identifier")
	}

	if len(ids) == 0 && len(usernames) == 0 {
		return nil
	}

	for _, id := range ids {
		if userID == id {
			return errors.New("cannot block self")
		}
		if uid, err := uuid.FromString(id); err != nil || uid == uuid.Nil {
			return fmt.Errorf("invalid user ID '%v'", id)
		}
	}

	for _, u := range usernames {
		if u == "" {
			return errors.New("username to block must not be empty")
		}
		if username == u {
			return errors.New("cannot block self")
		}
	}

	fetchIDs, err := fetchUserID(ctx, n.db, usernames)
	if err != nil {
		n.logger.Error("Could not fetch user IDs.", zap.Error(err), zap.Strings("usernames", usernames))
		return errors.New("error while trying to block friends")
	}

	if len(fetchIDs)+len(ids) == 0 {
		return errors.New("no valid ID or username was provided")
	}

	allIDs := make([]string, 0, len(ids)+len(fetchIDs))
	allIDs = append(allIDs, ids...)
	allIDs = append(allIDs, fetchIDs...)

	err = BlockFriends(ctx, n.logger, n.db, userUUID, allIDs)
	if err != nil {
		return err
	}

	return nil
}

func (n *RuntimeGoNakamaModule) SetEventFn(fn RuntimeEventCustomFunction) {
	n.Lock()
	n.eventFn = fn
+91 −0
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ func (n *runtimeJavascriptNakamaModule) mappings(r *goja.Runtime) map[string]fun
		"friendsList":                     n.friendsList(r),
		"friendsAdd":                      n.friendsAdd(r),
		"friendsDelete":                   n.friendsDelete(r),
		"friendsBlock":                    n.friendsBlock(r),
		"groupUserJoin":                   n.groupUserJoin(r),
		"groupUserLeave":                  n.groupUserLeave(r),
		"groupUsersAdd":                   n.groupUsersAdd(r),
@@ -6832,6 +6833,96 @@ func (n *runtimeJavascriptNakamaModule) friendsDelete(r *goja.Runtime) func(goja
	}
}

// @group friends
// @summary Block friends for a user.
// @param userId(type=string) The ID of the user for whom you want to block friends.
// @param username(type=string) The name of the user for whom you want to block friends.
// @param ids(type=[]string) Table array of IDs of the users you want to block as friends.
// @param usernames(type=[]string) Table array of usernames of the users you want to block as friends.
// @return error(error) An optional error value if an error occurred.
func (n *runtimeJavascriptNakamaModule) friendsBlock(r *goja.Runtime) func(goja.FunctionCall) goja.Value {
	return func(f goja.FunctionCall) goja.Value {
		userIDString := getJsString(r, f.Argument(0))
		userID, err := uuid.FromString(userIDString)
		if err != nil {
			panic(r.NewTypeError("expects user ID to be a valid identifier"))
		}

		username := getJsString(r, f.Argument(1))
		if username == "" {
			panic(r.NewTypeError("expects a username string"))
		}

		var userIDs []string
		if f.Argument(2) != goja.Undefined() && f.Argument(2) != goja.Null() {
			var ok bool
			userIdsIn, ok := f.Argument(2).Export().([]interface{})
			if !ok {
				panic(r.NewTypeError("Invalid argument - user ids must be an array."))
			}
			uIds := make([]string, 0, len(userIdsIn))
			for _, userID := range userIdsIn {
				id, ok := userID.(string)
				if !ok {
					panic(r.NewTypeError(fmt.Sprintf("invalid user id: %v - must be a string", userID)))
				} else if uid, err := uuid.FromString(id); err != nil || uid == uuid.Nil {
					panic(r.NewTypeError(fmt.Sprintf("invalid user id: %v", userID)))
				} else if userIDString == id {
					panic(r.NewTypeError("cannot block self"))
				}
				uIds = append(uIds, id)
			}
			userIDs = uIds
		}

		var usernames []string
		if f.Argument(3) != goja.Undefined() && f.Argument(3) != goja.Null() {
			usernamesIn, ok := f.Argument(3).Export().([]interface{})
			if !ok {
				panic(r.NewTypeError("Invalid argument - usernames must be an array."))
			}
			unames := make([]string, 0, len(usernamesIn))
			for _, unameIn := range usernamesIn {
				uname, ok := unameIn.(string)
				if !ok {
					panic(r.NewTypeError("Invalid argument - username must be a string"))
				} else if uname == "" {
					panic(r.NewTypeError("username to block must not be empty"))
				} else if uname == username {
					panic(r.NewTypeError("cannot block self"))
				}
				unames = append(unames, uname)
			}
			usernames = unames
		}

		if userIDs == nil && usernames == nil {
			return goja.Undefined()
		}

		fetchIDs, err := fetchUserID(context.Background(), n.db, usernames)
		if err != nil {
			n.logger.Error("Could not fetch user IDs.", zap.Error(err), zap.Strings("usernames", usernames))
			panic(r.NewTypeError("error while trying to block friends"))
		}

		if len(fetchIDs)+len(userIDs) == 0 {
			panic(r.NewTypeError("no valid ID or username was provided"))
		}

		allIDs := make([]string, 0, len(userIDs)+len(fetchIDs))
		allIDs = append(allIDs, userIDs...)
		allIDs = append(allIDs, fetchIDs...)

		err = BlockFriends(context.Background(), n.logger, n.db, userID, allIDs)
		if err != nil {
			panic(r.NewTypeError(err.Error()))
		}

		return goja.Undefined()
	}
}

// @group groups
// @summary Join a group for a particular user.
// @param groupId(type=string) The ID of the group to join.
Loading