コード例 #1
0
        private async Task ManualStartClientConnectionLoop(TcpClient client, IManagedNetworkClient <TPayloadReadType, TPayloadWriteType> internalNetworkClient, ManagedClientSession <TPayloadReadType, TPayloadWriteType> networkSession)
        {
            //So that sessions invoking the disconnection can internally disconnect to
            networkSession.OnSessionDisconnection += (source, args) => internalNetworkClient.Disconnect();

            //TODO: Better way to syncronize the strategies used?
            var dispatchingStrategy = new InPlaceAsyncLockedNetworkMessageDispatchingStrategy <TPayloadReadType, TPayloadWriteType>();

            while (client.Connected && internalNetworkClient.isConnected)
            {
                NetworkIncomingMessage <TPayloadWriteType> message = await internalNetworkClient.ReadMessageAsync(CancellationToken.None)
                                                                     .ConfigureAwait(false);

                //We don't want to stop the client just because an exception occurred.
                try
                {
                    //TODO: This will work for World of Warcraft since it requires no more than one packet
                    //from the same client be handled at one time. However it limits throughput and maybe we should
                    //handle this at a different level instead.
                    await dispatchingStrategy.DispatchNetworkMessage(new SessionMessageContext <TPayloadReadType, TPayloadWriteType>(networkSession, message))
                    .ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    //TODO: Remove this console log
                    Logger.Error($"[Error]: {e.Message}\n\nStack: {e.StackTrace}");
                }
            }

            client.Dispose();

            //TODO: Should we tell the client something when it ends?
            networkSession.DisconnectClientSession();
        }
コード例 #2
0
 /// <inheritdoc />
 public GenericProxiedMessageContext([NotNull] IManagedNetworkClient <TPayloadReadType, TPayloadWriteType> proxyConnection, [NotNull] IConnectionService connectionService, [NotNull] IPeerPayloadSendService <TPayloadWriteType> payloadSendService, [NotNull] IPeerRequestSendService <TPayloadWriteType> requestSendService)
 {
     ProxyConnection    = proxyConnection ?? throw new ArgumentNullException(nameof(proxyConnection));
     ConnectionService  = connectionService ?? throw new ArgumentNullException(nameof(connectionService));
     PayloadSendService = payloadSendService ?? throw new ArgumentNullException(nameof(payloadSendService));
     RequestSendService = requestSendService ?? throw new ArgumentNullException(nameof(requestSendService));
 }
コード例 #3
0
        /// <summary>
        /// Starts dispatching the messages and won't yield until
        /// the client has stopped or has disconnected.
        /// </summary>
        /// <returns></returns>
        protected async Task StartDispatchingAsync([NotNull] IManagedNetworkClient <TOutgoingPayloadType, TIncomingPayloadType> client)
        {
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            try
            {
                IPeerRequestSendService <TOutgoingPayloadType> requestService = new PayloadInterceptMessageSendService <TOutgoingPayloadType>(client, client);

                if (!client.isConnected && Logger.IsWarnEnabled)
                {
                    Logger.Warn($"The client was not connected before dispatching started.");
                }

                //TODO: Read the next message before awaiting the result of the dispatch message handling.
                while (client.isConnected && !CancelTokenSource.IsCancellationRequested)                 //if we exported we should reading messages
                {
                    NetworkIncomingMessage <TIncomingPayloadType> message = await client.ReadMessageAsync(CancelTokenSource.Token)
                                                                            .ConfigureAwaitFalse();

                    //Supress and continue reading
                    try
                    {
                        //We don't do anything with the result. We should hope someone registered
                        //a default handler to deal with this situation
                        bool result = await Handlers.TryHandleMessage(MessageContextFactory.Create(client, client, requestService), message)
                                      .ConfigureAwaitFalse();
                    }
                    catch (Exception e)
                    {
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info($"Error: {e.Message}\n\n Stack Trace: {e.StackTrace}");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info($"Error: {e.Message}\n\n Stack Trace: {e.StackTrace}");
                }

                throw;
            }
            finally
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info("Network client stopped reading.");
                }

                OnClientStoppedHandlingMessages();
            }
        }
コード例 #4
0
 /// <inheritdoc />
 public OnStartRestartNetworkClientHandlingInititablize(
     [NotNull] IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> client,
     [NotNull] INetworkClientManager clientManager,
     [NotNull] ILog logger)
 {
     Client        = client ?? throw new ArgumentNullException(nameof(client));
     ClientManager = clientManager ?? throw new ArgumentNullException(nameof(clientManager));
     Logger        = logger ?? throw new ArgumentNullException(nameof(logger));
 }
コード例 #5
0
        /// <inheritdoc />
        public Task StartHandlingNetworkClient(IManagedNetworkClient <TOutgoingPayloadType, TIncomingPayloadType> client)
        {
            //Don't await because we want start to end.
            Task.Factory.StartNew(async() => await StartDispatchingAsync(client).ConfigureAwait(false), CancelTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)
            .ConfigureAwait(false);

            //We don't want to await it, it needs to run at the same time
            return(Task.CompletedTask);
        }
コード例 #6
0
 public ConnectionCheckDebugTickable(INetworkClientDisconnectedEventSubscribable subService,
                                     [NotNull] IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> client,
                                     [NotNull] ILog logger,
                                     [NotNull] INetworkClientManager clientManager)
     : base(subService)
 {
     Client        = client ?? throw new ArgumentNullException(nameof(client));
     Logger        = logger ?? throw new ArgumentNullException(nameof(logger));
     ClientManager = clientManager ?? throw new ArgumentNullException(nameof(clientManager));
 }
コード例 #7
0
 /// <inheritdoc />
 public PreBurstStartInstanceClientConnection([NotNull] IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> client, [NotNull] ICharacterService characterDataService, [NotNull] IReadonlyAuthTokenRepository authTokenRepo, [NotNull] ICharacterDataRepository characterDataRepo, [NotNull] IZoneServerService zoneService, [NotNull] ILog logger, [NotNull] INetworkClientManager networkClientManager)
 {
     Client = client ?? throw new ArgumentNullException(nameof(client));
     CharacterDataService = characterDataService ?? throw new ArgumentNullException(nameof(characterDataService));
     AuthTokenRepo        = authTokenRepo ?? throw new ArgumentNullException(nameof(authTokenRepo));
     CharacterDataRepo    = characterDataRepo ?? throw new ArgumentNullException(nameof(characterDataRepo));
     ZoneService          = zoneService ?? throw new ArgumentNullException(nameof(zoneService));
     Logger = logger ?? throw new ArgumentNullException(nameof(logger));
     NetworkClientManager = networkClientManager ?? throw new ArgumentNullException(nameof(networkClientManager));
 }
コード例 #8
0
        /// <inheritdoc />
        public Task StartHandlingNetworkClient(IManagedNetworkClient <TOutgoingPayloadType, TIncomingPayloadType> client)
        {
            isNetworkHandling = true;

            //Don't await because we want start to end.
            Task.Factory.StartNew(async() => await StartDispatchingAsync(client).ConfigureAwaitFalseVoid(), TaskCreationOptions.LongRunning)
            .ConfigureAwaitFalse();

            //We don't want to await it, it needs to run at the same time
            return(Task.CompletedTask);
        }
コード例 #9
0
        private static async Task AsyncMain(IManagedNetworkClient <AuthenticationClientPayload, AuthenticationServerPayload> client)
        {
            try
            {
                if (!await client.ConnectAsync("127.0.0.1", 5050).ConfigureAwait(false))
                {
                    Console.WriteLine("Failed to connect");
                }

                AuthChallengeData challenge = new AuthChallengeData(ProtocolVersion.ProtocolVersionTwo, GameType.WoW, ExpansionType.WrathOfTheLichKing, 3, 5,
                                                                    ClientBuild.Wotlk_3_3_5a, PlatformType.x86, OperatingSystemType.Win, LocaleType.enUS,
                                                                    IPAddress.Parse("127.0.0.1"), "Glader");

                await client.SendMessage(new AuthLogonChallengeRequest(challenge))
                .ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }

            while (true)
            {
                var response = (await client.ReadMessageAsync()).Payload;

                Console.WriteLine("Recieved payload");

                AuthenticationLogonChallengeResponseMessageHandler handler = new AuthenticationLogonChallengeResponseMessageHandler();

                AuthenticationLogonProofResponseMessageHandler proofHandler = new AuthenticationLogonProofResponseMessageHandler();

                RealmListResponseMessageHandler realmListResponseHandler = new RealmListResponseMessageHandler(bytes => Serializer.Deserialize <RealmListContainer>(bytes));

                if (response is AuthLogonChallengeResponse challengeResponse)
                {
                    Console.WriteLine($"Response: Valid: {challengeResponse.isValid} Result: {challengeResponse.Result} SRP: {challengeResponse.Challenge}");

                    await handler.HandleMessage(new DefaultPeerMessageContext <AuthenticationClientPayload>(client, client, new PayloadInterceptMessageSendService <AuthenticationClientPayload>(client, client)), challengeResponse);
                }
                else if (response is AuthRealmListResponse realmListResponse)
                {
                    await realmListResponseHandler.HandleMessage(new DefaultPeerMessageContext <AuthenticationClientPayload>(client, client, new PayloadInterceptMessageSendService <AuthenticationClientPayload>(client, client)), realmListResponse);
                }
                else if (response is AuthLogonProofResponse proofResponse)
                {
                    await proofHandler.HandleMessage(new DefaultPeerMessageContext <AuthenticationClientPayload>(client, client, new PayloadInterceptMessageSendService <AuthenticationClientPayload>(client, client)), proofResponse);
                }
            }
        }
コード例 #10
0
        private static async Task HandlePayload(SharedLoginResponsePayload payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
        {
            Console.WriteLine($"Login Response: {payload.ResponseCode}");

            if (hasSecurityData && hasAskedForChars && !hasSelectedCharacter)
            {
                hasSelectedCharacter = true;
                await client.SendMessage(new CharacterCharacterSelectionRequestPayload(0, CharacterSelectionType.PlaySelection));

                Task.Factory.StartNew(async() =>
                {
                    await Task.Delay(3000);
                    DecryptionKeyInitializer.Uninitialize();
                    EncryptionKeyInitializer.Uninitialize();
                    await client.ConnectAsync("158.69.215.131", 12001);
                });

                return;
            }

            if (hasSecurityData && !hasAskedForChars)
            {
                hasAskedForChars = true;
                for (int i = 0; i < 4; i++)
                {
                    await client.SendMessage(new CharacterCharacterSelectionRequestPayload((byte)i, CharacterSelectionType.Preview));
                }

                Task.Factory.StartNew(async() =>
                {
                    await Task.Delay(6000);
                    await client.ConnectAsync("158.69.215.131", 12001);
                    DecryptionKeyInitializer.Uninitialize();
                    EncryptionKeyInitializer.Uninitialize();
                });
            }

            //We should recieve a 19 redirect after this
            //We should use the bytes from the response for future sessions
            ClientVerification = new ClientVerificationData(0x41, payload.SecurityData);            //.Take(32).Reverse().Concat(payload.SecurityData.Skip(32)).ToArray());
            hasSecurityData    = true;
            teamId             = payload.TeamId;
            Console.WriteLine($"Set 32bit key: {payload.TeamId}");
        }
コード例 #11
0
        private static async Task HandlePayload(SharedWelcomePayload payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
        {
            Console.WriteLine($"Server Vector: {payload.ServerVector.Aggregate("", (s, b) => $"{s} {b.ToString()}")}");
            Console.WriteLine($"Client Vector: {payload.ClientVector.Aggregate("", (s, b) => $"{s} {b.ToString()}")}");

            EncryptionKeyInitializer.Initialize(payload.ClientVector);
            DecryptionKeyInitializer.Initialize(payload.ServerVector);

            Console.WriteLine(payload.CopyrightMessage);

            if (hasSecurityData)
            {
                await client.SendMessage(new SharedLoginRequest93Payload(0x41, teamId, "glader", "playpso69", ClientVerification));
            }
            else
            {
                await client.SendMessage(new SharedLoginRequest93Payload(0x41, "glader", "playpso69", ClientVerificationData.FromVersionString("TethVer12510")));
            }
        }
コード例 #12
0
        public static async Task RunClientAsync(IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client, string ip, int port)
        {
            await client.ConnectAsync(ip, port);

            while (true)
            {
                NetworkIncomingMessage <PSOBBGamePacketPayloadServer> message = await client.ReadMessageAsync();

                LogMessage(message);

                try
                {
                    await HandlePayload((dynamic)message.Payload, client);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            }
        }
コード例 #13
0
        /// <inheritdoc />
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(context => LogLevel.All)
            .As <LogLevel>()
            .SingleInstance();

            builder.RegisterType <UnityLogger>()
            .As <ILog>()
            .SingleInstance();

            ProtobufNetGladNetSerializerAdapter serializer = new ProtobufNetGladNetSerializerAdapter(PrefixStyle.Fixed32);

            //The idea here is if the global network client it's null we should use it as the instance.
            if (GloballyManagedClient == null || !GloballyManagedClient.isConnected)
            {
                GloballyManagedClient = new DotNetTcpClientNetworkClient()
                                        .AddHeaderlessNetworkMessageReading(serializer)
                                        .For <GameServerPacketPayload, GameClientPacketPayload, IPacketPayload>()
                                        .Build()
                                        .AsManaged(new UnityLogger(LogLevel.All)); //TODO: How should we handle log level?
            }
            builder.RegisterInstance(GloballyManagedClient)
            .As <IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> >()
            .As <IPeerPayloadSendService <GameClientPacketPayload> >()
            .As <IPayloadInterceptable>()
            .As <IConnectionService>();

            builder.RegisterType <DefaultMessageContextFactory>()
            .As <IPeerMessageContextFactory>()
            .SingleInstance();

            builder.RegisterType <PayloadInterceptMessageSendService <GameClientPacketPayload> >()
            .As <IPeerRequestSendService <GameClientPacketPayload> >()
            .SingleInstance();

            //Now, with the new design we also have to register the game client itself
            builder.RegisterType <GameNetworkClient>()
            .AsImplementedInterfaces()
            .SingleInstance();
        }
コード例 #14
0
        /// <inheritdoc />
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(context => LogLevel.All)
            .As <LogLevel>()
            .SingleInstance();

            builder.Register <IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> >(context =>
            {
                //The idea here is if the global network client it's null we should use it as the instance.
                if (GloballyManagedClient == null || !GloballyManagedClient.isConnected)
                {
                    return(GloballyManagedClient = new GladMMOUnmanagedNetworkClient <DotNetTcpClientNetworkClient, GameServerPacketPayload, GameClientPacketPayload, IGamePacketPayload>(new DotNetTcpClientNetworkClient(), context.Resolve <INetworkSerializationService>(), context.Resolve <ILog>())
                                                   .AsManaged());
                }
                else
                {
                    return(GloballyManagedClient);
                }
            })
            .As <IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> >()
            .As <IPeerPayloadSendService <GameClientPacketPayload> >()
            .As <IPayloadInterceptable>()
            .As <IConnectionService>()
            .SingleInstance();

            builder.RegisterType <DefaultMessageContextFactory>()
            .As <IPeerMessageContextFactory>()
            .SingleInstance();

            builder.RegisterType <PayloadInterceptMessageSendService <GameClientPacketPayload> >()
            .As <IPeerRequestSendService <GameClientPacketPayload> >()
            .SingleInstance();

            //Now, with the new design we also have to register the game client itself
            builder.RegisterType <GameNetworkClient>()
            .AsImplementedInterfaces()
            .SingleInstance();
        }
コード例 #15
0
 public async Task StartHandlingNetworkClient(IManagedNetworkClient <GameClientPacketPayload, GameServerPacketPayload> client)
 {
     isNetworkHandling = true;
 }
コード例 #16
0
        /// <inheritdoc />
        protected override IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> BuildOutgoingSessionManagedClient(NetworkClientBase clientBase, INetworkSerializationService serializeService)
        {
            //Copied from the test client project
            IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client = clientBase
                                                                                                        .AddCryptHandling(ServerEncryptionService, ServerDecryptionService)
                                                                                                        .AddBufferredWrite(4)
                                                                                                        .AddHeaderReading <PSOBBPacketHeader>(serializeService, 2)
                                                                                                        .AddNetworkMessageReading(serializeService)
                                                                                                        .For <PSOBBGamePacketPayloadServer, PSOBBGamePacketPayloadClient, IPacketPayload>(new PSOBBPacketHeaderFactory())
                                                                                                        .AddReadBufferClearing()
                                                                                                        .Build()
                                                                                                        .AsManagedSession();

            return(client);
        }
コード例 #17
0
        private GenericProxiedManagedClientSession <TWriteType, TReadType> BuildSessionFromDependencies <TWriteType, TReadType>(IManagedNetworkClient <TWriteType, TReadType> client, SessionDetails details, IManagedNetworkClient <TReadType, TWriteType> proxyClient)
            where TReadType : class
            where TWriteType : class
        {
            GenericProxiedManagedClientSession <TWriteType, TReadType> connectionSession;

            using (ILifetimeScope lifetimeScope = this.ServiceContainer.BeginLifetimeScope(c =>
            {
                c.RegisterInstance(client)
                .AsImplementedInterfaces()
                .AsSelf();

                c.RegisterInstance(details)
                .As <SessionDetails>();

                c.RegisterInstance(new GenericMessageContextFactory <TWriteType, TReadType>(proxyClient))
                .AsSelf()
                .AsImplementedInterfaces();
            }))
            {
                connectionSession = GenerateClientFromLifetimeScope <TWriteType, TReadType>(lifetimeScope);
            }

            return(connectionSession);
        }
コード例 #18
0
 private static async Task HandlePayload(object payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
 {
 }
コード例 #19
0
        private static async Task HandlePayload(SharedConnectionRedirectPayload payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
        {
            Console.WriteLine($"Redirect: {payload.EndpointAddress}:{payload.EndpointerPort}");

            EncryptionKeyInitializer.Uninitialize();
            DecryptionKeyInitializer.Uninitialize();

            //Redirects to character the first time
            await client.ConnectAsync(payload.EndpointAddress, payload.EndpointerPort);
        }
コード例 #20
0
        private static async Task HandlePayload(SharedCreateMessageBoxEventPayload payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
        {
            Console.WriteLine($"MessageBox Message: {payload.Message}");

            //We should recieve a 19 redirect after this
        }
コード例 #21
0
 private static async Task HandlePayload(CharacterCharacterUpdateResponsePayload payload, IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client)
 {
     Console.WriteLine($"Character: {payload.CharacterData.CharacterName} Class: {payload.CharacterData.ClassRace} SecId: {payload.CharacterData.SectionId} Level: {payload.CharacterData.Progress.Level} PlayedTime: {payload.CharacterData.PlayedTime}");
     Console.WriteLine($"Character: {Encoding.Unicode.GetBytes(payload.CharacterData.CharacterName).Aggregate("", (s, b) => $"{s} {b}")}");
     //Console.WriteLine($"Leftover Bytes: {payload.CharacterData.LeftoverBytes.Aggregate("", (s, b) => $"{s} {b}")}");
 }
コード例 #22
0
 public GenericMessageContextFactory([NotNull] IManagedNetworkClient <TPayloadReadType, TPayloadWriteType> proxyConnection)
 {
     ProxyConnection = proxyConnection ?? throw new ArgumentNullException(nameof(proxyConnection));
 }