Пример #1
0
        void Cmd_Draw(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, "You are not part of an UNO game.");
                return;
            }

            if (uno.current_player != nick && !uno.CheckMode(UnoMode.LIGRETTO))
            {
                E.Notice(nick, "It is not your turn (current: " + uno.current_player + ").");
                return;
            }

            var drawn = player.DrawCards(Math.Max(1, uno.draw_count));

            uno.draw_count = 0;
            E.Notice(nick, "You drew following cards: " + FormatCards(drawn));

            uno.TurnNext();
            TellGameStatus(channel);
        }
Пример #2
0
        public override void OnUserLeave(string nick)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || !game.RemovePlayer(nick))
            {
                return;                 // Player was not part of the round
            }
            if (game.players.Count < 3 && game.is_active)
            {
                lchans.Remove(game);
                game = null;
                GC.Collect();
                channel.Say("Game ended.");
                return;
            }
            if (game.is_active)
            {
                channel.Say(nick + " left the game. Next player: " + game.GetPlayer().nick);
                return;
            }
            channel.Say(nick + " left the game.");

            if (game.players.Count == 0)
            {
                lchans.Remove(game);
                game = null;
                GC.Collect();                 // Force calling LGPlayer::~LGPlayer
            }
        }
Пример #3
0
        void Cmd_Deal(string nick, string message)
        {
            Channel    channel = p_manager.GetChannel();
            UnoChannel uno     = GetUnoChannel(channel.GetName());
            UnoPlayer  nplayer = uno != null?uno.GetPlayer(nick) : null;

            if (nplayer == null || uno.is_active)
            {
                E.Notice(nick, "You are either not part of the game or " +
                         " another is already ongoing.");
                return;
            }

            if (uno.players.Count < 2)
            {
                channel.Say("At least two player are required to start the game.");
                return;
            }

            foreach (UnoPlayer player in uno.players)
            {
                player.DrawCards(9);
            }

            uno.top_card  = nplayer.cards[0];
            uno.is_active = true;
            TellGameStatus(channel);
        }
Пример #4
0
        void Cmd_start(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || game.GetPlayer(nick) == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }

            if (game.is_active)
            {
                E.Notice(nick, "The game is already running.");
                return;
            }

            int total_players = game.players.Count;

            if (total_players < 3)
            {
                channel.Say(nick + ": At least 3 players are required to start the game.");
                return;
            }

            var cards = new List <string>();

            foreach (string card in CARD_TYPES)
            {
                int amount = (card == "Q") ? 3 : 4;
                while (amount > 0)
                {
                    cards.Add(card);
                    amount--;
                }
            }
            Utils.Shuffle(ref cards);

            foreach (string card in cards)
            {
                game.NextPlayer().cards.Add(card);
            }

            game.is_active = true;

            foreach (LGPlayer n in game.players)
            {
                E.Notice(n.nick, "Your cards: " + FormatCards(n.cards, true));
                Thread.Sleep(300);
            }
            game.CleanStack();

            channel.Say("Game started! Player " + game.GetPlayer().nick +
                        " can play the first card using \"$add <'main card'> <card nr.> [<card nr.> [<card nr.>]]\"" +
                        " (Card nr. from your hand)");

            CheckCards();
        }
Пример #5
0
        void Cmd_join(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game != null && game.is_active)
            {
                channel.Say(nick + ": Please wait for " + game.GetPlayer() +
                            " to finish their game.");
                return;
            }

            if (game != null && game.GetPlayer(nick) != null)
            {
                E.Notice(nick, "You already joined the game.");
                return;
            }

            if (game == null)
            {
                game = new LGameChannel(channel.GetName());
                lchans.Add(game);
            }

            UserData user = channel.GetUserData(nick);

            user.cmd_scope = m_subcommand;
            game.players.Add(new LGPlayer(nick, user));

            int    count = game.players.Count;
            string text  = "Player " + nick + " joined the game. Total " + count + " players ready.";

            if (count > 2)
            {
                text += " If you want to start the game, use \"$start\"";
            }
            else if (count == 1)
            {
                text += " At least 3 players are required to start the game.";
            }
            channel.Say(text);
        }
Пример #6
0
        public override void OnUserLeave(string nick)
        {
            Channel    channel    = p_manager.GetChannel();
            UnoChannel uno        = GetUnoChannel(channel.GetName());
            string     old_player = uno == null ? null : uno.current_player;

            if (uno == null || !uno.RemovePlayer(channel, nick))
            {
                return;
            }

            // Either close the game or echo the status
            if (!CheckGameEndDelete(channel.GetName()))
            {
                if (nick == old_player)
                {
                    TellGameStatus(channel);
                }
            }
        }
Пример #7
0
        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));
        }
Пример #8
0
        void Cmd_Leave(string nick, string message)
        {
            Channel    channel = p_manager.GetChannel();
            UnoChannel uno     = GetUnoChannel(channel.GetName());

            if (uno == null || uno.GetPlayer(nick) == null)
            {
                E.Notice(nick, "You are not part of an UNO game.");
                return;
            }

            OnUserLeave(nick);
        }
Пример #9
0
        void Cmd_leave(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || game.GetPlayer(nick) == null)
            {
                E.Notice(nick, "You are not part of a liar game.");
                return;
            }

            OnUserLeave(nick);
        }
Пример #10
0
        void Cmd_Top(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, "You are not part of an UNO game.");
                return;
            }

            TellGameStatus(channel, player);
        }
Пример #11
0
        void Cmd_cards(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || !game.is_active)
            {
                E.Notice(nick, "There's no game or it did not start yet.");
                return;
            }

            LGPlayer player = game.GetPlayer(nick);

            if (player == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }

            Utils.Shuffle(ref player.cards);
            E.Notice(nick, FormatCards(player.cards, true));
        }
Пример #12
0
        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.");
        }
Пример #13
0
        string LuaRun(string nick, Channel chan, string message)
        {
            if (!System.IO.File.Exists("plugins/security.lua"))
            {
                return("Error: File 'plugins/security.lua' does not exist");
            }

            bool is_private = chan.IsPrivate();

            // Initialize packet lock, packet and start time
            lua_lock   = false;
            lua_packet = new System.Text.StringBuilder();

            SE.ResetLua();
            SE.RegisterLuaFunction(l_print, "print");
            SE.RegisterLuaFunction(l_stringldistance, "stringldistance");
            SE.RegisterLuaFunction(l_getUserstatus, "getUserstatus");
            Lua.lua_atpanic(SE.L, l_panic);

            #region Nick list
            Lua.lua_newtable(SE.L);

            int index = 0;
            if (!is_private)
            {
                foreach (var user in chan.users)
                {
                    Lua.lua_pushinteger(SE.L, ++index);
                    Lua.lua_newtable(SE.L);

                    Lua.lua_pushstring(SE.L, "nick");
                    Lua.lua_pushstring(SE.L, user.Key);
                    Lua.lua_settable(SE.L, -3);

                    Lua.lua_pushstring(SE.L, "hostmask");
                    Lua.lua_pushstring(SE.L, user.Value.hostmask);
                    Lua.lua_settable(SE.L, -3);

                    Lua.lua_settable(SE.L, -3);
                }
            }
            Lua.lua_setglobal(SE.L, "N");
            #endregion

            #region Public chat variables variables
            SE.CreateLuaTable("L");
            Lua.lua_getglobal(SE.L, "L");
            SE.SetTableField("channel", chan.GetName());
            SE.SetTableField("nick", nick);
            SE.SetTableField("botname", G.settings["nickname"]);
            SE.SetTableField("hostmask", chan.GetUserData(nick).hostmask);
            SE.SetTableField("isprivate", is_private);
            SE.SetTableField("online", index);
            SE.SetTableField("owner_hostmask", G.settings["owner_hostmask"]);
            Lua.lua_settop(SE.L, 0);
            #endregion

            int    lua_error  = 1;
            string lua_output = null;

            lua_error = Lua.luaL_dofile(SE.L, "plugins/security.lua");
            if (lua_error == 0)
            {
                lua_error = Lua.luaL_dostring(SE.L, message);
            }

            while (lua_lock)
            {
                System.Threading.Thread.Sleep(100);
            }

            int type = Lua.lua_type(SE.L, -1);

            if (type == Lua.LUA_TSTRING)
            {
                int length = Lua.lua_strlen(SE.L, -1);
                if (length > LUA_TEXT_MAX)
                {
                    lua_output = "<too long message>";
                    Lua.lua_pop(SE.L, 1);
                    type = Lua.LUA_TNONE;
                }
            }
            if (type != Lua.LUA_TNIL && type != Lua.LUA_TNONE)
            {
                lua_output = Lua.lua_tostring(SE.L, -1);
            }

            lua_lock = true;
            if (lua_output != null)
            {
                lua_packet.Append(lua_output);
            }

            if (lua_error > 0)
            {
                L.Log("m_Lua::LuaRun, errorcode = " + lua_error, true);
            }

            lua_lock = false;

            SE.CloseLua();
            lua_timer.Reset();

            #region Remove control characters, '\n' to space
            char[] answer = new char[LUA_TEXT_MAX];
            int    pos    = 0;
            for (int i = 0; i < lua_packet.Length && pos < answer.Length; i++)
            {
                char cur = lua_packet[i];
                if (cur == '\t' || cur == '\n')
                {
                    cur = ' ';
                }

                if (cur == 0 || cur == '\r')
                {
                    continue;
                }

                answer[pos] = cur;
                pos++;
            }
            #endregion
            if (pos == answer.Length)
            {
                answer[--pos] = '.';
                answer[--pos] = '.';
                answer[--pos] = ' ';
                pos          += 3;
            }

            string answer_s = new string(answer, 0, pos);
            if (pos == 0)
            {
                answer_s = nick + ": <no return text>";
            }
            return(answer_s);
        }
Пример #14
0
        void OnUserSay(string nick, string message)
        {
            #region CTCP
            string message_l = message.ToLower();
            if (message_l == "\x01version\x01")
            {
                Notice(nick, "\x01VERSION " + G.settings["identifier"] + "\0x01");
                L.Log("E::OnChatMessage, sending version to " + nick);
                return;
            }
            if (message_l == "\x01time\x01")
            {
                Notice(nick, "\x01TIME " + DateTime.UtcNow.ToString("s") + "\0x01");
                L.Log("E::OnChatMessage, sending time to " + nick);
                return;
            }
            #endregion

            Channel chan = manager.GetChannel();
            L.Log(chan.GetName() + "\t <" + nick + "> " + message);

            #region Args
            {
                string to_replace = G.settings["nickname"] + ": ";
                if (message.StartsWith(to_replace, StringComparison.OrdinalIgnoreCase))
                {
                    message = message.Substring(to_replace.Length).Trim();
                    if (message.Length > 0 && !message.StartsWith(G.settings["prefix"]))
                    {
                        message = G.settings["prefix"] + message;
                    }
                }
            }

            string[] args   = Chatcommand.Split(message);
            int      length = args.Length;

            if (args.Length < 10)
            {
                Array.Resize(ref args, 10);
            }

            for (int i = length; i < args.Length; i++)
            {
                args[i] = "";
            }
            #endregion

            #region Handle NickServ + return
            if (nick == "NickServ" && length >= 3)
            {
                // NickServ can send different kinds of answers
                m_Lua module = (m_Lua)manager.GetModule("Lua");

                if (Utils.isYes(G.settings["nickserv_acc"]) == 1)
                {
                    if (args[1] == "ACC" && module != null)
                    {
                        module.userstatus_queue[args[0]] = args[2][0] - '0';
                        return;
                    }
                }
                else
                {
                    if (args[0] == "STATUS" && module != null)
                    {
                        module.userstatus_queue[args[1]] = args[2][0] - '0';
                        return;
                    }
                }
                // Add more here?

                return;
            }
            #endregion

            if (args[0] == ".bots")
            {
                chan.Say(G.settings["identifier"]);
                return;
            }

            if (message.Length < 2 || !message.StartsWith(G.settings["prefix"]))
            {
                return;
            }

            manager.OnUserSay(nick, message, length, ref args);
        }
Пример #15
0
        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);
            }
        }
Пример #16
0
        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));
        }
Пример #17
0
        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);
        }
Пример #18
0
        void CheckCards(string nick = null)
        {
            Channel      chan = p_manager.GetChannel();
            LGameChannel game = GetLChannel(chan.GetName());

            if (game == null || !game.is_active)
            {
                return;
            }

            List <string> player_remove = new List <string>();

            foreach (LGPlayer player in game.players)
            {
                int amount = player.cards.Count;

                if (amount >= 4)
                {
                    // Count cards
                    var cards = new Dictionary <string, int>();
                    foreach (string card in player.cards)
                    {
                        if (cards.ContainsKey(card))
                        {
                            cards[card]++;
                        }
                        else
                        {
                            cards.Add(card, 1);
                        }
                    }

                    // Discard pairs
                    var discarded = new List <string>();
                    foreach (KeyValuePair <string, int> card in cards)
                    {
                        if (card.Value >= 4)
                        {
                            player.cards.RemoveAll(item => item == card.Key);
                            discarded.Add(card.Key);
                        }
                    }
                    if (discarded.Count > 0)
                    {
                        chan.Say(player.nick + " can discard four " + FormatCards(discarded) +
                                 " cards. Left cards: " + player.cards.Count);
                        Thread.Sleep(300);
                    }
                }

                if (amount == 0)
                {
                    if (nick == null || (nick != null && nick != player.nick))
                    {
                        chan.Say(player.nick + " has no cards left. Congratulations, you're a winner!");
                        player_remove.Add(player.nick);
                    }
                    else
                    {
                        chan.Say(player.nick + " played " + Utils.Colorize("their last card", IRC_Color.ORANGE) + "!");
                    }
                }
                else if (amount <= 3)
                {
                    if (nick != null && nick == player.nick)
                    {
                        chan.Say(player.nick + " has " +
                                 Utils.Colorize("only " + amount + " cards", IRC_Color.ORANGE) + " left!");
                    }
                }
            }

            foreach (string player in player_remove)
            {
                OnUserLeave(player);
            }
        }
Пример #19
0
        void Cmd_check(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            #region Sanity check
            if (game == null || !game.is_active)
            {
                E.Notice(nick, "There's no game or it did not start yet.");
                return;
            }

            LGPlayer player = game.GetPlayer(nick);
            if (player == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }
            if (player != game.GetPlayer())
            {
                E.Notice(nick, "It's not your turn yet. Please wait for " +
                         game.GetPlayer().nick);
                return;
            }
            if (game.main_card == "")
            {
                E.Notice(nick, "You cannot check an empty stack.");
                return;
            }
            #endregion

            player = null;
            string main_card        = game.main_card;
            bool   contains_invalid = game.stack_top.FindIndex(item => item != main_card) >= 0;

            string card_msg = "";
            if (contains_invalid)
            {
                card_msg = "One or more top cards were not a [" + main_card + "]. ";
            }
            else
            {
                card_msg = "The top cards were correct! ";

                game.NextPlayer();
            }

            card_msg += "(" + FormatCards(game.stack_top) + ") ";

            // Add cards to previous player
            game.GetPlayer(-1).cards.AddRange(game.stack_all);
            game.CleanStack();
            CheckCards();

            // "channel" reference is not updated after deleting the channel!
            if (GetLChannel(channel.GetName()) == null)
            {
                channel.Say(card_msg);
                return;
            }

            var prev_player = game.GetPlayer(-1);
            var curr_player = game.GetPlayer(0);

            card_msg += "Complete stack goes to " + prev_player.nick + ". " +
                        curr_player.nick + " can start with an empty stack.";

            channel.Say(card_msg);
            E.Notice(prev_player.nick, FormatCards(prev_player.cards, true));
            E.Notice(curr_player.nick, FormatCards(curr_player.cards, true));
        }
Пример #20
0
        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);
        }
Пример #21
0
        void OnUserSay(string nick, string message)
        {
            #region CTCP
            string message_l = message.ToLower();
            if (message_l == "\x01version\x01")
            {
                Notice(nick, "\x01VERSION " + G.settings["identifier"] + "\0x01");
                L.Log("E::OnChatMessage, sending version to " + nick);
                return;
            }
            if (message_l == "\x01time\x01")
            {
                Notice(nick, "\x01TIME " + DateTime.UtcNow.ToString("s") + "\0x01");
                L.Log("E::OnChatMessage, sending time to " + nick);
                return;
            }
            #endregion

            Channel chan = manager.GetChannel();
            L.Log(chan.GetName() + "\t <" + nick + "> " + message);

            #region Args
            {
                string to_replace = G.settings["nickname"] + ": ";
                if (message.StartsWith(to_replace, StringComparison.OrdinalIgnoreCase))
                {
                    message = message.Substring(to_replace.Length).Trim();
                    if (message.Length > 0 && message[0] != '$')
                    {
                        message = '$' + message;
                    }
                }
            }

            string[] args   = Chatcommand.Split(message);
            int      length = args.Length;

            if (args.Length < 10)
            {
                Array.Resize(ref args, 10);
            }

            for (int i = length; i < args.Length; i++)
            {
                args[i] = "";
            }
            #endregion

            #region Handle NickServ + return
            if (nick == "NickServ" && length >= 3)
            {
                if (Utils.isYes(G.settings["nickserv_acc"]) == 1)
                {
                    if (args[1] == "ACC")
                    {
                        manager.ReceivedUserStatus(args[1], args[2][0] - '0');
                        return;
                    }
                }
                else
                {
                    if (args[0] == "STATUS")
                    {
                        manager.ReceivedUserStatus(args[1], args[2][0] - '0');
                        return;
                    }
                }
                // Add more here?

                return;
            }
            #endregion

            if (args[0] == ".bots")
            {
                chan.Say(G.settings["identifier"]);
                return;
            }

            if (message.Length < 2 || message[0] != '$')
            {
                return;
            }

            manager.Fork("E::OnUserSay", message, delegate() {
                manager.OnUserSay(nick, message, length, ref args);
            });
        }