示例#1
0
文件: BDO.cs 项目: ItsKaa/Ditto
        static BDO()
        {
            Ditto.Connected += async() =>
            {
                if (string.IsNullOrWhiteSpace(Ditto.Settings.BlackDesertOnline.Email) ||
                    string.IsNullOrWhiteSpace(Ditto.Settings.BlackDesertOnline.Password) ||
                    string.IsNullOrWhiteSpace(Ditto.Settings.BlackDesertOnline.LoginUrl))
                {
                    Log.Warn("Ignored the module Black Desert Online");
                    return;
                }

                // Properties & Fields
                Delay        = TimeSpan.FromMinutes(1);
                _launcherUrl = Ditto.Settings.BlackDesertOnline.LauncherUrl;
                _loginUrl    = string.Format(
                    Ditto.Settings.BlackDesertOnline.LoginUrl,
                    Ditto.Settings.BlackDesertOnline.Email,
                    Ditto.Settings.BlackDesertOnline.Password
                    );
                _loginTokenUrl = Ditto.Settings.BlackDesertOnline.LoginTokenUrl;

                _bdoChannels = new ConcurrentDictionary <ulong, ITextChannel>(
                    await Ditto.Client.DoAsync((client) => client.Guilds.ToDictionary(g => g.Id,
                                                                                      (gc) =>
                {
                    string channelIdString = null;
                    Ditto.Database.Read((uow) =>
                    {
                        channelIdString = uow.Configs.GetBdoMaintenanceChannel(gc as IGuild)?.Value;
                    });
                    if (ulong.TryParse(channelIdString, out ulong channelId))
                    {
                        return((ITextChannel)gc.GetTextChannel(channelId));
                    }
                    return(null);
                }
                                                                                      ))
                    );

                // Load default server status
                BdoStatus bdoStatus = null;
                await Ditto.Database.ReadAsync(uow =>
                {
                    bdoStatus = uow.BdoStatus.GetAll().FirstOrDefault();
                }).ConfigureAwait(false);

                if (bdoStatus == null)
                {
                    var serverStatus = await GetServerStatusAsync().ConfigureAwait(false);

                    await Ditto.Database.WriteAsync(uow =>
                    {
                        bdoStatus = uow.BdoStatus.Add(new BdoStatus()
                        {
                            Status          = serverStatus.Status,
                            MaintenanceTime = serverStatus.MaintenanceTime,
                            Error           = serverStatus.Error,
                            DateUpdated     = DateTime.Now
                        });
                    }).ConfigureAwait(false);
                }
                _lastServerStatusTime = bdoStatus.DateUpdated;
                ServerStatus          = new BdoStatusResult()
                {
                    Status          = bdoStatus.Status,
                    MaintenanceTime = bdoStatus.MaintenanceTime,
                    Error           = bdoStatus.Error
                };

                ServerStatusChanged += (@new, old) =>
                {
                    // Update database
                    var changed = @new != old;
                    var dbTask  = Task.Run(async() =>
                    {
                        BdoStatus dbStatus = null;
                        await Ditto.Database.ReadAsync(uow =>
                                                       dbStatus = uow.BdoStatus.GetAll().FirstOrDefault()
                                                       ).ConfigureAwait(false);

                        if (dbStatus == null)
                        {
                            dbStatus = await Ditto.Database.WriteAsync(uow =>
                                                                       uow.BdoStatus.Add(new BdoStatus()
                            {
                                Status          = @new.Status,
                                Error           = @new.Error,
                                MaintenanceTime = @new.MaintenanceTime,
                                DateUpdated     = DateTime.Now
                            })
                                                                       ).ConfigureAwait(false);
                        }
                        else if (changed)
                        {
                            bdoStatus.Status          = @new.Status;
                            bdoStatus.Error           = @new.Error;
                            bdoStatus.MaintenanceTime = @new.MaintenanceTime;
                            bdoStatus.DateUpdated     = DateTime.Now;

                            await Ditto.Database.WriteAsync(uow =>
                            {
                                uow.BdoStatus.Update(bdoStatus);
                            });
                        }
                    });
                    return(Task.CompletedTask);
                };

                // Automatically update the server status
                Running = true;
                var _ = Task.Run(async() =>
                {
                    await Task.Delay(1000).ConfigureAwait(false);
                    while (Running)
                    {
                        // Update status
                        await GetServerStatusAsync().ConfigureAwait(false);
                        await Task.Delay(TimeSpan.FromMinutes(1), _cancellationTokenSource.Token).ConfigureAwait(false);
                    }
                }, _cancellationTokenSource.Token);


                // Post channel updates
                //ServerStatusChanged += async (status, old) =>
                //{
                //    foreach (var channel in BdoMaintenanceLinking.GetLinkedChannels())
                //    {
                //        // TODO
                //    }
                //};

                Initialized = true;
            };

            Ditto.Exit += () =>
            {
                Running = false;
                _cancellationTokenSource?.Cancel();
                return(Task.CompletedTask);
            };
        }
示例#2
0
文件: BDO.cs 项目: ItsKaa/Ditto
        public static async Task <BdoStatusResult> GetServerStatusAsync()
        {
            if ((DateTime.Now - _lastServerStatusTime) < Delay)
            {
                return(ServerStatus);
            }

            var statusResult = BdoStatusResult.InvalidResult;

            using (var client = new HttpClient())
            {
                var loginDataJson = await client.GetStringAsync(_loginUrl).ConfigureAwait(false);

                if (!string.IsNullOrEmpty(loginDataJson))
                {
                    dynamic results      = JsonConvert.DeserializeObject <dynamic>(loginDataJson);
                    var     errorCode    = results?.api?.additionalInfo?.code;
                    string  token        = results?.result?.token;
                    string  errorMessage = results?.api?.additionalInfo?.msg ?? (results?.api?.codeMsg ?? "" + $"({results?.api?.additionalInfo.name})");

                    // Logged in
                    if (errorCode == null)
                    {
                        // Try and create the "play token"
                        var playTokenDataJson = await client.GetStringAsync(string.Format(_loginTokenUrl, token)).ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(playTokenDataJson))
                        {
                            results      = JsonConvert.DeserializeObject <dynamic>(playTokenDataJson);
                            errorCode    = results?.api?.additionalInfo?.code;
                            errorMessage = results?.api?.additionalInfo?.msg ?? (results?.api?.codeMsg ?? "" + $"({results?.api?.additionalInfo.name})");
                            if (errorCode == null)
                            {
                                statusResult = new BdoStatusResult()
                                {
                                    Status = BdoServerStatus.Online
                                };
                            }
                            else if (errorCode >= 412 && errorCode <= 415)
                            {
                                // Read maintenance time
                                var launcherHtmlCode = await client.GetStringAsync(_launcherUrl).ConfigureAwait(false);

                                var maintenance = launcherHtmlCode.Between("'error_maintenance':\"", "\",").Replace("\\n", "\n");
                                if (maintenance != null)
                                {
                                    //var maintenanceTimeString = maintenance.Between("~", ")")
                                    //    .Replace("UTC", "")
                                    //    .Trim();
                                    //var maintenanceTimeString = maintenance.From("time:").Between(" to ", "UTC").Trim();
                                    var      maintenanceTimeString = Regex.Match(maintenance, @"(?:(?<time>\d+:\d+) UTC)").Groups?.Values?.LastOrDefault()?.Value;
                                    DateTime?maintenanceDateTime   = null;
                                    if (TimeSpan.TryParse(maintenanceTimeString, out TimeSpan maintenanceTime))
                                    {
                                        var utcDate = DateTime.UtcNow;
                                        maintenanceDateTime = ((utcDate - utcDate.TimeOfDay) + maintenanceTime);
                                    }
                                    statusResult = new BdoStatusResult()
                                    {
                                        Status          = BdoServerStatus.Maintenance,
                                        Error           = maintenance,
                                        MaintenanceTime = maintenanceDateTime?.ToLocalTime()
                                    };
                                }
                            }
                        }
                    }

                    // Unknown error
                    if (statusResult.Status == BdoServerStatus.Unknown)
                    {
                        statusResult = new BdoStatusResult()
                        {
                            Status = BdoServerStatus.Unknown,
                            Error  = errorMessage
                        };
                    }
                }
            }

            // Modify value if changed and call the event handler if needed
            if (ServerStatus != statusResult)
            {
                if (_lastServerStatusTime != DateTime.MinValue)
                {
                    //var _ = Task.Run(async ()
                    //    => await ServerStatusChanged(statusResult, ServerStatus).ConfigureAwait(false)
                    //);
                    await ServerStatusChanged(statusResult, ServerStatus).ConfigureAwait(false);
                }
                ServerStatus = statusResult;
            }
            _lastServerStatusTime = DateTime.Now;
            return(statusResult);
        }