public async Task LinkSteam() { using (var context = _databaseContextFactory.Create()) { if (context.Users.FirstOrDefault(x => x != null && x.DiscordId == (long)Context.User.Id && !x.Unlinked) != null) { await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, your user is already linked with Steam. If you wish to remove this link use the command **!unlinksteam**."); return; } } var state = await _openId.LinkWithSteamTaskAsync(Context.User.Id); if (state == null) { await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, something went wrong... :( Please try sending the **!linksteam** command to me in a private conversation instead!"); return; } EmbedBuilder builder = new EmbedBuilder() { Title = "Steam Account Link", Description = $"Proceed to link your Discord user with your Steam account by [Logging into Steam]({state.StartUrl})", Url = state.StartUrl, Color = Color.Green }; var channel = await Context.User.GetOrCreateDMChannelAsync(); var msg = await channel.SendMessageAsync("", false, builder.Build()); if (Context.IsPrivate) { return; } await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, I have sent you a private message with instructions on how to proceed with linking your Discord user with Steam! If you do not receive this message, please try sending the **!linksteam** command to me in a private conversation!"); //todo: how to get state in 1.0? //if (msg.State == MessageState.Normal || msg.State == MessageState.Queued) // await Context.Channel.SendMessageAsync( // $"<@{Context.User.Id}>, I have sent you a private message with instructions on how to proceed with linking your Discord user with Steam! If you do not receive this message, please try sending the **!linksteam** command to me in a private conversation!"); //else // await Context.Channel.SendMessageAsync( // $"<@{Context.User.Id}>, it seems that I am unable to start a private conversation with you! :( Please try sending the **!linksteam** command to me in a private conversation instead!"); }
public async Task TimerUpdateVotes() { using (var db = _databaseContextFactory.Create()) { var elapsedBans = db.Votes.OfType <BanVote>().Where(x => x.Result == VoteResult.Passed && x.BannedUntil.HasValue && x.BannedUntil <= DateTime.Now).ToArray(); foreach (var ban in elapsedBans) { var serverContext = _contextManager.GetServer(ban.ServerKey); if (serverContext == null) { Logging.Log($"Failed to automatically unban player {ban.SteamId} on server ({ban.ServerKey}) because the server was not found.", typeof(ArkDiscordBot), LogLevel.WARN); continue; } if (await serverContext.Steam.SendRconCommand($"unbanplayer {ban.SteamId}") != null) { ban.BannedUntil = null; } } db.SaveChanges(); } }
public async Task LinkSteam() { using (var context = _databaseContextFactory.Create()) { if (context.Users.FirstOrDefault(x => x != null && x.DiscordId == (long)Context.User.Id && !x.Unlinked) != null) { await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, your user is already linked with Steam. If you wish to remove this link use the command **!unlinksteam**."); return; } } var state = await _openId.LinkWithSteamTaskAsync(Context.User.Id); if (state == null) { await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, something went wrong... :( Please try sending the **!linksteam** command to me in a private conversation instead!"); return; } var sb = new StringBuilder(); sb.AppendLine($"**Proceed to link your Discord user with your Steam account by following this link:**"); sb.AppendLine($"{(await _urlShortenerService?.ShortenUrl(state.StartUrl)) ?? state.StartUrl}"); var channel = await Context.User.GetOrCreateDMChannelAsync(); var msg = await channel.SendMessageAsync(sb.ToString().Trim('\r', '\n')); if (Context.IsPrivate) { return; } await Context.Channel.SendMessageAsync( $"<@{Context.User.Id}>, I have sent you a private message with instructions on how to proceed with linking your Discord user with Steam! If you do not receive this message, please try sending the **!linksteam** command to me in a private conversation!"); //todo: how to get state in 1.0? //if (msg.State == MessageState.Normal || msg.State == MessageState.Queued) // await Context.Channel.SendMessageAsync( // $"<@{Context.User.Id}>, I have sent you a private message with instructions on how to proceed with linking your Discord user with Steam! If you do not receive this message, please try sending the **!linksteam** command to me in a private conversation!"); //else // await Context.Channel.SendMessageAsync( // $"<@{Context.User.Id}>, it seems that I am unable to start a private conversation with you! :( Please try sending the **!linksteam** command to me in a private conversation instead!"); }
public async Task UnlinkSteam() { using (var context = _databaseContextFactory.Create()) { var user = context.Users.FirstOrDefault(x => x.DiscordId == (long)Context.User.Id && !x.Unlinked); if (user == null) { await Context.Channel.SendMessageAsync($"<@{Context.User.Id}>, your user is not linked with Steam."); } else { user.Unlinked = true; var result = context.SaveChanges(); //remove ark role from users when they unlink if (Context.Client?.Guilds != null) { foreach (var server in Context.Client.Guilds) { try { var duser = server.GetUser(Context.User.Id); var role = server.Roles.FirstOrDefault(x => x.Name.Equals(_config.Discord.MemberRoleName)); if (duser != null && role == null) { continue; } if (duser?.Roles.Any(x => x.Id == role.Id) == true) { await duser.RemoveRoleAsync(role); } } catch (HttpException) { //could be due to the order of roles on the server. bot role with "manage roles" permission must be higher up than the role it is trying to set } } } await Context.Channel.SendMessageAsync($"<@{Context.User.Id}>, your user is no longer linked with Steam."); } } }
public async Task Run(CommandEventArgs e) { using (var context = _databaseContextFactory.Create()) { var user = context.Users.FirstOrDefault(x => x.DiscordId == (long)e.User.Id && !x.Unlinked); if (user == null) { await e.Channel.SendMessage($"<@{e.User.Id}>, your user is not linked with Steam."); } else { user.Unlinked = true; var result = context.SaveChanges(); //remove ark role from users when they unlink if (_discord?.Servers != null) { foreach (var server in _discord.Servers) { try { var duser = server.GetUser(e.User.Id); var role = server.FindRoles(_config.MemberRoleName, true).FirstOrDefault(); if (duser != null && role == null) { continue; } if (duser.HasRole(role)) { await duser.RemoveRoles(role); } } catch (HttpException) { //could be due to the order of roles on the server. bot role with "manage roles" permission must be higher up than the role it is trying to set } } } await e.Channel.SendMessage($"<@{e.User.Id}>, your user is no longer linked with Steam."); } } }
public async Task Run(CommandEventArgs e) { using (var context = _databaseContextFactory.Create()) { var user = context.Users.FirstOrDefault(x => x.DiscordId == (long)e.User.Id && !x.Unlinked); if (user == null) { await e.Channel.SendMessage($"<@{e.User.Id}>, your existence is a mystery to us! :("); } else { if (!e.Channel.IsPrivate) { await e.Channel.SendMessage($"<@{e.User.Id}>, I will send you a private message with everything we know about you!"); } var sb = new StringBuilder(); sb.AppendLine($"**This is what we know about you:**"); sb.AppendLine($"● **Discord ID:** {user.DiscordId}"); sb.AppendLine($"● **Steam ID:** {user.SteamId}"); if (user.SteamDisplayName != null) { sb.AppendLine($"● **Steam nick:** {user.SteamDisplayName}"); } if (user.RealName != null) { sb.AppendLine($"● **Real name:** {user.RealName}"); } if (e.User.PrivateChannel == null) { await e.User.CreatePMChannel(); } foreach (var msg in sb.ToString().Partition(2000)) { await e.User.PrivateChannel.SendMessage(msg.Trim('\r', '\n')); } } } }
//todo: this method does not really belong here and should be moved elsewhere public static async Task <ArkSavegameToolkitNet.Domain.ArkPlayer> GetCurrentPlayerOrSendErrorMessage(CommandEventArgs e, EfDatabaseContextFactory databaseContextFactory, ArkServerContext serverContext) { using (var db = databaseContextFactory.Create()) { var user = db.Users.FirstOrDefault(x => x.DiscordId == (long)e.User.Id && !x.Unlinked); if (user == null) { await e.Channel.SendMessage($"<@{e.User.Id}>, this command can only be used after you link your Discord user with your Steam account using **!linksteam**."); return(null); } var player = serverContext.Players.FirstOrDefault(x => x.SteamId != null && x.SteamId.Equals(user.SteamId.ToString())); if (player == null) { await e.Channel.SendMessage($"<@{e.User.Id}>, we have no record of you playing in the last month."); return(null); } return(player); } }
public async Task Run(CommandEventArgs e) { if (!_context.IsInitialized) { await e.Channel.SendMessage($"**The data is loading but is not ready yet...**"); return; } //var args = CommandHelper.ParseArgs(e, new { Extended = false }, x => // x.For(y => y.Extended, flag: true)); var playersx = e.Message.Text.StartsWith("!playersx", StringComparison.OrdinalIgnoreCase); var serverContext = _contextManager.GetServer(_config.ServerKey); var serverInfo = serverContext.Steam.GetServerInfoCached(); var playerInfo = serverContext.Steam.GetServerPlayersCached(); var sb = new StringBuilder(); if (serverInfo == null || playerInfo == null) { sb.AppendLine($"**Player list is currently unavailable!**"); } else { var players = playerInfo?.Where(x => !string.IsNullOrEmpty(x.Name)).ToArray() ?? new PlayerInfo[] { }; var m = new Regex(@"^(?<name>.+?)\s+-\s+\(v(?<version>\d+\.\d+)\)$", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(serverInfo.Name); var name = m.Success ? m.Groups["name"].Value : serverInfo.Name; sb.AppendLine($"**{name} ({serverInfo.Players - (playerInfo.Count - players.Length)}/{serverInfo.MaxPlayers})**"); if (playersx) { using (var db = _databaseContextFactory.Create()) { var playerNames = players.Select(x => x.Name).ToArray(); var d = _context.Players.Where(x => playerNames.Contains(x.PlayerName, StringComparer.Ordinal)).Select(x => { long steamId; return(new Tuple <Data.Player, Database.Model.User, User, long?, TimeSpan>( x, null, null, long.TryParse(x.SteamId, out steamId) ? steamId : (long?)null, TimeSpan.Zero)); }).ToDictionary(x => x.Item1.PlayerName, StringComparer.OrdinalIgnoreCase); var ids = new List <int>(); var steamIds = d.Values.Select(x => x.Item4).Where(x => x != null).ToArray(); foreach (var user in db.Users.Where(y => steamIds.Contains(y.SteamId))) { var item = d.Values.FirstOrDefault(x => x.Item4 == user.SteamId); if (item == null) { continue; } ids.Add(item.Item1.Id); var discordUser = e.User?.Client?.Servers?.Select(x => x.GetUser((ulong)user.DiscordId)).FirstOrDefault(); var playedLastSevenDays = TimeSpan.FromSeconds(user?.Played?.OrderByDescending(x => x.Date).Take(7).Sum(x => x.TimeInSeconds) ?? 0); d[item.Item1.PlayerName] = new Tuple <Data.Player, Database.Model.User, User, long?, TimeSpan>(item.Item1, user, discordUser, item.Item4, playedLastSevenDays); } var remaining = d.Values.Where(x => !ids.Contains(x.Item1.Id)).Where(x => x.Item4 != null).Select(x => x.Item4.Value).ToArray(); foreach (var user in db.Played.Where(x => x.SteamId.HasValue && remaining.Contains(x.SteamId.Value)) .GroupBy(x => x.SteamId) .Select(x => new { key = x.Key, items = x.OrderByDescending(y => y.Date).Take(7).ToList() }) .ToArray()) { var item = d.Values.FirstOrDefault(x => x.Item4 == user.key); if (item == null) { continue; } var playedLastSevenDays = TimeSpan.FromSeconds(user?.items?.Sum(x => x.TimeInSeconds) ?? 0); d[item.Item1.PlayerName] = new Tuple <Data.Player, Database.Model.User, User, long?, TimeSpan>(item.Item1, item.Item2, item.Item3, item.Item4, playedLastSevenDays); } //var playerslist = players.Select(x => { // var extra = d.ContainsKey(x.Name) ? d[x.Name] : null; // return new // { // Steam = x.Name, // Name = extra?.Item1?.Name, // Tribe = extra?.Item1?.TribeName, // Discord = extra != null && extra.Item3 != null ? $"{extra.Item3.Name}#{extra.Item3.Discriminator}" : null, // TimeOnline = x.Time.ToStringCustom(), // PlayedLastSevenDays = extra != null && extra.Item5.TotalMinutes > 1 ? extra?.Item5.ToStringCustom() : null // }; //}).ToArray(); //sb.AppendLine("```"); //sb.AppendLine(FixedWidthTableHelper.ToString(playerslist, x => x // .For(y => y.TimeOnline, "Online For", alignment: 1) // .For(y => y.PlayedLastSevenDays, "Played/last 7 days", alignment: 1))); //sb.AppendLine("```"); foreach (var player in players) { var extra = d.ContainsKey(player.Name) ? d[player.Name] : null; sb.AppendLine($"● **{player.Name}" + (extra != null && extra.Item1.Name != null ? $" ({extra.Item1.Name})" + (extra.Item1.TribeName != null ? $" [{extra.Item1.TribeName}]" : "") : "") + "**" + (extra != null && extra.Item3 != null ? $" - **{extra.Item3.Name}#{extra.Item3.Discriminator}**" : "") + (player.Time != TimeSpan.Zero ? " (" + player.Time.ToStringCustom() + ")" : "") + (extra != null && extra.Item5.TotalMinutes > 1 ? " [" + extra.Item5.ToStringCustom() + " last 7d]" : null)); } } } else { foreach (var player in players) { sb.AppendLine($"● **{player.Name}** ({player.Time.ToStringCustom()})"); } } } await CommandHelper.SendPartitioned(e.Channel, sb.ToString()); }
public async Task <ServerStatusAllViewModel> Get() { var result = new ServerStatusAllViewModel(); foreach (var context in _contextManager.Servers) { var serverContext = _contextManager.GetServer(context.Config.Key); var status = serverContext.Steam.GetServerStatusCached(); if (status == null || status.Item1 == null || status.Item2 == null) { //Server status is currently unavailable } else { var info = status.Item1; var rules = status.Item2; var playerinfos = status.Item3; var m = new Regex(@"^(?<name>.+?)\s+-\s+\(v(?<version>\d+\.\d+)\)$", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(info.Name); var name = m.Success ? m.Groups["name"].Value : info.Name; var version = m.Success ? m.Groups["version"] : null; var currentTime = rules.FirstOrDefault(x => x.Name == "DayTime_s")?.Value; var tamedDinosCount = context.TamedCreatures?.Count(); //var uploadedDinosCount = _context.Cluster?.Creatures?.Count(); var wildDinosCount = context.WildCreatures?.Count(); //var tamedDinosMax = 6000; //todo: remove hardcoded value var structuresCount = context.Structures?.Count(); var totalPlayers = context.Players?.Count(); var totalTribes = context.Tribes?.Count(); //server uptime //DateTime? serverStarted = null; //try //{ // serverStarted = Process.GetProcessesByName(_constants.ArkServerProcessName)?.FirstOrDefault()?.StartTime; //} //catch { /* ignore exceptions */ } var nextUpdate = context.ApproxTimeUntilNextUpdate; var nextUpdateTmp = nextUpdate?.ToStringCustom(); var nextUpdateString = (nextUpdate.HasValue ? (!string.IsNullOrWhiteSpace(nextUpdateTmp) ? $"~{nextUpdateTmp}" : "waiting for new update ...") : null); var lastUpdate = context.LastUpdate; var lastUpdateString = lastUpdate.ToStringWithRelativeDay(); var sr = new ServerStatusViewModel { Key = context.Config.Key, Name = name, Address = info.Address, Version = version.ToString(), OnlinePlayerCount = info.Players, OnlinePlayerMax = info.MaxPlayers, MapName = info.Map, InGameTime = currentTime, TamedCreatureCount = tamedDinosCount ?? 0, WildCreatureCount = wildDinosCount ?? 0, StructureCount = structuresCount ?? 0, PlayerCount = totalPlayers ?? 0, TribeCount = totalTribes ?? 0, LastUpdate = lastUpdateString, NextUpdate = nextUpdateString }; var players = playerinfos?.Where(x => !string.IsNullOrEmpty(x.Name)).ToArray() ?? new PlayerInfo[] { }; using (var db = _databaseContextFactory.Create()) { Dictionary <string, Tuple <ArkPlayer, Database.Model.User, User, long?, TimeSpan, ArkTribe> > d = null; if (context.Players != null) { var playerNames = players.Select(x => x.Name).ToArray(); d = context.Players.Where(x => playerNames.Contains(x.Name, StringComparer.Ordinal)).Select(x => { long steamId; return(new Tuple <ArkPlayer, Database.Model.User, User, long?, TimeSpan, ArkTribe>( x, null, null, long.TryParse(x.SteamId, out steamId) ? steamId : (long?)null, TimeSpan.Zero, null)); }).ToDictionary(x => x.Item1.Name, StringComparer.OrdinalIgnoreCase); var ids = new List <ulong>(); var steamIds = d.Values.Select(x => x.Item4).Where(x => x != null).ToArray(); foreach (var user in db.Users.Where(y => steamIds.Contains(y.SteamId))) { var item = d.Values.FirstOrDefault(x => x.Item4 == user.SteamId); if (item == null) { continue; } ids.Add(item.Item1.Id); var discordUser = (User)null; //e.User?.Client?.Servers?.Select(x => x.GetUser((ulong)user.DiscordId)).FirstOrDefault(); var playedLastSevenDays = TimeSpan.MinValue; //TimeSpan.FromSeconds(user?.Played?.OrderByDescending(x => x.Date).Take(7).Sum(x => x.TimeInSeconds) ?? 0); d[item.Item1.Name] = Tuple.Create(item.Item1, user, discordUser, item.Item4, playedLastSevenDays, item.Item1.TribeId.HasValue ? context.Tribes?.FirstOrDefault(x => x.Id == item.Item1.TribeId.Value) : null); } var remaining = d.Values.Where(x => !ids.Contains(x.Item1.Id)).Where(x => x.Item4 != null).Select(x => x.Item4.Value).ToArray(); foreach (var user in db.Played.Where(x => x.SteamId.HasValue && remaining.Contains(x.SteamId.Value)) .GroupBy(x => x.SteamId) .Select(x => new { key = x.Key, items = x.OrderByDescending(y => y.Date).Take(7).ToList() }) .ToArray()) { var item = d.Values.FirstOrDefault(x => x.Item4 == user.key); if (item == null) { continue; } var playedLastSevenDays = TimeSpan.FromSeconds(user?.items?.Sum(x => x.TimeInSeconds) ?? 0); d[item.Item1.Name] = Tuple.Create(item.Item1, item.Item2, item.Item3, item.Item4, playedLastSevenDays, item.Item1.TribeId.HasValue ? context.Tribes?.FirstOrDefault(x => x.Id == item.Item1.TribeId.Value) : null); } } //var playerslist = players.Select(x => { // var extra = d.ContainsKey(x.Name) ? d[x.Name] : null; // return new // { // Steam = x.Name, // Name = extra?.Item1?.Name, // Tribe = extra?.Item1?.TribeName, // Discord = extra != null && extra.Item3 != null ? $"{extra.Item3.Name}#{extra.Item3.Discriminator}" : null, // TimeOnline = x.Time.ToStringCustom(), // PlayedLastSevenDays = extra != null && extra.Item5.TotalMinutes > 1 ? extra?.Item5.ToStringCustom() : null // }; //}).ToArray(); foreach (var player in players) { var extra = d?.ContainsKey(player.Name) == true ? d[player.Name] : null; sr.OnlinePlayers.Add(new OnlinePlayerViewModel { SteamName = player.Name, CharacterName = extra?.Item1?.Name, TribeName = extra?.Item6?.Name, DiscordName = extra != null && extra.Item3 != null ? $"{extra.Item3.Name}#{extra.Item3.Discriminator}" : null, TimeOnline = player.Time.ToStringCustom(), TimeOnlineSeconds = (int)Math.Round(player.Time.TotalSeconds) }); } } result.Servers.Add(sr); } } foreach (var context in _contextManager.Clusters) { var cc = new ClusterStatusViewModel { Key = context.Config.Key, ServerKeys = _contextManager.Servers .Where(x => x.Config.Cluster.Equals(context.Config.Key, StringComparison.OrdinalIgnoreCase)) .Select(x => x.Config.Key).ToArray() }; result.Clusters.Add(cc); } return(result); }
public async Task <ServerStatusAllViewModel> Get() { var demoMode = IsDemoMode() ? new DemoMode() : null; var anonymize = _config.AnonymizeWebApiData; var user = WebApiHelper.GetUser(Request, _config); if (anonymize) { var serverContext = _contextManager.Servers.FirstOrDefault(); var player = serverContext?.Players.Where(x => x.Tribe != null && x.Tribe.Creatures.Any(y => y.IsBaby) && x.Tribe.Structures.OfType <ArkStructureCropPlot>().Any() && x.Tribe.Structures.OfType <ArkStructureElectricGenerator>().Any() ).OrderByDescending(x => x.Creatures.Length).FirstOrDefault(); if (player == null) { user = null; } else { user.Name = player.Name; user.SteamId = player.SteamId; user.Roles = _config.AccessControl.SelectMany(x => x.Value.Values) .SelectMany(x => x) .Distinct(StringComparer.OrdinalIgnoreCase) .OrderBy(x => x) .ToArray(); } } var result = new ServerStatusAllViewModel { User = user, AccessControl = BuildViewModelForAccessControl(_config) }; foreach (var context in _contextManager.Servers) { var serverContext = _contextManager.GetServer(context.Config.Key); var status = serverContext.Steam.GetServerStatusCached(); //if (status == null || status.Item1 == null || status.Item2 == null) //{ // //Server status is currently unavailable //} //else //{ var info = status?.Item1; var rules = status?.Item2; var playerinfos = status?.Item3; var m = info != null ? new Regex(@"^(?<name>.+?)\s+-\s+\(v(?<version>\d+\.\d+)\)?$", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(info.Name) : null; var name = m?.Success == true ? m.Groups["name"].Value : (info?.Name ?? context.Config.Key); var version = m?.Success == true ? m.Groups["version"] : null; var currentTime = rules?.FirstOrDefault(x => x.Name == "DayTime_s")?.Value; var tamedDinosCount = context.TamedCreatures?.Count(); var uploadedDinosCount = context.CloudCreatures?.Count(); var wildDinosCount = context.WildCreatures?.Count(); //var tamedDinosMax = 6000; //todo: remove hardcoded value var structuresCount = context.Structures?.Count(); var totalPlayers = context.Players?.Count(); var totalTribes = context.Tribes?.Count(); var serverStarted = _serverService.GetServerStartTime(context.Config.Key); var nextUpdate = context.ApproxTimeUntilNextUpdate; var nextUpdateTmp = nextUpdate?.ToStringCustom(); var nextUpdateString = (nextUpdate.HasValue ? (!string.IsNullOrWhiteSpace(nextUpdateTmp) ? $"~{nextUpdateTmp}" : "waiting for new update ...") : null); var lastUpdate = context.LastUpdate; var lastUpdateString = lastUpdate.ToStringWithRelativeDay(); var anonymizedServer = anonymize ? _anonymizeData.GetServer(context.Config.Key) : null; var sr = new ServerStatusViewModel { Key = anonymizedServer?.Key ?? context.Config.Key, Name = anonymizedServer?.Name ?? name, Address = anonymizedServer?.Address ?? context.Config.DisplayAddress ?? info?.Address, Version = version?.ToString(), OnlinePlayerCount = info?.Players ?? 0, OnlinePlayerMax = info?.MaxPlayers ?? 0, MapName = info?.Map, InGameTime = currentTime, TamedCreatureCount = tamedDinosCount ?? 0, CloudCreatureCount = uploadedDinosCount ?? 0, WildCreatureCount = wildDinosCount ?? 0, StructureCount = structuresCount ?? 0, PlayerCount = totalPlayers ?? 0, TribeCount = totalTribes ?? 0, LastUpdate = lastUpdateString, NextUpdate = nextUpdateString, ServerStarted = serverStarted }; if (HasFeatureAccess("home", "online")) { var onlineplayers = playerinfos?.Where(x => !string.IsNullOrEmpty(x.Name)).ToArray() ?? new PlayerInfo[] { }; if (anonymize) { int n = 0; foreach (var player in context.Players.OrderByDescending(x => x.LastActiveTime).Take(onlineplayers.Length)) { sr.OnlinePlayers.Add(new OnlinePlayerViewModel { SteamName = player.Name, CharacterName = player.CharacterName, TribeName = player.Tribe?.Name, DiscordName = null, TimeOnline = onlineplayers[n].Time.ToStringCustom(), TimeOnlineSeconds = (int)Math.Round(onlineplayers[n].Time.TotalSeconds) }); n++; } } else { using (var db = _databaseContextFactory.Create()) { // Names of online players (steam does not provide ids) var onlineplayerNames = onlineplayers.Select(x => x.Name).ToArray(); // Get the player data for each name (null when no matching name or when multiple players share the same name) var onlineplayerData = context.Players != null ? (from k in onlineplayerNames join p in context.Players on k equals p.Name into grp select grp.Count() == 1 ? grp.ElementAt(0) : null).ToArray() : new ArkPlayer[] { }; // Parse all steam ids var parsedSteamIds = onlineplayerData.Select(x => { long steamId; return(x?.SteamId != null ? long.TryParse(x.SteamId, out steamId) ? steamId : (long?)null : null); }).ToArray(); // Get the player data for each name var databaseUsers = (from k in parsedSteamIds join u in db.Users on k equals u?.SteamId into grp select grp.FirstOrDefault()).ToArray(); // Get the discord users var discordUsers = databaseUsers.Select(x => x != null ? _discordManager.GetDiscordUserNameById((ulong)x.DiscordId) : null).ToArray(); int n = 0; foreach (var player in onlineplayers) { var extra = onlineplayerData.Length > n ? new { player = onlineplayerData[n], user = databaseUsers[n], discordName = discordUsers[n] } : null; var demoPlayerName = demoMode?.GetPlayerName(); sr.OnlinePlayers.Add(new OnlinePlayerViewModel { SteamName = demoPlayerName ?? player.Name, CharacterName = demoPlayerName ?? extra?.player?.CharacterName, TribeName = demoMode?.GetTribeName() ?? extra?.player?.Tribe?.Name, DiscordName = demoMode != null ? null : extra?.discordName, TimeOnline = player.Time.ToStringCustom(), TimeOnlineSeconds = (int)Math.Round(player.Time.TotalSeconds) }); n++; } } } } else { sr.OnlinePlayers = null; } result.Servers.Add(sr); //} } foreach (var context in _contextManager.Clusters) { var cc = new ClusterStatusViewModel { Key = context.Config.Key, ServerKeys = _contextManager.Servers .Where(x => x.Config.ClusterKey.Equals(context.Config.Key, StringComparison.OrdinalIgnoreCase)) .Select(x => x.Config.Key).ToArray() }; result.Clusters.Add(cc); } return(result); }
private async void _openId_SteamOpenIdCallback(object sender, SteamOpenIdCallbackEventArgs e) { if (e.Successful) { var player = new { RealName = (string)null, PersonaName = (string)null }; try { using (var wc = new WebClient()) { var data = await wc.DownloadStringTaskAsync($@"http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={_config.SteamApiKey}&steamids={e.SteamId}"); var response = JsonConvert.DeserializeAnonymousType(data, new { response = new { players = new[] { player } } }); player = response?.response?.players?.FirstOrDefault(); } } catch { /* ignore exceptions */ } //QueryMaster.Steam.GetPlayerSummariesResponsePlayer player = null; //await Task.Factory.StartNew(() => //{ // try // { // //this results in an exception (but it is easy enough to query by ourselves) // var query = new QueryMaster.Steam.SteamQuery(_config.SteamApiKey); // var result = query?.ISteamUser.GetPlayerSummaries(new[] { e.SteamId }); // if (result == null || !result.IsSuccess) return; // player = result.ParsedResponse.Players.FirstOrDefault(); // } // catch { /* ignore exceptions */} //}); //set ark role on users when they link //foreach(var server in _discord.Servers) //{ // var user = server.GetUser(e.DiscordUserId); // var role = server.FindRoles(_config.MemberRoleName, true).FirstOrDefault(); // if (user == null || role == null) continue; // //try // //{ // // if (!user.HasRole(role)) await user.AddRoles(role); // // var p = _context.Players?.FirstOrDefault(x => { ulong steamId = 0; return ulong.TryParse(x.SteamId, out steamId) ? steamId == e.SteamId : false; }); // // if (p != null && !string.IsNullOrWhiteSpace(p.Name)) // // { // // //must be less or equal to 32 characters // // await user.Edit(nickname: p.Name.Length > 32 ? p.Name.Substring(0, 32) : p.Name); // // } // //} // //catch (HttpException) // //{ // // //could be due to the order of roles on the server. bot role with "manage roles"/"change nickname" permission must be higher up than the role it is trying to set // //} //} using (var context = _databaseContextFactory.Create()) { var user = context.Users.FirstOrDefault(x => x.DiscordId == (long)e.DiscordUserId); if (user != null) { user.RealName = player?.RealName; user.SteamDisplayName = player?.PersonaName; user.SteamId = (long)e.SteamId; user.Unlinked = false; } else { user = new Database.Model.User { DiscordId = (long)e.DiscordUserId, SteamId = (long)e.SteamId, RealName = player?.RealName, SteamDisplayName = player?.PersonaName }; context.Users.Add(user); } foreach (var associatePlayed in context.Played.Where(x => x.SteamId == (long)e.SteamId)) { associatePlayed.SteamId = null; user.Played.Add(associatePlayed); } context.SaveChanges(); } var ch = await _discord.GetUser(e.DiscordUserId).GetOrCreateDMChannelAsync(); if (ch != null) { await ch.SendMessageAsync($"Your Discord user is now linked with your Steam account! :)"); } } else { var ch = await _discord.GetUser(e.DiscordUserId).GetOrCreateDMChannelAsync(); if (ch != null) { await ch.SendMessageAsync($"Something went wrong during the linking process. Please try again later!"); } } }
public async Task Run(CommandEventArgs e) { if (_savedstate.VotingDisabled) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"the voting system is currently disabled."); return; } //!vote ban24h <player name> reason <text> //!votes //!vote alpha yes //!vote alpha no var args = CommandHelper.ParseArgs(e, new { ServerKey = "", Ban = "", Ban24h = "", Unban = "", SetTimeOfDay = "", DestroyWildDinos = false, UpdateServer = false, RestartServer = false, Reason = "", Yes = false, No = false, Veto = false, History = false, Alfa = false, Bravo = false, Charlie = false, Delta = false, Echo = false, Foxtrot = false, Golf = false, Hotel = false, India = false, Juliett = false, Kilo = false, Lima = false, Mike = false, November = false, Oscar = false, Papa = false, Quebec = false, Romeo = false, Sierra = false, Tango = false, Uniform = false, Victor = false, Whiskey = false, Xray = false, Yankee = false, Zulu = false }, x => x.For(y => y.ServerKey, noPrefix: true) .For(y => y.Ban, untilNextToken: true) .For(y => y.Unban, untilNextToken: true) .For(y => y.Ban24h, untilNextToken: true) .For(y => y.Reason, untilNextToken: true) .For(y => y.DestroyWildDinos, flag: true) .For(y => y.UpdateServer, flag: true) .For(y => y.RestartServer, flag: true) .For(y => y.Yes, flag: true) .For(y => y.No, flag: true) .For(y => y.Veto, flag: true) .For(y => y.History, flag: true) .For(y => y.Alfa, flag: true) .For(y => y.Bravo, flag: true) .For(y => y.Charlie, flag: true) .For(y => y.Delta, flag: true) .For(y => y.Echo, flag: true) .For(y => y.Foxtrot, flag: true) .For(y => y.Golf, flag: true) .For(y => y.Hotel, flag: true) .For(y => y.India, flag: true) .For(y => y.Juliett, flag: true) .For(y => y.Kilo, flag: true) .For(y => y.Lima, flag: true) .For(y => y.Mike, flag: true) .For(y => y.November, flag: true) .For(y => y.Oscar, flag: true) .For(y => y.Papa, flag: true) .For(y => y.Quebec, flag: true) .For(y => y.Romeo, flag: true) .For(y => y.Sierra, flag: true) .For(y => y.Tango, flag: true) .For(y => y.Uniform, flag: true) .For(y => y.Victor, flag: true) .For(y => y.Whiskey, flag: true) .For(y => y.Xray, flag: true) .For(y => y.Yankee, flag: true) .For(y => y.Zulu, flag: true)); var identifiers = args.Alfa || args.Bravo || args.Charlie || args.Delta || args.Echo || args.Foxtrot || args.Golf || args.Hotel || args.India || args.Juliett || args.Kilo || args.Lima || args.Mike || args.November || args.Oscar || args.Papa || args.Quebec || args.Romeo || args.Sierra || args.Tango || args.Uniform || args.Victor || args.Whiskey || args.Xray || args.Yankee || args.Zulu; var identifierStrings = TypeDescriptor.GetProperties(args.GetType()).OfType <PropertyDescriptor>().Where(x => _identifierStrings.Contains(x.Name, StringComparer.OrdinalIgnoreCase) && x.PropertyType == typeof(bool) && (bool)x.GetValue(args)).Select(x => x.Name).ToArray(); var voteStrings = TypeDescriptor.GetProperties(args.GetType()).OfType <PropertyDescriptor>().Where(x => _voteStrings.Contains(x.Name, StringComparer.OrdinalIgnoreCase) && x.PropertyType == typeof(bool) && (bool)x.GetValue(args)).Select(x => x.Name).ToArray(); var isAdminOrDev = _discord.Servers.Any(x => x.Roles.Any(y => y != null && new[] { _config.AdminRoleName, _config.DeveloperRoleName }.Contains(y.Name, StringComparer.OrdinalIgnoreCase) == true && y.Members.Any(z => z.Id == e.User.Id))); if (args == null || (identifiers && (voteStrings.Length == 0 || voteStrings.Length > 1 || identifierStrings.Length == 0 || identifierStrings.Length > 1)) //votes require an identifier and a Yes/No/Veto ) { await e.Channel.SendMessage(string.Join(Environment.NewLine, new string[] { $"**My logic circuits cannot process this command! I am just a bot after all... :(**", !string.IsNullOrWhiteSpace(SyntaxHelp) ? $"Help me by following this syntax: **!{Name}** {SyntaxHelp}" : null }.Where(x => x != null))); return; } var now = DateTime.Now; var sb = new StringBuilder(); //this should match any type of vote if (!string.IsNullOrWhiteSpace(args.Ban) || !string.IsNullOrWhiteSpace(args.Ban24h) || !string.IsNullOrWhiteSpace(args.Unban) || !string.IsNullOrWhiteSpace(args.SetTimeOfDay) || args.DestroyWildDinos || args.UpdateServer || args.RestartServer) { var serverContext = args?.ServerKey != null?_contextManager.GetServer(args.ServerKey) : null; if (serverContext == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"**Votes need to be prefixed with a server instance key.**"); return; } if (!serverContext.IsInitialized) { await e.Channel.SendMessage($"The server data is loading but is not ready yet..."); return; } if (string.IsNullOrWhiteSpace(args.Reason)) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"specifying a reason is mandatory when starting a vote."); return; } //is the user allowed to start a vote? //level >= 50 && days registered >= 7 //is the username valid? //is there already an ongoing vote for the same thing? using (var db = _databaseContextFactory.Create()) { var user = db.Users.FirstOrDefault(x => x.DiscordId == (long)e.User.Id && !x.Unlinked); if (user == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"this command can only be used after you link your Discord user with your Steam account using **!linksteam**."); return; } if (user.DisallowVoting) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"you are not allowed to vote."); return; } if (!isAdminOrDev) { var player = serverContext.Players.FirstOrDefault(x => x.SteamId != null && x.SteamId.Equals(user.SteamId.ToString())); if (player == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"we have no record of you playing in the last month which is a requirement for using this command."); return; } if (player.CharacterLevel < 50) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"you have to reach level 50 in order to initiate votes."); return; } var firstPlayed = user.Played?.Count > 0 ? user.Played?.Min(x => x.Date) : null; if (!firstPlayed.HasValue || (now - user.Played.Min(x => x.Date)).TotalDays < 7d) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"you have to have played for atleast seven days in order to initiate votes."); return; } } var availableIdentifiers = _identifierStrings.Except(db.Votes.Where(x => x.Result == VoteResult.Undecided).Select(x => x.Identifier).ToArray(), StringComparer.OrdinalIgnoreCase).ToArray(); var identifier = availableIdentifiers.Length > 0 ? availableIdentifiers.ElementAt(_rnd.Next(availableIdentifiers.Length)) : null; if (identifier == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"there are too many active votes at the moment. Please try again later."); return; } InitiateVoteResult result = null; //handling of specific types if (!string.IsNullOrWhiteSpace(args.Ban)) { result = await BanVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason, args.Ban, 365 * 24 * 50); } else if (!string.IsNullOrWhiteSpace(args.Ban24h)) { result = await BanVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason, args.Ban24h, 24); } else if (!string.IsNullOrWhiteSpace(args.Unban)) { result = await UnbanVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason, args.Unban); } else if (!string.IsNullOrWhiteSpace(args.SetTimeOfDay)) { result = await SetTimeOfDayVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason, args.SetTimeOfDay); } else if (args.DestroyWildDinos) { result = await DestroyWildDinosVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason); } else if (args.UpdateServer) { result = await UpdateServerVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason); } else if (args.RestartServer) { result = await RestartServerVoteHandler.Initiate(e.Channel, serverContext, _config, db, e.User.Id, identifier, now, args.Reason); } else { //this should never happen throw new ApplicationException("The vote type is not handled in code..."); } if (result == null || result.Vote == null) { return; } result.Vote.Votes.Add(new UserVote { InitiatedVote = true, Reason = args.Reason, VotedFor = true, User = user, UserId = user.Id, VoteType = isAdminOrDev ? UserVoteType.Admin : UserVoteType.Trusted, When = now }); db.Votes.Add(result.Vote); db.SaveChanges(); if (!string.IsNullOrWhiteSpace(result.MessageInitiator)) { await e.Channel.SendMessageDirectedAt(e.User.Id, result.MessageInitiator); } try { if (!string.IsNullOrWhiteSpace(result.MessageRcon)) { await serverContext.Steam.SendRconCommand($"serverchat {result.MessageRcon.ReplaceRconSpecialChars()}"); } if (!string.IsNullOrWhiteSpace(result.MessageAnnouncement) && !string.IsNullOrWhiteSpace(_config.AnnouncementChannel)) { var channels = _discord.Servers.Select(x => x.TextChannels.FirstOrDefault(y => _config.AnnouncementChannel.Equals(y.Name, StringComparison.OrdinalIgnoreCase))).Where(x => x != null); foreach (var channel in channels) { await channel.SendMessage(result.MessageAnnouncement); } } } catch { /*ignore all exceptions */ } serverContext.OnVoteInitiated(result.Vote); return; } } else if (identifiers && (args.Yes || args.No || args.Veto)) { if (!_context.IsInitialized) { await e.Channel.SendMessage($"The server data is loading but is not ready yet..."); return; } //does the identifier match an ongoing vote? //have the user already voted? using (var db = _databaseContextFactory.Create()) { var identifier = identifierStrings.First(); var allvotes = db.Votes.ToArray(); var votes = db.Votes.Where(x => x.Result == VoteResult.Undecided && x.Finished > now && x.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)).ToArray(); if (votes.Length == 0) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"there is no active vote with the given identifier."); return; } if (votes.Length > 1) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"there are multiple active votes with this identifier. This is a bug and the vote cannot be cast."); return; } var vote = votes.First(); if (args.Veto && !isAdminOrDev) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"you do not have this permission."); return; } var user = db.Users.FirstOrDefault(x => x.DiscordId == (long)e.User.Id && !x.Unlinked); if (user == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"this command can only be used after you link your Discord user with your Steam account using **!linksteam**."); return; } if (user.DisallowVoting) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"you are not allowed to vote."); return; } //todo: players are only considered for one server var player = _context.Players.FirstOrDefault(x => x.SteamId != null && x.SteamId.Equals(user.SteamId.ToString())); if (player == null) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"we have no record of you playing in the last month which is a requirement for using this command."); return; } string message = null; UserVote uservote = null; if ((uservote = vote.Votes.FirstOrDefault(x => x.UserId == user.Id)) != null) { //await e.Channel.SendMessageDirectedAt(e.User.Id, $"you have already voted."); //return; uservote.Reason = args.Reason; uservote.VotedFor = args.Veto ? false : args.Yes; uservote.Vetoed = args.Veto; uservote.When = now; message = $"your vote has been changed!"; } else { var firstPlayed = user.Played?.Count > 0 ? user.Played.Min(x => x.Date) : (DateTime?)null; vote.Votes.Add(new UserVote { InitiatedVote = false, Reason = args.Reason, VotedFor = args.Veto ? false : args.Yes, Vetoed = args.Veto, User = user, UserId = user.Id, VoteType = isAdminOrDev ? UserVoteType.Admin : !firstPlayed.HasValue || (now - user.Played.Min(x => x.Date)).TotalDays < 7d ? UserVoteType.NewMember : player.Level < 50 ? UserVoteType.Member : UserVoteType.Trusted, When = now }); message = $"your vote has been recorded!"; } db.SaveChanges(); if (args.Veto) { var serverContext = _contextManager.GetServer(vote.ServerKey); if (serverContext != null) { serverContext.OnVoteResultForced(vote, VoteResult.Vetoed); message = $"you have vetoed this vote."; } else { message = $"could not veto vote because there was no server key."; } } await e.Channel.SendMessageDirectedAt(e.User.Id, message); } } else { using (var db = _databaseContextFactory.Create()) { if (args.History) { var votes = db.Votes.OrderByDescending(x => x.Started).Where(x => x.Result != VoteResult.Undecided && System.Data.Entity.DbFunctions.DiffDays(now, x.Started) <= 7).ToArray(); if (votes.Length == 0) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"there appear to be no history of votes from the last seven days."); return; } sb.AppendLine("**Previous votes**"); sb.AppendLine("--------------------"); foreach (var vote in votes) { sb.AppendLine($"***{vote.Started:yyyy-MM-dd HH:mm}***"); sb.AppendLine("**" + vote.ToString() + "**"); sb.AppendLine(vote.Result == VoteResult.Passed ? ":white_check_mark: The vote passed" : vote.Result == VoteResult.Failed ? ":x: The vote failed" : vote.Result == VoteResult.Vetoed ? ":x: The vote was vetoed" : "Result is unknown").AppendLine(); } } else { var votes = db.Votes.OrderByDescending(x => x.Started).Where(x => x.Result == VoteResult.Undecided).ToArray(); if (votes.Length == 0) { await e.Channel.SendMessageDirectedAt(e.User.Id, $"there are no active votes at this time."); return; } sb.AppendLine("**Active Votes**"); sb.AppendLine("--------------------"); foreach (var vote in votes) { sb.AppendLine("**" + vote.ToString() + "**"); sb.AppendLine($"To vote use the command: **!vote {vote.Identifier} yes**/**no**").AppendLine(); } } } } var msg = sb.ToString(); if (!string.IsNullOrWhiteSpace(msg)) { await CommandHelper.SendPartitioned(e.Channel, sb.ToString()); } }
public async Task Run(CommandEventArgs e) { //if (!e.Channel.IsPrivate) return; var args = CommandHelper.ParseArgs(e, new { ServerKey = "", StartServer = false, ShutdownServer = false, StopServer = false, RestartServer = false, UpdateServer = false, Backups = false, SaveWorld = false, DestroyWildDinos = false, EnableVoting = false, SetVotingAllowed = 0L, //steam id KickPlayer = 0L, //steam id BanPlayer = 0L, //steam id UnbanPlayer = 0L, //steam id KillPlayer = 0L, //ark player id DoExit = false, Broadcast = "", ListPlayers = false, RenamePlayer = "", RenameTribe = "", NewName = "", ServerChat = "", ServerChatTo = 0L, //steam id ServerChatToPlayer = "", Message = "", GetPlayerIDForSteamID = 0L, //steam id GetSteamIDForPlayerID = 0L, //ark player id GetTribeIdPlayerList = 0L, SetTimeOfDay = "", Countdown = "", True = false, False = false }, x => x.For(y => y.ServerKey, noPrefix: true, isRequired: true) .For(y => y.StartServer, flag: true) .For(y => y.ShutdownServer, flag: true) .For(y => y.StopServer, flag: true) .For(y => y.RestartServer, flag: true) .For(y => y.UpdateServer, flag: true) .For(y => y.Backups, flag: true) .For(y => y.SaveWorld, flag: true) .For(y => y.DestroyWildDinos, flag: true) .For(y => y.EnableVoting, flag: true) .For(y => y.DoExit, flag: true) .For(y => y.ListPlayers, flag: true) .For(y => y.Broadcast, untilNextToken: true) .For(y => y.RenamePlayer, untilNextToken: true) .For(y => y.RenameTribe, untilNextToken: true) .For(y => y.NewName, untilNextToken: true) .For(y => y.ServerChat, untilNextToken: true) .For(y => y.ServerChatToPlayer, untilNextToken: true) .For(y => y.Message, untilNextToken: true) .For(y => y.Countdown, untilNextToken: true) .For(y => y.True, flag: true) .For(y => y.False, flag: true)); var _rTimeOfDay = new Regex(@"^\s*\d{2,2}\:\d{2,2}(\:\d{2,2})?\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase); var _rCountdown = new Regex(@"^\s*(?<min>\d+)\s+(?<reason>.+)$", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); var sb = new StringBuilder(); var serverContext = args?.ServerKey != null?_contextManager.GetServer(args.ServerKey) : null; if (serverContext == null) { await e.Channel.SendMessage($"**Admin commands need to be prefixed with a valid server instance key.**"); return; } if (args.StartServer) { await _arkServerService.StartServer(serverContext.Config.Key, (s) => e.Channel.SendMessageDirectedAt(e.User.Id, s)); } else if (args.Countdown == null && (args.ShutdownServer || args.StopServer)) { await _arkServerService.ShutdownServer(serverContext.Config.Key, (s) => e.Channel.SendMessageDirectedAt(e.User.Id, s)); } else if (args.Countdown == null && args.RestartServer) { await _arkServerService.RestartServer(serverContext.Config.Key, (s) => e.Channel.SendMessageDirectedAt(e.User.Id, s)); } else if (args.Countdown == null && args.UpdateServer) { await _arkServerService.UpdateServer(serverContext.Config.Key, (s) => e.Channel.SendMessageDirectedAt(e.User.Id, s), (s) => e.Channel.GetMessageDirectedAtText(e.User.Id, s), 300); } else if (args.SaveWorld) { await _arkServerService.SaveWorld(serverContext.Config.Key, (s) => e.Channel.SendMessageDirectedAt(e.User.Id, s), 180); } else if (args.Backups) { var result = _savegameBackupService.GetBackupsList(serverContext.Config.Key); if (result?.Count > 0) { var data = result.OrderByDescending(x => x.DateModified).Take(25).Select(x => new { Path = x.Path, Age = (DateTime.Now - x.DateModified).ToStringCustom(), FileSize = x.ByteSize.ToFileSize() }).ToArray(); var table = FixedWidthTableHelper.ToString(data, x => x .For(y => y.Path, header: "Backup") .For(y => y.Age, alignment: 1) .For(y => y.FileSize, header: "File Size", alignment: 1)); sb.Append($"```{table}```"); } else { sb.AppendLine("**Could not find any savegame backups...**"); } } else if (args.DestroyWildDinos) { var result = await serverContext.Steam.SendRconCommand("destroywilddinos"); if (result == null) { sb.AppendLine("**Failed to wipe wild dinos... :(**"); } else { sb.AppendLine("**Wild dinos wiped!**"); } } else if (args.DoExit) { var result = await serverContext.Steam.SendRconCommand("doexit"); if (result == null) { sb.AppendLine("**Failed to shutdown server... :(**"); } else { sb.AppendLine("**Server shutting down!**"); } } else if (args.ListPlayers) { var result = await serverContext.Steam.SendRconCommand("listplayers"); if (result == null) { sb.AppendLine("**Failed to get a list of players... :(**"); } else { sb.AppendLine(result); } } else if (!string.IsNullOrWhiteSpace(args.Broadcast)) { var result = await serverContext.Steam.SendRconCommand($"broadcast {args.Broadcast}"); if (result == null) { sb.AppendLine("**Failed to broadcast message... :(**"); } else { sb.AppendLine("**Broadcast successfull!**"); } } else if (!string.IsNullOrWhiteSpace(args.ServerChat)) { var result = await serverContext.Steam.SendRconCommand($"serverchat {args.ServerChat}"); if (result == null) { sb.AppendLine("**Failed to send chat message... :(**"); } else { sb.AppendLine("**Chat message send!**"); } } else if (args.ServerChatTo > 0 && !string.IsNullOrWhiteSpace(args.Message)) { var result = await serverContext.Steam.SendRconCommand($@"serverchatto {args.ServerChatTo} ""{args.Message}"""); if (result == null) { sb.AppendLine("**Failed to send direct chat message... :(**"); } else { sb.AppendLine("**Direct chat message send!**"); } } else if (!string.IsNullOrWhiteSpace(args.ServerChatToPlayer) && !string.IsNullOrWhiteSpace(args.Message)) { var result = await serverContext.Steam.SendRconCommand($@"serverchattoplayer ""{args.ServerChatToPlayer}"" ""{args.Message}"""); if (result == null) { sb.AppendLine("**Failed to send direct chat message... :(**"); } else { sb.AppendLine("**Direct chat message send!**"); } } else if (!string.IsNullOrWhiteSpace(args.RenamePlayer) && !string.IsNullOrWhiteSpace(args.NewName)) { var result = await serverContext.Steam.SendRconCommand($@"renameplayer ""{args.RenamePlayer}"" {args.NewName}"); if (result == null) { sb.AppendLine("**Failed to rename player... :(**"); } else { sb.AppendLine("**Player renamed!**"); } } else if (!string.IsNullOrWhiteSpace(args.RenameTribe) && !string.IsNullOrWhiteSpace(args.NewName)) { var result = await serverContext.Steam.SendRconCommand($@"renametribe ""{args.RenameTribe}"" {args.NewName}"); if (result == null) { sb.AppendLine("**Failed to rename tribe... :(**"); } else { sb.AppendLine("**Tribe renamed!**"); } } else if (!string.IsNullOrWhiteSpace(args.SetTimeOfDay) && _rTimeOfDay.IsMatch(args.SetTimeOfDay)) { var result = await serverContext.Steam.SendRconCommand($"settimeofday {args.SetTimeOfDay}"); if (result == null) { sb.AppendLine("**Failed to set time of day... :(**"); } else { sb.AppendLine("**Time of day set!**"); } } else if (args.KickPlayer > 0) { var result = await serverContext.Steam.SendRconCommand($"kickplayer {args.KickPlayer}"); if (result == null) { sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); } else { sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); } } else if (args.EnableVoting) { if (!(args.True || args.False)) { sb.AppendLine($"**This command requires additional arguments!**"); } else { using (var context = _databaseContextFactory.Create()) { _savedstate.VotingDisabled = !args.True; _savedstate.Save(); sb.AppendLine($"**Voting system is now {(_savedstate.VotingDisabled ? "disabled" : "enabled")}!**"); } } //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); } else if (args.SetVotingAllowed > 0) { if (!(args.True || args.False)) { sb.AppendLine($"**This command requires additional arguments!**"); } else { using (var context = _databaseContextFactory.Create()) { var user = context.Users.FirstOrDefault(x => x != null && x.DiscordId == (long)e.User.Id); if (user != null) { user.DisallowVoting = !args.True; context.SaveChanges(); sb.AppendLine($"**The user is now {(user.DisallowVoting ? "unable" : "allowed")} to vote!**"); } else { sb.AppendLine($"**The user is not linked!**"); } } } //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); } else if (args.BanPlayer > 0) { var result = await serverContext.Steam.SendRconCommand($"ban {args.BanPlayer}"); if (result == null) { sb.AppendLine($"**Failed to ban player with steamid {args.BanPlayer}... :(**"); } else { sb.AppendLine($"**Banned player with steamid {args.BanPlayer}!**"); } } else if (args.UnbanPlayer > 0) { var result = await serverContext.Steam.SendRconCommand($"unban {args.UnbanPlayer}"); if (result == null) { sb.AppendLine($"**Failed to unban player with steamid {args.UnbanPlayer}... :(**"); } else { sb.AppendLine($"**Unbanned player with steamid {args.UnbanPlayer}!**"); } } else if (args.KillPlayer > 0) { var result = await serverContext.Steam.SendRconCommand($"killplayer {args.KillPlayer}"); if (result == null) { sb.AppendLine($"**Failed to kill player with id {args.KillPlayer}... :(**"); } else { sb.AppendLine($"**Killed player with id {args.KillPlayer}!**"); } } else if (args.GetSteamIDForPlayerID > 0) { var result = await serverContext.Steam.SendRconCommand($"GetSteamIDForPlayerID {args.GetSteamIDForPlayerID}"); if (result == null) { sb.AppendLine($"**Failed to get steamid from id {args.GetSteamIDForPlayerID}... :(**"); } else { sb.AppendLine(result); } } else if (args.GetPlayerIDForSteamID > 0) { var result = await serverContext.Steam.SendRconCommand($"GetPlayerIDForSteamID {args.GetPlayerIDForSteamID}"); if (result == null) { sb.AppendLine($"**Failed to get id from steamid {args.GetPlayerIDForSteamID}... :(**"); } else { sb.AppendLine(result); } } else if (args.GetTribeIdPlayerList > 0) { var result = await serverContext.Steam.SendRconCommand($"GetTribeIdPlayerList {args.GetTribeIdPlayerList}"); if (result == null) { sb.AppendLine("**Failed to get a list of players in tribe... :(**"); } else { sb.AppendLine(result); } } else if (!string.IsNullOrEmpty(args.Countdown) && _rCountdown.IsMatch(args.Countdown)) { var m = _rCountdown.Match(args.Countdown); var reason = m.Groups["reason"].Value; var delayInMinutes = int.Parse(m.Groups["min"].Value); if (delayInMinutes < 1) { delayInMinutes = 1; } Func <Task> react = null; if (args.StopServer || args.ShutdownServer) { react = new Func <Task>(async() => { string message = null; if (!await _arkServerService.ShutdownServer(serverContext.Config.Key, (s) => { message = s; return(Task.FromResult((Message)null)); })) { Logging.Log($@"Countdown to shutdown server ({serverContext.Config.Key}) execution failed (""{message ?? ""}"")", GetType(), LogLevel.DEBUG); } }); } else if (args.UpdateServer) { react = new Func <Task>(async() => { string message = null; if (!await _arkServerService.UpdateServer(serverContext.Config.Key, (s) => { message = s; return(Task.FromResult((Message)null)); }, (s) => s.FirstCharToUpper(), 300)) { Logging.Log($@"Countdown to update server ({serverContext.Config.Key}) execution failed (""{message ?? ""}"")", GetType(), LogLevel.DEBUG); } }); } else if (args.RestartServer) { react = new Func <Task>(async() => { string message = null; if (!await _arkServerService.RestartServer(serverContext.Config.Key, (s) => { message = s; return(Task.FromResult((Message)null)); })) { Logging.Log($@"Countdown to restart server ({serverContext.Config.Key}) execution failed (""{message ?? ""}"")", GetType(), LogLevel.DEBUG); } }); } sb.AppendLine($"**Countdown have been initiated. Announcement will be made.**"); await _scheduledTasksManager.StartCountdown(serverContext, reason, delayInMinutes, react); } else { await e.Channel.SendMessage(string.Join(Environment.NewLine, new string[] { $"**My logic circuits cannot process this command! I am just a bot after all... :(**", !string.IsNullOrWhiteSpace(SyntaxHelp) ? $"Help me by following this syntax: **!{Name}** {SyntaxHelp}" : null }.Where(x => x != null))); return; } var msg = sb.ToString(); if (!string.IsNullOrWhiteSpace(msg)) { await CommandHelper.SendPartitioned(e.Channel, sb.ToString()); } }
private async Task UpdateNicknamesAndRoles(Server _server = null) { try { //change nicknames, add/remove from ark-role Database.Model.User[] linkedusers = null; using (var db = _databaseContextFactory.Create()) { linkedusers = db.Users.Where(x => !x.Unlinked).ToArray(); } foreach (var server in _discord.Servers) { if (_server != null && server.Id != _server.Id) { continue; } var role = server.FindRoles(_config.MemberRoleName, true).FirstOrDefault(); if (role == null) { continue; } foreach (var user in server.Users) { try { var dbuser = linkedusers.FirstOrDefault(x => (ulong)x.DiscordId == user.Id); if (dbuser == null) { if (user.HasRole(role)) { Logging.Log($@"Removing role ({role.Name}) from user ({user.Name}#{user.Discriminator})", GetType(), LogLevel.DEBUG); await user.RemoveRoles(role); } continue; } if (!user.HasRole(role)) { Logging.Log($@"Adding role ({role.Name}) from user ({user.Name}#{user.Discriminator})", GetType(), LogLevel.DEBUG); await user.AddRoles(role); } var player = _context.Players?.FirstOrDefault(x => { long steamId = 0; return(long.TryParse(x.SteamId, out steamId) ? steamId == dbuser.SteamId : false); }); var playerName = player?.Name?.Length > 32 ? player?.Name?.Substring(0, 32) : player?.Name; if (!string.IsNullOrWhiteSpace(playerName) && !user.ServerPermissions.Administrator && !playerName.Equals(user.Name, StringComparison.Ordinal) && (user.Nickname == null || !playerName.Equals(user.Nickname, StringComparison.Ordinal))) { //must be less or equal to 32 characters Logging.Log($@"Changing nickname (from: ""{user.Nickname ?? "null"}"", to: ""{playerName}"") for user ({user.Name}#{user.Discriminator})", GetType(), LogLevel.DEBUG); await user.Edit(nickname : playerName); } } catch (HttpException ex) { //could be due to the order of roles on the server. bot role with "manage roles"/"change nickname" permission must be higher up than the role it is trying to set Logging.LogException("HttpException while trying to update nicknames/roles (could be due to permissions)", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); } } } } catch (WebException ex) { Logging.LogException("Exception while trying to update nicknames/roles", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); } }