public async Task AddLevels(CommandContext c, [Description("")] DiscordUser mention, [Description("")] int levels) { if (levels > 10) { await c.RejectMessage("Cannot add more then 10 levels at the same time"); return; } using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(mention.Id.ToString()); if (player == null) { await c.RejectMessage(Realm.GetMessage("user_not_registered")); return; } for (int i = 0; i < levels; i++) { var xpNeeded = player.XpNext - player.XpCurrent; await player.AddXpAsync(xpNeeded, c); } await session.SaveChangesAsync(); } await c.ConfirmMessage(); }
public async Task EnterBuilding(CommandContext c, [Description("Name of the building"), RemainingText] string buildingName) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Location>(loc => loc.Id) .LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync($"{c.User.Mention}, {Realm.GetMessage("not_registered")}"); await c.RejectMessage(); return; } if (player.IsIdle == false) { await c.RespondAsync(string.Format(Realm.GetMessage("player_not_idle"), c.User.Mention, player.CurrentActionDisplay)); await c.RejectMessage(); return; } var location = await session.LoadAsync <Location>(player.CurrentLocation); var building = location.Buildings.FirstOrDefault(b => b.Name.Equals(buildingName, System.StringComparison.OrdinalIgnoreCase)); if (building == null) { await c.RespondAsync($"{c.User.Mention}. No building called {buildingName} is located in {location.DisplayName}"); await c.RejectMessage(); return; } var bType = Realm.GetBuildingImplementation(building.BuildingImpl); if (bType == null) { await c.RespondAsync("An error occured. Contact one of the admins and (Error_BuildingImplNotFound)"); await c.RejectMessage(); return; } var bImpl = (Buildings.IBuilding)System.Activator.CreateInstance(bType); await bImpl.EnterBuilding(c, building); await c.ConfirmMessage(); } }
public async Task RegisterPlayer(CommandContext c, string race) { using (var session = Db.DocStore.OpenAsyncSession()) { // Check if player Exists if (await session.Advanced.ExistsAsync(c.User.Id.ToString())) { await c.RespondAsync($"{c.Member.Mention} You are already registered."); await c.RejectMessage(); return; } var raceInfo = await session.Query <Race>().FirstOrDefaultAsync(r => r.Id == $"races/{race}"); if (raceInfo == null) { await c.RejectMessage($"{c.Member.Mention} Race \"{race}\" is not valid. You can use *.info races* to get a list of races"); return; } var charClass = await session.Query <CharacterClass>().FirstOrDefaultAsync(cls => cls.Id == Realm.GetSetting <string>("startingclass")); if (charClass == null) { await c.RespondAsync($"Something went wrong while getting the startingclass (Error_StartingClassNull {Realm.GetSetting<string>("startingclass")})"); return; } var player = Realm.GetPlayerRegistration(c.Member, raceInfo, charClass); await session.StoreAsync(player); await session.SaveChangesAsync(); } var role = c.Guild.Roles.FirstOrDefault(r => r.Name == "Realm Player"); if (role == null) { await c.RejectMessage(Realm.GetMessage("missing_player_role")); return; } await c.Member.GrantRoleAsync(role, "Registered for Realm"); await c.RespondAsync($"{c.User.Mention} has joined the Realm"); await c.ConfirmMessage(); }
public async Task ListInventory(CommandContext c) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Item>(i => i.Id) .LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("user_not_registered")); await c.RejectMessage(); return; } var items = await session.LoadAsync <Item>(player.Inventory.Select(inv => inv.ItemId)); var itemDict = new SortedDictionary <Item.ItemTypes, List <string> >(); foreach (var item in player.Inventory) { var itemDef = items[item.ItemId]; if (itemDict.ContainsKey(itemDef.Type) == false) { itemDict.Add(itemDef.Type, new List <string>()); } itemDict[itemDef.Type].Add(itemDef.Type == Item.ItemTypes.Equipment ? $"{itemDef.DisplayName} (*{itemDef.EquipmentSlot} - x{item.Amount}*)" : $"{itemDef.DisplayName} *x{item.Amount}*"); } var desc = new System.Text.StringBuilder(); foreach (var e in itemDict) { desc.AppendLine($"*{e.Key}*"); e.Value.ForEach(v => desc.AppendLine(v)); desc.AppendLine(); } var embed = new DiscordEmbedBuilder() .WithTitle("Inventory") .WithDescription(desc.ToString()) .WithTimestamp(System.DateTime.Now); await c.Member.SendMessageAsync(embed : embed.Build()); await c.ConfirmMessage(); } }
public async Task Look(CommandContext c) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Location>(loc => loc.Id) .LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync($"{c.User.Mention}, {Realm.GetMessage("not_registered")}"); await c.RejectMessage(); return; } int exploreCounts = -1; if (player.LocationExploreCounts.ContainsKey(player.CurrentLocation)) { exploreCounts = player.LocationExploreCounts[player.CurrentLocation]; } var location = await session.LoadAsync <Location>(player.CurrentLocation); var playersOnLoc = await session.Query <Player>() .Where(pl => pl.CurrentLocation == location.Id && pl.Id != c.User.Id.ToString()) .Select(pl => pl.Id) .ToListAsync(); var locEmbed = new DiscordEmbedBuilder(location.GetLocationEmbed(player.FoundHiddenLocations, player.PreviousLocation, exploreCounts)); if (playersOnLoc.Count > 0) { var names = new List <string>(); foreach (var pl in playersOnLoc) { names.Add((await c.Guild.GetMemberAsync(ulong.Parse(pl))).DisplayName); } locEmbed.AddField("Also Here", string.Join(", ", names)); } await c.RespondAsync(c.User.Mention, embed : locEmbed.Build()); await c.ConfirmMessage(); } }
public async Task Teleport(CommandContext c, [Description("User to teleport")] DiscordUser mention, [Description("Location to teleport to"), RemainingText] string locationName) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Location>(loc => loc.DisplayName) .LoadAsync <Player>(mention.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("user_not_registered")); await c.RejectMessage(); return; } var location = await session.Query <Location>().FirstOrDefaultAsync(l => l.DisplayName.Equals(locationName, System.StringComparison.OrdinalIgnoreCase)); if (location == null) { await c.RespondAsync("Invalid location"); await c.RejectMessage(); return; } player.CurrentLocation = location.Id; await session.SaveChangesAsync(); var user = await c.Guild.GetMemberAsync(mention.Id); await user.SendMessageAsync($"[REALM] You have been teleported to {location.DisplayName}"); } await c.ConfirmMessage(); }
public async Task StopCurrentAction(CommandContext c) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("not_registered")); await c.RejectMessage(); return; } player.SetIdleAction(); await session.SaveChangesAsync(); await c.ConfirmMessage(); } }
public async Task LevelUp(CommandContext c, [Description("User mention who should get the levelup")] DiscordUser mention) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(mention.Id.ToString()); if (player == null) { await c.RejectMessage(Realm.GetMessage("user_not_registered")); return; } var xpNeeded = player.XpNext - player.XpCurrent; await player.AddXpAsync(xpNeeded, c); await session.SaveChangesAsync(); } await c.ConfirmMessage(); }
public async Task GiveItem(CommandContext c, [Description("User who will receive the item")] DiscordUser mention, [Description("The itemid as it's referenced in the database")] string itemId, [Description("Amount of the item to give. If ommited, defaults to 1")] int amount = 1) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Item>(itm => itm.Id) .LoadAsync <Player>(mention.Id.ToString()); if (player == null) { await c.RejectMessage(Realm.GetMessage("user_not_registered")); return; } var item = await session.LoadAsync <Item>(itemId); if (item == null) { await c.RejectMessage("No item with that ID exists"); return; } player.AddItemToInventory(item.Id, amount); if (session.Advanced.HasChanges) { await session.SaveChangesAsync(); } } await c.ConfirmMessage(); }
public async Task RemovePlayer(CommandContext c) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("not_registered")); await c.ConfirmMessage(); return; } session.Delete(player); await session.SaveChangesAsync(); } var role = c.Guild.Roles.FirstOrDefault(r => r.Name == "Realm Player"); if (role == null) { await c.RespondAsync("No Realm Player role exists"); await c.RejectMessage(); return; } await c.Member.RevokeRoleAsync(role, "Deleted player registration"); await c.RespondAsync($"{c.User.Mention} has left the Realm"); await c.ConfirmMessage(); }
public async Task GiveXp(CommandContext c, [Description("User mention who should receive the xp")] DiscordUser mention, [Description("The amount of xp the user will receive")] int xpAmount) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(mention.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("user_not_registered")); await c.RejectMessage(); return; } await player.AddXpAsync(xpAmount, c); await session.SaveChangesAsync(); await c.ConfirmMessage(); } }
public async Task EnterBuilding(CommandContext c, Building building) { var log = Serilog.Log.ForContext <SkillTrainer>(); using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RejectMessage(Realm.GetMessage("not_registered")); return; } var skillMenuBuilder = new DiscordEmbedBuilder() .WithTitle(building.Name); var description = new System.Text.StringBuilder(); description.AppendLine($"*\"{building.WelcomeMessage}\"*"); // Get skills var skillsDict = await session.LoadAsync <Skill>(building.Parameters.Where(p => p.Value.StartsWith("skills/")).Select(p => p.Value)); var skills = skillsDict.Where(kv => kv.Value != null).Select(s => s.Value).ToList(); foreach (var skill in skills) { if (skill.TrainingCosts == null) { log.Error("No trainingcosts defined for {skillname} ({skillid}).", skill.DisplayName, skill.Id); return; } var descriptionLines = skill.Description.Split('\n'); string descriptionText = descriptionLines[0]; if (descriptionLines.Length > 0) { descriptionText += "..."; } // Get the player rank int playerSkillRank = 0; var playerSkill = player.Skills.FirstOrDefault(ps => ps.Id == skill.Id); if (playerSkill != null) { playerSkillRank = playerSkill.Rank; } // Check if max rank if (skill.TrainingCosts.Count == playerSkillRank) { description.AppendLine($"{skill.ReactionIcon} {skill.DisplayName} (Max skill) - *{descriptionText}*"); continue; } // Get next cost int rankCost = skill.TrainingCosts[playerSkillRank]; description.AppendLine($"{skill.ReactionIcon} {skill.DisplayName} (Cost: {rankCost}) - *{descriptionText}*"); } skillMenuBuilder.WithDescription(description.ToString()); if (player.SkillPoints < 1) { skillMenuBuilder.WithFooter("You do not have any skillpoints"); } var msg = await c.RespondAsync(embed : skillMenuBuilder.Build()); if (player.SkillPoints < 1) { return; } foreach (var skill in skills) { if (skill.TrainingCosts == null) { continue; } // Get the player rank int playerSkillRank = 0; var playerSkill = player.Skills.FirstOrDefault(ps => ps.Id == skill.Id); if (playerSkill != null) { playerSkillRank = playerSkill.Rank; } // Check if max rank if (skill.TrainingCosts.Count != playerSkillRank) { await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, skill.ReactionIcon)); } } var interact = c.Client.GetInteractivity(); var response = await interact.WaitForMessageReactionAsync(msg, c.User, System.TimeSpan.FromSeconds(10)); if (response == null) { await c.RejectMessage(); await msg.DeleteAsync(); return; } await msg.DeleteAllReactionsAsync(); var responseName = response.Emoji.GetDiscordName().ToLower(); var selectedSkill = skills.FirstOrDefault(s => s.ReactionIcon.Equals(responseName)); var skillEntry = player.Skills.FirstOrDefault(ls => ls.Id.Equals(selectedSkill?.Id)); var currentPlayerSkill = player.Skills.FirstOrDefault(ps => ps.Id == selectedSkill.Id); int nextRankCost = currentPlayerSkill != null ? selectedSkill.TrainingCosts[currentPlayerSkill.Rank] : selectedSkill.TrainingCosts[0]; if (nextRankCost > player.SkillPoints) { await c.RejectMessage(string.Format(Realm.GetMessage("next_skill_not_enough_skillpts"), selectedSkill.DisplayName)); return; } if (skillEntry == null) { player.AddSkill(new TrainedSkill(selectedSkill.Id, 1)); await c.RespondAsync($"{c.User.Mention} learned {selectedSkill.DisplayName}"); } else { skillEntry.Rank += 1; await c.RespondAsync($"{c.User.Mention} {selectedSkill.DisplayName} has increased to {skillEntry.Rank}"); } player.SkillPoints -= nextRankCost; if (session.Advanced.HasChanged(player)) { await session.SaveChangesAsync(); } await msg.DeleteAsync(); await c.ConfirmMessage(); } }
public async Task UseSkill(CommandContext c, [Description("Skillname")] string skillName, [Description("Target, leave blank to target self/area")] DiscordMember target = null) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(c.User.Id.ToString()); if (player.IsIdle == false) { await c.RejectMessage(string.Format(Realm.GetMessage("player_not_idle"), c.User.Mention, player.CurrentActionDisplay)); return; } if (player.Skills?.Count == 0) { await c.RejectMessage($"{c.User.Mention} has no skills, poor you"); return; } var skill = await session.Query <Skill>() .FirstOrDefaultAsync(s => s.DisplayName.Equals(skillName, StringComparison.OrdinalIgnoreCase)); // TODO: Skill == null catch if (skill.IsActivatable == false) { await c.RejectMessage($"{c.User.Mention}, that skill cannot be activated"); return; } var playerSkill = player.Skills?.FirstOrDefault(ps => ps.Id == skill.Id); if (playerSkill == null) { await c.RejectMessage($"{c.User.Mention} tries and tries, but nothing happens"); return; } if (playerSkill.CooldownUntil > DateTime.Now) { var remaining = playerSkill.CooldownUntil - DateTime.Now; await c.ConfirmMessage($"{c.User.Mention}. That skill is still on cooldown ({(int)remaining.TotalSeconds}s more)"); return; } var sType = Realm.GetSkillImplementation(skill.SkillImpl); if (sType == null) { await c.RejectMessage($"An error occured. Contact one of the admins (Error_SkillWitouthSkillImpl: {skill.Id})"); return; } var sImpl = (Skills.ISkill)Activator.CreateInstance(sType); await sImpl.ExecuteSkill(c, skill, playerSkill, player, target); if (skill.CooldownRanks?.Count > 0 && sImpl.DoCooldown) { playerSkill.CooldownUntil = DateTime.Now.AddSeconds(playerSkill.Rank > skill.CooldownRanks.Count ? skill.CooldownRanks[skill.CooldownRanks.Count - 1] : skill.CooldownRanks[playerSkill.Rank - 1]); } if (session.Advanced.HasChanges) { session.Advanced.IgnoreChangesFor(skill); session.Advanced.IgnoreChangesFor(playerSkill); await session.SaveChangesAsync(); } } }
public async Task TravelMultiple(CommandContext c, [Description("Travel to a specific location that is linked to the current location"), RemainingText] string destinations) { var dests = destinations.Split(';'); if (dests.Length == 0) { await c.RespondAsync($"Something went wrong while parsing the travel command (Error_DestinationLengthZero {destinations})"); await c.RejectMessage(); return; } using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session .Include <Location>(l => l.Id) .LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync($"{c.User.Mention}, {Realm.GetMessage("not_registered")}"); await c.RejectMessage(); return; } if (player.IsIdle == false) { await c.RespondAsync(string.Format(Realm.GetMessage("player_not_idle"), c.User.Mention, player.CurrentActionDisplay)); await c.RejectMessage(); return; } Serilog.Log.ForContext <GeneralActionCommands>().Debug("({u}) Checking path {p}", c.GetFullUserName(), dests.ExtendToString()); var loc = await session.LoadAsync <Location>(player.CurrentLocation); bool arrivedWithIssue = false; string previousLocation = player.CurrentLocation; for (int i = 0; i < dests.Length; i++) { var d = dests[i]; if (loc.LocationConnections.Keys.Contains(d, System.StringComparer.OrdinalIgnoreCase)) { previousLocation = loc.Id; loc = await session.Query <Location>().FirstOrDefaultAsync(tl => tl.DisplayName == d); Serilog.Log.ForContext <GeneralActionCommands>().Debug("({usr}) {x}/{y} found {a}", c.GetFullUserName(), i + 1, dests.Length, loc.Id); } else if (loc.HiddenLocationConnections.Keys.Contains(d, System.StringComparer.OrdinalIgnoreCase)) { // check if the player has the point var hiddenLoc = loc.HiddenLocationConnections[loc.HiddenLocationConnections .FirstOrDefault(l => l.Key.Equals(d, System.StringComparison.OrdinalIgnoreCase)).Key]; if (player.FoundHiddenLocations.Contains(hiddenLoc)) { previousLocation = loc.Id; loc = await session.Query <Location>().FirstOrDefaultAsync(tl => tl.DisplayName == d); Serilog.Log.ForContext <GeneralActionCommands>().Debug("({usr}) {x}/{y} found hidden {a}", c.GetFullUserName(), i + 1, dests.Length, loc.Id); } else { Serilog.Log.ForContext <GeneralActionCommands>().Debug("({usr}) {x}/{y} not found {a}. Stopping", c.GetFullUserName(), i + 1, dests.Length, dests[i]); break; } } else { Serilog.Log.ForContext <GeneralActionCommands>().Debug("({usr}) {x}/{y} not found {a}. Stopping", c.GetFullUserName(), i + 1, dests.Length, dests[i]); arrivedWithIssue = true; break; } } Serilog.Log.ForContext <GeneralActionCommands>().Debug("({usr}) End destination: {a}", c.GetFullUserName(), loc.DisplayName); if (player.CurrentLocation == loc.Id) { await c.RespondAsync($"{c.User.Mention} couldn't find that exit"); } else if (arrivedWithIssue) { await c.RespondAsync($"{c.User.Mention} got lost, but eventually found {loc.DisplayName}"); } else { await c.RespondAsync($"{c.User.Mention} arrived at {loc.DisplayName}"); } player.PreviousLocation = previousLocation; player.CurrentLocation = loc.Id; await session.SaveChangesAsync(); } await c.ConfirmMessage(); }
public async Task TrainAttributes(CommandContext c) { using (var session = Db.DocStore.OpenAsyncSession()) { var player = await session.LoadAsync <Player>(c.User.Id.ToString()); if (player == null) { await c.RespondAsync(Realm.GetMessage("not_registered")); await c.RejectMessage(); return; } if (player.AttributePoints < 1) { await c.RespondAsync(Realm.GetMessage("not_enough_attrib_pts")); await c.RejectMessage(); return; } var interact = c.Client.GetInteractivity(); var desc = new System.Text.StringBuilder(); desc.AppendLine($"{c.User.Mention}, what attribute do you want to train. Current level in parentheses"); desc.AppendLine($"STR: :muscle: ({player.Attributes.Strength})"); desc.AppendLine($"AGI: :hand_splayed: ({player.Attributes.Agility})"); desc.AppendLine($"STA: :heart: ({player.Attributes.Stamina})"); desc.AppendLine($"INT: :eye_in_speech_bubble: ({player.Attributes.Intelligence})"); desc.AppendLine($"WIS: :six_pointed_star: ({player.Attributes.Wisdom})"); var embed = new DiscordEmbedBuilder().WithDescription(desc.ToString()); var msg = await c.RespondAsync(embed : embed); await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, Constants.ATTRIB_STR)); // Strength await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, Constants.ATTRIB_AGI)); // Agility await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, Constants.ATTRIB_STA)); // Stamina await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, Constants.ATTRIB_INT)); // Intelligence await msg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, Constants.ATTRIB_WIS)); // Wisdom var response = await interact.WaitForMessageReactionAsync(msg, c.User, System.TimeSpan.FromSeconds(10)); if (response == null) { await c.RejectMessage(); await msg.DeleteAsync(); return; } await msg.DeleteAllReactionsAsync(); var responsename = response.Emoji.GetDiscordName().ToLower(); switch (responsename) { case Constants.ATTRIB_STR: player.Attributes.Strength++; player.AttributePoints--; await c.RespondAsync(string.Format(Realm.GetMessage("train_str"), c.User.Mention)); break; case Constants.ATTRIB_AGI: player.Attributes.Agility++; player.AttributePoints--; await c.RespondAsync(string.Format(Realm.GetMessage("train_agi"), c.User.Mention)); break; case Constants.ATTRIB_STA: player.Attributes.Stamina++; player.AttributePoints--; await c.RespondAsync(string.Format(Realm.GetMessage("train_sta"), c.User.Mention)); break; case Constants.ATTRIB_INT: player.Attributes.Intelligence++; player.AttributePoints--; await c.RespondAsync(string.Format(Realm.GetMessage("train_int"), c.User.Mention)); break; case Constants.ATTRIB_WIS: player.Attributes.Wisdom++; player.AttributePoints--; await c.RespondAsync(string.Format(Realm.GetMessage("train_wis"), c.User.Mention)); break; } await msg.DeleteAsync(); if (session.Advanced.HasChanged(player)) { await session.SaveChangesAsync(); } } await c.ConfirmMessage(); }
public RpgBot() { var l = Serilog.Log.ForContext <RpgBot>(); Client = new DiscordClient(new DiscordConfiguration() { Token = Environment.GetEnvironmentVariable("REALMBOT_KEY", EnvironmentVariableTarget.User), TokenType = TokenType.Bot, LogLevel = LogLevel.Debug }); Client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived; // Commands var cmd = Client.UseCommandsNext(new CommandsNextConfiguration { StringPrefixes = new[] { "." }, CaseSensitive = false }); cmd.RegisterCommands(System.Reflection.Assembly.GetExecutingAssembly()); l.Information("Registered {n} command(s)", cmd.RegisteredCommands.Count - 1); cmd.CommandErrored += (e) => { return(Task.Run(async() => { Serilog.Log.ForContext <RpgBot>().Error(e.Exception, "Exception happened"); var checks = ((DSharpPlus.CommandsNext.Exceptions.ChecksFailedException)e.Exception).FailedChecks; // Check if the error is due to missing role if (checks.Any(x => x is RequireRolesAttribute)) { using (var s = Db.DocStore.OpenAsyncSession()) { var p = await s.LoadAsync <Models.Character.Player>(e.Context.User.Id.ToString()); if (p == null) { await e.Context.Member.SendMessageAsync(Realm.GetMessage("not_registered")); } else { var missingRoles = ((RequireRolesAttribute)checks .FirstOrDefault(x => x is RequireRolesAttribute))?.RoleNames .ExtendToString("", null, ", ", ""); await e.Context.Member.SendMessageAsync(string.Format(Realm.GetMessage("missing_roles"), missingRoles)); } } e.Handled = true; return; } if (checks.Any(x => x is CooldownAttribute)) { await e.Context.RespondAsync($"{e.Context.User.Mention}, you need to wait {((CooldownAttribute)checks[0]).Reset.TotalSeconds} more seconds."); e.Handled = true; return; } Serilog.Log.ForContext <RpgBot>() .Error(e.Exception, "Unhandled exception when executing command: {cmd}", e.Command.QualifiedName); })); }; // Interactivity Client.UseInteractivity(new InteractivityConfiguration()); l.Information("Bot initialized"); }
public async Task EnterBuilding(CommandContext c, Building building) { List <BuildingAction> actions = new List <BuildingAction>(); Player player; using (var session = Db.DocStore.OpenAsyncSession()) { var acts = await session.LoadAsync <BuildingAction>(building.Actions); actions.AddRange(acts.Values); player = await session.LoadAsync <Player>(c.User.Id.ToString()); } var desc = new System.Text.StringBuilder(); if (building.WelcomeMessage != null) { desc.AppendLine($"*\"{building.WelcomeMessage}\"*"); desc.AppendLine(); } foreach (var act in actions) { desc.AppendLine(act.Description); } var embed = new DiscordEmbedBuilder() .WithColor(DiscordColor.Blurple) .WithTitle(building.Name) .WithDescription(desc.ToString()) .WithFooter(Realm.GetMessage("building_timeout")); var playerRespondMsg = await c.RespondAsync(embed : embed); foreach (var act in actions) { await playerRespondMsg.CreateReactionAsync(DiscordEmoji.FromName(c.Client, act.ReactionIcon)); } await c.ConfirmMessage(); var interact = c.Client.GetInteractivity(); var response = await interact.WaitForMessageReactionAsync(playerRespondMsg, c.User, TimeSpan.FromSeconds(15)); if (response == null) { await c.RejectMessage(); await playerRespondMsg.DeleteAsync(); return; } await playerRespondMsg.DeleteAllReactionsAsync(); var responseName = response.Emoji.GetDiscordName().ToLower(); var buildingActionId = actions.FirstOrDefault(ba => ba.ReactionIcon.Equals(responseName))?.Id; if (buildingActionId == null) { Serilog.Log.ForContext <GenericBuilding>().Error("Could not find BuildingAction with id {response}", responseName); await c.RejectMessage("An error occured. Contact one of the admins (Error_BuildingActionReactionIdNotFound)"); return; } var attachment = await Db.DocStore.Operations.SendAsync(new GetAttachmentOperation(buildingActionId, "action.js", AttachmentType.Document, null)); if (attachment == null) { Serilog.Log.ForContext <GenericBuilding>().Error($"{building.Name} is missing an action script."); await c.RejectMessage($"{building.Name} is missing an action script. Contact one of the admins (Error_BuildingActionScriptNotFound)"); return; } string script = await new System.IO.StreamReader(attachment.Stream).ReadToEndAsync(); await playerRespondMsg.DeleteAsync(); await Script.ScriptManager.RunDiscordScriptAsync(buildingActionId, script, c, player, playerRespondMsg); }