private static async Task RunClient(string ip, int port)
        {
            EncryptionLazyWithoutKeyDecorator <byte[]> encrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishEncryptionService encryptionService = new BlowfishEncryptionService();
                encryptionService.Initialize(val);
                return(encryptionService);
            }, 8);
            EncryptionLazyWithoutKeyDecorator <byte[]> decrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishDecryptionService decryptionService = new BlowfishDecryptionService();
                decryptionService.Initialize(val);
                return(decryptionService);
            }, 8);

            EncryptionKeyInitializer = encrypt;
            DecryptionKeyInitializer = decrypt;


            //Configurs and builds the clients without all the
            //relevant decorators
            IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client = new DotNetTcpClientNetworkClient()
                                                                                                        .AddCryptHandling(encrypt, decrypt)
                                                                                                        .AddHeaderReading <PSOBBPacketHeader>(new FreecraftCoreGladNetSerializerAdapter(Serializer), 4)
                                                                                                        .AddNetworkMessageReading(new FreecraftCoreGladNetSerializerAdapter(Serializer))
                                                                                                        .For <PSOBBGamePacketPayloadServer, PSOBBGamePacketPayloadClient, IPacketPayload>(new PSOBBPacketHeaderFactory())
                                                                                                        .AddReadBufferClearing()
                                                                                                        .Build()
                                                                                                        .AsManaged();

            MessageContextFactory = new DefaultMessageContextFactory();

            await Task.Run(() => RunClientAsync(client, ip, port));
        }
        /// <inheritdoc />
        public override void Register(ContainerBuilder register)
        {
            EncryptionLazyWithoutKeyDecorator <byte[]> encrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishEncryptionService encryptionService = new BlowfishEncryptionService();
                encryptionService.Initialize(val);
                return(encryptionService);
            }, 8);
            EncryptionLazyWithoutKeyDecorator <byte[]> decrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishDecryptionService decryptionService = new BlowfishDecryptionService();
                decryptionService.Initialize(val);
                return(decryptionService);
            }, 8);

            IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client = new DotNetTcpClientNetworkClient()
                                                                                                        .AddCryptHandling(encrypt, decrypt)
                                                                                                        .AddBufferredWrite(4)
                                                                                                        .AddHeaderReading <PSOBBPacketHeader>(Serializer.Value, 2)
                                                                                                        .AddNetworkMessageReading(Serializer.Value)
                                                                                                        .For <PSOBBGamePacketPayloadServer, PSOBBGamePacketPayloadClient, IPacketPayload>(new PSOBBPacketHeaderFactory())
                                                                                                        .AddReadBufferClearing()
                                                                                                        .Build()
                                                                                                        .AsManaged(new UnityLoggingService(LoggingLevel));

            register.RegisterInstance(client)
            .As <IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> >()
            .As <IPeerPayloadSendService <PSOBBGamePacketPayloadClient> >()
            .As <IPayloadInterceptable>();

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

            register.RegisterType <PayloadInterceptMessageSendService <PSOBBGamePacketPayloadClient> >()
            .As <IPeerRequestSendService <PSOBBGamePacketPayloadClient> >()
            .SingleInstance();

            register.RegisterInstance(new SeperateAggregateCryptoInitializationService <byte[]>(encrypt, decrypt))
            .As <IFullCryptoInitializationService <byte[]> >()
            .SingleInstance();

            //TODO: This is all so hacky, is this really what we're going to do forever??
            register.RegisterType <GlobalExportableClient>()
            .As <INetworkClientExportable>()
            .SingleInstance();

            register.RegisterType <DefaultConnectionRedirector>()
            .As <IConnectionRedirector>();

            register.RegisterType <GlobalConnectionService>()
            .As <IConnectionService>()
            .SingleInstance();

            //TODO: This is a hack to help prevent mobile network issues
            this.gameObject.AddComponent <DisconnectClientOnNonExportableSceneChange>();
        }
        /// <inheritdoc />
        protected override ContainerBuilder RegisterHandlerDependencies(ContainerBuilder builder)
        {
            //Client crypto
            //We create the shared block cipher service here.
            ClientEncryptionService = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishEncryptionService encryptionService = new BlowfishEncryptionService();
                encryptionService.Initialize(val.ToArray());
                return(encryptionService);
            }, 8);

            ClientDecryptionService = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishDecryptionService decryptionService = new BlowfishDecryptionService();
                decryptionService.Initialize(val.ToArray());
                return(decryptionService);
            }, 8);

            //Server crypto
            ServerEncryptionService = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishEncryptionService encryptionService = new BlowfishEncryptionService();
                encryptionService.Initialize(val.ToArray());
                return(encryptionService);
            }, 8);

            ServerDecryptionService = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishDecryptionService decryptionService = new BlowfishDecryptionService();
                decryptionService.Initialize(val.ToArray());                 //for PROXY PURPOSES ONLY we have to copy so we don't modify the key used by the other end
                return(decryptionService);
            }, 8);

            //Register all the crypto providers as crypto initializers
            RegisterCryptoInitializable(builder, ClientEncryptionService, CryptoType.Decryption);
            RegisterCryptoInitializable(builder, ClientDecryptionService, CryptoType.Encryption);
            RegisterCryptoInitializable(builder, ServerEncryptionService, CryptoType.Encryption);
            RegisterCryptoInitializable(builder, ServerDecryptionService, CryptoType.Decryption);


            builder
            .Register <IFullCryptoInitializationService <byte[]> >(context =>
            {
                return(new ProxiedFullCryptoInitializable(new AggergateCryptoInitializer(context.ResolveKeyed <IEnumerable <ICryptoKeyInitializable <byte[]> > >(CryptoType.Encryption)), new AggergateCryptoInitializer(context.ResolveKeyed <IEnumerable <ICryptoKeyInitializable <byte[]> > >(CryptoType.Decryption))));
            });

            builder.RegisterInstance(new BinaryPacketWriter("Packets"))
            .AsSelf()
            .SingleInstance()
            .ExternallyOwned();

            return(builder);
        }
        /// <inheritdoc />
        public override void Register(ContainerBuilder register)
        {
            EncryptionLazyWithoutKeyDecorator <byte[]> encrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishEncryptionService encryptionService = new BlowfishEncryptionService();
                encryptionService.Initialize(val);
                return(encryptionService);
            }, 8);
            EncryptionLazyWithoutKeyDecorator <byte[]> decrypt = new EncryptionLazyWithoutKeyDecorator <byte[]>(val =>
            {
                BlowfishDecryptionService decryptionService = new BlowfishDecryptionService();
                decryptionService.Initialize(val);
                return(decryptionService);
            }, 8);

            IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> client = new DotNetTcpClientNetworkClient()
                                                                                                        .AddCryptHandling(encrypt, decrypt)
                                                                                                        .AddBufferredWrite(4)
                                                                                                        .AddHeaderReading <PSOBBPacketHeader>(Serializer.Value, 2)
                                                                                                        .AddNetworkMessageReading(Serializer.Value)
                                                                                                        .For <PSOBBGamePacketPayloadServer, PSOBBGamePacketPayloadClient, IPacketPayload>(new PSOBBPacketHeaderFactory())
                                                                                                        .AddReadBufferClearing()
                                                                                                        .Build()
                                                                                                        .AsManaged(new UnityLoggingService(LoggingLevel));

            register.RegisterInstance(client)
            .As <IManagedNetworkClient <PSOBBGamePacketPayloadClient, PSOBBGamePacketPayloadServer> >()
            .As <IPeerPayloadSendService <PSOBBGamePacketPayloadClient> >()
            .As <IPayloadInterceptable>()
            .As <IConnectionService>();

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

            register.RegisterType <PayloadInterceptMessageSendService <PSOBBGamePacketPayloadClient> >()
            .As <IPeerRequestSendService <PSOBBGamePacketPayloadClient> >()
            .SingleInstance();

            register.RegisterInstance(new SeperateAggregateCryptoInitializationService <byte[]>(encrypt, decrypt))
            .As <IFullCryptoInitializationService <byte[]> >()
            .SingleInstance();
        }
        private async Task InitializeNetworkingClient()
        {
            ContainerBuilder builder = new ContainerBuilder();

            EncryptionLazyWithoutKeyDecorator <uint> encrypt     = new EncryptionLazyWithoutKeyDecorator <uint>(val => new PatchServerCryptoProvider(PatchEncryptionKeyFactory.Create(val)), 4);
            EncryptionLazyWithoutKeyDecorator <uint> decrypt     = new EncryptionLazyWithoutKeyDecorator <uint>(val => new PatchServerCryptoProvider(PatchEncryptionKeyFactory.Create(val)), 4);
            IFullCryptoInitializationService <uint>  intializers = new SeperateAggregateCryptoInitializationService <uint>(encrypt, decrypt);

            builder.RegisterInstance(intializers)
            .As <IFullCryptoInitializationService <uint> >();

            INetworkSerializationService serializerService = new FreecraftCoreGladNetSerializerAdapter(CreateSerializerService());

            //Configurs and builds the clients without all the
            //relevant decorators
            IManagedNetworkClient <PSOBBPatchPacketPayloadClient, PSOBBPatchPacketPayloadServer> client = new DotNetTcpClientNetworkClient()
                                                                                                          .AddCryptHandling(encrypt, decrypt)
                                                                                                          .AddHeaderReading <PSOBBPacketHeader>(serializerService, 2)
                                                                                                          .AddNetworkMessageReading(serializerService)
                                                                                                          .For <PSOBBPatchPacketPayloadServer, PSOBBPatchPacketPayloadClient, IPacketPayload>(null)
                                                                                                          .AddReadBufferClearing()
                                                                                                          .Build()
                                                                                                          .AsManaged();

            builder.RegisterInstance(client)
            .As <IManagedNetworkClient <PSOBBPatchPacketPayloadClient, PSOBBPatchPacketPayloadServer> >();

            //Patch welcome message
            builder.RegisterHandler <PatchWelcomeMessageHandler, PatchingWelcomePayload>();
            builder.RegisterHandler <PatchingLoginReadyMessageHandler, PatchingReadyForLoginRequestPayload>();
            builder.RegisterHandler <PatchingRedirectionMessageHandler, PatchingRedirectPayload>();
            builder.RegisterHandler <PatchingInfoDoneMessageHandler, PatchingInfoRequestDonePayload>(async h =>
            {
                await Dispatcher.InvokeAsync(() => PlayButton.DataContext = h);
            });
            builder.RegisterHandler <PatchMessageMessageHandler, PatchingMessagePayload>(async h =>
            {
                await Dispatcher.InvokeAsync(() => PatchNotesData.DataContext = h);
            });

            IContainer container = builder.Build();

            IEnumerable <IPeerMessageHandler <PSOBBPatchPacketPayloadServer, PSOBBPatchPacketPayloadClient> > Handlers =
                container.Resolve <IEnumerable <IPeerMessageHandler <PSOBBPatchPacketPayloadServer, PSOBBPatchPacketPayloadClient> > >();

            IPeerMessageContextFactory MessageContextFactory = new DefaultMessageContextFactory();

            await client.ConnectAsync("158.69.215.131", 11000);

            while (client.isConnected)
            {
                NetworkIncomingMessage <PSOBBPatchPacketPayloadServer> message = await client.ReadMessageAsync();

                Console.WriteLine($"Recieved {message.Payload?.GetType().Name}");

                foreach (var h in Handlers)
                {
                    //TODO: Fix this and enable request service
                    if (await h.TryHandleMessage(MessageContextFactory.Create(client, client, null), message))
                    {
                        break;
                    }
                }
            }
        }