/// <summary> /// Gets all channels from DB. Looksup all flagged as autojoin channels against Twitch.API. Then checks if we are in the valid channels. If not we join them. /// </summary> /// <returns></returns> public async Task JoinAllAutoJoinTwitchChannels() { List <string> chansToLookup = new List <string>(); foreach (BotChannel chan in await GetChannels()) { if (chan.TwitchChannelName != string.Empty && chan.TwitchAutojoin) { chansToLookup.Add(chan.TwitchChannelName); } } if (chansToLookup.Count < 1) { return; } TwitchLib.Api.V5.Models.Users.Users channelEntries = await Program.TwitchAPI.V5.Users.GetUsersByNameAsync(chansToLookup); if (channelEntries.Matches.Length < 1) { return; } foreach (TwitchLib.Api.V5.Models.Users.User usr in channelEntries.Matches) { var channel = Program.TwitchClient.GetJoinedChannel(usr.Name); if (channel == null) { Program.TwitchClient.JoinChannel(usr.Name); } } //await LaunchAllPubSubs(); // TODO eneable pubsubs somehow later }
public static async Task <TwitchLib.Api.V5.Models.Users.User> GetUserByName(string name) { TwitchLib.Api.V5.Models.Users.Users x = await Api.V5.Users.GetUserByNameAsync(name); try { return(x.Matches[0]); } catch (Exception e) { Logger.Instance.WriteLog($"Api controller GetUserByName ex : Err User not found . Details : {e.Message}", "TwitchApiController_GetUserByName"); } return(null); }
private async void OnRewardRedeemed(object sender, OnRewardRedeemedArgs e) { // Check if the reward is a buy spice reward in the format ... (xN) where N is amount of spice bought if (e.Status == "ACTION_TAKEN") { Regex rxCheck = new Regex(@"\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase); MatchCollection matches = rxCheck.Matches(e.RewardTitle); foreach (Match match in matches) { int amount = Int32.Parse(match.Value); TwitchLib.Api.V5.Models.Users.Users user = await UsernameToUser(e.DisplayName); UpdateSpiceStorage(ref userStorage, user.Matches[0].Id, user.Matches[0].DisplayName, amount); } } }
/// <summary> /// Tries to connect to the channel after validation through Twitch.API. /// </summary> /// <param name="channelName"></param> /// <returns></returns> public async Task <bool> JoinTwitchChannel(string channelName) { try { TwitchLib.Api.V5.Models.Users.Users channelEntry = await Program.TwitchAPI.V5.Users.GetUserByNameAsync(channelName.ToLower()); if (channelEntry.Matches.Length < 1) { await Core.LOG(new LogEntry(LOGSEVERITY.ERROR, PLUGINNAME, $"Twitch channel lookup failed! Couldn't find channel. Not connecting to \"{channelName.ToLower()}\"")); return(false); } } catch (Exception) { await Core.LOG(new LogEntry(LOGSEVERITY.ERROR, PLUGINNAME, $"Twitch channel lookup failed! Couldn't find channel. Not connecting to \"{channelName.ToLower()}\"")); return(false); } Program.TwitchClient.JoinChannel(channelName); return(true); }
/// <summary> /// Returns 1 match from DB. Creates one if needed and then resolves the Twitchname against Twitch.API to get the Twitch.ID /// Return Null if unkown user fails a lookup through Twitch API /// </summary> /// <param name="TwitchName"></param> /// <returns></returns> public async Task <BotChannel> GetTwitchChannelByName(string TwitchName) { if (!await ChannelDataExists(TwitchName)) { TwitchLib.Api.V5.Models.Users.Users channelEntry = null; try { while (apiQueryLock) { } if (!await ChannelDataExists(TwitchName)) { apiQueryLock = true; channelEntry = await Program.TwitchAPI.V5.Users.GetUserByNameAsync(TwitchName.ToLower()); } if (channelEntry == null || channelEntry.Matches.Length < 1) { apiQueryLock = false; return(null); } await ChannelDataWrite(new BotChannel(channelEntry.Matches[0].Name, channelEntry.Matches[0].Id)); apiQueryLock = false; return(await ChannelDataRead(TwitchName)); } catch (Exception) { apiQueryLock = false; return(null); } } else { return(await ChannelDataRead(TwitchName)); } }
private async void OnCommandRecieved(BotWideCommandArguments args) { BotChannel bChan = await GetBotChannel(args); BotWideResponseArguments response = new BotWideResponseArguments(args); // TEMPORARY this should later move to a better suited plugin if (args.command == "juanage") { response.message = JuanAge(); Respond(bChan, response); return; } if (args.isBroadcaster || args.isModerator || args.canManageMessages) { switch (args.command) { case "twitch": // anything twitch has to go through discord if (args.source != MESSAGESOURCE.DISCORD) { return; } // Clean command response if (args.arguments.Count == 0) { if (bChan.TwitchChannelName == string.Empty) { response.message = $"There is no twitch channel tied to this Discord. Use \"{CMC}twitch channel <NameOfTwitchChannel>\" to tie a channel to this Discord."; } else { response.message = $"Currently this Discord is tied to the Twitch channel \"{bChan.TwitchChannelName}\""; } Respond(bChan, response); return; } switch (args.arguments[0]) { case "channel": if (args.arguments.Count == 2) { TwitchLib.Api.V5.Models.Users.Users users = await Program.TwitchAPI.V5.Users.GetUserByNameAsync(args.arguments[1].ToLower()); if (users.Matches.Length != 1) { // Failed to look up twitch channel so notify and exit response.message = "Sorry. Could not find that channel. Make sure you enter it correctly and try again."; Respond(bChan, response); return; } bChan.TwitchChannelName = args.arguments[1].ToLower(); bChan.TwitchChannelID = users.Matches[0].Id; bChan.TwitchAutojoin = true; response.message = $"This Discord is now tied to the Twitch channel \"{bChan.TwitchChannelName}\"."; Program.Channels.ChannelSave(bChan); if (Program.TwitchConnected) { await Program.Channels.JoinAllAutoJoinTwitchChannels(); } else { response.message += " Not connected to Twitch so can't join the channel right now."; } Respond(bChan, response); } break; } break; case "pubsub": // has to go through discord if (args.source != MESSAGESOURCE.DISCORD) { return; } // Clean command response if (args.arguments.Count == 0 || args.arguments[0] == "help") { response.message = PubSubHelpDump(bChan); Respond(bChan, response); return; } switch (args.arguments[0]) { case "settoken": if (args.arguments.Count == 2) { bChan.pubsubOauth = Cipher.Encrypt(args.arguments[1]); Program.Channels.ChannelSave(bChan); response.message = "Token set. Engaging PubSub Connection!"; Program.PubSubStart(bChan); Program.DiscordRemoveMessage(Core.StringToUlong(args.channel), args.messageID); } else { response.message = "Did you forget the token?"; } Respond(bChan, response); return; case "cleartoken": bChan.pubsubOauth = string.Empty; Program.Channels.ChannelSave(bChan); response.message = "ClearToken"; Program.PubSubStop(bChan); Respond(bChan, response); return; case "start": Program.PubSubStart(bChan); return; case "stop": Program.PubSubStop(bChan); return; /*case "status": * response.message = Program.PubSubStatus(bChan); * Respond(bChan, response); * return; */ } break; case "setadminchannel": bChan.discordAdminChannel = Core.StringToUlong(args.channel); Program.Channels.ChannelSave(bChan); response.message = $"This is now set as the default adminchannel for this DiscordServer. This is needed to direct some important messages and notifications"; Respond(bChan, response); return; } } }
/* * Central function to parse through an handle all artifact chat commands * Needs cleanup/modularization but I can't be bothered to do that right now */ private async void HandleArtifactChatCommands(OnChatCommandReceivedArgs e) { if (e.Command.ArgumentsAsList.Count == 0) // No arguments just sends a list of current artifacts for sale { if (ArtifactDisplayCooldown) { return; } // Ignore this command while on cooldown foreach (Artifact art in curArtifacts) { botClient.SendMessage(e.Command.ChatMessage.Channel, Artifact.ToChat(art)); } // Have this on an arbitrary 30 second cooldown to avoid chat spam ArtifactDisplayCooldown = true; ArtifactCooldownTimer.Start(); } if (e.Command.ArgumentsAsList.Count == 1 && e.Command.ArgumentsAsList[0].ToLower() == "help") // !artifacts help { botClient.SendMessage(e.Command.ChatMessage.Channel, ArtifactHelp); } if (e.Command.ArgumentsAsList.Count == 2 && e.Command.ArgumentsAsList[0].ToLower() == "buy") // !artifacts buy <ID> { // Check if the ID they are trying to buy is valid bool isValid = false; int index = 0; for (int i = 0; i < curArtifacts.Count; i++) { if (!Int32.TryParse(e.Command.ArgumentsAsList[1], out int artID)) { break; } // if the input ID isn't even an int don't try to find it if (curArtifacts[i].ID == artID) { // If the ID is a valid int and matches an artifact for sale set the valid flag and stop searching isValid = true; index = i; break; } } // Response for invalid ID if (!isValid) { botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format(ArtifactInvalidPurchase, e.Command.ArgumentsAsList[1])); return; } // Check first if the user even has a spice account if (!userStorage.TryGetValue(e.Command.ChatMessage.UserId, out UserStorage storage)) { botClient.SendMessage(e.Command.ChatMessage.Channel, NoStorageReply); return; } // If everything checks out, attempt to make the transaction if (curArtifacts[index].Value <= storage.spice) // If has enough spice to buy the artifact { // Update the user's new spice amount and add the artifact to their list UpdateSpiceStorage(ref userStorage, e.Command.ChatMessage.UserId, e.Command.ChatMessage.DisplayName, -curArtifacts[index].Value); AddArtifact(ref userStorage, e.Command.ChatMessage.UserId, curArtifacts[index]); Artifact.SaveToHistory(curArtifacts[index]); botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format(ArtifactBought, e.Command.ArgumentsAsList[1], curArtifacts[index].Name, curArtifacts[index].Value)); } else { // Shame the user for trying to buy an artifact they can't afford botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format( ArtifactNotEnoughSpice, curArtifacts[index].Name, curArtifacts[index].Value, e.Command.ChatMessage.DisplayName, storage.spice)); } } if ((e.Command.ArgumentsAsList.Count == 1 || e.Command.ArgumentsAsList.Count == 2) && e.Command.ArgumentsAsList[0].ToLower() == "check") // !artifacts check <username> { // Check if the user being checked has a spice account string userName = ""; string userID = ""; // If the command has a user argument check to see if that user exists if (e.Command.ArgumentsAsList.Count == 2) { try { TwitchLib.Api.V5.Models.Users.Users users = await UsernameToUser(e.Command.ArgumentsAsList[1]); userName = users.Matches[0].Name; userID = users.Matches[0].Id; } catch { botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format(ArtifactUserNotFound, e.Command.ArgumentsAsList[1])); return; } } else // Otherwise set the user as the caller { userName = e.Command.ChatMessage.DisplayName; userID = e.Command.ChatMessage.UserId; } if (!userStorage.TryGetValue(userID, out UserStorage storage)) { botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format(NoStorageReply, userName)); return; } // Check if the user has any artifacts if (storage.artifacts.Count == 0) { botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format( ArtifactNoneInAccount, userName)); return; } foreach (Artifact art in storage.artifacts) { botClient.SendMessage(e.Command.ChatMessage.Channel, Artifact.ToChat(art)); } } if (e.Command.ArgumentsAsList.Count == 2 && e.Command.ArgumentsAsList[0].ToLower() == "history") // !artifacts history <ID> { // If the ID is valid send the artifact if (Int32.TryParse(e.Command.ArgumentsAsList[1], out int artID) && prevArtifacts.TryGetValue(artID, out Artifact art)) { botClient.SendMessage(e.Command.ChatMessage.Channel, Artifact.ToChat(art)); } else { // If the ID is invalid/artifact doesn't exist then send an error and exit botClient.SendMessage(e.Command.ChatMessage.Channel, string.Format( ArtifactInvalid, artID)); return; } } }