@@ -46,7 +46,6 @@ public class Connection : Communication, IDisposable
4646
4747 private ZStream _zStream = new ZStream ( ) ;
4848
49- private LoginData _loginData ;
5049
5150 private Socket _clientSocket ;
5251 private Socket _serverSocket ;
@@ -56,6 +55,8 @@ public class Connection : Communication, IDisposable
5655
5756 private TcpListener _tcpListener ;
5857
58+ private dynamic _loginData ;
59+
5960 private uint _clientSequenceNumber = 1 ;
6061 private uint _serverSequenceNumber = 1 ;
6162
@@ -247,7 +248,7 @@ public void SendToServer(byte[] data)
247248 /// connection requests from the Tibia client.
248249 /// </summary>
249250 /// <returns></returns>
250- internal bool Start ( bool enablePacketParsing = true )
251+ internal bool Start ( bool enablePacketParsing = true , int httpPort = 80 )
251252 {
252253 if ( _isStarted )
253254 {
@@ -261,11 +262,10 @@ internal bool Start(bool enablePacketParsing = true)
261262 _tcpListener = new TcpListener ( IPAddress . Loopback , 0 ) ;
262263 }
263264
264- if ( ! _httpListener . Prefixes . Contains ( "http://127.0.0.1:80/" ) )
265+ var uriPrefix = $ "http://127.0.0.1:{ httpPort } /";
266+ if ( ! _httpListener . Prefixes . Contains ( uriPrefix ) )
265267 {
266- // The HTTP listener must be listening on port 80 as the
267- // Tibia client sends HTTP requests over port 80.
268- _httpListener . Prefixes . Add ( "http://127.0.0.1:80/" ) ;
268+ _httpListener . Prefixes . Add ( uriPrefix ) ;
269269 }
270270
271271 //_zStream.deflateInit(zlibConst.Z_DEFAULT_COMPRESSION, -15);
@@ -544,24 +544,24 @@ private void BeginGetContextCallback(IAsyncResult ar)
544544 }
545545
546546 // Login data is the only thing we have to modify, everything else can be piped through.
547- var loginData = JsonConvert . DeserializeObject < LoginData > ( response ) ;
548- if ( loginData != null && loginData . Session != null )
547+ dynamic loginData = JsonConvert . DeserializeObject ( response ) ;
548+ if ( loginData != null && loginData . session != null )
549549 {
550550 // Change the address and port of each game world to that of the TCP listener so that
551551 // the Tibia client connects to the TCP listener instead of a game world.
552552 var address = ( ( IPEndPoint ) _tcpListener . LocalEndpoint ) . Address . ToString ( ) ;
553553 var port = ( ( IPEndPoint ) _tcpListener . LocalEndpoint ) . Port ;
554- foreach ( var world in loginData . PlayData . Worlds )
554+ foreach ( var world in loginData . playdata . worlds )
555555 {
556- world . ExternalAddressProtected = address ;
557- world . ExternalAddressUnprotected = address ;
558- world . ExternalPortProtected = port ;
559- world . ExternalPortUnprotected = port ;
556+ world . externaladdressprotected = address ;
557+ world . externaladdressunprotected = address ;
558+ world . externalportprotected = port ;
559+ world . externalportunprotected = port ;
560560 }
561561
562562 // Store the original login data so when the Tibia client tries to connect to a game world
563563 // the server socket can recall the address and port to connect to.
564- _loginData = JsonConvert . DeserializeObject < LoginData > ( response ) ;
564+ _loginData = JsonConvert . DeserializeObject ( response ) ;
565565 response = JsonConvert . SerializeObject ( loginData ) ;
566566 }
567567
@@ -653,18 +653,22 @@ private void BeginReceiveWorldNameCallback(IAsyncResult ar)
653653 }
654654
655655 var worldName = Encoding . UTF8 . GetString ( _clientInMessage . GetBuffer ( ) , 0 , count - 1 ) ;
656- var world = _loginData . PlayData . Worlds . Find ( w => w . Name . Equals ( worldName , StringComparison . CurrentCultureIgnoreCase ) ) ;
657- if ( world == null )
656+ foreach ( var world in _loginData . playdata . worlds )
658657 {
659- throw new Exception ( $ "[Connection.BeginReceiveWorldNameCallback] Login data not found for world: { worldName } .") ;
660- }
658+ var name = ( string ) world . name ;
659+ if ( name . Equals ( worldName , StringComparison . CurrentCultureIgnoreCase ) )
660+ {
661+ _clientSocket . BeginReceive ( _clientInMessage . GetBuffer ( ) , 0 , 2 , SocketFlags . None , new AsyncCallback ( BeginReceiveClientCallback ) , 0 ) ;
661662
662- _clientSocket . BeginReceive ( _clientInMessage . GetBuffer ( ) , 0 , 2 , SocketFlags . None , new AsyncCallback ( BeginReceiveClientCallback ) , 0 ) ;
663+ _serverSocket = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) ;
664+ _serverSocket . Connect ( ( string ) world . externaladdressprotected , ( int ) world . externalportprotected ) ;
665+ _serverSocket . Send ( _clientInMessage . GetBuffer ( ) , 0 , count , SocketFlags . None ) ;
666+ _serverSocket . BeginReceive ( _serverInMessage . GetBuffer ( ) , 0 , 2 , SocketFlags . None , new AsyncCallback ( BeginReceiveServerCallback ) , 0 ) ;
667+ return ;
668+ }
669+ }
663670
664- _serverSocket = new Socket ( AddressFamily . InterNetwork , SocketType . Stream , ProtocolType . Tcp ) ;
665- _serverSocket . Connect ( world . ExternalAddressProtected , world . ExternalPortProtected ) ;
666- _serverSocket . Send ( _clientInMessage . GetBuffer ( ) , 0 , count , SocketFlags . None ) ;
667- _serverSocket . BeginReceive ( _serverInMessage . GetBuffer ( ) , 0 , 2 , SocketFlags . None , new AsyncCallback ( BeginReceiveServerCallback ) , 0 ) ;
671+ throw new Exception ( $ "[Connection.BeginReceiveWorldNameCallback] Login data not found for world: { worldName } .") ;
668672 }
669673 catch ( SocketException )
670674 {
0 commit comments