public async Task Trophy(string name) { // Find the trophy with this name. ITrophy trophy = TrophyService.GetTrophies() .Where(t => t.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); // If no such trophy exists, return an error. if (trophy is null) { await BotUtils.ReplyAsync_Error(Context, "No such trophy exists."); return; } // Show trophy information. double completion_rate = await Db.GetTrophyCompletionRateAsync(trophy); bool hide_description = trophy.Flags.HasFlag(TrophyFlags.Hidden) && completion_rate <= 0.0; string embed_title = string.Format("{0} {1} ({2:0.#}%)", trophy.Icon, trophy.Name, completion_rate); string embed_description = string.Format("_{0}_", hide_description ? TrophyBase.HiddenTrophyDescription : trophy.Description); long times_unlocked = await Db.GetTimesTrophyUnlockedAsync(trophy); embed_description += string.Format("\n\nThis trophy has been earned by **{0}** user{1} ({2:0.#}%).", times_unlocked, times_unlocked == 1 ? "" : "s", completion_rate); EmbedBuilder embed = new EmbedBuilder(); embed.WithTitle(embed_title); embed.WithDescription(embed_description); embed.WithColor(new Color(255, 204, 77)); // Show first/latest earners. IEnumerable <IUnlockedTrophyInfo> earners = (await Db.GetCreatorsWithTrophyAsync(trophy)).OrderBy(x => x.DateUnlocked); string date_format = "MMMM dd, yyyy"; if (Context.Guild != null) { foreach (IUnlockedTrophyInfo trophy_user in earners) { IUser user = await Context.Guild.GetUserAsync(trophy_user.Creator.UserId.Value); if (!(user is null)) { embed.AddField("First earned", string.Format("**{0}** ({1})", user.Username, trophy_user.DateUnlocked.ToString(date_format)), inline: true); break; } } foreach (IUnlockedTrophyInfo trophy_user in earners.Reverse()) { IUser user = await Context.Guild.GetUserAsync(trophy_user.Creator.UserId.Value); if (!(user is null)) { embed.AddField("Latest earned", string.Format("**{0}** ({1})", user.Username, trophy_user.DateUnlocked.ToString(date_format)), inline: true); break; } } } await ReplyAsync("", false, embed.Build()); }
public static async Task CloseActionEmbedAsync(ActionEmbed embed) { await embed.Message.ModifyAsync(x => x.Content = BotUtils.KamtroText("This embed is no longer in use.")); // Notify the user that the embed is disabled await embed.Message.ModifyAsync(x => x.Embed = null); // Remove embed }
public async Task AddPeriod(string name, string startDate, string endDate) { // Make sure we don't already have a period with the same name. Period p = await BotUtils.GetPeriodFromDb(name); if (!(p is null)) { await BotUtils.ReplyAsync_Warning(Context, string.Format("The period **{0}** already exists.", p.GetName())); return; } startDate = startDate.ToLower(); endDate = endDate.ToLower(); long start_ts = 0; long end_ts = 0; // Try to parse the dates and convert them to timestamps. if (Period.TryParseDate(startDate, out DateTime start_dt) && Period.TryParseDate(endDate, out DateTime end_dt)) { start_ts = new DateTimeOffset(start_dt).ToUnixTimeSeconds(); end_ts = new DateTimeOffset(end_dt).ToUnixTimeSeconds(); if (end_ts >= start_ts) { // If the end date is "now", update the previous period that ended "now" to end at the start date of this period. if (endDate == "now") { using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Period SET end_ts = $end_ts WHERE end_ts=\"now\";")) { cmd.Parameters.AddWithValue("$end_ts", start_ts.ToString()); await Database.ExecuteNonQuery(cmd); } } // Insert the new period into the database. using (SQLiteCommand cmd = new SQLiteCommand("INSERT OR IGNORE INTO Period(name, start_ts, end_ts) VALUES ($name, $start_ts, $end_ts);")) { cmd.Parameters.AddWithValue("$name", name.ToLower()); cmd.Parameters.AddWithValue("$start_ts", start_ts.ToString()); // Period can't start with "now", but can use the "now" timestamp cmd.Parameters.AddWithValue("$end_ts", endDate == "now" ? "now" : end_ts.ToString()); await Database.ExecuteNonQuery(cmd); } await BotUtils.ReplyAsync_Success(Context, string.Format("Successfully created new period **{0}**.", StringUtils.ToTitleCase(name))); } else { await BotUtils.ReplyAsync_Error(Context, "The period end date must occur after the period start date."); } } else { await BotUtils.ReplyAsync_Error(Context, string.Format("Invalid date format provided. Please use the format \"{0}\".", Period.DATE_FORMAT)); } }
public void CleanStringTest() { string s = "lool\n\rhehexd"; Assert.AreEqual("loolhehexd", BotUtils.CleanString(s)); }
public virtual async Task <ActionResult> Show(string slug, int?p) { // Set the page index var pageIndex = p ?? 1; var loggedOnReadOnlyUser = User.GetMembershipUser(MembershipService); var loggedOnUsersRole = loggedOnReadOnlyUser.GetRole(RoleService); // Get the topic var topic = _topicService.GetTopicBySlug(slug); if (topic != null) { var settings = SettingsService.GetSettings(); // Note: Don't use topic.Posts as its not a very efficient SQL statement // Use the post service to get them as it includes other used entities in one // statement rather than loads of sql selects var sortQuerystring = Request.QueryString[Constants.PostOrderBy]; var orderBy = !string.IsNullOrWhiteSpace(sortQuerystring) ? EnumUtils.ReturnEnumValueFromString <PostOrderBy>(sortQuerystring) : PostOrderBy.Standard; // Store the amount per page var amountPerPage = settings.PostsPerPage; if (sortQuerystring == Constants.AllPosts) { // Overide to show all posts amountPerPage = int.MaxValue; } // Get the posts var posts = await _postService.GetPagedPostsByTopic(pageIndex, amountPerPage, int.MaxValue, topic.Id, orderBy); // Get the topic starter post var starterPost = _postService.GetTopicStarterPost(topic.Id); // Get the permissions for the category that this topic is in var permissions = RoleService.GetPermissions(topic.Category, loggedOnUsersRole); // If this user doesn't have access to this topic then // redirect with message if (permissions[ForumConfiguration.Instance.PermissionDenyAccess].IsTicked) { return(ErrorToHomePage(LocalizationService.GetResourceString("Errors.NoPermission"))); } // Set editor permissions ViewBag.ImageUploadType = permissions[ForumConfiguration.Instance.PermissionInsertEditorImages].IsTicked ? "forumimageinsert" : "image"; var postIds = posts.Select(x => x.Id).ToList(); var votes = _voteService.GetVotesByPosts(postIds); var favourites = _favouriteService.GetAllPostFavourites(postIds); var viewModel = ViewModelMapping.CreateTopicViewModel(topic, permissions, posts, postIds, starterPost, posts.PageIndex, posts.TotalCount, posts.TotalPages, loggedOnReadOnlyUser, settings, _notificationService, _pollService, votes, favourites, true); // If there is a quote querystring var quote = Request["quote"]; if (!string.IsNullOrWhiteSpace(quote)) { try { // Got a quote var postToQuote = _postService.Get(new Guid(quote)); viewModel.QuotedPost = postToQuote.PostContent; viewModel.ReplyTo = postToQuote.Id; viewModel.ReplyToUsername = postToQuote.User.UserName; } catch (Exception ex) { LoggingService.Error(ex); } } var reply = Request["reply"]; if (!string.IsNullOrWhiteSpace(reply)) { try { // Set the reply var toReply = _postService.Get(new Guid(reply)); viewModel.ReplyTo = toReply.Id; viewModel.ReplyToUsername = toReply.User.UserName; } catch (Exception ex) { LoggingService.Error(ex); } } var updateDatabase = false; // User has permission lets update the topic view count // but only if this topic doesn't belong to the user looking at it var addView = !(User.Identity.IsAuthenticated && loggedOnReadOnlyUser.Id == topic.User.Id); if (addView) { updateDatabase = true; } // Check the poll - To see if it has one, and whether it needs to be closed. if (viewModel.Poll?.Poll?.ClosePollAfterDays != null && viewModel.Poll.Poll.ClosePollAfterDays > 0 && !viewModel.Poll.Poll.IsClosed) { // Check the date the topic was created var endDate = viewModel.Poll.Poll.DateCreated.AddDays((int)viewModel.Poll.Poll.ClosePollAfterDays); if (DateTime.UtcNow > endDate) { topic.Poll.IsClosed = true; viewModel.Topic.Poll.IsClosed = true; updateDatabase = true; } } if (!BotUtils.UserIsBot() && updateDatabase) { if (addView) { // Increase the topic views topic.Views = topic.Views + 1; } try { Context.SaveChanges(); } catch (Exception ex) { LoggingService.Error(ex); } } return(View(viewModel)); } return(ErrorToHomePage(LocalizationService.GetResourceString("Errors.GenericMessage"))); }
public void Execute() { Combat(); WowGameobject FlagNode = WowInterface.ObjectManager.WowObjects .OfType <WowGameobject>() .Where(x => Enum.IsDefined(typeof(Flags), x.DisplayId) && x.Position.GetDistance(WowInterface.ObjectManager.Player.Position) < 15) .OrderBy(x => x.Position.GetDistance(WowInterface.ObjectManager.Player.Position)) .FirstOrDefault(); if (FlagNode != null) { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, FlagNode.Position); if (WowInterface.ObjectManager.Player.Position.GetDistance(FlagNode.Position) <= 4) { WowInterface.MovementEngine.StopMovement(); if (CaptureFlagEvent.Run()) { WowInterface.HookManager.WowObjectRightClick(FlagNode); } } else { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, FlagNode.Position); } } else { if (WowInterface.HookManager.WowExecuteLuaAndRead(BotUtils.ObfuscateLua("{v:0}=\"\" for i = 1, GetNumMapLandmarks(), 1 do base, status = GetMapLandmarkInfo(i) {v:0}= {v:0}..base..\":\"..status..\";\" end"), out string result)) { Vector3 currentNode = PathBase[CurrentNodeCounter]; string[] AllBaseList = result.Split(';'); if (WowInterface.ObjectManager.Player.HasBuffById(34976)) { if (AllBaseList[CurrentNodeCounter].Contains(factionFlagState)) { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, currentNode); } else { ++CurrentNodeCounter; if (CurrentNodeCounter >= PathBase.Count) { CurrentNodeCounter = 0; } } } else { if (AllBaseList[CurrentNodeCounter].Contains("Uncontrolled") || AllBaseList[CurrentNodeCounter].Contains("In Conflict") || AllBaseList[CurrentNodeCounter].Contains(factionFlagState)) { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, currentNode); } if (WowInterface.Player.Position.GetDistance(currentNode) < 10.0f) { ++CurrentNodeCounter; if (CurrentNodeCounter >= PathBase.Count) { CurrentNodeCounter = 0; } } else if (factionFlagState != null && AllBaseList[CurrentNodeCounter].Contains(factionFlagState)) { ++CurrentNodeCounter; if (CurrentNodeCounter >= PathBase.Count) { CurrentNodeCounter = 0; } } else if (FlagNode != null) { IEnumerable <WowPlayer> enemiesNearFlag = WowInterface.ObjectManager.GetNearEnemies <WowPlayer>(FlagNode.Position, 40); IEnumerable <WowPlayer> friendsNearFlag = WowInterface.ObjectManager.GetNearFriends <WowPlayer>(FlagNode.Position, 40); IEnumerable <WowPlayer> friendsNearPlayer = WowInterface.ObjectManager.GetNearFriends <WowPlayer>(WowInterface.ObjectManager.Player.Position, 20); if (enemiesNearFlag != null) { if (enemiesNearFlag.Count() >= 2) { if (friendsNearFlag != null && (friendsNearFlag.Count() >= 1 || friendsNearPlayer.Count() >= 1)) { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, currentNode); return; } } else { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, currentNode); return; } } } else { WowInterface.MovementEngine.SetMovementAction(MovementAction.Move, currentNode); } } } } }
public override Embed GetEmbed() { EmbedBuilder builder = new EmbedBuilder(); builder.WithTitle("Kamtro Roles"); builder.WithAuthor("Role List"); builder.WithDescription($"Hover over a role to see it's description\nRoles in **Bold** are ones you already have"); string roleList = ""; string cursor; // The type of cursor bool shouldBeBold; // If the line should be bold, as in if the user already has the role bool onId; for (int i = 0; i < ServerData.ModifiableRoles.Count; i++) { if (cursorPos == i) { // If the cursor is on this line cursor = CustomEmotes.CursorAnimated; // Show it //cursor = ">"; } else { // otherwise cursor = CustomEmotes.CursorBlankSpace; // Don't //cursor = " "; } onId = ServerData.ModifiableRoles[i].Id == boldId; shouldBeBold = BotUtils.GetGUser(Context).HasRole(ServerData.ModifiableRoles[i]); // if the user has the role, make it bold. shouldBeBold = shouldBeBold || (boldOverride && onId); shouldBeBold = shouldBeBold && (!boldNoverride || !onId); if (boldOverride && ServerData.ModifiableRoles[i].Id == boldId) { boldOverride = false; boldId = 0; } if (boldNoverride && ServerData.ModifiableRoles[i].Id == boldId) { boldNoverride = false; boldId = 0; } roleList += ((i == 0) ? "" : "\n") + cursor + MakeBold(ServerData.ModifiableRoles[i].Name, shouldBeBold); } uint colorHex = Convert.ToUInt32(Program.Settings.RoleDescriptions[ServerData.ModifiableRoles[cursorPos].Id].Color.Replace("#", ""), 16); Color embedColor = new Color(colorHex); builder.WithColor(embedColor); builder.AddField("Roles", roleList); // Get the description from the settings class string roleDesc = Program.Settings.RoleDescriptions[ServerData.ModifiableRoles[cursorPos].Id].Description; builder.AddField("Description", roleDesc); if (Program.Debug) { builder.AddField("Debug Info", $"MRFC: {ServerData.ModifiableRoles.Count} C: {cursorPos}\nBO: {boldOverride} BN: {boldNoverride} "); } AddMenu(builder); // Adds the menu key at the bottom return(builder.Build()); // Build the embed and return it }
public async Task DirectMessageAsync([Remainder] string args = null) { if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN)) { return; } SocketGuildUser user = BotUtils.GetGUser(Context); // Check if admin if (user.GuildPermissions.Administrator || ServerData.AdminUsers.Contains(user)) { /// TO DO /// /// Get the user in remainder of the message [DONE] /// Make prompt on what message to send to the user [DONE] /// Include attachments /// Sends the message to the user [DONE] // Inform user to specify the user to DM if (args == null) { await ReplyAsync(BotUtils.KamtroText("You must specify the user to directly message.")); return; } else { // Split the message to get the corresponding parts string[] msgSplit = Context.Message.Content.Split(' '); SocketGuildUser target = BotUtils.GetUser(msgSplit[1]); if (target == null) { await ReplyAsync(BotUtils.KamtroText("I cannot find that user.")); return; } else if (msgSplit.Length == 2) { /// To Do: /// Show embed for messaging the user [DONE] /// Toggle on messaging that user MessagingEmbed embed = new MessagingEmbed(user); // Send embed in DMs to user try { await embed.Display((IMessageChannel)user.GetOrCreateDMChannelAsync()); } // Could not send to the user catch (Exception) { if (user.Nickname != null) { await ReplyAsync(BotUtils.KamtroText($"I cannot send direct messages to you, {user.Nickname}. Please allow direct messages from me.")); } else { await ReplyAsync(BotUtils.KamtroText($"I cannot send direct messages to you, {user.Username}. Please allow direct messages from me.")); } } } else { // Build the message back together string msgSend = ""; for (int i = 2; i < msgSplit.Length; i++) { msgSend += msgSplit[i]; if (i != msgSplit.Length - 1) { msgSend += " "; } } // Send message and notify user using the command try { await target.SendMessageAsync(msgSend); await ReplyAsync(BotUtils.KamtroText($"Message sent to {target.Username}#{user.Discriminator}.")); } // Could not send to the user catch (Exception) { await ReplyAsync(BotUtils.KamtroText($"Message could not be sent to the user. The user either has messages from only friends allowed or has blocked me.")); } } } } }
/// <summary> /// Happens whenever anything about a user (except roles) updates /// </summary> /// <remarks> /// This is pretty dumb. /// It's up to you to figure out what changed. It could be anything from a new pfp or username, /// to changing your status from idle to online. /// </remarks> /// <param name="before">User before</param> /// <param name="after">User after</param> /// <returns></returns> public async Task OnMemberUpdate(SocketGuildUser before, SocketGuildUser after) { if (before.Guild != ServerData.Server || before.Status != after.Status) return; // If it's not on kamtro, or it was just a status update (online to AFK, etc), ignore it KLog.Debug($"Member {BotUtils.GetFullUsername(before)} updated."); if(BotUtils.GetFullUsername(before) != BotUtils.GetFullUsername(after)) { // If the user changed their name. KLog.Debug($"Username Change: {BotUtils.GetFullUsername(before)} --> {BotUtils.GetFullUsername(after)}"); NameChangeEmbed nce = new NameChangeEmbed(before, after); await nce.Display(ServerData.LogChannel, after.Username + "#" + after.Discriminator); } KLog.Debug("FLAG GH-A"); if (before.Nickname != after.Nickname) { // If the nickame changed KLog.Debug($"Nickname Change: {BotUtils.GetFullUsername(before)}: {(before.Nickname == null ? "[No Nickname]":$"'{before.Nickname}'")} --> {(after.Nickname == null ? "[No Nickname]" : $"'{after.Nickname}'")}"); NameChangeEmbed nce = new NameChangeEmbed(before, after, true); await nce.Display(ServerData.LogChannel, after.Username + "#" + after.Discriminator); }
public override async Task ButtonAction(SocketReaction action) { switch (action.Emote.ToString()) { case ReactionHandler.CHECK_STR: // verify inputs int k, t, p; // kamtrokens, temp rep, and perm rep respectively if (!(int.TryParse(KamtrokenReward, out k) && int.TryParse(TempRepReward, out t) && int.TryParse(PermRepReward, out p))) { InvalidNumberWarning = true; await UpdateEmbed(); return; } // Color string c = EmbedColor.Replace("#", "").Replace("0x", "").Replace("x", ""); uint cc; if (!uint.TryParse(c, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out cc)) { InvalidNumberWarning = true; await UpdateEmbed(); return; } Color ec = new Color(cc); // Add the stats UserDataNode data = UserDataManager.GetUserData(Winner); data.Kamtrokens += k; data.ReputationToGive += t; data.MaxReputation += p; UserDataManager.SaveUserData(); // Send the gift string wins = ""; if (k > 0) { wins += $"{k} Kamtroken{(k == 1 ? "":"s")}"; } if (t > 0) { if (wins.Length != 0) { wins += ", "; } wins += $"{t} Temporary Reputation Point{(t == 1 ? "" : "s")}"; } wins.TrimEnd(',', ' '); if (k == 0 && t == 0) { wins = ""; } if (p > 0) { wins += $"\n\nIn addition, the amount of repuation you get per week has been increaced by {p}"; } await BotUtils.DMUserAsync(Winner, new BasicEmbed("Congradulations!", $"You have won {(string.IsNullOrWhiteSpace(wins) ? "my appreciation!":wins)}", "Winnings", ec, "", MessageText).GetEmbed()); // Update the embed GiftSent = true; await UpdateEmbed(); EventQueueManager.RemoveMessageEvent(this); break; case ReactionHandler.DECLINE_STR: EventQueueManager.RemoveMessageEvent(this); await Message.DeleteAsync(); await Context.Channel.SendMessageAsync(BotUtils.KamtroText("Reward Sending Canceled.")); break; } }
public async Task MessageChannelAsync([Remainder] string args = "") { if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN)) { return; } if (string.IsNullOrWhiteSpace(args)) { await ReplyAsync(BotUtils.KamtroText("You need to say a message!")); return; } SocketTextChannel target = null; // Check if a channel name was specified string[] arrayCheck = Context.Message.Content.Split(' '); string channelToCheck; // Check if a channel was even in the message if (arrayCheck.Length > 1) { channelToCheck = arrayCheck[1]; // Check if channel is mentioned in DMs if (Context.Channel is IDMChannel && channelToCheck.StartsWith("<#")) { target = ServerData.Server.GetTextChannel(ulong.Parse(channelToCheck.Substring(2, channelToCheck.Length - 3))); } else { // Check for name matches foreach (SocketTextChannel textChannel in ServerData.Server.TextChannels) { if (UtilStringComparison.CompareWordScore(channelToCheck, textChannel.Name) > 0.66) { target = textChannel; break; } } } } else if (Context.Message.MentionedChannels.Count < 1) { await ReplyAsync(BotUtils.KamtroText("You need to specify the channel!")); return; } if (target == null) { try { target = Context.Message.MentionedChannels.ElementAt(0) as SocketTextChannel; } catch (Exception) { } } if (target == null) { await ReplyAsync(BotUtils.KamtroText("You need to specify a text channel!")); return; } List <string> msgl = args.Split(' ').ToList(); msgl.RemoveAt(0); if (msgl.Count <= 0) { await ReplyAsync(BotUtils.KamtroText("You need to say a message!")); return; } string msg = string.Join(" ", msgl.ToArray()); await target.SendMessageAsync(BotUtils.KamtroText(msg)); await Context.Message.AddReactionAsync(ReactionHandler.CHECK_EM); KLog.Info($"Kamtro Message Sent in #{target.Name} from [{BotUtils.GetFullUsername(Context.User)}]: {msg}"); }
public void Execute() { if (!IsGateOpen()) { WowInterface.CombatClass.OutOfCombatExecute(); return; } // --- set new state --- if (hasStateChanged) { hasStateChanged = false; hasFlag = WowInterface.ObjectManager.Player.Auras != null && WowInterface.ObjectManager.Player.Auras.Any(e => e.SpellId == 23333 || e.SpellId == 23335); WowUnit teamFlagCarrier = getTeamFlagCarrier(); ownTeamHasFlag = teamFlagCarrier != null; if (ownTeamHasFlag) { TeamFlagCarrierGuid = teamFlagCarrier.Guid; } WowUnit enemyFlagCarrier = getEnemyFlagCarrier(); enemyTeamHasFlag = enemyFlagCarrier != null; if (enemyTeamHasFlag) { EnemyFlagCarrierGuid = enemyFlagCarrier.Guid; } } // --- reaction --- if (hasFlag) { // you've got the flag! WowObject tmpFlag = getOwnFlagObject(); ownFlag = tmpFlag == null ? ownFlag : tmpFlag; if (ownFlag != null) { // own flag lies around WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, ownFlag.Position); if (isAtPosition(ownFlag.Position)) { // own flag reached, save it! WowInterface.HookManager.WowObjectOnRightClick(ownFlag); hasStateChanged = true; } } else { // bring it outside! WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseHord : baseAlly); } } else if (ownTeamHasFlag && enemyTeamHasFlag) { // team mate and enemy got the flag if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Dps) { // run to the enemy WowUnit enemyFlagCarrier = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(EnemyFlagCarrierGuid); if (enemyFlagCarrier != null) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotUtils.MoveAhead(enemyFlagCarrier.Position, enemyFlagCarrier.Rotation, ((float)WowInterface.ObjectManager.Player.Position.GetDistance2D(enemyFlagCarrier.Position)) / 2f)); if (isInCombatReach(enemyFlagCarrier.Position)) { WowInterface.HookManager.TargetGuid(enemyFlagCarrier.Guid); } if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } else { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseAlly : baseHord); } WowInterface.CombatClass.OutOfCombatExecute(); } else { // run to the own flag carrier WowUnit teamFlagCarrier = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(TeamFlagCarrierGuid); if (teamFlagCarrier != null) { if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Dps) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotMath.CalculatePositionBehind(teamFlagCarrier.Position, teamFlagCarrier.Rotation, 1f)); } else if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Tank) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotUtils.MoveAhead(teamFlagCarrier.Position, teamFlagCarrier.Rotation, 2f)); } else if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Heal) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, teamFlagCarrier.Position); } if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } else { // run to the enemy WowUnit enemyFlagCarrier = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(EnemyFlagCarrierGuid); if (enemyFlagCarrier != null) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotUtils.MoveAhead(enemyFlagCarrier.Position, enemyFlagCarrier.Rotation, ((float)WowInterface.ObjectManager.Player.Position.GetDistance2D(enemyFlagCarrier.Position)) / 2f)); if (WowInterface.CombatClass.Role != Statemachine.Enums.CombatClassRole.Heal && isInCombatReach(enemyFlagCarrier.Position)) { WowInterface.HookManager.TargetGuid(enemyFlagCarrier.Guid); } if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } else { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseHord : baseAlly); } WowInterface.CombatClass.OutOfCombatExecute(); } } } else if (ownTeamHasFlag) { // a team mate got the flag WowUnit teamFlagCarrier = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(TeamFlagCarrierGuid); if (teamFlagCarrier != null) { if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Dps) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotMath.CalculatePositionBehind(teamFlagCarrier.Position, teamFlagCarrier.Rotation, 1f)); } else if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Tank) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotUtils.MoveAhead(teamFlagCarrier.Position, teamFlagCarrier.Rotation, 2f)); } else if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Heal) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, teamFlagCarrier.Position); } if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } else { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseHord : baseAlly); } if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Dps) { if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } WowInterface.CombatClass.OutOfCombatExecute(); } else if (enemyTeamHasFlag) { // the enemy got the flag if (WowInterface.CombatClass.Role == Statemachine.Enums.CombatClassRole.Tank) { WowObject tmpFlag = getEnemyFlagObject(); enemyFlag = tmpFlag == null ? enemyFlag : tmpFlag; if (enemyFlag != null) { // flag lies around WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, enemyFlag.Position); if (isAtPosition(enemyFlag.Position)) { // flag reached, save it! hasStateChanged = true; WowInterface.HookManager.WowObjectOnRightClick(enemyFlag); } } else { // go outside! WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseAlly : baseHord); WowInterface.CombatClass.OutOfCombatExecute(); } } else { WowUnit enemyFlagCarrier = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(EnemyFlagCarrierGuid); if (enemyFlagCarrier != null) { WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, BotUtils.MoveAhead(enemyFlagCarrier.Position, enemyFlagCarrier.Rotation, ((float)WowInterface.ObjectManager.Player.Position.GetDistance2D(enemyFlagCarrier.Position)) / 2f)); if (WowInterface.CombatClass.Role != Statemachine.Enums.CombatClassRole.Heal && isInCombatReach(enemyFlagCarrier.Position)) { WowInterface.HookManager.TargetGuid(enemyFlagCarrier.Guid); } if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } } WowInterface.CombatClass.OutOfCombatExecute(); } } else { // go and get the enemy flag!!! WowObject tmpFlag = getEnemyFlagObject(); enemyFlag = tmpFlag == null ? enemyFlag : tmpFlag; if (enemyFlag != null) { // flag lies around WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, enemyFlag.Position); if (isAtPosition(enemyFlag.Position)) { // flag reached, save it! hasStateChanged = true; WowInterface.HookManager.WowObjectOnRightClick(enemyFlag); } } else { // go outside! WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseAlly : baseHord); WowInterface.CombatClass.OutOfCombatExecute(); } } if (WowInterface.MovementEngine.MovementAction == Movement.Enums.MovementAction.None) { hasStateChanged = true; WowInterface.MovementEngine.SetMovementAction(Movement.Enums.MovementAction.Moving, this.isHorde ? baseAlly : baseHord); if (isEnemyClose()) { WowInterface.Globals.ForceCombat = true; return; } WowInterface.CombatClass.OutOfCombatExecute(); } }
public static async Task <Bot.PaginatedMessageBuilder> BuildRecentEventsEmbedAsync(long startTimestamp, long endTimestamp, TimeUnits timeUnit = 0) { // Get all species created within the given timespan. List <Species> new_species = new List <Species>(); TimeAmount time_amount = new TimeAmount(endTimestamp - startTimestamp, TimeUnits.Seconds); if (timeUnit != 0) { time_amount = time_amount.ConvertTo(timeUnit); } else { time_amount = time_amount.Reduce(); } using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Species WHERE timestamp >= $start_ts AND timestamp < $end_ts")) { cmd.Parameters.AddWithValue("$start_ts", startTimestamp); cmd.Parameters.AddWithValue("$end_ts", endTimestamp); using (DataTable table = await Database.GetRowsAsync(cmd)) foreach (DataRow row in table.Rows) { new_species.Add(await SpeciesUtils.SpeciesFromDataRow(row)); } } new_species.Sort(); // Get all extinctions that occurred recently. List <Species> extinct_species = new List <Species>(); using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Extinctions WHERE timestamp >= $start_ts AND timestamp < $end_ts")) { cmd.Parameters.AddWithValue("$start_ts", startTimestamp); cmd.Parameters.AddWithValue("$end_ts", endTimestamp); using (DataTable table = await Database.GetRowsAsync(cmd)) foreach (DataRow row in table.Rows) { extinct_species.Add(await BotUtils.GetSpeciesFromDb(row.Field <long>("species_id"))); } } extinct_species.Sort(); // Build embed. Bot.PaginatedMessageBuilder embed = new Bot.PaginatedMessageBuilder(); List <EmbedBuilder> pages = new List <EmbedBuilder>(); List <string> field_lines = new List <string>(); if (new_species.Count() > 0) { foreach (Species sp in new_species) { field_lines.Add(sp.FullName); } EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("New species ({0})", new_species.Count())); field_lines.Clear(); } if (extinct_species.Count() > 0) { foreach (Species sp in extinct_species) { field_lines.Add(sp.FullName); } EmbedUtils.AddLongFieldToEmbedPages(pages, field_lines, fieldName: string.Format("Extinctions ({0})", extinct_species.Count())); field_lines.Clear(); } embed.AddPages(pages); embed.SetTitle(string.Format("Recent events ({0})", time_amount.ToString())); embed.SetFooter(string.Empty); // remove page numbers added automatically embed.AddPageNumbers(); if (embed.FieldCount <= 0) { embed.SetDescription("No events"); } return(embed); }
public async Task GiveItemAsync([Remainder] string args = "") { if (!ServerData.HasPermissionLevel(BotUtils.GetGUser(Context), ServerData.PermissionLevel.ADMIN)) { return; } List <string> data = args.Split(' ').ToList(); int id_ind = data.Count - 2; int count_ind = data.Count - 1; uint id; int count; if (!uint.TryParse(data[id_ind], out id) || ItemManager.GetItem(ItemId) == null) { await ReplyAsync(BotUtils.KamtroText("Please specify a valid item ID")); return; } if (!int.TryParse(data[count_ind], out count)) { await ReplyAsync(BotUtils.KamtroText("The count must be over 0!")); return; } ItemId = id; Count = count; data.RemoveRange(id_ind, 2); string search = ""; foreach (string s in data) { search += $"{s} "; } List <SocketGuildUser> users = BotUtils.GetUsers(search.Trim(' ')); if (users.Count == 0) { await ReplyAsync(BotUtils.KamtroText("I can't find a user with that name, make sure the name is spelt correctly!")); return; } else if (users.Count > 10) { await ReplyAsync(BotUtils.KamtroText("Please be more specific! You can attach a discriminator if you need to (Username#1234)")); return; } else if (users.Count == 1) { await GiveItem(users[0]); } else { UserSelectionEmbed use = new UserSelectionEmbed(users, GiveItem, BotUtils.GetGUser(Context)); await use.Display(Context.Channel); } }
public static void SaveUserSettings() { BotUtils.WriteToJson(UserSettings, DataFileNames.UserSettingsFile); KLog.Info("Saved user settings."); }
public async Task Map() { // Get map images from the database. Gallery gallery = await GalleryUtils.GetGalleryAsync(MAP_GALLERY_NAME); Picture primary = null; Picture labeled = null; if (!(gallery is null)) { primary = await BotUtils.GetPicFromDb(gallery, "primary"); labeled = await BotUtils.GetPicFromDb(gallery, "labeled"); } // If no primary image has been provided, display an error message. if (primary is null) { await BotUtils.ReplyAsync_Error(Context, string.Format("No map images have been set. Use the \"{0}setmap\" command to set map images.", OurFoodChainBot.Instance.Config.Prefix)); return; } // Build the embed. string worldName = OurFoodChainBot.Instance.Config.WorldName; string title = string.IsNullOrEmpty(worldName) ? "" : string.Format("Map of {0}", StringUtils.ToTitleCase(worldName)); string footer = (labeled is null) ? "" : "Click the Z reaction to toggle zone labels."; Bot.PaginatedMessage paginatedMessage = new Bot.PaginatedMessage(); // Add the first page (primary image without zone labels). paginatedMessage.Pages.Add(new EmbedBuilder { Title = title, ImageUrl = primary.url, Footer = new EmbedFooterBuilder { Text = footer } }.Build()); // A second page (with zone labels) is only included in the case an image has been provided. if (!(labeled is null)) { paginatedMessage.Pages.Add(new EmbedBuilder { Title = title, ImageUrl = labeled.url, Footer = new EmbedFooterBuilder { Text = footer } }.Build()); } // Send the embed. paginatedMessage.PrevEmoji = string.Empty; paginatedMessage.NextEmoji = string.Empty; if (paginatedMessage.Pages.Count > 1) { paginatedMessage.ToggleEmoji = "🇿"; } await Bot.DiscordUtils.SendMessageAsync(Context, paginatedMessage); }
private bool SearchNewTarget(ref WowUnit target, bool grinding) { if (DateTime.Now.Subtract(LastTargetCheck).TotalSeconds < 1 && target != null && !(target.IsDead || target.Health == 0)) { return(false); } LastTargetCheck = DateTime.Now; List <WowUnit> wowUnits = ObjectManager.WowObjects.OfType <WowUnit>().Where(e => HookManager.GetUnitReaction(ObjectManager.Player, e) != WowUnitReaction.Friendly && HookManager.GetUnitReaction(ObjectManager.Player, e) != WowUnitReaction.Neutral).ToList(); bool newTargetFound = false; int areaToLookAt = grinding ? 500 : 100; bool inCombat = (target == null || target.IsDead) ? false : target.IsInCombat; int targetHealth = (target == null || target.IsDead) ? 2147483647 : target.Health; ulong memberGuid = (target == null || target.IsDead) ? 0 : target.TargetGuid; WowUnit member = (target == null || target.IsDead) ? null : ObjectManager.WowObjects.OfType <WowUnit>().FirstOrDefault(t => t.Guid == memberGuid); int memberHealth = member == null ? 2147483647 : member.Health; int targetCount = 0; multipleTargets = false; foreach (WowUnit unit in wowUnits) { if (BotUtils.IsValidUnit(unit) && unit != target && !unit.IsDead) { double tmpDistance = ObjectManager.Player.Position.GetDistance(unit.Position); if (tmpDistance < areaToLookAt) { int compHealth = 2147483647; if (tmpDistance < 6.0) { targetCount++; } if (unit.IsInCombat) { member = ObjectManager.WowObjects.OfType <WowUnit>().FirstOrDefault(t => t.Guid == unit.TargetGuid); if (member != null) { compHealth = member.Health; } } if ((unit.IsInCombat && compHealth < memberHealth) || (!inCombat && grinding && (target == null || target.IsDead) && unit.Health < targetHealth)) { target = unit; newTargetFound = true; inCombat = unit.IsInCombat; memberHealth = compHealth; targetHealth = unit.Health; } } } } if (target == null || target.IsDead) { HookManager.ClearTarget(); ulong leaderGuid = ObjectManager.PartyleaderGuid; if (leaderGuid != ObjectManager.PlayerGuid) { WowUnit leader = ObjectManager.WowObjects.OfType <WowUnit>().FirstOrDefault(t => t.Guid == leaderGuid); HandleMovement(leader); } } else if (targetCount > 1) { multipleTargets = true; } if (newTargetFound) { HookManager.TargetGuid(target.Guid); } return(newTargetFound); }
public bool ExecuteTactic(CombatClassRole role, bool isMelee, out bool preventMovement, out bool allowAttacking) { preventMovement = false; allowAttacking = true; WowUnit wowUnit = WowInterface.I.ObjectManager.GetClosestWowUnitByDisplayId(BronjahmDisplayId, false); if (wowUnit != null) { if (wowUnit.CurrentlyCastingSpellId == 68872 || wowUnit.CurrentlyChannelingSpellId == 68872 || wowUnit.HasBuffById(68872)) // soulstorm { if (WowInterface.I.ObjectManager.Player.Position.GetDistance(MidPosition) > 8.0) { WowInterface.I.MovementEngine.SetMovementAction(MovementAction.Moving, BotUtils.MoveAhead(MidPosition, BotMath.GetFacingAngle(WowInterface.I.ObjectManager.Player.Position, MidPosition), -5.0f)); preventMovement = true; allowAttacking = true; return(true); } // stay at the mid return(false); } if (role == CombatClassRole.Tank) { if (wowUnit.TargetGuid == WowInterface.I.ObjectManager.PlayerGuid) { Vector3 modifiedCenterPosition = BotUtils.MoveAhead(MidPosition, BotMath.GetFacingAngle(WowInterface.I.ObjectManager.MeanGroupPosition, MidPosition), 8.0f); float distanceToMid = WowInterface.I.ObjectManager.Player.Position.GetDistance(modifiedCenterPosition); // flee from the corrupted souls target bool needToFlee = wowUnit.CurrentlyChannelingSpellId == 68839 || WowInterface.I.ObjectManager.WowObjects.OfType <WowUnit>().Any(e => e.DisplayId == 30233 && e.IsInCombat); if (needToFlee) { if (distanceToMid < 16.0f) { WowInterface.I.MovementEngine.SetMovementAction(MovementAction.Fleeing, modifiedCenterPosition); preventMovement = true; allowAttacking = false; return(true); } // we cant run away further preventMovement = true; return(false); } if (distanceToMid > 5.0f && WowInterface.I.ObjectManager.Player.Position.GetDistance(wowUnit.Position) < 3.5) { // move the boss to mid WowInterface.I.MovementEngine.SetMovementAction(MovementAction.Moving, modifiedCenterPosition); preventMovement = true; allowAttacking = false; return(true); } } } else if (role == CombatClassRole.Dps || role == CombatClassRole.Heal) { float distanceToMid = WowInterface.I.ObjectManager.Player.Position.GetDistance(MidPosition); if (!isMelee && distanceToMid < 20.0f) { // move to the outer ring of the arena WowInterface.I.MovementEngine.SetMovementAction(MovementAction.Moving, BotUtils.MoveAhead(MidPosition, BotMath.GetFacingAngle(WowInterface.I.ObjectManager.Player.Position, MidPosition), -22.0f)); preventMovement = true; allowAttacking = false; return(true); } } } return(false); }
public async Task AddZoneType(params string[] args) { if (args.Count() <= 0) { await BotUtils.ReplyAsync_Error(Context, "You must specify a name for the zone type."); } else if (args.Count() > 4) { await BotUtils.ReplyAsync_Error(Context, "Too many arguments have been provided."); } else { string name = args[0]; string icon = ZoneTypeBase.DefaultIcon; System.Drawing.Color color = ZoneTypeBase.DefaultColor; string description = ""; if (await Db.GetZoneTypeAsync(name) != null) { // If a zone type with this name already exists, do not create a new one. await BotUtils.ReplyAsync_Warning(Context, string.Format("A zone type named \"{0}\" already exists.", name)); } else { // Read the rest of the arguments. for (int i = 1; i < args.Count(); ++i) { if (DiscordUtils.IsEmoji(args[i])) { icon = args[i]; } else if (StringUtilities.TryParseColor(args[i], out System.Drawing.Color result)) { color = result; } else if (string.IsNullOrEmpty(description)) { description = args[i]; } else { await BotUtils.ReplyAsync_Warning(Context, string.Format("Invalid argument provided: {0}", args[i])); } } ZoneType type = new ZoneType { Name = name, Icon = icon, Description = description, Color = color }; // Add the zone type to the database. await Db.AddZoneTypeAsync(type); await BotUtils.ReplyAsync_Success(Context, string.Format("Successfully created new zone type **{0}**.", type.Name)); } } }
public async Task SetSpecies(string genus, string species, string newName) { // Get the specified species. Species sp = await BotUtils.ReplyFindSpeciesAsync(Context, genus, species); if (sp is null) { return; } // Update the species. using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Species SET name=$name WHERE id=$species_id;")) { cmd.Parameters.AddWithValue("$name", newName.ToLower()); cmd.Parameters.AddWithValue("$species_id", sp.Id); await Database.ExecuteNonQuery(cmd); } await BotUtils.ReplyAsync_Success(Context, string.Format("**{0}** has been successfully renamed to **{1}**.", sp.ShortName, BotUtils.GenerateSpeciesName(sp.GenusName, newName))); }
public void CapitalizeTest() { string s = "lool"; Assert.AreEqual("Lool", BotUtils.Capitalize(s)); }
public async Task AddSpecies(string genus, string species, string zone = "", string description = "") { // Check if the species already exists before attempting to add it. if ((await BotUtils.GetSpeciesFromDb(genus, species)).Count() > 0) { await BotUtils.ReplyAsync_Warning(Context, string.Format("The species \"{0}\" already exists.", BotUtils.GenerateSpeciesName(genus, species))); return; } await BotUtils.AddGenusToDb(genus); Taxon genus_info = await BotUtils.GetGenusFromDb(genus); using (SQLiteCommand cmd = new SQLiteCommand("INSERT INTO Species(name, description, genus_id, owner, timestamp, user_id) VALUES($name, $description, $genus_id, $owner, $timestamp, $user_id);")) { cmd.Parameters.AddWithValue("$name", species.ToLower()); cmd.Parameters.AddWithValue("$description", description); cmd.Parameters.AddWithValue("$genus_id", genus_info.id); cmd.Parameters.AddWithValue("$owner", Context.User.Username); cmd.Parameters.AddWithValue("$user_id", Context.User.Id); cmd.Parameters.AddWithValue("$timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds()); await Database.ExecuteNonQuery(cmd); } Species[] sp_list = await BotUtils.GetSpeciesFromDb(genus, species); Species sp = sp_list.Count() > 0 ? sp_list[0] : null; long species_id = sp == null ? -1 : sp.Id; if (species_id < 0) { await BotUtils.ReplyAsync_Error(Context, "Failed to add species (invalid Species ID)."); return; } // Add to all given zones. await _plusZone(sp, zone, string.Empty, onlyShowErrors : true); // Add the user to the trophy scanner queue in case their species earned them any new trophies. if (OurFoodChainBot.Instance.Config.TrophiesEnabled) { await Global.TrophyScanner.AddToQueueAsync(Context, Context.User.Id); } await BotUtils.ReplyAsync_Success(Context, string.Format("Successfully created new species, **{0}**.", BotUtils.GenerateSpeciesName(genus, species))); }
public async Task Mod([Remainder] string mod) { mod = mod.RemoveWhitespace(); if (mod.EqualsIgnoreCase(">count")) { await ReplyAsync($"Found `{ModsManager.Mods.Count()}` cached mods"); return; } var(result, str) = await ShowSimilarMods(mod); if (result) { if (string.IsNullOrEmpty(str)) { // Fixes not finding files mod = ModsManager.Mods.FirstOrDefault(m => string.Equals(m, mod, StringComparison.CurrentCultureIgnoreCase)); if (mod == null) { return; } } else { mod = str; } // Some mod is found continue. var modjson = JObject.Parse(await BotUtils.FileReadToEndAsync(new SemaphoreSlim(1, 1), ModsManager.ModPath(mod))); var eb = new EmbedBuilder() .WithTitle("Mod: ") .WithCurrentTimestamp() .WithAuthor(new EmbedAuthorBuilder { IconUrl = Context.Message.Author.GetAvatarUrl(), Name = $"Requested by {Context.Message.Author.FullName()}" }); foreach (var property in modjson.Properties().Where(x => !string.IsNullOrEmpty(x.Value.ToString()))) { var name = property.Name; var value = property.Value; if (name.EqualsIgnoreCase("displayname")) { eb.Title += value.ToString(); } else if (name.EqualsIgnoreCase("downloads")) { eb.AddField("# of Downloads", $"{property.Value:n0}", true); } else if (name.EqualsIgnoreCase("updatetimestamp")) { eb.AddField("Last updated", DateTime.Parse($"{property.Value}").ToString("dddd, MMMMM d, yyyy h:mm:ss tt", new CultureInfo("en-US")), true); } else if (name.EqualsIgnoreCase("iconurl")) { eb.ThumbnailUrl = value.ToString(); } else { eb.AddField(name.FirstCharToUpper(), value, true); } } eb.AddField("Widget", $"<{ModsManager.WidgetUrl}{mod}.png>", true); using (var client = new System.Net.Http.HttpClient()) { var response = await client.GetAsync(ModsManager.QueryHomepageUrl + mod); var postResponse = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrEmpty(postResponse) && !postResponse.StartsWith("Failed:")) { eb.Url = postResponse; eb.AddField("Homepage", $"<{postResponse}>", true); } } await ReplyAsync("", embed : eb.Build()); } }
public static async Task ShowSpeciesInfoAsync(ICommandContext context, Species species) { if (await BotUtils.ReplyValidateSpeciesAsync(context, species)) { EmbedBuilder embed = new EmbedBuilder(); StringBuilder descriptionBuilder = new StringBuilder(); string embed_title = species.FullName; Color embed_color = Color.Blue; CommonName[] common_names = await SpeciesUtils.GetCommonNamesAsync(species); if (common_names.Count() > 0) { embed_title += string.Format(" ({0})", string.Join(", ", (object[])common_names)); } // Show generation only if generations are enabled. if (OurFoodChainBot.Instance.Config.GenerationsEnabled) { Generation gen = await GenerationUtils.GetGenerationByTimestampAsync(species.Timestamp); embed.AddField("Gen", gen is null ? "???" : gen.Number.ToString(), inline: true); } embed.AddField("Owner", await SpeciesUtils.GetOwnerOrDefaultAsync(species, context), inline: true); SpeciesZone[] zone_list = await SpeciesUtils.GetZonesAsync(species); if (zone_list.Count() > 0) { embed_color = Bot.DiscordUtils.ConvertColor((await ZoneUtils.GetZoneTypeAsync(zone_list .GroupBy(x => x.Zone.ZoneTypeId) .OrderBy(x => x.Count()) .Last() .Key)).Color); } string zones_value = new SpeciesZoneCollection(zone_list).ToString(SpeciesZoneCollectionToStringOptions.Default, Bot.DiscordUtils.MaxFieldLength); embed.AddField("Zone(s)", string.IsNullOrEmpty(zones_value) ? "None" : zones_value, inline: true); // Check if the species is extinct. using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM Extinctions WHERE species_id=$species_id;")) { cmd.Parameters.AddWithValue("$species_id", species.Id); DataRow row = await Database.GetRowAsync(cmd); if (!(row is null)) { embed_title = "[EXTINCT] " + embed_title; embed_color = Color.Red; string reason = row.Field <string>("reason"); long timestamp = (long)row.Field <decimal>("timestamp"); if (!string.IsNullOrEmpty(reason)) { descriptionBuilder.AppendLine(string.Format("**Extinct ({0}):** _{1}_\n", await BotUtils.TimestampToDateStringAsync(timestamp), reason)); } } } descriptionBuilder.Append(species.GetDescriptionOrDefault()); embed.WithTitle(embed_title); embed.WithThumbnailUrl(species.Picture); embed.WithColor(embed_color); if (!string.IsNullOrEmpty(OurFoodChainBot.Instance.Config.WikiUrlFormat)) { // Discord automatically encodes certain characters in URIs, which doesn't allow us to update the config via Discord when we have "{0}" in the URL. // Replace this with the proper string before attempting to call string.Format. string format = OurFoodChainBot.Instance.Config.WikiUrlFormat.Replace("%7B0%7D", "{0}"); embed.WithUrl(string.Format(format, Uri.EscapeUriString(GetWikiPageTitleForSpecies(species, common_names)))); } if (embed.Length + descriptionBuilder.Length > DiscordUtils.MaxEmbedLength) { // If the description puts us over the character limit, we'll paginate. int pageLength = DiscordUtils.MaxEmbedLength - embed.Length; List <EmbedBuilder> pages = new List <EmbedBuilder>(); foreach (string pageText in new StringPaginator(descriptionBuilder.ToString()) { MaxPageLength = pageLength }) { EmbedBuilder page = new EmbedBuilder(); page.WithTitle(embed.Title); page.WithThumbnailUrl(embed.ThumbnailUrl); page.WithFields(embed.Fields); page.WithDescription(pageText); pages.Add(page); } PaginatedMessageBuilder builder = new Bot.PaginatedMessageBuilder(pages); builder.AddPageNumbers(); builder.SetColor(embed_color); await DiscordUtils.SendMessageAsync(context, builder.Build()); } else { embed.WithDescription(descriptionBuilder.ToString()); await context.Channel.SendMessageAsync("", false, embed.Build()); } } }
private bool HandleMovement(WowUnit target) { // handle the LOS check if (target == null || target.Guid == WowInterface.ObjectManager.PlayerGuid) { TargetInLos = true; } else if (LineOfSightCheck.Run(out bool isInLos, () => WowInterface.HookManager.WowIsInLineOfSight(WowInterface.ObjectManager.Player.Position, target.Position))) { TargetInLos = isInLos; } // set LOS in CombatClass if (WowInterface.CombatClass != null) { WowInterface.CombatClass.TargetInLineOfSight = WowInterface.ObjectManager.TargetGuid == 0 || TargetInLos; } // check if we are facing the unit if (target != null && !WowInterface.HookManager.WowIsClickToMoveActive() && FacingCheck.Run() && target.Guid != WowInterface.ObjectManager.PlayerGuid && !BotMath.IsFacing(WowInterface.ObjectManager.Player.Position, WowInterface.ObjectManager.Player.Rotation, target.Position)) { WowInterface.HookManager.WowFacePosition(WowInterface.ObjectManager.Player, target.Position); } // do we need to move if (target == null) { // just move to our group WowInterface.MovementEngine.SetMovementAction(MovementAction.Moving, WowInterface.ObjectManager.MeanGroupPosition); return(true); } else { float distance = WowInterface.ObjectManager.Player.Position.GetDistance(target.Position); if (distance > DistanceToKeep || !TargetInLos) { Vector3 positionToGoTo = Vector3.Zero; if (WowInterface.CombatClass != null) { // handle special movement needs if (WowInterface.CombatClass.WalkBehindEnemy) { if (WowInterface.CombatClass.Role == CombatClassRole.Dps && (WowInterface.ObjectManager.Target.TargetGuid != WowInterface.ObjectManager.PlayerGuid || WowInterface.ObjectManager.Target.Type == WowObjectType.Player)) // prevent spinning { // walk behind enemy positionToGoTo = BotMath.CalculatePositionBehind(target.Position, target.Rotation); } else if (WowInterface.CombatClass.Role == CombatClassRole.Tank && WowInterface.ObjectManager.Partymembers.Any()) // no need to rotate { // rotate the boss away from the group Vector3 meanGroupPosition = WowInterface.ObjectManager.MeanGroupPosition; positionToGoTo = BotMath.CalculatePositionBehind(target.Position, BotMath.GetFacingAngle(target.Position, meanGroupPosition)); } } else if (WowInterface.CombatClass.Role == CombatClassRole.Heal) { // move to group positionToGoTo = target != null ? target.Position : WowInterface.ObjectManager.MeanGroupPosition; } else { // just move to the enemies melee/ranged range positionToGoTo = target.Position; } if (TargetInLos) { positionToGoTo = BotUtils.MoveAhead(WowInterface.ObjectManager.Player.Position, positionToGoTo, -(DistanceToKeep * 0.8f)); } WowInterface.MovementEngine.SetMovementAction(MovementAction.Moving, positionToGoTo); return(true); } if (TargetInLos) { positionToGoTo = BotUtils.MoveAhead(WowInterface.ObjectManager.Player.Position, positionToGoTo, -(DistanceToKeep * 0.8f)); } // just move to the enemies melee/ranged range positionToGoTo = target.Position; WowInterface.MovementEngine.SetMovementAction(MovementAction.Moving, positionToGoTo); return(true); } } // no need to move WowInterface.MovementEngine.StopMovement(); return(false); }
public async Task ListSpecies(string taxonName) { // Get the taxon. Taxon taxon = await BotUtils.GetTaxonFromDb(taxonName); if (taxon is null) { await BotUtils.ReplyAsync_Error(Context, "No such taxon exists."); return; } // Get all species under that taxon. List <Species> species = new List <Species>(); species.AddRange(await BotUtils.GetSpeciesInTaxonFromDb(taxon)); species.Sort((lhs, rhs) => lhs.FullName.CompareTo(rhs.FullName)); // We might get a lot of species, which may not fit in one embed. // We'll need to use a paginated embed to reliably display the full list. // Create embed pages. List <EmbedBuilder> pages = EmbedUtils.SpeciesListToEmbedPages(species, fieldName: string.Format("Species in this {0} ({1}):", taxon.GetTypeName(), species.Count())); if (pages.Count <= 0) { pages.Add(new EmbedBuilder()); } // Add description to the first page. StringBuilder description_builder = new StringBuilder(); description_builder.AppendLine(taxon.GetDescriptionOrDefault()); if (species.Count() <= 0) { description_builder.AppendLine(); description_builder.AppendLine(string.Format("This {0} contains no species.", Taxon.GetRankName(taxon.type))); } // Add title to all pages. foreach (EmbedBuilder page in pages) { page.WithTitle(string.IsNullOrEmpty(taxon.CommonName) ? taxon.GetName() : string.Format("{0} ({1})", taxon.GetName(), taxon.GetCommonName())); page.WithDescription(description_builder.ToString()); page.WithThumbnailUrl(taxon.pics); } // Send the result. Bot.PaginatedMessage reply = new Bot.PaginatedMessage(); foreach (EmbedBuilder page in pages) { reply.Pages.Add(page.Build()); } await Bot.DiscordUtils.SendMessageAsync(Context, reply); }
private bool SearchNewTarget(ref WowUnit target, bool grinding) { if (WowInterface.ObjectManager.TargetGuid != 0 && target != null && !(target.IsDead || target.Health < 1 || target.Auras.Any(e => e.Name.Contains("Spirit of Redem")))) { return(false); } List <WowUnit> wowUnits = WowInterface.ObjectManager.WowObjects.OfType <WowUnit>().Where(e => WowInterface.HookManager.WowGetUnitReaction(WowInterface.ObjectManager.Player, e) != WowUnitReaction.Friendly && WowInterface.HookManager.WowGetUnitReaction(WowInterface.ObjectManager.Player, e) != WowUnitReaction.Neutral).ToList(); bool newTargetFound = false; int areaToLookAt = grinding ? 100 : 50; bool inCombat = (target == null || target.IsDead || target.Health < 1) ? false : target.IsInCombat; int targetHealth = (target == null || target.IsDead || target.Health < 1) ? 2147483647 : target.Health; ulong memberGuid = (target == null || target.IsDead || target.Health < 1) ? 0 : target.TargetGuid; WowUnit member = (target == null || target.IsDead || target.Health < 1) ? null : WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(memberGuid); int memberHealth = member == null ? 2147483647 : member.Health; int targetCount = 0; multipleTargets = false; foreach (WowUnit unit in wowUnits) { if (BotUtils.IsValidUnit(unit) && unit != target && !(unit.IsDead || unit.Health < 1 || unit.Auras.Any(e => e.Name.Contains("Spirit of Redem")))) { double tmpDistance = WowInterface.ObjectManager.Player.Position.GetDistance(unit.Position); if (tmpDistance < areaToLookAt) { int compHealth = 2147483647; if (tmpDistance < 6.0) { targetCount++; } if (unit.IsInCombat) { member = WowInterface.ObjectManager.GetWowObjectByGuid <WowUnit>(unit.TargetGuid); if (member != null) { compHealth = member.Health; } } if (((unit.IsInCombat && (compHealth < memberHealth || (compHealth == memberHealth && targetHealth < unit.Health))) || (!inCombat && grinding && (target == null || target.IsDead) && unit.Health < targetHealth)) && WowInterface.HookManager.WowIsInLineOfSight(WowInterface.ObjectManager.Player.Position, unit.Position)) { target = unit; newTargetFound = true; inCombat = unit.IsInCombat; memberHealth = compHealth; targetHealth = unit.Health; } } } } if (target == null || target.IsDead || target.Health < 1 || target.Auras.Any(e => e.Name.Contains("Spirit of Redem"))) { WowInterface.HookManager.WowClearTarget(); newTargetFound = false; target = null; } else if (newTargetFound) { WowInterface.HookManager.WowTargetGuid(target.Guid); } if (targetCount > 1) { multipleTargets = true; } return(newTargetFound); }
public override void Execute() { // dont follow when casting, or player is dead/ghost if (WowInterface.ObjectManager.Player.IsCasting || (PlayerToFollow != null && (PlayerToFollow.IsDead || PlayerToFollow.Health == 1))) { return; } if (PlayerToFollow == null) { // handle nearby portals, if our groupleader enters a portal, we follow WowGameobject nearestPortal = WowInterface.ObjectManager.WowObjects .OfType <WowGameobject>() .Where(e => e.DisplayId == (int)GameobjectDisplayId.UtgardeKeepDungeonPortalNormal || e.DisplayId == (int)GameobjectDisplayId.UtgardeKeepDungeonPortalHeroic) .FirstOrDefault(e => e.Position.GetDistance(WowInterface.ObjectManager.Player.Position) < 12.0); if (nearestPortal != null) { WowInterface.MovementEngine.SetMovementAction(MovementAction.DirectMove, BotUtils.MoveAhead(WowInterface.ObjectManager.Player.Position, nearestPortal.Position, 6f)); } else { StateMachine.SetState(BotState.Idle); } return; } Vector3 posToGoTo; if (Config.FollowPositionDynamic) { posToGoTo = PlayerToFollow.Position + Offset; } else { posToGoTo = PlayerToFollow.Position; } double distance = WowInterface.ObjectManager.Player.Position.GetDistance(posToGoTo); if (distance < Config.MinFollowDistance || distance > Config.MaxFollowDistance) { StateMachine.SetState(BotState.Idle); return; } if (Config.UseMountsInParty && WowInterface.CharacterManager.Mounts?.Count > 0 && PlayerToFollow != null && PlayerToFollow.IsMounted && !WowInterface.ObjectManager.Player.IsMounted) { if (CastMountEvent.Run()) { List <WowMount> filteredMounts; if (Config.UseOnlySpecificMounts) { filteredMounts = WowInterface.CharacterManager.Mounts.Where(e => Config.Mounts.Split(",", StringSplitOptions.RemoveEmptyEntries).Contains(e.Name)).ToList(); } else { filteredMounts = WowInterface.CharacterManager.Mounts; } if (filteredMounts != null && filteredMounts.Count >= 0) { WowMount mount = filteredMounts[new Random().Next(0, filteredMounts.Count)]; WowInterface.MovementEngine.StopMovement(); WowInterface.HookManager.LuaCallCompanion(mount.Index); } } return; } double zDiff = posToGoTo.Z - WowInterface.ObjectManager.Player.Position.Z; if (LosCheckEvent.Run()) { if (WowInterface.HookManager.WowIsInLineOfSight(WowInterface.ObjectManager.Player.Position, posToGoTo, 2f)) { InLos = true; } else { InLos = false; } } if (zDiff < -4.0 && InLos) // target is below us and in line of sight, just run down { WowInterface.MovementEngine.SetMovementAction(MovementAction.DirectMove, posToGoTo); } else { WowInterface.MovementEngine.SetMovementAction(MovementAction.Following, posToGoTo); } }
public WowInterface548(WowMemoryApi memory) { Memory = memory; HookModules = new(); // lua variable names for the event hook string handlerName = BotUtils.FastRandomStringOnlyLetters(); string tableName = BotUtils.FastRandomStringOnlyLetters(); string eventHookOutput = BotUtils.FastRandomStringOnlyLetters(); // name of the frame used to capture wows events string eventHookFrameName = BotUtils.FastRandomStringOnlyLetters(); EventManager = new(LuaDoString, eventHookFrameName); // module to process wows events. HookModules.Add(new RunLuaHookModule ( (x) => { if (x != IntPtr.Zero && memory.ReadString(x, Encoding.UTF8, out string s) && !string.IsNullOrWhiteSpace(s)) { EventManager.OnEventPush(s); } }, null, memory, LuaEventHook.Get(eventHookFrameName, tableName, handlerName, eventHookOutput), eventHookOutput )); string staticPopupsVarName = BotUtils.FastRandomStringOnlyLetters(); string oldPoupString = string.Empty; // module that monitors the STATIC_POPUP windows. HookModules.Add(new RunLuaHookModule ( (x) => { if (x != IntPtr.Zero && memory.ReadString(x, Encoding.UTF8, out string s) && !string.IsNullOrWhiteSpace(s)) { if (!oldPoupString.Equals(s, StringComparison.Ordinal)) { OnStaticPopup?.Invoke(s); oldPoupString = s; } } else { oldPoupString = string.Empty; } }, null, memory, $"{staticPopupsVarName}=\"\"for b=1,STATICPOPUP_NUMDIALOGS do local c=_G[\"StaticPopup\"..b]if c:IsShown()then {staticPopupsVarName}={staticPopupsVarName}..b..\":\"..c.which..\"; \"end end", staticPopupsVarName )); string battlegroundStatusVarName = BotUtils.FastRandomStringOnlyLetters(); string oldBattlegroundStatus = string.Empty; // module to monitor the battleground (and queue) status. HookModules.Add(new RunLuaHookModule ( (x) => { if (x != IntPtr.Zero && memory.ReadString(x, Encoding.UTF8, out string s) && !string.IsNullOrWhiteSpace(s)) { if (!oldBattlegroundStatus.Equals(s, StringComparison.Ordinal)) { OnBattlegroundStatus?.Invoke(s); oldBattlegroundStatus = s; } } else { oldBattlegroundStatus = string.Empty; } }, null, memory, $"{battlegroundStatusVarName}=\"\"for b=1,2 do local c,d,e,f,g,h=GetBattlefieldStatus(b)local i=GetBattlefieldTimeWaited(b)/1000;{battlegroundStatusVarName}={battlegroundStatusVarName}..b..\":\"..tostring(c or\"unknown\")..\":\"..tostring(d or\"unknown\")..\":\"..tostring(e or\"unknown\")..\":\"..tostring(f or\"unknown\")..\":\"..tostring(g or\"unknown\")..\":\"..tostring(h or\"unknown\")..\":\"..tostring(i or\"unknown\")..\";\"end", battlegroundStatusVarName )); // module to detect small obstacles that we can jump over HookModules.Add(new TracelineJumpHookModule ( null, (x) => { IntPtr dataPtr = x.GetDataPointer(); if (dataPtr != IntPtr.Zero && Player != null) { Vector3 playerPosition = Player.Position; playerPosition.Z += 1.3f; Vector3 pos = BotUtils.MoveAhead(playerPosition, Player.Rotation, 0.25f); memory.Write(dataPtr, (1.0f, playerPosition, pos)); } }, memory )); ObjectManager = new(memory); Hook = new(memory); Hook.OnGameInfoPush += ObjectManager.HookManagerOnGameInfoPush; }
private async Task _endBattle(ICommandContext context) { PlayerState winner = player1.Gotchi.Stats.Hp <= 0.0 ? player2 : player1; PlayerState loser = player1.Gotchi.Stats.Hp <= 0.0 ? player1 : player2; // Calculate the amount of EXP awarded to the winner. // The loser will get 50% of the winner's EXP. double exp = _getExpEarned(winner.Gotchi.Gotchi, loser.Gotchi.Gotchi, won: true); double exp1 = player2.Gotchi.Stats.Hp <= 0.0 ? exp : exp * .5; double exp2 = player1.Gotchi.Stats.Hp <= 0.0 ? exp : exp * .5; long levels1 = player1.Gotchi.Stats.AddExperience((int)exp1); long levels2 = player2.Gotchi.Stats.AddExperience((int)exp2); StringBuilder sb = new StringBuilder(); sb.AppendLine(battleText); // Show the winner's accomplishments, then the loser's. if (!IsCpuGotchi(winner.Gotchi.Gotchi)) { double winner_exp = winner.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? exp1 : exp2; long winner_levels = winner.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? levels1 : levels2; long winner_g = (long)Math.Round(loser.Gotchi.Stats.Level * (BotUtils.RandomInteger(150, 200) / 100.0)); sb.AppendLine(string.Format("🏆 **{0}** won the battle! Earned **{1} EXP** and **{2}G**.", winner.Gotchi.Gotchi.Name, winner_exp, winner_g)); if (winner_levels > 0) { sb.AppendLine(string.Format("🆙 **{0}** leveled up to level **{1}**!", winner.Gotchi.Gotchi.Name, winner.Gotchi.Stats.Level)); } if (((winner.Gotchi.Stats.Level - winner_levels) / 10) < (winner.Gotchi.Stats.Level / 10)) { if (await GotchiUtils.EvolveAndUpdateGotchiAsync(winner.Gotchi.Gotchi)) { Species sp = await BotUtils.GetSpeciesFromDb(winner.Gotchi.Gotchi.SpeciesId); sb.AppendLine(string.Format("🚩 Congratulations, **{0}** evolved into **{1}**!", winner.Gotchi.Gotchi.Name, sp.ShortName)); } } // Update the winner's G. GotchiUserInfo user_data = await GotchiUtils.GetUserInfoAsync(winner.Gotchi.Gotchi.OwnerId); user_data.G += winner_g; await GotchiUtils.UpdateUserInfoAsync(user_data); sb.AppendLine(); } if (!IsCpuGotchi(loser.Gotchi.Gotchi)) { double loser_exp = loser.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? exp1 : exp2; long loser_levels = loser.Gotchi.Gotchi.Id == player1.Gotchi.Gotchi.Id ? levels1 : levels2; sb.AppendLine(string.Format("💀 **{0}** lost the battle... Earned **{1} EXP**.", loser.Gotchi.Gotchi.Name, loser_exp)); if (loser_levels > 0) { sb.AppendLine(string.Format("🆙 **{0}** leveled up to level **{1}**!", loser.Gotchi.Gotchi.Name, loser.Gotchi.Stats.Level)); } if (((loser.Gotchi.Stats.Level - loser_levels) / 10) < (loser.Gotchi.Stats.Level / 10)) { if (await GotchiUtils.EvolveAndUpdateGotchiAsync(loser.Gotchi.Gotchi)) { Species sp = await BotUtils.GetSpeciesFromDb(loser.Gotchi.Gotchi.SpeciesId); sb.AppendLine(string.Format("🚩 Congratulations, **{0}** evolved into **{1}**!", loser.Gotchi.Gotchi.Name, sp.ShortName)); } } } // Update exp in the database. using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Gotchi SET level=$level, exp=$exp WHERE id=$id;")) { cmd.Parameters.AddWithValue("$id", player1.Gotchi.Gotchi.Id); cmd.Parameters.AddWithValue("$level", DBNull.Value); cmd.Parameters.AddWithValue("$exp", player1.Gotchi.Stats.Experience); await Database.ExecuteNonQuery(cmd); } if (!IsCpuGotchi(player2.Gotchi.Gotchi)) { using (SQLiteCommand cmd = new SQLiteCommand("UPDATE Gotchi SET level=$level, exp=$exp WHERE id=$id;")) { cmd.Parameters.AddWithValue("$id", player2.Gotchi.Gotchi.Id); cmd.Parameters.AddWithValue("$level", DBNull.Value); cmd.Parameters.AddWithValue("$exp", player2.Gotchi.Stats.Experience); await Database.ExecuteNonQuery(cmd); } } // Deregister the battle state. DeregisterBattle(context.User.Id); battleText = sb.ToString(); }