66using System . Collections . Generic ;
77using System . Net ;
88using System . Net . Sockets ;
9+ using static Fika . Core . Networking . LiteNetLib . EventBasedNatPunchListener ;
910
1011namespace FikaServer . Servers ;
1112
1213[ Injectable ( InjectionType . Singleton ) ]
1314public class NatPunchServer ( ConfigService fikaConfig , ISptLogger < NatPunchServer > logger ) : INatPunchListener , INetEventListener
1415{
15- private readonly Dictionary < string , NatPunchServerPeer > _natPunchServerPeers = [ ] ;
16+ private readonly List < NatPunchServerPeer > _serverPeers = [ ] ;
1617 private NetManager ? _netServer ;
1718 private CancellationTokenSource ? _pollEventsRoutineCts ;
1819
@@ -51,67 +52,71 @@ public void Stop()
5152
5253 public void PollEvents ( )
5354 {
54- _netServer ? . PollEvents ( ) ;
5555 _netServer ? . NatPunchModule . PollEvents ( ) ;
5656 }
5757
5858 public void OnNatIntroductionRequest ( IPEndPoint localEndPoint , IPEndPoint remoteEndPoint , string token )
5959 {
60- string introductionType ;
61- string sessionId ;
60+ DateTime dateTimeNow = DateTime . UtcNow ;
61+
62+ NatIntroductionRequest ? natIntroductionRequest ;
6263
6364 try
6465 {
65- introductionType = token . Split ( ':' ) [ 0 ] ;
66- sessionId = token . Split ( ':' ) [ 1 ] ;
66+ natIntroductionRequest = GetNatIntroductionRequestFromToken ( token ) ;
6767 }
68- catch ( Exception ex )
68+ catch
6969 {
70- logger . Error ( $ "[Fika NatPunch] Error when parsing NatIntroductionRequest : { ex . Message } ") ;
70+ Console . WriteLine ( $ "[Fika NatPunch] Error when parsing token : { token } ") ;
7171 return ;
7272 }
7373
74- switch ( introductionType )
74+ if ( natIntroductionRequest == null )
7575 {
76- case "server" :
77- if ( _natPunchServerPeers . ContainsKey ( sessionId ) )
78- {
79- logger . Info ( $ "[Fika NatPunch] KeepAlive { sessionId } ({ remoteEndPoint } )") ;
80- }
81- else
82- {
83- logger . Info ( $ "[Fika NatPunch] Added { sessionId } ({ remoteEndPoint } ) to server list") ;
84- }
76+ Console . WriteLine ( $ "[Fika NatPunch] Malformed Nat Introduction Request sent by client: { remoteEndPoint } . Token: { token } ") ;
77+ return ;
78+ }
8579
86- _natPunchServerPeers [ sessionId ] = new ( localEndPoint , remoteEndPoint ) ;
87- break ;
80+ NatPunchServerPeer ? serverPeer = _serverPeers . FirstOrDefault ( peer => peer . SessionId == natIntroductionRequest . SessionId ) ;
8881
89- case "client" :
90- if ( _natPunchServerPeers . TryGetValue ( sessionId , out NatPunchServerPeer ? sPeer ) )
91- {
92- logger . Info ( $ "[Fika NatPunch] Introducing server { sessionId } ({ sPeer . ExternalAddr } ) to client ({ remoteEndPoint } )") ;
93-
94- for ( int i = 0 ; i < fikaConfig . Config . NatPunchServer . NatIntroduceAmount ; i ++ )
95- {
96- _netServer ? . NatPunchModule . NatIntroduce (
97- sPeer . InternalAddr ,
98- sPeer . ExternalAddr ,
99- localEndPoint ,
100- remoteEndPoint ,
101- token
102- ) ;
103- }
104- }
105- else
106- {
107- logger . Info ( $ "[Fika NatPunch] Unknown ServerId provided by client.") ;
108- }
109- break ;
82+ if ( natIntroductionRequest . Type == NatIntroductionType . Server )
83+ {
84+ if ( serverPeer != null )
85+ {
86+ serverPeer . LastKeepAliveTime = dateTimeNow ;
11087
111- default :
112- logger . Info ( $ "[Fika NatPunch] Unknown request received: { token } ") ;
113- break ;
88+ Console . WriteLine ( $ "[Fika NatPunch] KeepAlive { natIntroductionRequest . SessionId } ({ remoteEndPoint } )") ;
89+ }
90+ else
91+ {
92+ serverPeer = new ( natIntroductionRequest . SessionId , localEndPoint , remoteEndPoint ) ;
93+ _serverPeers . Add ( serverPeer ) ;
11494
95+ Console . WriteLine ( $ "[Fika NatPunch] Added { serverPeer . SessionId } ({ serverPeer . ExternalAddr } ) to server list") ;
96+ }
97+ }
98+
99+ if ( natIntroductionRequest . Type == NatIntroductionType . Client )
100+ {
101+ if ( serverPeer != null )
102+ {
103+ Console . WriteLine ( $ "[Fika NatPunch] Introducing server { serverPeer . SessionId } ({ serverPeer . ExternalAddr } ) to client ({ remoteEndPoint } )") ;
104+
105+ for ( int i = 0 ; i < fikaConfig . Config . NatPunchServer . NatIntroduceAmount ; i ++ )
106+ {
107+ _netServer ? . NatPunchModule . NatIntroduce (
108+ serverPeer . InternalAddr ,
109+ serverPeer . ExternalAddr ,
110+ localEndPoint ,
111+ remoteEndPoint ,
112+ token
113+ ) ;
114+ }
115+ }
116+ else
117+ {
118+ Console . WriteLine ( $ "Unknown sessionId ({ natIntroductionRequest . SessionId } ) provided by client: { remoteEndPoint } ") ;
119+ }
115120 }
116121 }
117122
@@ -160,23 +165,11 @@ public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo)
160165 // Do nothing
161166 }
162167
163- private void RemoveInactiveServerPeers ( )
168+ private void RemoteInactivePeers ( )
164169 {
165170 DateTime dateTimeNow = DateTime . UtcNow ;
166171
167- foreach ( string sessionId in _natPunchServerPeers . Keys )
168- {
169- NatPunchServerPeer peer = _natPunchServerPeers [ sessionId ] ;
170-
171- if ( peer != null )
172- {
173- if ( dateTimeNow - peer . CreationTime > TimeSpan . FromMinutes ( 1 ) )
174- {
175- _natPunchServerPeers . Remove ( sessionId ) ;
176- logger . Info ( $ "[Fika NatPunch] Removed inactive server: { sessionId } ({ peer . ExternalAddr } )") ;
177- }
178- }
179- }
172+ _serverPeers . RemoveAll ( peer => dateTimeNow - peer . LastKeepAliveTime > TimeSpan . FromMinutes ( 1 ) ) ;
180173 }
181174
182175 private async Task PollEventsRoutine ( )
@@ -189,9 +182,37 @@ private async Task PollEventsRoutine()
189182 }
190183
191184 PollEvents ( ) ;
192- RemoveInactiveServerPeers ( ) ;
185+ RemoteInactivePeers ( ) ;
193186
194- await Task . Delay ( TimeSpan . FromSeconds ( 1 ) ) ;
187+ await Task . Delay ( TimeSpan . FromMilliseconds ( 500 ) ) ;
195188 }
196189 }
190+
191+ private NatIntroductionRequest ? GetNatIntroductionRequestFromToken ( string token )
192+ {
193+ if ( ! token . Contains ( ':' ) )
194+ {
195+ return null ;
196+ }
197+
198+ string introductionType = token . Split ( ':' ) [ 0 ] ;
199+ string sessionId = token . Split ( ':' ) [ 1 ] ;
200+
201+ if ( introductionType != "Client" && introductionType != "Server" )
202+ {
203+ return null ;
204+ }
205+
206+ if ( sessionId . Length != 24 )
207+ {
208+ return null ;
209+ }
210+
211+ if ( Enum . TryParse ( introductionType , out NatIntroductionType natIntroductionType ) )
212+ {
213+ return new ( natIntroductionType , sessionId ) ;
214+ }
215+
216+ return null ;
217+ }
197218}
0 commit comments