3

我的 IRC Bot 有问题我正在尝试用 c# 编写,只是为了帮助我了解 IRC 协议,我计划在未来编写一个客户端/服务器,但你可以猜到我是离这个很远:P

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace LolBot
{
struct IRCConfig
{
    public string server;
    public int port;
    public string nick;
    public string name;

}

class IRCBot
{
    TcpClient IRCConnection = null;
    IRCConfig config;
    NetworkStream ns = null;
    StreamReader sr = null;
    StreamWriter sw = null;

    public IRCBot(IRCConfig config)
    {
        this.config = config;
        try
        {
            IRCConnection = new TcpClient(config.server, config.port);
        }
        catch
        {
            Console.WriteLine("Connection Error");
        }

        try
        {
            ns = IRCConnection.GetStream();
            sr = new StreamReader(ns);
            sw = new StreamWriter(ns);
            sendData("USER", config.nick + config.name);
            sendData("NICK", config.nick);
        }
        catch
        {
            Console.WriteLine("Communication error");
        }
        finally
        {
            if (sr != null)
                sr.Close();
            if (sw != null)
                sw.Close();
            if (ns != null)
                ns.Close();
            if (IRCConnection != null)
                IRCConnection.Close();
        }

    }

    public void sendData(string cmd, string param)
    {
        if (param == null)
        {
            sw.WriteLine(cmd);
            sw.Flush();
            Console.WriteLine(cmd);
        }
        else
        {
            sw.WriteLine(cmd + " " + param);
            sw.Flush();
            Console.WriteLine(cmd + " " + param);
        }
    }

    public void IRCWork()
    {
        string[] ex;
        string data;
        bool shouldRun = true;
        while (shouldRun)
        {
            data = sr.ReadLine();
            Console.WriteLine(data);
            char[] charSeparator = new char[] { ' ' };
            ex = data.Split(charSeparator, 5);

            if (ex[0] == "PING")
            {
                sendData("PONG", ex[1]);
            }

            if (ex.Length > 4) //is the command received long enough to be a bot command?
            {
                string command = ex[3]; //grab the command sent

                switch (command)
                {
                    case ":!join":
                        sendData("JOIN", ex[4]); //if the command is !join send the "JOIN" command to the server with the parameters set by the user
                        break;
                    case ":!say":
                        sendData("PRIVMSG", ex[2] + " " + ex[4]); //if the command is !say, send a message to the chan (ex[2]) followed by the actual message (ex[4]).
                        break;
                    case ":!quit":
                        sendData("QUIT", ex[4]); //if the command is quit, send the QUIT command to the server with a quit message
                        shouldRun = false; //turn shouldRun to false - the server will stop sending us data so trying to read it will not work and result in an error. This stops the loop from running and we will close off the connections properly
                        break;
                }
            }
        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        IRCConfig conf = new IRCConfig();
        conf.name = "LolBot";
        conf.nick = "LolBot";
        conf.port = 6667;
        conf.server = "irc.strictfp.com";
        new IRCBot(conf);
        Console.WriteLine("Bot quit/crashed");
        Console.ReadLine();
    }
}

}

每当我执行 Bot 时,它都会出现:

USER AspiBot google.com google.com :AspiBot
NICK AspiBot
Bot quit/crashed

我真的不明白为什么它在连接到服务器之前就退出了,我也在研究如何设置它来加入频道,我知道我需要使用 JOIN 但我不确定如何实现它.

4

1 回答 1

3

您可能不应该在构造函数中做太多事情,但是您在这里遇到的问题是您IRCWork()在更新机器人后没有调用。

var bot = new IRCBot(conf);
bot.IRCWork();

编辑您还在构造函数的 finally 块中关闭所有连接,因此 IRCWork() 无论如何都不会工作。尝试实施IDisposable,并将您的关闭逻辑放入Dispose()

using (var bot = new IRCBot(conf))
{
    bot.IRCWork();
}

发布代码的快速重构

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace LolBot
{
    internal struct IRCConfig
    {
        public string server;
        public int port;
        public string nick;
        public string name;

    }

    internal class IRCBot : IDisposable
    {
        private TcpClient IRCConnection = null;
        private IRCConfig config;
        private NetworkStream ns = null;
        private StreamReader sr = null;
        private StreamWriter sw = null;

        public IRCBot(IRCConfig config)
        {
            this.config = config;
        }

        public void Connect()
        {
            try
            {
                IRCConnection = new TcpClient(config.server, config.port);
            }
            catch
            {
                Console.WriteLine("Connection Error");
                throw;
            }

            try
            {
                ns = IRCConnection.GetStream();
                sr = new StreamReader(ns);
                sw = new StreamWriter(ns);
                sendData("USER", config.nick + config.name);
                sendData("NICK", config.nick);
            }
            catch
            {
                Console.WriteLine("Communication error");
                throw;
            }
        }

        public void sendData(string cmd, string param)
        {
            if (param == null)
            {
                sw.WriteLine(cmd);
                sw.Flush();
                Console.WriteLine(cmd);
            }
            else
            {
                sw.WriteLine(cmd + " " + param);
                sw.Flush();
                Console.WriteLine(cmd + " " + param);
            }
        }

        public void IRCWork()
        {
            string[] ex;
            string data;
            bool shouldRun = true;
            while (shouldRun)
            {
                data = sr.ReadLine();
                Console.WriteLine(data);
                char[] charSeparator = new char[] {' '};
                ex = data.Split(charSeparator, 5);

                if (ex[0] == "PING")
                {
                    sendData("PONG", ex[1]);
                }

                if (ex.Length > 4) //is the command received long enough to be a bot command?
                {
                    string command = ex[3]; //grab the command sent

                    switch (command)
                    {
                        case ":!join":
                            sendData("JOIN", ex[4]);
                                //if the command is !join send the "JOIN" command to the server with the parameters set by the user
                            break;
                        case ":!say":
                            sendData("PRIVMSG", ex[2] + " " + ex[4]);
                                //if the command is !say, send a message to the chan (ex[2]) followed by the actual message (ex[4]).
                            break;
                        case ":!quit":
                            sendData("QUIT", ex[4]);
                                //if the command is quit, send the QUIT command to the server with a quit message
                            shouldRun = false;
                                //turn shouldRun to false - the server will stop sending us data so trying to read it will not work and result in an error. This stops the loop from running and we will close off the connections properly
                            break;
                    }
                }
            }
        }

        public void Dispose()
        {
            if (sr != null)
                sr.Close();
            if (sw != null)
                sw.Close();
            if (ns != null)
                ns.Close();
            if (IRCConnection != null)
                IRCConnection.Close();
        }
    }


    internal class Program
    {
        private static void Main(string[] args)
        {
            IRCConfig conf = new IRCConfig();
            conf.name = "LolBot";
            conf.nick = "LolBot";
            conf.port = 6667;
            conf.server = "irc.strictfp.com";
            using (var bot = new IRCBot(conf))
            {
                bot.Connect();
                bot.IRCWork();
            }
            Console.WriteLine("Bot quit/crashed");
            Console.ReadLine();
        }
    }
}
于 2012-06-01T14:59:15.437 回答