void Cmd_help(string nick, string message) { var channel = p_manager.GetChannel(); var cmd = p_manager.GetChatcommand(); string part = Chatcommand.GetNext(ref message); if (part == "") { channel.Say(nick + ": [$lua/$] <text../help()>, $c <text..>, " + cmd.CommandsToString() + ". See also: " + "https://github.com/SmallJoker/NyisBot/blob/master/HELP.txt"); return; } part = "$" + part; // Add cmd prefix do { cmd = cmd.GetSubCmdGroup(part); if (cmd == null) { channel.Say(nick + ": No subcommands found for '" + part + "'."); return; } part = Chatcommand.GetNext(ref message); } while (part != ""); // The main command should display information only cmd.Run(nick, ""); }
void Cmd_Join(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); if (uno != null && uno.is_active) { channel.Say(nick + ": Please wait for " + uno.current_player + " to finish their game."); return; } if (uno != null && uno.GetPlayer(nick) != null) { E.Notice(nick, "You already joined the game."); return; } // Create a new UnoChannel if (uno == null) { string modes_s = Chatcommand.GetNext(ref message); byte modes = 0x03; try { modes = Convert.ToByte(modes_s, 16); } catch { } uno = new UnoChannel(modes); m_channels[channel.GetName()] = uno; } UserData user = channel.GetUserData(nick); user.cmd_scope = m_subcommand; uno.players.Add(new UnoPlayer(nick, user)); uno.current_player = nick; channel.Say("[UNO] " + uno.players.Count + " player(s) are waiting for a new UNO game. " + string.Format("Modes: 0x{0:X2}", uno.modes)); }
void Cmd_Elo(string nick, string message) { Channel channel = p_manager.GetChannel(); string who = Chatcommand.GetNext(ref message); if (who.Length == 0) { who = nick; } var player = new UnoPlayer(who, null); if (!m_settings.Get(who, ref player)) { channel.Say("[UNO] " + who + ": No information available"); } else { channel.Say("[UNO] " + who + ": " + player.ShowElo(true)); } }
void Cmd_cutwire(string nick, string message) { Channel chan = p_manager.GetChannel(); string channel = chan.GetName(); if (!m_timers.ContainsKey(channel)) { chan.Say("There's no timebomb to disarm."); return; } var data = m_timers[channel]; if (data.nick != nick) { chan.Say(nick + ": You may not help to disarm the bomb."); return; } int color_i = Array.IndexOf(colors, Chatcommand.GetNext(ref message)); if (color_i < 0) { chan.Say(nick + ": Unknown or missing wire color."); return; } if (data.color != colors[color_i]) { // Explode instantly BoomTimerElapsed(channel); return; } // Disarmed m_timers.Remove(channel); chan.Say(nick + ": You successfully disarmed the bomb."); }
void Cmd_tell(string nick, string message) { Channel channel = p_manager.GetChannel(); string dst_nick = Chatcommand.GetNext(ref message); if (dst_nick.Length < 3) { channel.Say(nick + ": Expected arguments: <nick> <text ..>"); return; } if (message.Length < 7) { E.Notice(nick, "Too short input text."); return; } if (message.Length > byte.MaxValue - 5) { E.Notice(nick, "Too long input text."); return; } if (message == tell_last) { E.Notice(nick, "Text too repetitive."); return; } foreach (TellInfo info in tell_text) { if (info.text == message && CheckSimilar(info.dst_nick, dst_nick)) { E.Notice(nick, "That message is already in the queue."); return; } } tell_last = message; var in_channel = new List <Channel>(); string user_normal = null; foreach (Channel chan in p_manager.UnsafeGetChannels()) { string found = chan.FindNickname(dst_nick); if (found != null) { user_normal = found; in_channel.Add(chan); } } if (in_channel.Count > 0) { foreach (Channel chan in in_channel) { if (chan.GetUserData(nick) != null) { E.Notice(nick, "Found " + user_normal + " in channel " + chan.GetName() + $". No need to use {G.settings["prefix"]}tell."); return; } } in_channel[0].Say(user_normal + ": TELL from " + nick + ": " + message); E.Notice(nick, "Message directly sent to " + user_normal + " in channel " + in_channel[0].GetName() + "."); return; } tell_text.Add(new TellInfo { dst_nick = dst_nick, src_nick = nick, datetime = DateTime.UtcNow.ToString("s"), text = message }); channel.Say(nick + ": meh okay. I'll look out for that user."); TellSave(true); }
void Cmd_timebomb(string nick, string message) { Channel chan = p_manager.GetChannel(); if (chan.IsPrivate()) { return; } string channel = chan.GetName(); if (m_timers.ContainsKey(channel)) { chan.Say("Only one timebomb is allowed at a time."); return; } if (m_cooldown.ContainsKey(channel)) { chan.Say("Assembling a new bomb. Please wait... (" + (int)(m_cooldown[channel].GetRemaining() / 1000.0) + "s)"); return; } string dst_name = Chatcommand.GetNext(ref message); dst_name = chan.FindNickname(dst_name, false); if (dst_name == null) { chan.Say(nick + ": Unknown or invalid nickname specified."); return; } if (dst_name == G.settings["nickname"]) { E.Notice(nick, "You fell for it, fool! Thunder Cross Split Attack!"); dst_name = nick; } // Take a random amount from "colors" string[] choices = new string[Utils.random.Next(2, 5)]; string choice_str = ""; for (int i = 0; i < choices.Length; ++i) { choices[i] = (string)Utils.RandomIn(colors); // Format chat output choice_str += choices[i]; if (i < choices.Length - 1) { choice_str += ", "; } } string color = (string)Utils.RandomIn(choices); var data = new DisarmData(dst_name, color, Utils.random.Next(50, 90) * 1000.0); data.timer.Elapsed += delegate { BoomTimerElapsed(channel); }; m_timers[channel] = data; chan.Say(dst_name + ": Tick tick.. " + (int)(data.timer.Interval / 1000.0) + "s until explosion. Try $cutwire <color> from one of these colors: " + choice_str); }
void Cmd_Put(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); UnoPlayer player = uno != null?uno.GetPlayer(nick) : null; if (player == null || !uno.is_active) { E.Notice(nick, "huh?? You don't have any cards."); return; } if (uno.current_player != nick && !uno.CheckMode(UnoMode.LIGRETTO)) { E.Notice(nick, "It is not your turn (current: " + uno.current_player + ")."); return; } uno.current_player = nick; // UnoMode.LIGRETTO string put_color_s = Chatcommand.GetNext(ref message).ToUpper(); CardColor put_color = CardColor.NONE; string put_face = Chatcommand.GetNext(ref message).ToUpper(); if (put_color_s.Length >= 2) { // The following format: "gwd4", "g4" put_face = put_color_s.Substring(1); put_color_s = put_color_s.Remove(1); } // Convert user input to internal format switch (put_color_s) { case "B": put_color = CardColor.BLUE; break; case "R": put_color = CardColor.RED; break; case "G": put_color = CardColor.GREEN; break; case "Y": put_color = CardColor.YELLOW; break; } bool change_face = false; if (put_face.Contains("W")) { // Convert/validate W and WD4 change_face = true; } if (put_color == CardColor.NONE || !card_faces.Contains(put_face)) { E.Notice(nick, "Invalid input. Syntax: $uno p <color> <face>, $p <color><face>."); return; } // Check whether color of face matches if (put_color != uno.top_card.Key && put_face != uno.top_card.Value && !change_face) { E.Notice(nick, "This card cannot be played. Please check color and face."); return; } int card_index = -1; if (change_face) { card_index = player.cards.FindIndex(item => item.Value == put_face); } else { card_index = player.cards.FindIndex( item => item.Key == put_color && item.Value == put_face); } if (card_index < 0) { E.Notice(nick, "You don't have this card."); return; } if (uno.draw_count > 0) { bool ok = false; if (put_face == "D2" && put_face == uno.top_card.Value && // No downgrade uno.CheckMode(UnoMode.STACK_D2)) { ok = true; } else if (put_face == "WD4" && put_face == uno.top_card.Value && uno.CheckMode(UnoMode.STACK_WD4)) { ok = true; } else if (put_face == "WD4" && uno.top_card.Value == "D2" && uno.CheckMode(UnoMode.UPGRADE)) { ok = true; } if (!ok) { E.Notice(nick, "You cannot play this card due to the top card."); return; } } // All OK. Put the card on top uno.top_card = new Card(put_color, put_face); player.cards.RemoveAt(card_index); bool pending_autodraw = false; switch (put_face) { case "D2": uno.draw_count += 2; pending_autodraw = !uno.CheckMode(UnoMode.STACK_D2); break; case "WD4": uno.draw_count += 4; pending_autodraw = !uno.CheckMode(UnoMode.STACK_WD4); break; case "R": if (uno.players.Count > 2) { uno.players.Reverse(); } else { uno.TurnNext(); // Acts as Skip for 2 players } break; case "S": uno.TurnNext(); break; } uno.TurnNext(); // Player won, except when it's again their turn (last card = skip) if (player.cards.Count == 0 && uno.current_player != player.name) { uno.RemovePlayer(channel, player.name); } if (CheckGameEndDelete(channel.GetName())) { return; // Game ended } if (pending_autodraw) { Cmd_Draw(uno.current_player, ""); } else { TellGameStatus(channel); } }
void Cmd_Join(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); if (uno != null && uno.is_active) { channel.Say(nick + ": Please wait for " + uno.current_player + " to finish their game."); return; } if (uno != null && uno.GetPlayer(nick) != null) { E.Notice(nick, "You already joined the game."); return; } // Create a new UnoChannel if (uno == null) { string modes_s = Chatcommand.GetNext(ref message); byte modes = 0x87; try { modes = Convert.ToByte(modes_s, 16); } catch { } uno = new UnoChannel(modes, m_settings); } if (uno.CheckMode(UnoMode.RANKED) && p_manager.GetUserStatus(nick) != 3) { E.Notice(nick, "You must be logged in to play ranked UNO."); return; } m_channels[channel.GetName()] = uno; // For new channels UserData user = channel.GetUserData(nick); user.cmd_scope = m_subcommand; var player = new UnoPlayer(nick, user); m_settings.Get(nick, ref player); uno.AddPlayer(player); // Human readable modes var modes_list = new List <string>(); for (int i = 1; i < byte.MaxValue; i <<= 1) { if ((uno.modes & i) > 0) { modes_list.Add(FormatMode((UnoMode)(uno.modes & i))); } } channel.Say("[UNO] " + uno.players.Count + " player(s) are waiting for a new UNO game. " + string.Format("Modes: [0x{0:X2}] ", uno.modes) + string.Join(", ", modes_list)); }
void Cmd_add(string nick, string message) { Channel channel = p_manager.GetChannel(); LGameChannel game = GetLChannel(channel.GetName()); LGPlayer player = game != null?game.GetPlayer(nick) : null; #region Sanity check if (player == null || !game.is_active) { E.Notice(nick, "There's no game ongoing yet. Join & start to begin."); return; } if (player != game.GetPlayer()) { E.Notice(nick, "It's not your turn yet. Please wait for " + game.GetPlayer().nick); return; } #endregion string card = Chatcommand.GetNext(ref message); string card_upper = card.ToUpper(); string main_card = game.main_card; // Check for valid card, correct name bool valid_main_card = false; string cards = ""; for (int i = 0; i < CARD_TYPES.Length; i++) { string l_card = CARD_TYPES[i].ToUpper(); if (l_card == card_upper) { valid_main_card = true; // Correct spelling card = CARD_TYPES[i]; break; } if (l_card != "Q") { cards += CARD_TYPES[i] + " "; } } // $lg <fake> <c1> <c2> if (main_card != "" && main_card != card) { channel.Say(nick + ": Wrong card type! Please pretend to place a card of type [" + main_card + "]!"); return; } if (card_upper == "Q") { channel.Say(nick + ": The Queen is the bad card and can not be used as the main card of a stack."); return; } if (!valid_main_card) { channel.Say(nick + ": There is no such card type. Valid types: " + cards); return; } if (main_card == "") { main_card = card; } string[] card_mirror = player.cards.ToArray(); var card_add = new List <int>(); for (int n = 0; true; n++) { string index_s = Chatcommand.GetNext(ref message); if (index_s == "" && n == 0) { channel.Say(nick + ": Expected arguments <'main card'> <index> [<index> ..]" + "(Blue number: card value, Black number: index)"); return; } if (index_s == "") { break; } int index_i = Utils.toInt(index_s) - 1; if (index_i < 0 || index_i >= card_mirror.Length) { E.Notice(nick, "Invalid card index \"" + index_s + "\". Play one between 1 and " + card_mirror.Length + " from your hand."); return; } if (!card_add.Contains(index_i)) { card_add.Add(index_i); } } game.stack_top.Clear(); foreach (int card_i in card_add) { string l_card = card_mirror[card_i]; game.stack_all.Add(l_card); game.stack_top.Add(l_card); bool success = player.cards.Remove(l_card); if (!success) { L.Log("m_lGame::$ladd, failed to remove cards", true); } } game.main_card = main_card; player = game.NextPlayer(); channel.Say("[LGame] Main card: [" + main_card + "]" + ", Stack height: " + game.stack_all.Count + ", Next player: " + player.nick); Thread.Sleep(300); E.Notice(player.nick, FormatCards(player.cards, true)); CheckCards(nick); }