public void RunOnBitsEvent(BitsEvent bitsEvent) { BotLogger.LogMessage($"{bitsEvent.Username} sent {bitsEvent.NumberOfBits} bits!"); foreach (var callback in this.Callbacks_BitsEvent) { if (callback(bitsEvent) == CallbackAction.SKIP_OTHERS) { break; } } }
/// <summary> /// Tries to parse raw message into message object. /// </summary> /// <param name="message">Raw message received from a server</param> /// <param name="msg">Output message object when successfully parsed</param> /// <returns></returns> public bool TryParsePrivateMessage(string message, out Message msg) { msg = new Message(); JsonData data = JsonMapper.ToObject(new JsonReader(message)); string msgType = data["type"].ToString().ToLower(); switch (msgType) { case "pong": controller._log.LogMessage("PubSub Pong Recieved!"); return(false); case "RESPONSE": if (data.ContainsKey("error") && !string.IsNullOrWhiteSpace(data["error"].ToString())) { controller._log.LogFatal($"Failed to properly connect to PubSub! Restarting game REQUIRED!"); } else { controller._log.LogWarning($"Connected to PubSub!"); } return(false); case "reconnect": controller._log.LogFatal($"Twitch Server Restarting connection will be lost within 30 seconds."); _twitchMessageClient.DisconnectAsync(Controller._instance.cts2).Wait(); break; case "message": MessageResponse messageResponse = JsonMapper.ToObject <MessageResponse>(message); string MR = messageResponse.data.message.Replace(@"\", ""); string host = messageResponse.data.topic; switch (host.Split('.')[0]) { case "channel-subscribe-events-v1": try { SubEvent subEvent = JsonMapper.ToObject <SubEvent>(MR); msg.Host = host; msg.RawMessage = message; msg.TriggerText = subEvent.sub_plan; msg.User = subEvent.is_gift ? subEvent.recipient_display_name : subEvent.display_name; return(true); } catch (Exception e) { controller._log.LogError($"Failed to convert {MR} into SubEvent."); controller._log.LogError(e); return(false); } case "channel-bits-events-v2": try { BitsEvent bitsEvent = JsonMapper.ToObject <BitsEvent>(MR); msg.Host = host; msg.RawMessage = message; msg.TriggerText = bitsEvent.data.bits_used.ToString(); msg.User = bitsEvent.is_anonymous ? "Anonymous" : bitsEvent.data.user_name; msg.UserInput = bitsEvent.data.chat_message; return(true); } catch (Exception e) { controller._log.LogWarning($"Failed to convert {MR} into BitsEvent."); controller._log.LogError(e); return(false); } case "channel-points-channel-v1": if (MR.Contains("reward-redeemed")) { try { JsonReader reader = new JsonReader(MR) { SkipNonMembers = true, AllowComments = true, AllowSingleQuotedStrings = true }; ChannelPointsMessageResponse pointsMessage = JsonMapper.ToObject <ChannelPointsMessageResponse>(reader); msg.Host = $"channel-points-channel-v1.{controller._secrets.nick_id}"; msg.RawMessage = message; msg.User = pointsMessage.data.redemption.user.display_name; msg.TriggerText = pointsMessage.data.redemption.reward.title; msg.UserInput = pointsMessage.data.redemption.user_input; return(true); } catch (Exception e) { controller._log.LogError($"Failed to convert {MR} into Points Event."); controller._log.LogError(e); return(false); } } return(false); case "hype-train-events-v1": if (MR.Contains("hype-train-start")) { Controller.HypeTrain = true; if (controller.eventLookup.TryGetEvent("HypeTrain", out EventInfo eventInfo)) { eventInfo.BitCost = 100; } controller.eventLookup.Lookup("HypeTrainStart", $"LEVEL {Controller.HypeLevel} HYPETRAIN!!!", ""); return(false); } else if (MR.Contains("hype-train-level-up")) { Controller.HypeLevel += 1; controller.eventLookup.Lookup($"HypeTrainLevel{Controller.HypeLevel}", $"!!!LEVEL {Controller.HypeLevel} HYPETRAIN!!!", ""); return(false); } else if (MR.Contains("hype-train-end")) { Controller.HypeTrain = false; Controller.HypeLevel = 1; if (controller.eventLookup.TryGetEvent("HypeTrain", out EventInfo eventInfo)) { eventInfo.BitCost = 0; } controller.eventLookup.Lookup("HypeTrainEnd", $"!!!HYPETRAIN FINISHED!!!", ""); return(false); } return(false); default: controller._log.LogError($"PubSub Event Failed to Parse \n {message}"); return(false); } default: break; } return(false); }
private void DefaultActions() { /* * This responds to Ping requests */ CallbackHandler.AddToplevelCallback((string data) => { if (Regex.Match(data, IRCSymbols.Keywords.PING).Success) { sendPONG(); } return(CallbackAction.SKIP_OTHERS); }); /* * This parses the channel,username and message and fires the OnChannelMessage Event */ CallbackHandler.AddToplevelCallback((string data) => { /* * There are two cases, * * one is a regular privmsg * second is privmsg with bits information * */ if (data.Contains(IRCSymbols.Keywords.BITS)) { Match match = Regex.Match(data, @"@badges=([a-zA-Z]+/\d+).+;bits=(\d+).+:([a-zA-Z_0-9]+)!.+PRIVMSG\s#(\w+)\s:(.+)"); if (match.Success) { var tuple = IRCSymbols.ParseBadge(match.Groups[1].Value); int bits = Int32.Parse(match.Groups[2].Value); string username = match.Groups[3].Value; string channel = match.Groups[4].Value; string message = match.Groups[5].Value; BitsEvent bitsEvent = new BitsEvent(tuple.badge, tuple.version, bits, username, channel, message); return(CallbackAction.SKIP_OTHERS); } } else if (data.Contains(IRCSymbols.Keywords.PRIVMSG)) { Match match = Regex.Match(data, @":(\w+)!.+#(\w+) :(.+)$"); if (match.Success) { string username = match.Groups[1].Value; string channel = match.Groups[2].Value; string message = match.Groups[3].Value; string badge = String.Empty; int version = -1; Match match_message_id = Regex.Match(data, @";id=([a-zA-Z0-9-]+);"); string message_id = null; if (match_message_id.Success) { message_id = match_message_id.Groups[1].Value; } Match match_badge = Regex.Match(data, @"@badges=(\w+/\d+|);"); if (match_badge.Success) { badge = match_badge.Groups[1].Value; if (!String.IsNullOrEmpty(badge)) { string[] parsed = badge.Split('/'); badge = parsed[0]; version = Int32.Parse(parsed[1]); } } ChannelMessageEvent channel_message = new ChannelMessageEvent(channel, username, message, message_id, badge, version); CallbackHandler.RunOnChannelMessageCallbacks(channel_message); } } return(CallbackAction.SKIP_OTHERS); }); /* * Callback that parses and triggers & logs bad error */ CallbackHandler.AddToplevelCallback((string data) => { if (Regex.Match(data, @":Unknown command").Success) { BotLogger.LogError("[ >> Unknown command! ]"); } return(CallbackAction.SKIP_OTHERS); }); /* * This parses that user joins the channel and fires onJoinChannel callbacks */ CallbackHandler.AddToplevelCallback((string data) => { Match match = Regex.Match(data, @":(.+)!.+ JOIN #(.+)"); if (match.Success) { UserActionUponChannel joinChannel = new UserActionUponChannel(channel: match.Groups[2].Value, username: match.Groups[1].Value); CallbackHandler.RunOnJoinedChannelCallback(joinChannel); } return(CallbackAction.SKIP_OTHERS); }); /* * Callback to parse and trigger OnLeaveChannel event */ CallbackHandler.AddToplevelCallback((string data) => { Match match = Regex.Match(data, @":(.+)!.+ PART #(.+)"); if (match.Success) { UserActionUponChannel leaveChannel = new UserActionUponChannel(channel: match.Groups[2].Value, username: match.Groups[1].Value); CallbackHandler.RunOnLeaveChannelCallback(leaveChannel); } return(CallbackAction.SKIP_OTHERS); }); /* Usernotice */ CallbackHandler.AddToplevelCallback((string data) => { //If it matches a sub/resub Match match = Regex.Match(data, @"@badges=(\w+/\d+).+;display-name=([a-zA-Z0-9]+).+;msg-id=(resub|sub);msg-param-cumulative-months=(\d+);msg-param-streak-months=(\d+);.+;msg-param-sub-plan=([a-zA-Z0-9]+).+USERNOTICE\s#(\w+)\s:(.+)"); if (match.Success) { var badge_version = match.Groups[1].Value.Split('/'); string badge = badge_version[0]; string version = badge_version[1]; string username = match.Groups[2].Value; string subtype = match.Groups[3].Value; int commulative_months = Int32.Parse(match.Groups[3].Value); int consecutive_months = Int32.Parse(match.Groups[4].Value); string subplan = match.Groups[6].Value; string channel = match.Groups[7].Value; string message = match.Groups[8].Value; SubscriptionEvent subs_event = new SubscriptionEvent (badge, version, username, subtype, commulative_months, consecutive_months, subplan, channel, message); CallbackHandler.RunOnSubscribeCallback(subs_event); return(CallbackAction.SKIP_OTHERS); } return(CallbackAction.CONTINUE); }); /* * Parses a gift event */ CallbackHandler.AddToplevelCallback((string data) => { Match match = Regex.Match(data, @"@badges=(\w+/\d+).+;display-name=([a-zA-Z0-9]+).+;msg-id=(\w+);msg-param-months=(\d+);msg-param-recipient-display-name=([a-zA-Z0-9_]+);.+msg-param-sub-plan=([a-bA-Z0-9]+);"); if (match.Success) { var badge_version = IRCSymbols.ParseBadge(match.Groups[1].Value); string gifter = match.Groups[2].Value; string typeOfGift = match.Groups[3].Value; int total_months = Int32.Parse(match.Groups[4].Value); string recipient = match.Groups[5].Value; string subplan = match.Groups[6].Value; string message = match.Groups[7].Value; GiftEvent giftevent = new GiftEvent(badge_version.badge, badge_version.version, gifter, typeOfGift, total_months, subplan, recipient, message); CallbackHandler.RunOnSubGiftCallback(giftevent); return(CallbackAction.SKIP_OTHERS); } return(CallbackAction.CONTINUE); }); /* * Parses a RaidingEvent */ CallbackHandler.AddToplevelCallback((string data) => { Match match = Regex.Match(data, @"@badges=([a-zA-Z0-9]+/\d+);.+login=([a-zA-Z0-9]+);.+;msg-param-viewerCount=(\d+).+;system-msg=(.+)\sUSERNOTICE\s#(.+)"); if (match.Success) { var tuple = IRCSymbols.ParseBadge(match.Groups[1].Value); var raiderchannel = match.Groups[2].Value; var viewers = Int32.Parse(match.Groups[3].Value); var message = match.Groups[4].Value; var raidedchannel = match.Groups[5].Value; RaidingEvent raiding_event = new RaidingEvent(tuple.badge, tuple.version, raiderchannel, viewers, message, raidedchannel); CallbackHandler.RunOnRaidingCallbacks(raiding_event); return(CallbackAction.SKIP_OTHERS); } return(CallbackAction.CONTINUE); }); /* * Parses a RitualEvent */ CallbackHandler.AddToplevelCallback((string data) => { Match match = Regex.Match(data, @"display-name=([a-zA-Z_0-9]+).+;login=([a-zA-Z_0-9]+).+;msg-id=(ritual);msg-param-ritual-name=([a-zA-Z0-9_]+);.+;system-msg=(.+);tmi.+USERNOTICE\s#([a-zA-Z0-9]+)\s+:(.+)"); if (match.Success) { string username = match.Groups[2].Value; string ritual = match.Groups[3].Value; string typeOfRitual = match.Groups[4].Value; string event_message = match.Groups[5].Value; string channel = match.Groups[6].Value; string user_message = match.Groups[7].Value; RitualEvent ritual_event = new RitualEvent(username, ritual, typeOfRitual, event_message, channel, user_message); CallbackHandler.RunOnRitualEvent(ritual_event); return(CallbackAction.SKIP_OTHERS); } return(CallbackAction.CONTINUE); }); /* * Callback if user sends !github command, it responds back with github url */ CallbackHandler.AddToChannelMessageCallback((ChannelMessageEvent channelMessage) => { if (channelMessage.Message.ToLower().Contains(IRCSymbols.CustomChannelCommands.GITHUB)) { SendToChannel(channel: channelMessage.Channel, message: GITHUB_URL); return(CallbackAction.SKIP_OTHERS); } return(CallbackAction.CONTINUE); }); CallbackHandler.AddToSubscriptionCallback( (SubscriptionEvent subscription) => { SendToChannel(subscription.Channel, "Thanks for the (re)subscription!"); return(CallbackAction.SKIP_OTHERS); }); }