Example #1
0
        public async Task StartCountdown(ArkServerContext serverContext, string reason, int delayInMinutes, Func <Task> react = null)
        {
            await serverContext.Steam.SendRconCommand($"serverchat Countdown started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...");

            if (!string.IsNullOrWhiteSpace(_config.AnnouncementChannel))
            {
                await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, $"**Countdown started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...**");
            }

            foreach (var min in Enumerable.Range(1, delayInMinutes))
            {
                AddTimedTask(new TimedTask
                {
                    When     = DateTime.Now.AddMinutes(min),
                    Callback = new Func <Task>(async() =>
                    {
                        var countdown = delayInMinutes - min;
                        await serverContext.Steam.SendRconCommand(countdown > 0 ? $"serverchat {reason} in {countdown} minute{(countdown > 1 ? "s" : "")}..." : $"serverchat {reason}...");
                        if (!string.IsNullOrWhiteSpace(_config.AnnouncementChannel))
                        {
                            await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, countdown > 0 ? $"**{reason} in {countdown} minute{(countdown > 1 ? "s" : "")}...**" : $"**{reason}...**");
                        }
                        if (countdown <= 0 && react != null)
                        {
                            await react();
                        }
                    })
                });
            }
        }
        public static async Task <InitiateVoteResult> Initiate(Channel channel, ArkServerContext context, IConfig config, IEfDatabaseContext db, ulong userId, string identifier, DateTime when, string reason)
        {
            var votes = db.Votes.OfType <DestroyWildDinosVote>().Where(x => x.Result == VoteResult.Undecided).ToArray();

            if (votes.Length > 0)
            {
                await channel.SendMessageDirectedAt(userId, $"there is already an active vote to wipe wild dinos.");

                return(null);
            }

            //proceed to initiate vote
            var vote = new DestroyWildDinosVote
            {
                Reason  = reason,
                Started = when,
#if DEBUG
                Finished = when.AddSeconds(10),
#else
                Finished = when.AddMinutes(5),
#endif
                Result     = VoteResult.Undecided,
                ServerKey  = context.Config.Key,
                Identifier = identifier
            };

            return(new InitiateVoteResult
            {
                MessageInitiator = $"the vote to wipe wild dinos have been initiated. Announcement will be made.",
                MessageAnnouncement = $@"**A vote to wipe wild dinos on server ({context.Config.Key}) due to ""{reason}"" have been started. Please cast your vote in the next five minutes!**{Environment.NewLine}To vote use the command: **!vote {identifier} yes**/**no**",
                MessageRcon = $@"A vote to wipe wild dinos due to ""{reason}"" have been started. Please cast your vote on Discord using !vote {identifier} yes/no in the next five minutes!",
                Vote = vote
            });
        }
Example #3
0
        internal static PlayerServerViewModel BuildViewModelForTransferedPlayer(ArkServerContext context, string steamId, ulong[] playerIds)
        {
            if (playerIds == null || playerIds.Length == 0)
            {
                return(null);
            }

            //there will be no player profile so most data cannot be set
            //a tribe where the player is a member may exist tho

            var tribe = context.Tribes?.FirstOrDefault(x => playerIds.Any(y => x.MemberIds.Contains((int)y)));

            if (tribe == null)
            {
                return(null);
            }
            var playerId = playerIds.First(x => tribe.MemberIds.Contains((int)x));

            var vm = new PlayerServerViewModel
            {
                ClusterKey = context.Config.Key,
                SteamId    = steamId,
                TribeId    = tribe.Id,
                TribeName  = tribe.Name,
                SavedAt    = tribe.SavedAt
            };

            vm.Creatures.AddRange(BuildCreatureViewModelsForPlayerId(context, playerId));

            return(vm);
        }
Example #4
0
        private void _contextManager_VoteInitiated(ArkServerContext serverContext, VoteInitiatedEventArgs args)
        {
            if (args == null || args.Item == null)
            {
                return;
            }

            var handler = GetVoteHandler(args.Item);

            if (handler == null)
            {
                return;
            }

            //reminder, one minute before expiry
            var reminderAt = args.Item.Finished.AddMinutes(-1);

            if (DateTime.Now < reminderAt)
            {
                _scheduledTasksManager.AddTimedTask(new TimedTask
                {
                    When     = reminderAt,
                    Tag      = "vote_" + args.Item.Id,
                    Callback = new Func <Task>(async() =>
                    {
                        var result = handler.VoteIsAboutToExpire();
                        if (result == null)
                        {
                            return;
                        }

                        if (result.MessageRcon != null)
                        {
                            await serverContext.Steam.SendRconCommand($"serverchat {result.MessageRcon.ReplaceRconSpecialChars()}");
                        }
                        if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel))
                        {
                            await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, result.MessageAnnouncement);
                        }
                    })
                });
            }

            //on elapsed
            _scheduledTasksManager.AddTimedTask(new TimedTask
            {
                When     = args.Item.Finished,
                Tag      = "vote_" + args.Item.Id,
                Callback = new Func <Task>(async() =>
                {
                    using (var db = _databaseContextFactory.Create())
                    {
                        var vote = db.Votes.FirstOrDefault(x => x.Id == args.Item.Id);

                        await VoteFinished(serverContext, db, vote);
                    }
                })
            });
        }
Example #5
0
        private async Task VoteFinished(ArkServerContext serverContext, IEfDatabaseContext db, Database.Model.Vote vote, bool noAnnouncement = false, VoteResult?forcedResult = null)
        {
            var handler = GetVoteHandler(vote);

            if (handler == null)
            {
                return;
            }

            var votesFor     = vote.Votes.Count(x => x.VotedFor);
            var votesAgainst = vote.Votes.Count(x => !x.VotedFor);

#if DEBUG
            vote.Result = forcedResult ?? (vote.Votes.Count >= 1 && votesFor > votesAgainst ? VoteResult.Passed : VoteResult.Failed);
#else
            vote.Result = forcedResult ?? (vote.Votes.Count >= 3 && votesFor > votesAgainst ? VoteResult.Passed : VoteResult.Failed);
#endif

            VoteStateChangeResult result = null;
            try
            {
                result = await handler.VoteFinished(serverContext, _config, _constants, db);

                try
                {
                    if (!noAnnouncement && result != null)
                    {
                        if (result.MessageRcon != null)
                        {
                            await serverContext.Steam.SendRconCommand($"serverchat {result.MessageRcon.ReplaceRconSpecialChars()}");
                        }
                        if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel))
                        {
                            await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, result.MessageAnnouncement);
                        }
                    }
                }
                catch { /* ignore all exceptions */ }

                if (result != null && result.React != null)
                {
                    if (result.ReactDelayInMinutes <= 0)
                    {
                        await result.React();
                    }
                    else
                    {
                        await _scheduledTasksManager.StartCountdown(serverContext, result.ReactDelayFor, result.ReactDelayInMinutes, result.React);
                    }
                }
            }
            catch (Exception ex)
            {
                //todo: better exception handling structure
                Logging.LogException(ex.Message, ex, GetType(), LogLevel.ERROR, ExceptionLevel.Unhandled);
            }
            db.SaveChanges();
        }
Example #6
0
        public ArkSaveFileWatcher(ArkServerContext serverContext)
        {
            _serverContext = serverContext;

            _watcher          = new FileSystemWatcher();
            _watcher.Changed += _watcher_Changed;
            _watcher.Created += _watcher_Changed;

            SaveFilePath = serverContext.Config.SaveFilePath;
        }
Example #7
0
        public async Task StartCountdown(ArkServerContext serverContext, string reason, int delayInMinutes, Func <Task> react = null)
        {
            // collection of servers that should receive notifications via rcon for this countdown event
            var serverContexts = serverContext == null?_contextManager.Servers.Where(x => !x.Config.DisableChatNotifications).ToArray() : new ArkServerContext[]
            {
                serverContext
            };

            foreach (var sc in serverContexts)
            {
                await sc.Steam.SendRconCommand($"serverchat Countdown started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...");
            }
            if (!string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel))
            {
                await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, $"**Countdown{(serverContext == null ? "" : $" on server {serverContext.Config.Key}")} started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...**");
Example #8
0
        private async void _contextManager_VoteResultForced(ArkServerContext sender, VoteResultForcedEventArgs args)
        {
            if (args == null || args.Item == null)
            {
                return;
            }

            _scheduledTasksManager.RemoveTimedTaskByTag("vote_" + args.Item.Id);

            using (var db = _databaseContextFactory.Create())
            {
                var vote = db.Votes.FirstOrDefault(x => x.Id == args.Item.Id);

                await VoteFinished(sender, db, vote, forcedResult : args.Result);
            }
        }
Example #9
0
        public async Task <VoteStateChangeResult> VoteFinished(ArkServerContext serverContext, IConfig config, IConstants constants, IEfDatabaseContext db)
        {
            if (_vote == null)
            {
                return(null);
            }

            if (_vote.Result == VoteResult.Passed)
            {
                await serverContext.Steam.SendRconCommand($"settimeofday {_vote.TimeOfDay}");
            }

            return(new VoteStateChangeResult
            {
                MessageAnnouncement = $@"{(_vote.Result == VoteResult.Passed ? ":white_check_mark:" : ":x:")} **Vote to set time of day on server ({_vote.ServerKey}) to {_vote.TimeOfDay} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}**",
                MessageRcon = $@"Vote to set time of day to {_vote.TimeOfDay} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}."
            });
        }
Example #10
0
        public static async Task <InitiateVoteResult> Initiate(Channel channel, ArkServerContext context, IConfig config, IEfDatabaseContext db, ulong userId, string identifier, DateTime when, string reason, string timeOfDayRaw)
        {
            var _rTimeOfDay = new Regex(@"^\s*\d{2,2}\:\d{2,2}(\:\d{2,2})?\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (!_rTimeOfDay.IsMatch(timeOfDayRaw))
            {
                await channel.SendMessageDirectedAt(userId, $"time of day format is invalid.");

                return(null);
            }

            var votes = db.Votes.OfType <SetTimeOfDayVote>().Where(x => x.Result == VoteResult.Undecided).ToArray();

            if (votes.Length > 0)
            {
                await channel.SendMessageDirectedAt(userId, $"there is already an active vote to set the time of day.");

                return(null);
            }

            //proceed to initiate vote
            var vote = new SetTimeOfDayVote
            {
                TimeOfDay = timeOfDayRaw.Trim(),
                Reason    = reason,
                Started   = when,
#if DEBUG
                Finished = when.AddSeconds(10),
#else
                Finished = when.AddMinutes(2),
#endif
                Result     = VoteResult.Undecided,
                ServerKey  = context.Config.Key,
                Identifier = identifier
            };

            return(new InitiateVoteResult
            {
                MessageInitiator = $"the vote to set time of day to {vote.TimeOfDay} have been initiated. Announcement will be made.",
                MessageAnnouncement = $@"**A vote to set time of day on server ({context.Config.Key}) to {vote.TimeOfDay} due to ""{reason}"" have been started. Please cast your vote in the next two minutes!**{Environment.NewLine}To vote use the command: **!vote {identifier} yes**/**no**",
                MessageRcon = $@"A vote to set time of day to {vote.TimeOfDay} due to ""{reason}"" have been started. Please cast your vote on Discord using !vote {identifier} yes/no in the next two minutes!",
                Vote = vote
            });
        }
Example #11
0
        public async Task <VoteStateChangeResult> VoteFinished(ArkServerContext serverContext, IConfig config, IConstants constants, IEfDatabaseContext db)
        {
            if (_vote == null)
            {
                return(null);
            }

            if (_vote.Result == VoteResult.Passed)
            {
                _vote.BannedUntil = _vote.Started.AddHours(_vote.DurationInHours);

                await serverContext.Steam.SendRconCommand($"banplayer {_vote.SteamId}");
            }

            return(new VoteStateChangeResult
            {
                MessageAnnouncement = $@"{(_vote.Result == VoteResult.Passed ? ":white_check_mark:" : ":x:")} **Vote to ban {_vote.FullName} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}**",
                MessageRcon = $@"Vote to ban {_vote.FullName} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}."
            });
        }
Example #12
0
        internal static List <CropPlotViewModel> BuildCropPlotViewModelsForPlayerId(ArkServerContext context, int playerId)
        {
            var player = context.Players?.FirstOrDefault(x => x.Id == playerId);
            var tribe  = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));

            var cropPlots = new[] { player?.Structures, tribe?.Structures }.Where(x => x != null).SelectMany(x => x).OfType <ArkStructureCropPlot>().Where(x => x.PlantedCropClassName != null).ToArray();

            var results = cropPlots.Select(x =>
            {
                return(new CropPlotViewModel(x.Location)
                {
                    ClassName = x.ClassName,
                    FertilizerQuantity = (int)Math.Round(GetFertilizerQuantityFromItems(x.Inventory), 0),
                    WaterAmount = x.WaterAmount,
                    PlantedCropClassName = x.PlantedCropClassName,
                    PlantedCropName = ArkItems.Instance.Data?.GetItem(x.PlantedCropClassName, structuresPlusHack: true)?.Name?.Replace(" Seed", "") ?? x.PlantedCropClassName
                });
            }).OrderBy(x => x.Latitude).ThenBy(x => x.Longitude).ToList();

            return(results);
        }
Example #13
0
        internal static PlayerServerViewModel BuildViewModelForPlayer(ArkServerContext context, ArkPlayer player)
        {
            var vm = new PlayerServerViewModel
            {
                ClusterKey    = context.Config.Key,
                SteamId       = player.SteamId,
                CharacterName = player.CharacterName,
                Gender        = player.Gender.ToString(),
                Level         = player.CharacterLevel,
                Latitude      = player.Location?.Latitude,
                Longitude     = player.Location?.Longitude,
                TopoMapX      = player.Location?.TopoMapX,
                TopoMapY      = player.Location?.TopoMapY,
                EngramPoints  = player.TotalEngramPoints,
                TribeId       = player.TribeId,
                TribeName     = player.TribeId.HasValue ? context.Tribes.FirstOrDefault(x => x.Id == player.TribeId.Value)?.Name : null,
                SavedAt       = player.SavedAt
            };

            vm.Creatures.AddRange(BuildCreatureViewModelsForPlayerId(context, player.Id));

            return(vm);
        }
Example #14
0
        public async Task <VoteStateChangeResult> VoteFinished(ArkServerContext serverContext, IConfig config, IConstants constants, IEfDatabaseContext db)
        {
            if (_vote == null)
            {
                return(null);
            }

            return(new VoteStateChangeResult
            {
                MessageAnnouncement = $@"{(_vote.Result == VoteResult.Passed ? ":white_check_mark:" : ":x:")} **Vote to update the server ({_vote.ServerKey}) have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}**",
                MessageRcon = $@"Vote to update the server have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}.",
                ReactDelayInMinutes = 5,
                ReactDelayFor = "Server update",
                React = _vote.Result == VoteResult.Passed ? new Func <Task>(async() =>
                {
                    string message = null;
                    if (!await _arkServerService.UpdateServer(_vote.ServerKey, (s) => { message = s; return Task.FromResult((IUserMessage)null); }, (s) => s.FirstCharToUpper(), 300))
                    {
                        Logging.Log($@"Vote to update server ({_vote.ServerKey}) execution failed (""{message ?? ""}"")", GetType(), LogLevel.DEBUG);
                    }
                }) : null
            });
        }
Example #15
0
        public async Task <VoteStateChangeResult> VoteFinished(ArkServerContext serverContext, IConfig config, IConstants constants, IEfDatabaseContext db)
        {
            if (_vote == null)
            {
                return(null);
            }

            if (_vote.Result == VoteResult.Passed)
            {
                var bans = db.Votes.OfType <BanVote>().Where(x => x.SteamId == _vote.SteamId && x.Result == VoteResult.Passed && x.BannedUntil.HasValue && x.BannedUntil.Value > DateTime.Now);
                foreach (var ban in bans)
                {
                    ban.BannedUntil = null;
                }

                await serverContext.Steam.SendRconCommand($"unbanplayer {_vote.SteamId}");
            }

            return(new VoteStateChangeResult
            {
                MessageAnnouncement = $@"{(_vote.Result == VoteResult.Passed ? ":white_check_mark:" : ":x:")} **Vote to unban {_vote.FullName} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}**",
                MessageRcon = $@"Vote to unban {_vote.FullName} have {(_vote.Result == VoteResult.Vetoed ? "been vetoed" : _vote.Result == VoteResult.Passed ? "passed" : "failed")}."
            });
        }
Example #16
0
        internal static PlayerServerViewModel BuildViewModelForTransferedPlayer(
            ArkServerContext context,
            IConfig config,
            string steamId,
            int[] playerIds,
            DemoMode demoMode,
            bool incProfile,
            bool incProfileDetailed,
            bool incCreatures,
            bool incCreaturesBaseStats,
            bool incCreaturesCloud,
            bool incCrops,
            bool incGenerators,
            bool incKibblesEggs,
            bool incTribeLog)
        {
            if (playerIds == null || playerIds.Length == 0)
            {
                return(null);
            }

            //there will be no player profile so most data cannot be set
            //a tribe where the player is a member may exist tho

            //note: potentially there could be multiple tribes with the same player, which player.Tribe protects us against. here we just select the first one which is not optimal
            var tribe = context.Tribes?.FirstOrDefault(x => playerIds.Any(y => x.MemberIds.Contains(y)));

            if (tribe == null)
            {
                return(null);
            }
            var playerId = playerIds.First(x => tribe.MemberIds.Contains(x));

            var vm = new PlayerServerViewModel
            {
                ClusterKey = context.Config.Key,
                SteamId    = steamId,
                TribeId    = tribe.Id,
                TribeName  = demoMode?.GetTribeName(tribe.Id) ?? tribe.Name,
                SavedAt    = tribe.SavedAt
            };

            if (demoMode != null)
            {
                vm.FakeSteamId = demoMode.GetSteamId(steamId);
            }

            if (incCreatures)
            {
                vm.Creatures.AddRange(BuildCreatureViewModelsForPlayerId(context, config, playerId, demoMode, incCreaturesBaseStats));
            }
            if (incKibblesEggs)
            {
                vm.KibblesAndEggs = BuildKibblesAndEggsViewModelsForPlayerId(context, playerId);
            }
            if (incCrops)
            {
                vm.CropPlots = BuildCropPlotViewModelsForPlayerId(context, playerId);
            }
            if (incGenerators)
            {
                vm.Generators = BuildGeneratorViewModelsForPlayerId(context, playerId);
            }
            if (incTribeLog)
            {
                vm.TribeLog = BuildTribeLogViewModelsForPlayerId(context, playerId, config.WebApp.TribeLogLimit, config.WebApp.TribeLogColors);
            }

            return(vm);
        }
Example #17
0
        public static async Task <InitiateVoteResult> Initiate(Channel channel, ArkServerContext context, IConfig config, IEfDatabaseContext db, ulong userId, string identifier, DateTime when, string reason, string targetRaw, int durationInHours)
        {
            var _rId = new Regex(@"^\s*(id|(steam\s*id))\s*\:\s*(?<id>\d+)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
            var m    = _rId.Match(targetRaw);

            var targets = m.Success ?
                          context.Players.Where(x => x.Id.ToString().Equals(m.Groups["id"].Value) || x.SteamId.Equals(m.Groups["id"].Value)).ToArray()
                : context.Players.Where(x => (x.Name != null && x.Name.Equals(targetRaw, StringComparison.OrdinalIgnoreCase)) || (x.Name != null && x.Name.Equals(targetRaw, StringComparison.OrdinalIgnoreCase))).ToArray();

            if (targets.Length == 0)
            {
                await channel.SendMessageDirectedAt(userId, $"could not find a player with that name (maybe they have not been saved yet?). Try using their steam id instead.");

                return(null);
            }
            if (targets.Length > 1)
            {
                await channel.SendMessageDirectedAt(userId, $"there are more than one player with that name. Try using their steam id instead.");

                return(null);
            }
            var target  = targets.First();
            var steamId = long.Parse(target.SteamId);
            var votes   = db.Votes.OfType <BanVote>().Where(x => x.SteamId == steamId).ToArray();

            if (votes.Any(x => x.BannedUntil.HasValue && x.BannedUntil.Value > when))
            {
                await channel.SendMessageDirectedAt(userId, $"this player is already banned.");

                return(null);
            }
            var unvotes = db.Votes.OfType <UnbanVote>().Where(x => x.SteamId == steamId).ToArray();

            if (votes.Any(x => x.Result == VoteResult.Undecided) || unvotes.Any(x => x.Result == VoteResult.Undecided))
            {
                await channel.SendMessageDirectedAt(userId, $"there is already an active vote to ban/unban this player.");

                return(null);
            }

            //proceed to initiate vote
            var vote = new BanVote
            {
                SteamId       = steamId,
                PlayerName    = target.Name,
                CharacterName = target.Name,
                TribeName     = target.TribeId.HasValue ? context.Tribes?.FirstOrDefault(x => x.Id == target.TribeId)?.Name : null, //target.TribeName,
                Reason        = reason,
                Started       = when,
#if DEBUG
                Finished = when.AddSeconds(10),
#else
                Finished = when.AddMinutes(5),
#endif
                DurationInHours = durationInHours,
                Result          = VoteResult.Undecided,
                ServerKey       = context.Config.Key,
                Identifier      = identifier
            };

            return(new InitiateVoteResult
            {
                MessageInitiator = $"the vote to ban this player have been initiated. Announcement will be made.",
                MessageAnnouncement = $@"**A vote to ban {vote.FullName}{(vote.DurationInHours <= (24 * 90) ? $" for {vote.DurationInHours}h" : "")} due to ""{reason}"" have been started. Please cast your vote in the next five minutes!**{Environment.NewLine}To vote use the command: **!vote {identifier} yes**/**no**",
                MessageRcon = $@"A vote to ban {vote.FullName}{(vote.DurationInHours <= (24 * 90) ? $" for {vote.DurationInHours}h" : "")} due to ""{reason}"" have been started. Please cast your vote on Discord using !vote {identifier} yes/no in the next five minutes!",
                Vote = vote
            });
        }
Example #18
0
        //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);
            }
        }
Example #19
0
        internal static List <ElectricalGeneratorViewModel> BuildElectricalGeneratorViewModelsForPlayerId(ArkServerContext context, int playerId)
        {
            var player = context.Players?.FirstOrDefault(x => x.Id == playerId);
            var tribe  = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));

            var electricalGenerators = new[] { player?.Structures, tribe?.Structures }.Where(x => x != null).SelectMany(x => x).OfType <ArkStructureElectricGenerator>().ToArray();

            var results = electricalGenerators.Select(x =>
            {
                return(new ElectricalGeneratorViewModel(x.Location)
                {
                    Activated = x.Activated,
                    //FuelTime = x.FuelTime,
                    GasolineQuantity = (int)(x.Inventory?.Where(y => y.ClassName.Equals("PrimalItemResource_Gasoline_C", StringComparison.Ordinal)).Sum(y => y.Quantity) ?? 0)
                });
            }).OrderBy(x => x.Latitude).ThenBy(x => x.Longitude).ToList();

            return(results);
        }
Example #20
0
        internal static List <GeneratorViewModel> BuildGeneratorViewModelsForPlayerId(ArkServerContext context, int playerId)
        {
            if (!ArkSavegameToolkitNet.ArkToolkitSettings.Instance.ObjectTypes.TryGetValue(ArkSavegameToolkitNet.ObjectType.ItemElectricGeneratorGasoline, out var classNames))
            {
                return(new List <GeneratorViewModel>());
            }

            var player = context.Players?.FirstOrDefault(x => x.Id == playerId);
            var tribe  = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));

            var generators = new[] { player?.Structures, tribe?.Structures }.Where(x => x != null).SelectMany(x => x).OfType <ArkStructureElectricGenerator>().ToArray();

            var results = generators.Select(x =>
            {
                return(new GeneratorViewModel(x.Location)
                {
                    Activated = x.Activated,
                    //FuelTime = x.FuelTime, PrimalItemResource_Gasoline_C , PrimalItemResource_Gasoline_JStacks_C
                    FuelQuantity = (int)(x.Inventory?.Where(y => classNames.Contains(y.ClassName, StringComparer.Ordinal)).Sum(y => y.Quantity) ?? 0)
                });
            }).OrderBy(x => x.Latitude).ThenBy(x => x.Longitude).ToList();

            return(results);
        }
Example #21
0
        internal static List <TribeLogEntryViewModel> BuildTribeLogViewModelsForPlayerId(ArkServerContext context, int playerId, int?limit = null, bool logColors = false)
        {
            var player = context.Players?.FirstOrDefault(x => x.Id == playerId);
            var tribe  = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));

            var tribelogs = tribe?.Logs?.Reverse().Take(limit ?? tribe.Logs.Length).Select(x => TribeLog.FromLog(x)).ToArray() ?? new TribeLog[] { };
            var results   = tribelogs.Select(x =>
            {
                return(new TribeLogEntryViewModel
                {
                    Day = x.Day,
                    Time = x.Time,
                    Message = logColors ? x.MessageHtml : x.MessageUnformatted
                });
            }).ToList();

            return(results);
        }
Example #22
0
        internal static List <TamedCreatureViewModel> BuildCreatureViewModelsForPlayerId(ArkServerContext context, ulong playerId)
        {
            var result = new List <TamedCreatureViewModel>();

            if (context.TamedCreatures != null)
            {
                var playercreatures = context.NoRafts.Where(x => (ulong)x.TargetingTeam == playerId || (x.OwningPlayerId.HasValue && (ulong)x.OwningPlayerId == playerId)).ToArray();
                var tribe           = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains((int)playerId));
                var tribecreatures  = tribe != null?context.NoRafts.Where(x => x.TargetingTeam == tribe.Id && !playercreatures.Any(y => y.Id == x.Id)).ToArray() : new ArkTamedCreature[]
                {
                };
                foreach (var item in playercreatures.Select(x => new { c = x, o = "player" }).Concat(tribecreatures.Select(x => new { c = x, o = "tribe" })))
                {
                    var currentFood = item.c.CurrentStatusValues?.Length > 4 ? item.c.CurrentStatusValues[4] : null;
                    var maxFood     = item.c.BaseStats?.Length > 4 && item.c.TamedStats?.Length > 4 ?
                                      ArkContext.CalculateMaxStat(
                        ArkSpeciesStatsData.Stat.Food,
                        item.c.ClassName,
                        item.c.BaseStats[4],
                        item.c.TamedStats[4],
                        (decimal)(item.c.DinoImprintingQuality ?? 0f),
                        (decimal)(item.c.TamedIneffectivenessModifier ?? 0f)) : null;

                    //baby food formula: max * 0.1 + (max - (max * 0.1)) * age
                    if (maxFood.HasValue && item.c.BabyAge.HasValue)
                    {
                        maxFood = maxFood.Value * 0.1 + (maxFood.Value - (maxFood.Value * 0.1)) * item.c.BabyAge.Value;
                    }

                    var foodStatus = currentFood.HasValue && maxFood.HasValue ? currentFood.Value / (float)maxFood.Value : (float?)null;
                    if (foodStatus.HasValue && foodStatus > 1f)
                    {
                        foodStatus = 1f;
                    }

                    var aliases = ArkSpeciesAliases.Instance.GetAliases(item.c.ClassName);
                    var vmc     = new TamedCreatureViewModel
                    {
                        Name           = item.c.Name,
                        ClassName      = item.c.ClassName,
                        Species        = aliases?.FirstOrDefault(),
                        Aliases        = aliases?.Skip(2).ToArray() ?? new string[] { }, //skip primary name and class name
                        Gender         = item.c.Gender.ToString(),
                        BaseLevel      = item.c.BaseLevel,
                        Level          = item.c.Level,
                        BabyAge        = item.c.IsBaby ? item.c.BabyAge : null,
                        Imprint        = item.c.DinoImprintingQuality,
                        FoodStatus     = foodStatus,
                        Latitude       = item.c.Location?.Latitude,
                        Longitude      = item.c.Location?.Longitude,
                        TopoMapX       = item.c.Location?.TopoMapX,
                        TopoMapY       = item.c.Location?.TopoMapY,
                        NextMating     = item.c.NextAllowedMatingTimeApprox,
                        BabyNextCuddle = item.c.BabyNextCuddleTimeApprox,
                        OwnerType      = item.o
                    };
                    result.Add(vmc);
                }
            }

            return(result);
        }
Example #23
0
        internal static List <KibbleAndEggViewModel> BuildKibblesAndEggsViewModelsForPlayerId(ArkServerContext context, int playerId)
        {
            var player = context.Players?.FirstOrDefault(x => x.Id == playerId);
            var tribe  = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));

            //PrimalItemConsumable_Egg_Kaprosuchus_C, PrimalItemConsumable_Egg_Kaprosuchus_Fertilized_C, PrimalItemConsumable_Egg_Wyvern_Fertilized_Lightning_C
            var _rEgg = new Regex(@"^PrimalItemConsumable_Egg_(?<name>.+?)_C$", RegexOptions.Singleline);

            //PrimalItemConsumable_Kibble_GalliEgg_C, PrimalItemConsumable_Kibble_Compy_C
            var _rKibble = new Regex(@"^PrimalItemConsumable_Kibble_(?<name>.+?)(?:Egg)?_C$", RegexOptions.IgnoreCase | RegexOptions.Singleline);

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

            var kibbles = inv.Where(x => x.ClassName.StartsWith("PrimalItemConsumable_Kibble", StringComparison.Ordinal))
                          .GroupBy(x => x.ClassName)
                          .Select(x =>
            {
                return(new { Name = ArkItems.Instance.Data?.GetItem(x.Key)?.Name ?? x.Key, Count = x.Sum(y => y.Quantity) });
            })
                          .ToArray();

            var eggs = inv.Where(x => x.ClassName.StartsWith("PrimalItemConsumable_Egg", StringComparison.Ordinal) && !x.ClassName.Contains("_Fertilized_"))
                       .GroupBy(x => x.ClassName)
                       .Select(x =>
            {
                return(new { Name = ArkItems.Instance.Data?.GetItem(x.Key)?.Name ?? x.Key, Count = x.Sum(y => y.Quantity) });
            })
                       .ToList();

            var keys = kibbles.Select(x => x.Name).Concat(eggs.Select(x => x.Name)).Distinct();

            var results = keys.Select(x =>
            {
                var k = kibbles.FirstOrDefault(y => y.Name.Equals(x));
                var e = eggs.FirstOrDefault(y => y.Name.Equals(x));
                return(new KibbleAndEggViewModel
                {
                    Name = k?.Name ?? e?.Name,
                    KibbleCount = k?.Count ?? 0L,
                    EggCount = e?.Count ?? 0L
                });
            }).OrderByDescending(x => x.EggCount + x.KibbleCount).ToList();

            return(results);
        }
Example #24
0
        internal static List <TamedCreatureViewModel> BuildCreatureViewModelsForPlayerId(ArkServerContext context, IConfig config, int playerId, DemoMode demoMode, bool incBaseStats = false)
        {
            var result = new List <TamedCreatureViewModel>();

            if (context.TamedCreatures != null)
            {
                var player               = context.Players?.FirstOrDefault(x => x.Id == playerId);
                var playercreatures      = context.NoRafts.Where(x => x.TargetingTeam == playerId || x.OwningPlayerId.HasValue && x.OwningPlayerId == playerId).ToArray();
                var playercreatures_cryo = player?.Items?.OfType <ArkItemCryopod>().Where(x => x.Dino != null).Select(x => x.Dino).ToArray() ?? new ArkTamedCreature[] { };
                var tribe          = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId));
                var tribecreatures = tribe != null?context.NoRafts.Where(x => x.TargetingTeam == tribe.Id && !playercreatures.Any(y => y.Id == x.Id)).ToArray() : new ArkTamedCreature[]
                {
                };
                var tribecreatures_cryo = tribe?.Items?.OfType <ArkItemCryopod>().Where(x => x.Dino != null).Select(x => x.Dino).ToArray() ?? new ArkTamedCreature[] { };
                foreach (var item in playercreatures.Select(x => new { c = x, o = "player", cryo = false })
                         .Concat(playercreatures_cryo.Select(x => new { c = x, o = "player", cryo = true }))
                         .Concat(tribecreatures.Select(x => new { c = x, o = "tribe", cryo = false }))
                         .Concat(tribecreatures_cryo.Select(x => new { c = x, o = "tribe", cryo = true })))
                {
                    var currentFood = item.c.CurrentStatusValues?.Length > 4 ? item.c.CurrentStatusValues[4] : null;
                    var maxFood     = item.c.BaseStats?.Length > 4 && item.c.TamedStats?.Length > 4 ?
                                      ArkDataHelper.CalculateMaxStat(
                        ArkSpeciesStatsData.Stat.Food,
                        item.c.ClassName,
                        true,
                        item.c.BaseStats[4],
                        item.c.TamedStats[4],
                        (decimal)(item.c.DinoImprintingQuality ?? 0f),
                        (decimal)(item.c.TamedIneffectivenessModifier ?? 0f)) : null;

                    //baby food formula: max * 0.1 + (max - (max * 0.1)) * age
                    if (maxFood.HasValue && item.c.BabyAge.HasValue)
                    {
                        maxFood = maxFood.Value * 0.1 + (maxFood.Value - maxFood.Value * 0.1) * item.c.BabyAge.Value;
                    }

                    var foodStatus = currentFood.HasValue && maxFood.HasValue ? currentFood.Value / (float)maxFood.Value : (float?)null;
                    if (foodStatus.HasValue && foodStatus > 1f)
                    {
                        foodStatus = 1f;
                    }

                    //baby fully grown
                    var babyFullyGrownTimeApprox = (DateTime?)null;
                    if (item.c.IsBaby && item.c.BabyAge.HasValue && context.SaveState.GameTime.HasValue)
                    {
                        var babyFullyGrown = ArkDataHelper.CalculateBabyFullyGrown(item.c.ClassName, item.c.BabyAge.Value, context.Config.ArkMultipliers);
                        babyFullyGrownTimeApprox = context.SaveState.GetApproxDateTimeOf(context.SaveState.GameTime.Value + babyFullyGrown);
                    }

                    var aliases = ArkSpeciesAliases.Instance.GetAliasesByClassName(item.c.ClassName);
                    var vmc     = new TamedCreatureViewModel
                    {
                        Id1            = item.c.Id1,
                        Id2            = item.c.Id2,
                        Name           = demoMode?.GetCreatureName(item.c.Id1, item.c.Id2, aliases?.FirstOrDefault()) ?? item.c.Name,
                        ClassName      = item.c.ClassName,
                        Species        = aliases?.FirstOrDefault(),
                        Aliases        = aliases?.Skip(2).ToArray() ?? new string[] { }, //skip primary name and class name
                        Gender         = item.c.Gender.ToString(),
                        BaseLevel      = item.c.BaseLevel,
                        Level          = item.c.Level,
                        Experience     = item.c.ExperiencePoints ?? 0f,
                        BabyAge        = item.c.IsBaby ? item.c.BabyAge : null,
                        Imprint        = item.c.DinoImprintingQuality,
                        FoodStatus     = foodStatus,
                        Latitude       = item.cryo ? null : item.c.Location?.Latitude,
                        Longitude      = item.cryo ? null : item.c.Location?.Longitude,
                        TopoMapX       = item.cryo ? null : item.c.Location?.TopoMapX,
                        TopoMapY       = item.cryo ? null : item.c.Location?.TopoMapY,
                        NextMating     = !item.c.IsBaby && item.c.Gender == ArkCreatureGender.Female ? item.c.NextAllowedMatingTimeApprox : null,
                        BabyFullyGrown = babyFullyGrownTimeApprox,
                        BabyNextCuddle = item.c.BabyNextCuddleTimeApprox,
                        OwnerType      = item.o,
                        InCryopod      = item.cryo,
                        Parents        = item.c.DinoAncestors?.Length > 0 && item.c.DinoAncestorsMale?.Length > 0 ? new CreatureParentsViewModel
                        {
                            Female = new CreatureIdViewModel {
                                Id1 = item.c.DinoAncestors.First().FemaleId1, Id2 = item.c.DinoAncestors.First().FemaleId2
                            },
                            Male = new CreatureIdViewModel {
                                Id1 = item.c.DinoAncestorsMale.First().MaleId1, Id2 = item.c.DinoAncestorsMale.First().MaleId2
                            }
                        } : null,
                        RandomMutationsFemale = item.c.RandomMutationsFemale,
                        RandomMutationsMale   = item.c.RandomMutationsMale,
                    };
                    if (incBaseStats)
                    {
                        //0: health
                        //1: stamina
                        //2: torpor
                        //3: oxygen
                        //4: food
                        //5: water
                        //6: temperature
                        //7: weight
                        //8: melee damage
                        //9: movement speed
                        //10: fortitude
                        //11: crafting speed

                        vmc.BaseStats = new CreatureStatsViewModel
                        {
                            Health        = item.c.BaseStats[0],
                            Stamina       = item.c.BaseStats[1],
                            Oxygen        = item.c.BaseStats[3],
                            Food          = item.c.BaseStats[4],
                            Weight        = item.c.BaseStats[7],
                            Melee         = item.c.BaseStats[8],
                            MovementSpeed = item.c.BaseStats[9]
                        };

                        vmc.TamedStats = new CreatureStatsViewModel
                        {
                            Health        = item.c.TamedStats[0],
                            Stamina       = item.c.TamedStats[1],
                            Oxygen        = item.c.TamedStats[3],
                            Food          = item.c.TamedStats[4],
                            Weight        = item.c.TamedStats[7],
                            Melee         = item.c.TamedStats[8],
                            MovementSpeed = item.c.TamedStats[9]
                        };

                        var statValues = ArkSpeciesStats.Instance.Data.GetStatValues(item.c);
                        vmc.StatValues = new CreatureStatValuesViewModel
                        {
                            Tamed          = statValues.tamed,
                            TamedNoImprint = statValues.tamedNoImprint,
                            Wild           = statValues.wild,
                        };
                    }
                    result.Add(vmc);
                }
            }

            return(result);
        }
Example #25
0
        internal static PlayerServerViewModel BuildViewModelForTransferedPlayer(
            ArkServerContext context,
            IConfig config,
            string steamId,
            int[] playerIds,
            DemoMode demoMode,
            bool incProfile,
            bool incProfileDetailed,
            bool incCreatures,
            bool incCreaturesBaseStats,
            bool incCreaturesCloud,
            bool incCrops,
            bool incGenerators,
            bool incKibblesEggs,
            bool incTribeLog)
        {
            if (playerIds == null || playerIds.Length == 0)
            {
                return(null);
            }

            //there will be no player profile so most data cannot be set
            //a tribe where the player is a member may exist tho

            var tribe = context.Tribes?.FirstOrDefault(x => playerIds.Any(y => x.MemberIds.Contains((int)y)));

            if (tribe == null)
            {
                return(null);
            }
            var playerId = playerIds.First(x => tribe.MemberIds.Contains((int)x));

            var vm = new PlayerServerViewModel
            {
                ClusterKey = context.Config.Key,
                SteamId    = steamId,
                TribeId    = tribe.Id,
                TribeName  = demoMode?.GetTribeName(tribe.Id) ?? tribe.Name,
                SavedAt    = tribe.SavedAt
            };

            if (demoMode != null)
            {
                vm.FakeSteamId = demoMode.GetSteamId(steamId);
            }

            if (incCreatures)
            {
                vm.Creatures.AddRange(BuildCreatureViewModelsForPlayerId(context, config, playerId, demoMode, incCreaturesBaseStats));
            }
            if (incKibblesEggs)
            {
                vm.KibblesAndEggs = BuildKibblesAndEggsViewModelsForPlayerId(context, playerId);
            }
            if (incCrops)
            {
                vm.CropPlots = BuildCropPlotViewModelsForPlayerId(context, playerId);
            }
            if (incGenerators)
            {
                vm.ElectricalGenerators = BuildElectricalGeneratorViewModelsForPlayerId(context, playerId);
            }
            if (incTribeLog)
            {
                vm.TribeLog = BuildTribeLogViewModelsForPlayerId(context, playerId, 100);
            }

            return(vm);
        }
Example #26
0
 private void ContextManager_BackupCompleted(ArkServerContext sender, bool backupsEnabled, SavegameBackupResult result)
 {
     _signaller.PulseAll(Tuple.Create(sender, backupsEnabled, result));
 }
Example #27
0
        internal static PlayerServerViewModel BuildViewModelForPlayer(
            ArkServerContext context,
            IConfig config,
            ArkPlayer player,
            DemoMode demoMode,
            bool incProfile,
            bool incProfileDetailed,
            bool incCreatures,
            bool incCreaturesBaseStats,
            bool incCreaturesCloud,
            bool incCrops,
            bool incGenerators,
            bool incKibblesEggs,
            bool incTribeLog)
        {
            var tribe = player.Tribe;
            var vm    = new PlayerServerViewModel
            {
                ClusterKey    = context.Config.Key,
                SteamId       = player.SteamId,
                FakeSteamId   = demoMode?.GetSteamId(player.SteamId),
                CharacterName = demoMode?.GetPlayerName(player.Id) ?? player.CharacterName,
                TribeId       = player.TribeId,
                TribeName     = tribe != null?demoMode?.GetTribeName(tribe.Id) ?? tribe?.Name : null,
                SavedAt       = player.SavedAt
            };

            if (incProfileDetailed)
            {
                vm.Latitude  = player.Location?.Latitude;
                vm.Longitude = player.Location?.Longitude;
                vm.TopoMapX  = player.Location?.TopoMapX;
                vm.TopoMapY  = player.Location?.TopoMapY;

                if (!player.IsExternalPlayer)
                {
                    vm.Gender       = player.Gender.ToString();
                    vm.Level        = player.CharacterLevel;
                    vm.EngramPoints = player.TotalEngramPoints;
                }
            }

            if (incCreatures)
            {
                vm.Creatures.AddRange(BuildCreatureViewModelsForPlayerId(context, config, player.Id, demoMode, incCreaturesBaseStats));
            }
            if (incKibblesEggs)
            {
                vm.KibblesAndEggs = BuildKibblesAndEggsViewModelsForPlayerId(context, player.Id);
            }
            if (incCrops)
            {
                vm.CropPlots = BuildCropPlotViewModelsForPlayerId(context, player.Id);
            }
            if (incGenerators)
            {
                vm.Generators = BuildGeneratorViewModelsForPlayerId(context, player.Id);
            }
            if (incTribeLog)
            {
                vm.TribeLog = BuildTribeLogViewModelsForPlayerId(context, player.Id, config.WebApp.TribeLogLimit, config.WebApp.TribeLogColors);
            }

            return(vm);
        }
Example #28
0
        public ArkSaveFileWatcherTimer(ArkServerContext serverContext)
        {
            _serverContext = serverContext;

            _timer = new Timer(_timer_Callback, null, TimeSpan.Zero, _delay);
        }