@@ -25,8 +25,7 @@ public class MultiplayerManagerDedicated : MultiplayerManagerBase, IMultiplayerM
2525 private static readonly Logger _log = LogManager . GetCurrentClassLogger ( ) ;
2626
2727#pragma warning disable 649
28- [ ReflectedGetter ( Name = "m_members" ) ]
29- private static Func < MyDedicatedServerBase , List < ulong > > _members ;
28+ [ ReflectedGetter ( Name = "m_members" ) ] private static Func < MyDedicatedServerBase , List < ulong > > _members ;
3029 [ ReflectedGetter ( Name = "m_waitingForGroup" ) ]
3130 private static Func < MyDedicatedServerBase , HashSet < ulong > > _waitingForGroup ;
3231#pragma warning restore 649
@@ -37,7 +36,9 @@ public class MultiplayerManagerDedicated : MultiplayerManagerBase, IMultiplayerM
3736 private Dictionary < ulong , ulong > _gameOwnerIds = new Dictionary < ulong , ulong > ( ) ;
3837
3938 /// <inheritdoc />
40- public MultiplayerManagerDedicated ( ITorchBase torch ) : base ( torch ) { }
39+ public MultiplayerManagerDedicated ( ITorchBase torch ) : base ( torch )
40+ {
41+ }
4142
4243 /// <inheritdoc />
4344 public void KickPlayer ( ulong steamId ) => Torch . Invoke ( ( ) => MyMultiplayer . Static . KickClient ( steamId ) ) ;
@@ -54,16 +55,19 @@ public void BanPlayer(ulong steamId, bool banned = true)
5455 }
5556
5657 /// <inheritdoc />
57- public bool IsBanned ( ulong steamId ) => _isClientBanned . Invoke ( MyMultiplayer . Static , steamId ) || MySandboxGame . ConfigDedicated . Banned . Contains ( steamId ) ;
58+ public bool IsBanned ( ulong steamId ) => _isClientBanned . Invoke ( MyMultiplayer . Static , steamId ) ||
59+ MySandboxGame . ConfigDedicated . Banned . Contains ( steamId ) ;
5860
5961 /// <inheritdoc/>
6062 public override void Attach ( )
6163 {
6264 base . Attach ( ) ;
6365 _gameServerValidateAuthTicketReplacer = _gameServerValidateAuthTicketFactory . Invoke ( ) ;
6466 _gameServerUserGroupStatusReplacer = _gameServerUserGroupStatusFactory . Invoke ( ) ;
65- _gameServerValidateAuthTicketReplacer . Replace ( new Action < ulong , JoinResult , ulong > ( ValidateAuthTicketResponse ) , MyGameService . GameServer ) ;
66- _gameServerUserGroupStatusReplacer . Replace ( new Action < ulong , ulong , bool , bool > ( UserGroupStatusResponse ) , MyGameService . GameServer ) ;
67+ _gameServerValidateAuthTicketReplacer . Replace (
68+ new Action < ulong , JoinResult , ulong > ( ValidateAuthTicketResponse ) , MyGameService . GameServer ) ;
69+ _gameServerUserGroupStatusReplacer . Replace ( new Action < ulong , ulong , bool , bool > ( UserGroupStatusResponse ) ,
70+ MyGameService . GameServer ) ;
6771 _log . Info ( "Inserted steam authentication intercept" ) ;
6872 }
6973
@@ -80,94 +84,151 @@ public override void Detach()
8084
8185
8286#pragma warning disable 649
83- [ ReflectedEventReplace ( typeof ( MySteamGameServer ) , nameof ( MySteamGameServer . ValidateAuthTicketResponse ) , typeof ( MyDedicatedServerBase ) , "GameServer_ValidateAuthTicketResponse" ) ]
87+ [ ReflectedEventReplace ( typeof ( MySteamGameServer ) , nameof ( MySteamGameServer . ValidateAuthTicketResponse ) ,
88+ typeof ( MyDedicatedServerBase ) , "GameServer_ValidateAuthTicketResponse" ) ]
8489 private static Func < ReflectedEventReplacer > _gameServerValidateAuthTicketFactory ;
85- [ ReflectedEventReplace ( typeof ( MySteamGameServer ) , nameof ( MySteamGameServer . UserGroupStatusResponse ) , typeof ( MyDedicatedServerBase ) , "GameServer_UserGroupStatus" ) ]
90+
91+ [ ReflectedEventReplace ( typeof ( MySteamGameServer ) , nameof ( MySteamGameServer . UserGroupStatusResponse ) ,
92+ typeof ( MyDedicatedServerBase ) , "GameServer_UserGroupStatus" ) ]
8693 private static Func < ReflectedEventReplacer > _gameServerUserGroupStatusFactory ;
94+
8795 private ReflectedEventReplacer _gameServerValidateAuthTicketReplacer ;
8896 private ReflectedEventReplacer _gameServerUserGroupStatusReplacer ;
8997#pragma warning restore 649
9098
9199 #region CustomAuth
100+
92101#pragma warning disable 649
93102 [ ReflectedStaticMethod ( Type = typeof ( MyDedicatedServerBase ) , Name = "ConvertSteamIDFrom64" ) ]
94103 private static Func < ulong , string > _convertSteamIDFrom64 ;
95104
96105 [ ReflectedStaticMethod ( Type = typeof ( MyGameService ) , Name = "GetServerAccountType" ) ]
97106 private static Func < ulong , MyGameServiceAccountType > _getServerAccountType ;
98107
99- [ ReflectedMethod ( Name = "UserAccepted" ) ]
100- private static Action < MyDedicatedServerBase , ulong > _userAcceptedImpl ;
108+ [ ReflectedMethod ( Name = "UserAccepted" ) ] private static Action < MyDedicatedServerBase , ulong > _userAcceptedImpl ;
101109
102110 [ ReflectedMethod ( Name = "UserRejected" ) ]
103111 private static Action < MyDedicatedServerBase , ulong , JoinResult > _userRejected ;
104- [ ReflectedMethod ( Name = "IsClientBanned" ) ]
105- private static Func < MyMultiplayerBase , ulong , bool > _isClientBanned ;
106- [ ReflectedMethod ( Name = "IsClientKicked" ) ]
107- private static Func < MyMultiplayerBase , ulong , bool > _isClientKicked ;
112+
113+ [ ReflectedMethod ( Name = "IsClientBanned" ) ] private static Func < MyMultiplayerBase , ulong , bool > _isClientBanned ;
114+ [ ReflectedMethod ( Name = "IsClientKicked" ) ] private static Func < MyMultiplayerBase , ulong , bool > _isClientKicked ;
115+
108116 [ ReflectedMethod ( Name = "RaiseClientKicked" ) ]
109117 private static Action < MyMultiplayerBase , ulong > _raiseClientKicked ;
110118#pragma warning restore 649
111119
120+ private const int _waitListSize = 32 ;
121+ private readonly List < WaitingForGroup > _waitingForGroupLocal = new List < WaitingForGroup > ( _waitListSize ) ;
122+
123+ private struct WaitingForGroup
124+ {
125+ public readonly ulong SteamId ;
126+ public readonly JoinResult Response ;
127+ public readonly ulong SteamOwner ;
128+
129+ public WaitingForGroup ( ulong id , JoinResult response , ulong owner )
130+ {
131+ SteamId = id ;
132+ Response = response ;
133+ SteamOwner = owner ;
134+ }
135+ }
136+
112137 //Largely copied from SE
113138 private void ValidateAuthTicketResponse ( ulong steamID , JoinResult response , ulong steamOwner )
114139 {
115140 _log . Debug ( $ "ValidateAuthTicketResponse(user={ steamID } , response={ response } , owner={ steamOwner } ") ;
116- if ( IsBanned ( steamOwner ) )
117- {
118- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , JoinResult . BannedByAdmins ) ;
119- _raiseClientKicked . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID ) ;
120- }
121- else if ( _isClientKicked . Invoke ( MyMultiplayer . Static , steamOwner ) )
122- {
123- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , JoinResult . KickedRecently ) ;
124- _raiseClientKicked . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID ) ;
125- }
126- if ( response != JoinResult . OK )
127- {
128- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , response ) ;
129- return ;
130- }
131- if ( MyMultiplayer . Static . MemberLimit > 0 && _members . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static ) . Count - 1 >= MyMultiplayer . Static . MemberLimit )
132- {
133- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , JoinResult . ServerFull ) ;
134- return ;
135- }
136- if ( MySandboxGame . ConfigDedicated . GroupID == 0uL ||
137- MySandboxGame . ConfigDedicated . Administrators . Contains ( steamID . ToString ( ) ) ||
138- MySandboxGame . ConfigDedicated . Administrators . Contains ( _convertSteamIDFrom64 ( steamID ) ) )
139- {
140- this . UserAccepted ( steamID ) ;
141- return ;
142- }
143- if ( _getServerAccountType ( MySandboxGame . ConfigDedicated . GroupID ) != MyGameServiceAccountType . Clan )
141+ if ( MySandboxGame . ConfigDedicated . GroupID == 0uL )
142+ RunEvent ( new ValidateAuthTicketEvent ( steamID , steamOwner , response , 0 , true , false ) ) ;
143+ else if ( _getServerAccountType ( MySandboxGame . ConfigDedicated . GroupID ) != MyGameServiceAccountType . Clan )
144+ UserRejected ( steamID , JoinResult . GroupIdInvalid ) ;
145+ else if ( MyGameService . GameServer . RequestGroupStatus ( steamID , MySandboxGame . ConfigDedicated . GroupID ) )
146+ lock ( _waitingForGroupLocal )
147+ {
148+ if ( _waitingForGroupLocal . Count >= _waitListSize )
149+ _waitingForGroupLocal . RemoveAt ( 0 ) ;
150+ _waitingForGroupLocal . Add ( new WaitingForGroup ( steamID , response , steamOwner ) ) ;
151+ }
152+ else
153+ UserRejected ( steamID , JoinResult . SteamServersOffline ) ;
154+ }
155+
156+ private void RunEvent ( ValidateAuthTicketEvent info )
157+ {
158+ MultiplayerManagerDedicatedEventShim . RaiseValidateAuthTicket ( ref info ) ;
159+
160+ if ( info . FutureVerdict == null )
144161 {
145- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , JoinResult . GroupIdInvalid ) ;
162+ if ( IsBanned ( info . SteamOwner ) || IsBanned ( info . SteamID ) )
163+ CommitVerdict ( info . SteamID , JoinResult . BannedByAdmins ) ;
164+ else if ( _isClientKicked ( MyMultiplayer . Static , info . SteamID ) ||
165+ _isClientKicked ( MyMultiplayer . Static , info . SteamOwner ) )
166+ CommitVerdict ( info . SteamID , JoinResult . KickedRecently ) ;
167+ else if ( info . SteamResponse != JoinResult . OK )
168+ CommitVerdict ( info . SteamID , info . SteamResponse ) ;
169+ else if ( MyMultiplayer . Static . MemberLimit > 0 &&
170+ MyMultiplayer . Static . MemberCount + 1 > MyMultiplayer . Static . MemberLimit )
171+ CommitVerdict ( info . SteamID , JoinResult . ServerFull ) ;
172+ else if ( MySandboxGame . ConfigDedicated . GroupID == 0uL ||
173+ MySandboxGame . ConfigDedicated . Administrators . Contains ( info . SteamID . ToString ( ) ) ||
174+ MySandboxGame . ConfigDedicated . Administrators . Contains ( _convertSteamIDFrom64 ( info . SteamID ) ) )
175+ CommitVerdict ( info . SteamID , JoinResult . OK ) ;
176+ else if ( MySandboxGame . ConfigDedicated . GroupID == info . Group && ( info . Member || info . Officer ) )
177+ CommitVerdict ( info . SteamID , JoinResult . OK ) ;
178+ else
179+ CommitVerdict ( info . SteamID , JoinResult . NotInGroup ) ;
146180 return ;
147181 }
148- if ( MyGameService . GameServer . RequestGroupStatus ( steamID , MySandboxGame . ConfigDedicated . GroupID ) )
182+
183+ info . FutureVerdict . ContinueWith ( ( task ) =>
149184 {
150- _waitingForGroup . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static ) . Add ( steamID ) ;
151- return ;
152- }
153- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamID , JoinResult . SteamServersOffline ) ;
185+ JoinResult verdict ;
186+ if ( task . IsFaulted )
187+ {
188+ _log . Error ( task . Exception , $ "Future validation verdict faulted") ;
189+ verdict = JoinResult . TicketCanceled ;
190+ }
191+ else
192+ verdict = task . Result ;
193+ Torch . Invoke ( ( ) => { CommitVerdict ( info . SteamID , verdict ) ; } ) ;
194+ } ) ;
195+ }
196+
197+ private void CommitVerdict ( ulong steamId , JoinResult verdict )
198+ {
199+ if ( verdict == JoinResult . OK )
200+ UserAccepted ( steamId ) ;
201+ else
202+ UserRejected ( steamId , verdict ) ;
154203 }
155204
156205 private void UserGroupStatusResponse ( ulong userId , ulong groupId , bool member , bool officer )
157206 {
158- if ( groupId == MySandboxGame . ConfigDedicated . GroupID && _waitingForGroup . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static ) . Remove ( userId ) )
159- {
160- if ( member || officer )
161- UserAccepted ( userId ) ;
162- else
163- _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , userId , JoinResult . NotInGroup ) ;
164- }
207+ lock ( _waitingForGroupLocal )
208+ for ( var j = 0 ; j < _waitingForGroupLocal . Count ; j ++ )
209+ {
210+ var wait = _waitingForGroupLocal [ j ] ;
211+ if ( wait . SteamId == userId )
212+ {
213+ RunEvent ( new ValidateAuthTicketEvent ( wait . SteamId , wait . SteamOwner , wait . Response , groupId ,
214+ member , officer ) ) ;
215+ _waitingForGroupLocal . RemoveAt ( j ) ;
216+ break ;
217+ }
218+ }
219+ }
220+
221+ private void UserRejected ( ulong steamId , JoinResult reason )
222+ {
223+ _userRejected . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamId , reason ) ;
165224 }
225+
166226 private void UserAccepted ( ulong steamId )
167227 {
168- _userAcceptedImpl . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamId ) ;
228+ _userAcceptedImpl . Invoke ( ( MyDedicatedServerBase ) MyMultiplayer . Static , steamId ) ;
169229 base . RaiseClientJoined ( steamId ) ;
170230 }
231+
171232 #endregion
172233 }
173- }
234+ }
0 commit comments