@@ -4,11 +4,14 @@ import (
44 "github.com/PretendoNetwork/minecraft-wiiu/globals"
55 "github.com/PretendoNetwork/nex-go/v2"
66 "github.com/PretendoNetwork/nex-go/v2/types"
7+ commonglobals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
8+ "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making/database"
79 commonnattraversal "github.com/PretendoNetwork/nex-protocols-common-go/v2/nat-traversal"
810 commonsecure "github.com/PretendoNetwork/nex-protocols-common-go/v2/secure-connection"
911 nattraversal "github.com/PretendoNetwork/nex-protocols-go/v2/nat-traversal"
1012 secure "github.com/PretendoNetwork/nex-protocols-go/v2/secure-connection"
1113 "os"
14+ "slices"
1215
1316 commonmatchmaking "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making"
1417 commonmatchmakingext "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making-ext"
@@ -69,6 +72,63 @@ func stubBrowseMatchmakeSession(err error, packet nex.PacketInterface, callID ui
6972 return rmcResponse , nil
7073}
7174
75+ func gameSpecificCanJoinMatchmakeSession (manager * commonglobals.MatchmakingManager , pid * types.PID , session * matchmakingtypes.MatchmakeSession ) * nex.Error {
76+ if ! session .OpenParticipation .Value {
77+ return nex .NewError (nex .ResultCodes .RendezVous .PermissionDenied , "Gathering is not open to new participants" )
78+ }
79+
80+ isPublic := false
81+ attrib , err := session .Attributes .Get (0 )
82+ if err == nil {
83+ // * I wish this was a joke. top 8 bits are GameMode
84+ // * This is the only difference between a public and a Friends match
85+ isPublic = (attrib .Value & 0xFFFFFF ) == 0x30881
86+ }
87+
88+ if isPublic && os .Getenv ("PN_MINECRAFT_ALLOW_PUBLIC_MATCHMAKING" ) == "1" {
89+ //globals.Logger.Info("Game is public")
90+ return nil
91+ }
92+
93+ host := session .OwnerPID
94+ hostFriends := manager .GetUserFriendPIDs (host .LegacyValue ())
95+ if slices .Contains (hostFriends , pid .LegacyValue ()) {
96+ //globals.Logger.Info("User is friend of host")
97+ return nil
98+ }
99+
100+ isFriendsOfFriends := false
101+ if len (session .ApplicationBuffer .Value ) > 0xc3 {
102+ isFriendsOfFriends = session .ApplicationBuffer .Value [0xc3 ] == 0x8F
103+ }
104+
105+ if ! isFriendsOfFriends {
106+ return nex .NewError (nex .ResultCodes .RendezVous .NotFriend , "User is not a friend of host" )
107+ }
108+
109+ // * Get the participants of this gathering so we don't have to check all 100whatever of host's friends
110+ _ , _ , participants , _ , nerr := database .FindGatheringByID (manager , session .ID .Value )
111+ if err != nil {
112+ globals .Logger .Errorf ("Can't find gathering for pariticpation check: %v" , nerr )
113+ return nerr
114+ }
115+
116+ for _ , friend := range hostFriends {
117+ // * Make sure this friend is actually in-game
118+ // * This cast feels bad
119+ if slices .Contains (participants , uint64 (friend )) {
120+ // * Are you a friend of the host's friend?
121+ friendsFriends := manager .GetUserFriendPIDs (friend )
122+ if slices .Contains (friendsFriends , pid .LegacyValue ()) {
123+ //globals.Logger.Infof("User is friend of host's friend %v", friend)
124+ return nil
125+ }
126+ }
127+ }
128+
129+ return nex .NewError (nex .ResultCodes .RendezVous .NotFriend , "User is not a friend of host's friends" )
130+ }
131+
72132func registerCommonSecureServerProtocols () {
73133 secureProtocol := secure .NewProtocol ()
74134 globals .SecureEndpoint .RegisterServiceProtocol (secureProtocol )
@@ -95,6 +155,9 @@ func registerCommonSecureServerProtocols() {
95155 commonMatchmakeExtensionProtocol := commonmatchmakeextension .NewCommonProtocol (matchmakeExtensionProtocol )
96156 commonMatchmakeExtensionProtocol .SetManager (globals .MatchmakingManager )
97157
158+ globals .MatchmakingManager .GetUserFriendPIDs = globals .GetUserFriendPIDs
159+ globals .MatchmakingManager .CanJoinMatchmakeSession = gameSpecificCanJoinMatchmakeSession
160+
98161 commonMatchmakeExtensionProtocol .CleanupSearchMatchmakeSession = cleanupSearchMatchmakeSessionHandler
99162 if os .Getenv ("PN_MINECRAFT_ALLOW_PUBLIC_MATCHMAKING" ) != "1" {
100163 globals .Logger .Warning ("Public minigames are disabled for safety reasons." )
0 commit comments