示例#1
0
        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();
        }
示例#2
0
        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();
            }
        }
示例#3
0
        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();
        }
示例#4
0
        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();
            }
        }
示例#5
0
        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();
            }
        }
示例#6
0
        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();
        }
示例#7
0
        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();
            }
        }
示例#8
0
        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();
        }
示例#9
0
        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();
        }
示例#10
0
        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();
        }
示例#11
0
        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();
            }
        }
示例#12
0
        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();
            }
        }
示例#13
0
        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();
                }
            }
        }
示例#14
0
        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();
        }
示例#15
0
        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();
        }
示例#16
0
文件: RpgBot.cs 项目: arxae/Realm-Rpg
        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");
        }
示例#17
0
        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);
        }