예제 #1
0
        public string Get(int?playerId, int?tribeId)
        {
            if (playerId == null && tribeId == null)
            {
                return(null);                                     //both cannot be null
            }
            var player = playerId.HasValue ? _context.Players?.FirstOrDefault(x => x.Id == playerId.Value) : null;
            var tribe  = tribeId.HasValue ? _context.Tribes?.FirstOrDefault(x => x.Id == tribeId.Value) : null;

            var inv = new[] { player?.Inventory, tribe?.Items }.Where(x => x != null).SelectMany(x => x).ToArray();

            var includedResources = new[]
            {
                "Hide", "Thatch", "Cementing Paste", "Fiber", "Narcotic", "Spoiled Meat", "Raw Meat",
                "Wood", "Chitin", "Flint", "Silica Pearls", "Metal Ingot", "Obsidian", "Stone",
                "Keratin", "Cooked Meat Jerky", "Oil", "Prime Meat Jerky", "Pelt", "Crystal",
                "Narcoberry", "Mejoberry", "Stimberry",
                "Amarberry", "Azulberry", "Tintoberry",
                "Black Pearl", "Element"
            };

            var combined          = new Dictionary <string, string[]> {
                { "Chitin/Keratin", new [] { "Chitin", "Keratin", "Chitin/Keratin" } },
                { "Editable berries", new [] { "Amarberry", "Azulberry", "Tintoberry", "Mejoberry" } }
            };

            var resources = inv.Where(x => includedResources.Contains(x.Name, StringComparer.OrdinalIgnoreCase))
                            .GroupBy(x => x.Name)
                            .Select(x => new EntityNameWithCount {
                Name = x.Key, Count = x.Sum(y => y.Count)
            })
                            .ToList();

            var n = combined.Select(c => new EntityNameWithCount {
                Name = c.Key, Count = resources.Where(x => c.Value.Contains(x.Name, StringComparer.OrdinalIgnoreCase)).Sum(x => x.Count)
            }).ToArray();
            var remove = combined.SelectMany(y => y.Value).Except(new[] { "Mejoberry" }).ToArray();

            resources.RemoveAll(x => remove.Contains(x.Name));
            n = n.Where(x => x.Count > 0).ToArray();

            resources = (n.Length > 0 ? resources.Concat(n) : resources).OrderBy(x => x.Name).ToList();

            if (resources.Count == 0)
            {
                return(null);
            }

            var sb = new StringBuilder();

            sb.AppendLine("```");
            sb.AppendLine(FixedWidthTableHelper.ToString(resources, x => x
                                                         .For(y => y.Name, "Type")
                                                         .For(y => y.Count, null, 1, "N0")));
            sb.AppendLine("```");

            return(sb.ToString());
        }
예제 #2
0
        /// <summary>
        /// Convert backup list entries into a fixed width table
        /// </summary>
        string OutputCloudBackupListingTable(IEnumerable <BackupListEntity> result, int skip, int take = 25)
        {
            var data = result.OrderByDescending(x => x.DateModified).Skip(skip).Take(take).Select(x => new
            {
                Path       = $"{x.Path}",
                BackupHash = x.Path.GetHashCode(),
                Age        = (DateTime.Now - x.DateModified).ToStringCustom(),
                Files      = x.Files.Length,
                FileSize   = x.ByteSize.ToFileSize()
            }).ToArray();

            var table = FixedWidthTableHelper.ToString(data, x => x
                                                       .For(y => y.Path, header: "Cloud Save Backup")
                                                       .For(y => y.BackupHash, header: "Backup Hash", alignment: 1, format: "X")
                                                       .For(y => y.Age, alignment: 1)
                                                       .For(y => y.Files, header: "Saves", alignment: 1)
                                                       .For(y => y.FileSize, header: "File Size", alignment: 1));

            return($"```{table}```");
        }
예제 #3
0
        internal string Get(int?playerId, int?tribeId, bool sortByEggs = false)
        {
            if (playerId == null && tribeId == null)
            {
                return(null);                                     //both cannot be null
            }
            var player = playerId.HasValue ? _context.Players?.FirstOrDefault(x => x.Id == playerId.Value) : null;
            var tribe  = tribeId.HasValue ? _context.Tribes?.FirstOrDefault(x => x.Id == tribeId.Value) : null;

            var inv = new[] { player?.Inventory, tribe?.Items }.Where(x => x != null).SelectMany(x => x).ToArray();

            var _rEgg    = new Regex(@"^(?<name>.+?)\s+Egg$", RegexOptions.Singleline);
            var _rKibble = new Regex(@"^Kibble\s+\((?<name>.+?)\s+Egg\)$", RegexOptions.IgnoreCase | RegexOptions.Singleline);

            var kibbles = inv.Where(x => x.Name.StartsWith("Kibble", StringComparison.Ordinal))
                          .GroupBy(x => x.Name)
                          .Select(x => new EntityNameWithCount {
                Name = _rKibble.Match(x.Key, m => m.Success ? m.Groups["name"].Value : x.Key), Count = x.Sum(y => y.Count)
            })
                          .ToArray();

            var eggs = inv.Where(x => x.Name.EndsWith("Egg", StringComparison.Ordinal) && !x.Name.StartsWith("Fertilized"))
                       .GroupBy(x => x.Name)
                       .Select(x => new EntityNameWithCount {
                Name = _rEgg.Match(x.Key, m => m.Success ? m.Groups["name"].Value : x.Key), Count = x.Sum(y => y.Count)
            })
                       .ToList();

            var results = kibbles.Select(x =>
            {
                var aliases = ArkSpeciesAliases.Instance.GetAliases(x.Name);
                var egg     = aliases == null || aliases.Length == 0 ? null : eggs.FirstOrDefault(y =>
                {
                    return(aliases.Contains(y.Name, StringComparer.OrdinalIgnoreCase));
                });
                if (egg != null)
                {
                    eggs.Remove(egg);
                }
                return(new
                {
                    Name = x.Name,
                    Count = x.Count,
                    EggCount = egg?.Count ?? 0
                });
            }).Concat(eggs.Select(x => new
            {
                Name     = x.Name,
                Count    = 0,
                EggCount = x.Count
            })).OrderByDescending(x => sortByEggs ? x.EggCount : x.Count).ThenByDescending(x => sortByEggs ? x.Count : x.EggCount).ToArray();

            if (results.Length == 0)
            {
                return(null);
            }

            var sb = new StringBuilder();

            sb.AppendLine("```");
            sb.AppendLine(FixedWidthTableHelper.ToString(results, x => x
                                                         .For(y => y.Name, "Type")
                                                         .For(y => y.EggCount, "Eggs", 1, "N0", total: true)
                                                         .For(y => y.Count, "Kibbles", 1, "N0", total: true)));
            sb.AppendLine("```");

            return(sb.ToString());
        }
예제 #4
0
        public async Task Run(CommandEventArgs e)
        {
            if (!e.Channel.IsPrivate)
            {
                return;
            }

            var args = CommandHelper.ParseArgs(e, new
            {
                resources = false, kibbles = false, eggs = false, structures = false, blueprints = false, @base = false,
                tribelog  = false, tribelogs = false, engrams = false, id = false, ids = false, steamid = false,
                noprefix  = "", player = "", tribe = "", raw = false
            }, x =>
                                               x.For(y => y.resources, flag: true)
                                               .For(y => y.kibbles, flag: true)
                                               .For(y => y.eggs, flag: true)
                                               .For(y => y.structures, flag: true)
                                               .For(y => y.blueprints, flag: true)
                                               .For(y => y.@base, flag: true)
                                               .For(y => y.tribelog, flag: true)
                                               .For(y => y.tribelogs, flag: true)
                                               .For(y => y.engrams, flag: true)
                                               .For(y => y.id, flag: true)
                                               .For(y => y.ids, flag: true)
                                               .For(y => y.steamid, flag: true)
                                               .For(y => y.noprefix, noPrefix: true, untilNextToken: true)
                                               .For(y => y.player, untilNextToken: true)
                                               .For(y => y.tribe, untilNextToken: true)
                                               .For(y => y.raw, flag: true));

            var playerandtribe = args != null && (args.resources || args.kibbles || args.eggs || args.structures || args.blueprints || args.@base);
            var playeronly     = args != null && (args.id || args.ids || args.steamid || args.engrams);
            var tribeonly      = args != null && (args.tribelog || args.tribelogs);

            if (args == null ||
                (playerandtribe && (string.IsNullOrWhiteSpace(args.player) && string.IsNullOrWhiteSpace(args.tribe))) ||
                (playeronly && string.IsNullOrWhiteSpace(args.player) && string.IsNullOrWhiteSpace(args.noprefix)) ||
                (tribeonly && string.IsNullOrWhiteSpace(args.tribe) && string.IsNullOrWhiteSpace(args.noprefix)))
            {
                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 pname = args.player ?? (playeronly ? args.noprefix : null);
            var tname = args.tribe ?? (tribeonly ? args.noprefix : null);

            var player = new Lazy <Data.Player>(() =>
                                                !string.IsNullOrEmpty(pname) ? _context.Players?.FirstOrDefault(x => (x?.Name != null && x.Name.Equals(pname, StringComparison.OrdinalIgnoreCase)) || (x?.PlayerName != null && x.PlayerName.Equals(pname, StringComparison.OrdinalIgnoreCase))) : null);
            var tribe = new Lazy <Data.Tribe>(() =>
                                              !string.IsNullOrEmpty(tname) ? _context.Tribes?.FirstOrDefault(x => x?.Name != null && x.Name.Equals(tname, StringComparison.OrdinalIgnoreCase)) : null);
            var playertribeortribe = new Lazy <Data.Tribe>(() =>
                                                           player.Value != null ? (player.Value.TribeId != null ? _context.Tribes?.FirstOrDefault(x => x.Id == player.Value.TribeId.Value) : null) : (!string.IsNullOrEmpty(tname) ? _context.Tribes?.FirstOrDefault(x => x?.Name != null && x.Name.Equals(tname, StringComparison.OrdinalIgnoreCase)) : null));
            var namelabel = new Lazy <string>(() =>
                                              (playerandtribe || playeronly) && playertribeortribe.IsValueCreated && playertribeortribe.Value?.Name != null ? playertribeortribe.Value?.Name
                : (tribeonly) && tribe.IsValueCreated && tribe.Value?.Name != null ? tribe.Value?.Name
                : (playerandtribe || playeronly) && player.IsValueCreated && player.Value?.Name != null ? player.Value.Name
                : playerandtribe ? "Player/Tribe" : tribeonly ? "Tribe" : playeronly ? "Player" : "Entity");

            var sb = new StringBuilder();

            if (args.id || args.ids || args.steamid)
            {
                var name    = args.player ?? args.noprefix;
                var matches = _context.Players?.Where(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase) || x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase)).ToArray();
                if (matches.Length == 0)
                {
                    sb.AppendLine("**Could not find the specified player name...**");
                }
                else
                {
                    sb.AppendLine("**Matching players**");
                    var playerslist = matches.Select(x => new
                    {
                        Steam   = x.Name,
                        Name    = x.PlayerName,
                        Tribe   = x.TribeName,
                        Id      = x.Id,
                        SteamId = x.SteamId
                    }).ToArray();

                    sb.AppendLine("```");
                    sb.AppendLine(FixedWidthTableHelper.ToString(playerslist, x => x
                                                                 .For(y => y.Id, "Id", alignment: 1)
                                                                 .For(y => y.SteamId, "SteamId", alignment: 1)));
                    sb.AppendLine("```");
                }
            }
            else if (args.resources)
            {
                if (player.Value == null && playertribeortribe.Value == null)
                {
                    sb.AppendLine("**Could not find the specified player or tribe...**");
                }
                else
                {
                    var result = _myresources.Get(player.Value?.Id, playertribeortribe.Value?.Id);
                    if (result == null)
                    {
                        sb.AppendLine($"**It appears that {namelabel.Value} do not have any Resources...**");
                    }
                    else
                    {
                        sb.AppendLine($"**{namelabel.Value} have these Resources**");
                        sb.Append(result);
                    }
                }
            }
            else if (args.kibbles || args.eggs)
            {
                if (player.Value == null && playertribeortribe.Value == null)
                {
                    sb.AppendLine("**Could not find the specified player or tribe...**");
                }
                else
                {
                    var kibbleoregg = args.eggs ? "Eggs" : "Kibbles";
                    var result      = _mykibbles.Get(player.Value?.Id, playertribeortribe.Value?.Id, args.eggs);
                    if (result == null)
                    {
                        sb.AppendLine($"**It appears that {namelabel.Value} do not have any {kibbleoregg}...**");
                    }
                    else
                    {
                        sb.AppendLine($"**{namelabel.Value} have these {kibbleoregg }* *");
                        sb.Append(result);
                    }
                }
            }
            else if (args.structures)
            {
                //not implemented
                sb.AppendLine("**Not yet implemented... :(**");
            }
            else if (args.blueprints)
            {
                //not implemented
                sb.AppendLine("**Not yet implemented... :(**");
            }
            else if (args.@base)
            {
                //not implemented
                sb.AppendLine("**Not yet implemented... :(**");
            }
            else if (args.tribelog || args.tribelogs)
            {
                if (tribe.Value == null)
                {
                    sb.AppendLine("**Could not find the specified tribe name...**");
                }
                else if (!(tribe.Value.TribeLog?.Length > 0))
                {
                    sb.AppendLine($"**There are no tribe logs for {namelabel.Value}...**");
                }
                else
                {
                    var path = FileHelper.GetAvailableFilePathSequential(Path.Combine(_config.TempFileOutputDirPath, "tribelog.txt"));
                    try
                    {
                        if (!args.raw)
                        {
                            File.WriteAllLines(path, tribe.Value.TribeLog.Select(x => Data.TribeLog.FromLog(x).ToStringPretty()).ToArray());
                        }
                        else
                        {
                            File.WriteAllLines(path, tribe.Value.TribeLog);
                        }
                        await e.Channel.SendFile(path);
                    }
                    finally
                    {
                        if (File.Exists(path))
                        {
                            File.Delete(path);
                        }
                    }
                }
            }
            else if (args.engrams)
            {
                //not implemented
                sb.AppendLine("**Not yet implemented... :(**");
            }
            var msg = sb.ToString();

            if (!string.IsNullOrWhiteSpace(msg))
            {
                await CommandHelper.SendPartitioned(e.Channel, sb.ToString());
            }
        }
예제 #5
0
        public async Task Cloud([Remainder] string arguments = null)
        {
            var args = CommandHelper.ParseArgs(arguments, new
            {
                ClusterKey = "",
                Backup     = 0L,
                Stash      = 0L,
                Pop        = 0L,
                Delete     = 0L,
                List       = 0L,
                Details    = 0L,
                Restore    = 0L,
                Target1    = "",
                Target2    = "",
                Skip       = 0
            }, x =>
                                               x.For(y => y.ClusterKey, noPrefix: true)
                                               .For(y => y.Target1, noPrefix: true)
                                               .For(y => y.Target2, noPrefix: true));

            var sb           = new StringBuilder();
            var r_allowedExt = new Regex(@"^(?!tmpprofile)([a-z0-9])+$", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            //for details and restore commands, get hashes from target1 and target2
            int?backupHash = null, cloudSaveHash = null;

            if (args.Details > 0 || args.Restore > 0)
            {
                try
                {
                    backupHash = !string.IsNullOrWhiteSpace(args.Target1) ? (int?)Convert.ToInt32(args.Target1, 16) : null;
                }
                catch { /*ignore exceptions*/ }
            }
            if (args.Restore > 0)
            {
                try
                {
                    cloudSaveHash = !string.IsNullOrWhiteSpace(args.Target2) ? (int?)Convert.ToInt32(args.Target2, 16) : null;
                }
                catch { /*ignore exceptions*/ }
            }

            // for stash and pop commands, check that target1 is a valid tag
            if ((args.Stash > 0 || args.Pop > 0) && !r_allowedExt.IsMatch(args.Target1))
            {
                await Context.Channel.SendMessageAsync($"**The supplied tag is not allowed (only a-z, 0-9)!**");

                return;
            }

            // check that the cluster key is valid
            ArkClusterContext clusterContext = args.ClusterKey != null?_contextManager.GetCluster(args.ClusterKey) : null;

            if (clusterContext == null)
            {
                await Context.Channel.SendMessageAsync($"**Cloud commands need to be prefixed with a valid cluster key.**");

                return;
            }

            // check that there are one or more servers in the cluster
            var serverContexts = _contextManager.GetServersInCluster(clusterContext.Config.Key);

            if (!(serverContexts?.Length > 0))
            {
                await Context.Channel.SendMessageAsync($"**There are no servers in the cluster.**");

                return;
            }

            /* ---------------------------------------------------------------
            *  List cloud save backups available for a given player.
            *  --------------------------------------------------------------- */
            if (args.List > 0)
            {
                var result = GetBackupFiles(clusterContext.Config, serverContexts.Select(x => x.Config.Key).ToArray(), args.List);

                if (result.Count > 0)
                {
                    var tbl = OutputCloudBackupListingTable(result, args.Skip);
                    sb.Append(tbl);
                }
                else
                {
                    sb.AppendLine("**Could not find any cloud save backups...**");
                }
            }

            /* ---------------------------------------------------------------
            *  Stash the current cloud save with a given tag to fetch at a later time.
            *  --------------------------------------------------------------- */
            else if (args.Stash > 0)
            {
                var result = _savegameBackupService.StashCloudSave(clusterContext.Config, args.Stash, args.Target1);
                if (result == StashResult.Successfull)
                {
                    sb.AppendLine($"**Cloud save stashed as '{args.Target1}'!**");
                }
                else if (result == StashResult.SourceMissing)
                {
                    sb.AppendLine("**There is no cloud save to stash...**");
                }
                else if (result == StashResult.TargetExists)
                {
                    sb.AppendLine("**The supplied tag is already being used...**");
                }
                else
                {
                    sb.AppendLine("**Failed to stash cloud save...**");
                }
            }

            /* ---------------------------------------------------------------
            *  Fetch a cloud save previously stashed with a given tag and set it as the current cloud save.
            *  --------------------------------------------------------------- */
            else if (args.Pop > 0)
            {
                var result = _savegameBackupService.PopCloudSave(clusterContext.Config, args.Pop, args.Target1);
                if (result == StashResult.Successfull)
                {
                    sb.AppendLine($"**Cloud save popped from '{args.Target1}'!**");
                }
                else if (result == StashResult.SourceMissing)
                {
                    sb.AppendLine("**The supplied tag does not exist...**");
                }
                else if (result == StashResult.TargetExists)
                {
                    sb.AppendLine("**A cloud save already exists, please delete/stash it before popping...**");
                }
                else
                {
                    sb.AppendLine("**Failed to pop cloud save...**");
                }
            }

            /* ---------------------------------------------------------------
            *  Delete the current cloud save for a given player.
            *  --------------------------------------------------------------- */
            else if (args.Delete > 0)
            {
                var targetPath = Path.Combine(clusterContext.Config.SavePath, $"{args.Delete}");
                if (File.Exists(targetPath))
                {
                    try
                    {
                        File.Delete(targetPath);
                        sb.AppendLine($"**Cloud save deleted!**");
                    }
                    catch
                    {
                        sb.AppendLine($"**Failed to delete cloud save...**");
                    }
                }
                else
                {
                    sb.AppendLine($"**There is no cloud save to delete...**");
                }
            }

            /* ---------------------------------------------------------------
            *  Create a backup of all cloud save files for a given player (including stashed, .tmpprofile etc.)
            *  --------------------------------------------------------------- */
            else if (args.Backup > 0)
            {
                var result = _savegameBackupService.CreateClusterBackupForSteamId(clusterContext.Config, args.Backup);
                if (result != null && result.ArchivePaths?.Length > 0)
                {
                    sb.AppendLine($"**Cloud save backup successfull!**");
                }
                else
                {
                    sb.AppendLine("**Failed to backup cloud save...**");
                }
            }

            /* ---------------------------------------------------------------
            *  Get detailed information for a single backup archive or cloud save file.
            *  --------------------------------------------------------------- */
            else if (args.Details > 0 && backupHash.HasValue)
            {
                var result = GetBackupFiles(clusterContext.Config, serverContexts.Select(x => x.Config.Key).ToArray(), args.Details, backupHash.Value)
                             .Find(x => x.Path.GetHashCode() == backupHash.Value);

                if (result == null)
                {
                    await Context.Channel.SendMessageAsync($"**Failed to find the given backup hash!**");

                    return;
                }

                var data = result.Files.Select(file =>
                {
                    string tmpFilePath = null;
                    ArkCloudInventory cloudInventory = null;
                    try
                    {
                        string filePath = null;
                        if (result is FromServerBackupListEntity)
                        {
                            filePath = result.FullPath;
                        }
                        else
                        {
                            filePath = tmpFilePath = FileHelper.ExtractFileInZipFile(result.FullPath, file);
                        }

                        var cresult    = ArkClusterData.LoadSingle(filePath, CancellationToken.None, true, true);
                        cloudInventory = cresult.Success ? cresult.Data : null;
                    }
                    catch
                    {
                        /*ignore exception*/
                    }
                    finally
                    {
                        if (tmpFilePath != null)
                        {
                            File.Delete(tmpFilePath);
                        }
                    }

                    return(new
                    {
                        FilePath = file,
                        CloudSaveHash = file.GetHashCode(),
                        DinoCount = cloudInventory?.Dinos?.Length,
                        CharactersCount = cloudInventory?.Characters?.Length,
                        ItemsCount = cloudInventory?.Items?.Length
                    });
                }).ToArray();

                var tableBackupFiles = FixedWidthTableHelper.ToString(data, x => x
                                                                      .For(y => y.FilePath, header: "Cloud Save")
                                                                      .For(y => y.CloudSaveHash, header: "Cloud Save Hash", alignment: 1, format: "X")
                                                                      .For(y => y.DinoCount, header: "Dinos", alignment: 1)
                                                                      .For(y => y.CharactersCount, header: "Characters", alignment: 1)
                                                                      .For(y => y.ItemsCount, header: "Items", alignment: 1));

                var tableBackupEntries = OutputCloudBackupListingTable(new[] { result }, 0, 1);

                sb.Append(tableBackupEntries);
                sb.Append($"```{tableBackupFiles}```");
            }

            /* ---------------------------------------------------------------
            *  Restore a single cloud save file from a backup archive or cloud save file (some overlap with the less verbose pop command).
            *  --------------------------------------------------------------- */
            else if (args.Restore > 0 && backupHash.HasValue && cloudSaveHash.HasValue)
            {
                var result = GetBackupFiles(clusterContext.Config, serverContexts.Select(x => x.Config.Key).ToArray(), args.Restore, backupHash.Value)
                             .Find(x => x.Path.GetHashCode() == backupHash.Value);

                if (result == null)
                {
                    await Context.Channel.SendMessageAsync($"**Failed to find the given backup hash!**");

                    return;
                }

                var cloudSaveFile = result.Files.FirstOrDefault(x => x.GetHashCode() == cloudSaveHash.Value);
                if (cloudSaveFile == null)
                {
                    await Context.Channel.SendMessageAsync($"**Failed to find the given cloud save hash!**");

                    return;
                }

                var targetPath = Path.Combine(clusterContext.Config.SavePath, $"{args.Restore}");
                if (File.Exists(targetPath))
                {
                    await Context.Channel.SendMessageAsync("**A cloud save already exists, please delete/stash it before restoring...**");

                    return;
                }

                string tmpFilePath = null;
                try
                {
                    string filePath = null;
                    if (result is FromServerBackupListEntity)
                    {
                        filePath = result.FullPath;
                    }
                    else
                    {
                        filePath = tmpFilePath = FileHelper.ExtractFileInZipFile(result.FullPath, cloudSaveFile);
                    }

                    File.Copy(filePath, targetPath);

                    sb.AppendLine($"**Cloud save successfully restored!**");
                }
                catch
                {
                    /*ignore exception*/
                    sb.AppendLine($"**Failed to restore cloud save...**");
                }
                finally
                {
                    if (tmpFilePath != null)
                    {
                        File.Delete(tmpFilePath);
                    }
                }
            }
            else
            {
                var syntaxHelp = MethodBase.GetCurrentMethod().GetCustomAttribute <SyntaxHelpAttribute>()?.SyntaxHelp;
                var name       = MethodBase.GetCurrentMethod().GetCustomAttribute <CommandAttribute>()?.Text;

                await Context.Channel.SendMessageAsync(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(Context.Channel, sb.ToString());
            }
        }
예제 #6
0
        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());
            }
        }