public NetworkHelper(PacketTypeRegistry packetTypeRegistry, PacketHandlerRegistry packetHandlerRegistry)
        {
            Parent = null;

            HandlerRegistry = packetHandlerRegistry ?? throw new ArgumentNullException(nameof(packetHandlerRegistry));
            TypeRegistry    = packetTypeRegistry ?? throw new ArgumentNullException(nameof(packetTypeRegistry));

            PluginPacketTypes = new List <Type>();
        }
        public static void InitNetwork()
        {
            if (EditorLidgrenNetwork == null)
            {
                var logger             = Log.Default;
                var packetTypeRegistry = new PacketTypeRegistry(logger);
                if (!packetTypeRegistry.TryRegisterBuiltIn())
                {
                    throw new Exception("Failed to register built-in packets.");
                }

                var packetHandlerRegistry = new PacketHandlerRegistry(packetTypeRegistry, logger);
                var networkHelper         = new NetworkHelper(packetTypeRegistry, packetHandlerRegistry);
                PackedIntersectPacket.AddKnownTypes(networkHelper.AvailablePacketTypes);
                var virtualEditorContext = new VirtualEditorContext(networkHelper, logger);
                PacketHandler = new PacketHandler(virtualEditorContext, packetHandlerRegistry);

                var config = new NetworkConfiguration(
                    ClientConfiguration.Instance.Host, ClientConfiguration.Instance.Port
                    );

                var assembly = Assembly.GetExecutingAssembly();
                using (var stream = assembly.GetManifestResourceStream("Intersect.Editor.network.handshake.bkey.pub"))
                {
                    var rsaKey = EncryptionKey.FromStream <RsaKey>(stream);
                    Debug.Assert(rsaKey != null, "rsaKey != null");
                    EditorLidgrenNetwork = new ClientNetwork(networkHelper, config, rsaKey.Parameters);
                }

                EditorLidgrenNetwork.Handler             = PacketHandler.HandlePacket;
                EditorLidgrenNetwork.OnDisconnected     += HandleDc;
                EditorLidgrenNetwork.OnConnectionDenied += delegate
                {
                    Connecting       = false;
                    ConnectionDenied = true;
                };
            }

            if (!Connected)
            {
                Connecting = true;
                if (!EditorLidgrenNetwork.Connect())
                {
                    Log.Error("An error occurred while attempting to connect.");
                }
            }
        }
        public static void Start(params string[] args)
        {
            var parser = new Parser(
                parserSettings =>
            {
                if (parserSettings == null)
                {
                    throw new ArgumentNullException(
                        nameof(parserSettings), @"If this is null the CommandLineParser dependency is likely broken."
                        );
                }

                parserSettings.AutoHelp               = true;
                parserSettings.AutoVersion            = true;
                parserSettings.IgnoreUnknownArguments = true;
            }
                );

            var logger             = Log.Default;
            var packetTypeRegistry = new PacketTypeRegistry(logger);

            if (!packetTypeRegistry.TryRegisterBuiltIn())
            {
                logger.Error("Failed to register built-in packets.");
                return;
            }

            var packetHandlerRegistry = new PacketHandlerRegistry(packetTypeRegistry, logger);
            var networkHelper         = new NetworkHelper(packetTypeRegistry, packetHandlerRegistry);

            FactoryRegistry <IPluginBootstrapContext> .RegisterFactory(PluginBootstrapContext.CreateFactory(args ?? Array.Empty <string>(), parser, networkHelper));

            var commandLineOptions = parser.ParseArguments <ClientCommandLineOptions>(args)
                                     .MapResult(HandleParsedArguments, HandleParserErrors);

            if (!string.IsNullOrWhiteSpace(commandLineOptions.WorkingDirectory))
            {
                var workingDirectory = commandLineOptions.WorkingDirectory.Trim();
                if (Directory.Exists(workingDirectory))
                {
                    Directory.SetCurrentDirectory(workingDirectory);
                }
            }

            Context = new ClientContext(commandLineOptions, logger, networkHelper);
            Context.Start();
        }
        public static void Start(params string[] args)
        {
            (string[] Args, Parser Parser, ServerCommandLineOptions CommandLineOptions)parsedArguments = ParseCommandLineArgs(args);
            if (!string.IsNullOrWhiteSpace(parsedArguments.CommandLineOptions.WorkingDirectory))
            {
                var workingDirectory = parsedArguments.CommandLineOptions.WorkingDirectory.Trim();
                if (Directory.Exists(workingDirectory))
                {
                    Directory.SetCurrentDirectory(workingDirectory);
                }
            }

            if (!PreContextSetup(args))
            {
                return;
            }

            var logger             = Log.Default;
            var packetTypeRegistry = new PacketTypeRegistry(logger);

            if (!packetTypeRegistry.TryRegisterBuiltIn())
            {
                logger.Error("Failed to load built-in packet types.");
                return;
            }

            var packetHandlerRegistry = new PacketHandlerRegistry(packetTypeRegistry, logger);
            var networkHelper         = new NetworkHelper(packetTypeRegistry, packetHandlerRegistry);

            FactoryRegistry <IPluginBootstrapContext> .RegisterFactory(
                PluginBootstrapContext.CreateFactory(
                    parsedArguments.Args ?? Array.Empty <string>(),
                    parsedArguments.Parser,
                    networkHelper
                    )
                );

            Context = new ServerContext(parsedArguments.CommandLineOptions, logger, networkHelper);
            var noHaltOnError = Context?.StartupOptions.DoNotHaltOnError ?? false;

            if (!PostContextSetup())
            {
                return;
            }

            MainThread = Context.StartWithActionQueue();
            Action action;

            while (null != (action = MainThread.NextAction))
            {
                action.Invoke();
            }

            Log.Diagnostic("Bootstrapper exited.");

            // At this point dbs should be saved and all threads should be killed. Give a message saying that the server has shutdown and to press any key to exit.
            // Having the message and the console.readline() allows the server to exit properly if the console has crashed, and it allows us to know that the server context has shutdown.
            if (Context.HasErrors)
            {
                if (noHaltOnError)
                {
                    Console.WriteLine(Strings.Errors.errorservercrashnohalt);
                }
                else
                {
                    Console.WriteLine(Strings.Errors.errorservercrash);
                    Console.ReadLine();
                }
            }
        }