/// <summary>Tries to connect to a server.</summary> /// <param name="conData">Set the connection information properties as needed. /// For further details about each setting see the respective property documentation in <see cref="ConnectionData"/></param> /// <exception cref="ArgumentException">When some required values are not set or invalid.</exception> /// <exception cref="TsException">When the connection could not be established.</exception> public override async CmdR Connect(ConnectionData conData) { scheduler.VerifyOwnThread(); if (!(conData is ConnectionDataFull conDataFull)) { throw new ArgumentException($"Use the {nameof(ConnectionDataFull)} derivative to connect with the full client.", nameof(conData)); } if (conDataFull.Identity is null) { throw new ArgumentNullException(nameof(conDataFull.Identity)); } if (conDataFull.VersionSign is null) { throw new ArgumentNullException(nameof(conDataFull.VersionSign)); } await Disconnect(); remoteAddress = await TsDnsResolver.TryResolve(conData.Address); if (remoteAddress is null) { return(CommandError.Custom("Could not read or resolve address.")); } ConnectionData = conData; ServerConstants = TsConst.Default; Book.Reset(); returnCode = 0; var ctx = new ConnectionContext(conDataFull); context = ctx; ctx.PacketHandler.PacketEvent = (ref Packet <S2C> packet) => { if (status == TsClientStatus.Disconnected) { return; } PacketEvent(ctx, ref packet); }; ctx.PacketHandler.StopEvent = (closeReason) => { _ = scheduler.Invoke(() => { ctx.ExitReason ??= closeReason; ChangeState(ctx, TsClientStatus.Disconnected); }); }; ChangeState(ctx, TsClientStatus.Connecting); if (!ctx.PacketHandler.Connect(remoteAddress).GetOk(out var error)) { ChangeState(ctx, TsClientStatus.Disconnected); return(CommandError.Custom(error)); } return(await ctx.ConnectEvent.Task); // TODO check error state }
public async Task Run(ParameterData setup) { scheduler.VerifyOwnThread(); AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler; TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler; Console.CancelKeyPress += ConsoleInterruptHandler; var config = ConfRoot.OpenOrCreate(configFilePath); if (config is null) { throw new Exception("Could not create config"); } ConfigUpgrade2.Upgrade(config.Configs.BotsPath.Value); config.Save(); var builder = new DependencyBuilder(injector); injector.AddModule(this); injector.AddModule(scheduler); injector.AddModule(injector); injector.AddModule(config); injector.AddModule(config.Db); injector.AddModule(config.Plugins); injector.AddModule(config.Web); injector.AddModule(config.Web.Interface); injector.AddModule(config.Web.Api); injector.AddModule(config.Rights); injector.AddModule(config.Factories); builder.RequestModule <SystemMonitor>(); builder.RequestModule <DbStore>(); builder.RequestModule <PluginManager>(); builder.RequestModule <WebServer>(); builder.RequestModule <RightsManager>(); builder.RequestModule <BotManager>(); builder.RequestModule <TokenManager>(); builder.RequestModule <CommandManager>(); builder.RequestModule <ResourceResolver>(); builder.RequestModule <Stats>(); if (!builder.Build()) { throw new Exception("Could not load all core modules"); } Upgrader.PerformUpgrades(injector); YoutubeDlHelper.DataObj = config.Tools.YoutubeDl; injector.GetModuleOrThrow <CommandManager>().RegisterCollection(MainCommands.Bag); injector.GetModuleOrThrow <RightsManager>().CreateConfigIfNotExists(setup.Interactive); injector.GetModuleOrThrow <WebServer>().StartWebServer(); injector.GetModuleOrThrow <Stats>().StartTimer(setup.SendStats); await injector.GetModuleOrThrow <BotManager>().RunBots(setup.Interactive); }