How to ensure that a player can only join at most one party

How to ensure that a player can only join at most one party? I found no hook for before partyjoin. Is it judged by adding an rpc or the client makes the judgment locally?

Hello @hexun80149128,

A way to achieve this right now would be to use a beforeHook on PartyJoin and then checking if the user already has any party mode stream presences.

However, this seems like a good candidate for a feature request, please open an issue in the Nakama Github repository and we’ll consider implementing it in a future release.

[Feature Request] need beforehook on PartyJoin · Issue #1019 · heroiclabs/nakama · GitHub done.thanks

@hexun80149128 you misunderstood, apologies if I wasn’t clear - you can prevent a player from joining multiple parties using a beforeHook on PartyJoin right now, using the latest Nakama release.
You’d need to look for a stream with mode 7 (currently not documented, we’ll fix that in the docs) to know if the player is already a member of a party.

However, this seems like a common use case that we could add a configuration such as (e.g.) single_party to the server to automatically disallow players from joining multiple parties if set.

I’ve created the following issue: [Feature Request] Add config to disallow joining multiple parties · Issue #1020 · heroiclabs/nakama · GitHub.

thanks。i plan to write like this:
if err := initializer.RegisterBeforeRt(“PartyCreate”, beforePartyCreate); err != nil {
logger.Error(“Unable to register: %v”, err)
return err
}

if err := initializer.RegisterBeforeRt("PartyJoin", beforePartyJoin); err != nil {
	logger.Error("Unable to register: %v", err)
	return err
}

I wonder single_party feature when publish

You’d need to look for a stream with mode 7 (currently not documented, we’ll fix that in the docs) to know if the player is already a member of a party.
can you give me a example ? thanks

I find this may be work.

	exists, err := p.tracker.StreamExists(session.Context(), PresenceStream{
		Mode:    StreamModeParty,
		Subject: partyID,
		Label:   node,
	}, session.UserID())

here are 2 problems. need your help.thanks.@sesposito
1.partyID and node shouble be empty or ?
2. from nk runtime.NakamaModule , is there a way to get tracker?


type RuntimeGoNakamaModule struct {
	sync.RWMutex
	logger               *zap.Logger
	db                   *sql.DB
	protojsonMarshaler   *protojson.MarshalOptions
	config               Config
	socialClient         *social.Client
	leaderboardCache     LeaderboardCache
	leaderboardRankCache LeaderboardRankCache
	leaderboardScheduler LeaderboardScheduler
	sessionRegistry      SessionRegistry
	sessionCache         SessionCache
	statusRegistry       *StatusRegistry
	matchRegistry        MatchRegistry
	tracker              Tracker
	metrics              Metrics
	streamManager        StreamManager
	router               MessageRouter

	eventFn RuntimeEventCustomFunction

	node string

	matchCreateFn RuntimeMatchCreateFunction
}

but tracker is lowercase. outside can not visit it。

@hexun80149128 have a look at Heroic Labs Documentation | Streams.

1 Like
	if metaPresence, err := nk.StreamUserGet(server.StreamModeParty, "", "", "", userID, sessionID); err != nil {
		// Handle error.
		logger.Info("StreamUserGet err", err)
	} else if metaPresence != nil {
		logger.Info("User found on stream")
	} else {
		logger.Info("User not found on stream")
	}

I use this want to find wether the player is in party, but it not work. since I guess the subject id should not be blank,but be the party id.but the server don’t know the party id. how should I find wether the player is in party.Thanks.@sesposito

Hello @hexun80149128, can you try to use streamUserList instead and look if the userID is within the returned results?

members, err := nk.StreamUserList(7, "", "", "", true, true)
	if err != nil {
		// Handle error here
		logger.Error("StreamUserList", err)
		return envelope, nil
	}
	logger.Info("BeforePartyJoin len(members):", len(members))
	for _, m := range members {
		logger.Info("BeforePartyJoin Found user: %s\n", m.GetUserId())
	}

stille not work ,when player join party ,the len(members) is also 0,since I guess the subject id should not be blank.
should I implement by client,not the server now?

Just to double check, have you attempted to join a second party after the user is the member of one already?

yes。I tried。,the len(members) is also 0

You should be able to obtain the partyId as follows to use in the subject param,

if err = initializer.RegisterBeforeRt("PartyJoin", func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, envelope *rtapi.Envelope) (*rtapi.Envelope, error) {
  partyJoin := envelope.GetPartyJoin()
  partyId := partyJoin.PartyId

  if partyId == "" {
    return nil, errors.New("Empty party id")
  }

  (...)
		
  return envelope, nil
}); err != nil {
  return err
}

Best

yes,the party id is the new will join。I need the party id alreay join。。however,I limit by the client now。thanks

@zyro is there a better way of doing this?