protected virtual void ProcessJsonEvent(JObject evt) { var eventName = (string)evt["event"]; CommunicationLogger.LogDebug("received event {EventName}", eventName); bool playNow = false; switch (eventName) { case CurrentPlayerEventName: { // my turn? not my turn? (legacy) var currentPlayer = (string)evt["player"]; playNow = (currentPlayer == ConnectionManager.MyNickname); break; } case CurrentPlayerOrderEventName: { // my turn? not my turn? var upcomingPlayers = (JArray)evt["order"]; playNow = ((string)upcomingPlayers[0] == ConnectionManager.MyNickname); NextPlayer = (upcomingPlayers.Count > 1) ? (string)upcomingPlayers[1] : null; // if upcomingPlayers.Count <= 2, then NextPlayer == PreviousPlayer PreviousPlayer = (upcomingPlayers.Count > 2) ? (string)upcomingPlayers.Last : null; // if upcomingPlayers.Count <= 2, then NextButOnePlayer == me NextButOnePlayer = (upcomingPlayers.Count > 2) ? (string)upcomingPlayers[2] : null; CurrentPlayers.Clear(); CurrentPlayers.UnionWith(upcomingPlayers.Select(tok => (string)tok)); break; } case CardCountsEventName: { var cardCounts = (JArray)evt["counts"]; CurrentCardCounts.Clear(); foreach (var playerAndCount in cardCounts.OfType <JObject>()) { var player = (string)playerAndCount["player"]; var count = (int)playerAndCount["count"]; CurrentCardCounts[player] = count; } break; } case TopCardEventName: { var currentCardName = (string)evt["current_card"]; TopCard = CardUtils.ParseColorAndValue(currentCardName).Value; break; } case HandInfoEventName: { var handCards = (JArray)evt["hand"]; CurrentHand = handCards .Select(e => CardUtils.ParseColorAndValue((string)e)) .Where(cav => cav.HasValue) .Select(cav => cav.Value) .ToList(); if (LastHandCount > 0 && Config.ManyCardsCurseThreshold > 0 && CurrentHand.Count - LastHandCount >= Config.ManyCardsCurseThreshold) { StrategyLogger.LogDebug("cursing because of overfilled hand"); Curse(); } LastHandCount = CurrentHand.Count; break; } case CardDrawnEventName: { var player = (string)evt["player"]; if (player == ConnectionManager.MyNickname) { playNow = true; } break; } } if (playNow) { PlayACard(); } }
protected virtual void HandleChannelMessage(object sender, IChannelMessageEventArgs args, MessageFlags flags) { if (flags.HasFlag(MessageFlags.UserBanned)) { return; } if (args.SenderNickname == ConnectionManager.MyNickname) { return; } if (Config.UnoChannel != args.Channel) { return; } if (IsBotCommand(args.Message, "?join")) { ConnectionManager.SendChannelMessage(args.Channel, "!botjoin"); // don't curse if the number of cards jumps up from 1 to 7 ;) LastHandCount = 0; return; } if (IsBotCommand(args.Message, "?leave")) { ConnectionManager.SendChannelMessage(args.Channel, "!leave"); return; } if (args.Message.StartsWith("??color ")) { var denyColor = false; if (!CurrentPlayers.Contains(args.SenderNickname)) { // player is not taking part StrategyLogger.LogDebug("denying {Nickname}'s color request because they are a spectator", args.SenderNickname); denyColor = true; } if (CurrentCardCounts.Values.All(v => v > Config.PlayToWinThreshold)) { // everybody has more than two cards StrategyLogger.LogDebug("denying {Nickname}'s color request because everybody has more than {CardCount} cards", args.SenderNickname, Config.PlayToWinThreshold); denyColor = true; } if (CurrentCardCounts.ContainsKey(args.SenderNickname) && CurrentCardCounts[args.SenderNickname] <= Config.PlayToWinThreshold) { // the person who is asking has two cards or less StrategyLogger.LogDebug("denying {Nickname}'s color request because they have {CardThreshold} cards or fewer ({CardCount})", args.SenderNickname, Config.PlayToWinThreshold, CurrentCardCounts[args.SenderNickname]); denyColor = true; } if (CurrentHand.Count <= Config.PlayToWinThreshold) { // I have two cards or less StrategyLogger.LogDebug("denying {Nickname}'s color request because I have {CardThreshold} cards or fewer ({CardCount})", args.SenderNickname, Config.PlayToWinThreshold, CurrentHand.Count); denyColor = true; } if (denyColor) { ConnectionManager.SendChannelMessageFormat(args.Channel, "Sorry, {0}, no can do.", args.SenderNickname); return; } var colorString = args.Message.Substring(("??color ").Length); var color = CardUtils.ParseColor(colorString); if (!color.HasValue || color == CardColor.Wild) { ConnectionManager.SendChannelMessage(args.Channel, "Uhh, what color is that?"); return; } ColorRequest = color; // can I change the color? if (CurrentHand.Any(c => c.Color == CardColor.Wild)) { ConnectionManager.SendChannelMessageFormat(args.Channel, "Yeah, I think that's doable, {0}.", args.SenderNickname); } else if (CurrentHand.Any(c => c.Color == color)) { ConnectionManager.SendChannelMessageFormat(args.Channel, "No color changers, but I'll try, {0}.", args.SenderNickname); } else { ConnectionManager.SendChannelMessageFormat(args.Channel, "Ain't got the cards, {0}, but I'll try...", args.SenderNickname); } return; } var runtimeTweakMatch = RuntimeTweakPattern.Match(args.Message); if (runtimeTweakMatch.Success) { if (!Config.RuntimeTweakable) { ConnectionManager.SendChannelMessageFormat(args.Channel, "Sorry, {0}, I'm not allowed to do that.", args.SenderNickname); return; } try { ConfigTweaking.TweakConfig(Config, runtimeTweakMatch.Groups["property"].Value, runtimeTweakMatch.Groups["value"].Value); } catch (ArgumentException ae) { ConnectionManager.SendChannelMessageFormat(args.Channel, "That didn't work out, {0}: {1}", args.SenderNickname, ae.Message); return; } ConnectionManager.SendChannelMessageFormat(args.Channel, "{0}: Done.", args.SenderNickname); return; } }