Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C#: IRC Bot

Sivun loppuun

apex [29.06.2005 11:46:59]

#

Ensimmäinen C# projektini jonka aloitin melkein vuosi sitten. Pari viikkoa sitä tässä uudelleen duunannut.

Ei toimi välttämättä kaikkia identdiä vaativilla servereillä, koska sitä ei siinä ole.

Ominaisuuksia
-login otto
-reconnect
-aikaleima
-tuki monelle kanavalle
-skandinaaviset merkit
-etäkäyttö
-help

http://mbnet.fi/~rths/ircbot/ Exe ja pari screenshottia

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;


class Variables
{
    //message when making connection
    public string values1 = "Making connection...";

    //message when reconnecting
    public string doReconnect = "Reconnecting...";

    //message when value is typed wrong
    public string values2 = "Invalid value";

    //message when error has been occured
    public string uError = "Unexpected error";

    //message when returning to main
    public string toMain = "Press enter to return to Main";

    //log's max size's minimum value in KB
    public int logMinValue = 10;

    //bot say log error
    public string noLogging = "Logging is not ON.";

    //variable asker method
    public string WhatValue(string question)
    {
        Console.Write("\t{0}: ", question);
        string answer = Console.ReadLine();
        return answer;
    }

    //version number
    public string version = "1.5.0";

    //version number
    public string years = "2004-2005";

    //search characters from variable
    public bool IsNumeric(string str)
    {
        try
        {
            Convert.ToInt32(str);
        }
        catch
        {
            return false;
        }
        return true;
    }

    //check does index exists
    public bool IndexExists(string[] array, int iNum)
    {
        try
        {
            string testIndex = array[iNum];
        }
        catch
        {
            return false;
        }
        return true;
    }

    //reconnect asker method
    public bool Reconnect()
    {
        Console.Write("Reconnect (YES or NO): ");
        string answer = Console.ReadLine().ToLower();
        if ( answer != "yes" && answer != "no" )
        {
            Console.WriteLine("\n*{0} - only YES or NO\n", values2);
            Reconnect();
        }
        if ( answer == "yes" )
        {
            return true;
        }
        return false;
    }
}

class Sockets
{
    TcpClient tcpClient;
    NetworkStream networkStream;
    StreamReader ircReader;
    StreamWriter ircWriter;

    FileInfo logInfo;
    StreamWriter logWriter;

    public void LogHeader(string server, int port, string showTime, string logPath, int logMaxSize, string remotePass)
    {
        logWriter.WriteLine("IRC server:\t\t" + server);
        logWriter.WriteLine("Server port:\t\t" + port);
        logWriter.WriteLine("Show timestamp:\t\t" + showTime);
        logWriter.WriteLine("Log's path:\t\t" + logPath);
        logWriter.WriteLine("Log's max size:\t\t" + logMaxSize/1024 + "KB");
        logWriter.WriteLine("Remote password:\t" + remotePass);
        logWriter.WriteLine();
    }

    public void ConsoleWriter(bool isTimePresent, string content)
    {
        if ( isTimePresent == true )
        {
            Console.WriteLine("[" + DateTime.Now + "]\t" + content + "\n");
        }
        else
        {
            Console.WriteLine(content + "\n");
        }
    }

    public void LogWriter(bool isTimePresent, string content)
    {
        if ( isTimePresent == true )
        {
            logWriter.WriteLine("[" + DateTime.Now + "]\t" + content);
        }
        else
        {
            logWriter.WriteLine(content);
        }
    }

    public void Connect(string server, int port, string nick, string[] channelArray, string showTime, string logPath, int logMaxSize, string remotePass)
    {
        Variables variables = new Variables();

        tcpClient = new TcpClient(server, port);
        networkStream = tcpClient.GetStream();
        ircReader = new StreamReader(networkStream, Encoding.Default);
        ircWriter = new StreamWriter(networkStream, Encoding.Default);
        ircWriter.AutoFlush = true;

        string output;

        bool authed = false;
        bool isPathPresent = false;
        bool isTimePresent = false;

        long logSize = 0;

        int i;

        //authing
        ircWriter.WriteLine("USER " + nick + " 8 * :" + nick);
        ircWriter.WriteLine("NICK " + nick);
        for ( i = 0; i < channelArray.Length; i++ )
        {
            ircWriter.WriteLine("JOIN " + channelArray[i]);
        }
        //end

        logInfo = null;
        logWriter = null;

        //enable logging if logPath variable is not empty
        if ( logPath != "" )
        {
            isPathPresent = true;
            logInfo = new FileInfo(logPath);
            logWriter = new StreamWriter(logPath);
            logWriter.AutoFlush = true;

            LogHeader(server, port, showTime, logPath, logMaxSize, remotePass);
        }
        //end

        //enable timestamp if showTime variable is set to "ON"
        if ( showTime == "ON" )
        {
            isTimePresent = true;
        }
        //end

        try
        {
            do
            {
                output = ircReader.ReadLine();
                string[] outputArray = output.Split(null);

                //write messages that are received from server to console
                ConsoleWriter(isTimePresent, output);

                //delete log file if log's max size is reached
                if ( logSize > logMaxSize )
                {
                    logWriter.Close();
                    logInfo.Delete();
                    logWriter = new StreamWriter(logPath);
                    logWriter.AutoFlush = true;

                    LogHeader(server, port, showTime, logPath, logMaxSize, remotePass);
                }
                //end

                //write messages that are received from server to log if it's enabled
                if ( isPathPresent == true )
                {
                    LogWriter(isTimePresent, output);

                    logInfo.Refresh();
                    logSize = logInfo.Length;
                }
                //end

                //message reader
                for ( i = 0; i < outputArray.Length; i++ )
                {
                    //pong sender
                    if ( outputArray[i].ToLower() == "ping" && i + 1 < outputArray.Length && variables.IndexExists(outputArray, i-1) == false )
                    {
                        ircWriter.WriteLine("PONG " + outputArray[i+1].Replace(":", null));
                        ConsoleWriter(isTimePresent, "*PONG sent");

                        //write messages that are received from server to log if it's enabled
                        if ( isPathPresent == true )
                        {
                            LogWriter(isTimePresent, "*PONG sent");

                            logInfo.Refresh();
                            logSize = logInfo.Length;
                        }
                        //end
                    }
                    //end

                    //backup joining
                    if ( outputArray[i] == "451" && variables.IndexExists(outputArray, i-2) == false && authed == false )
                    {
                        authed = true;
                        for ( i = 0; i < channelArray.Length; i++ )
                        {
                            ircWriter.WriteLine("JOIN " + channelArray[i]);
                        }
                    }
                    //end

                    //remote control
                    if ( remotePass != "" )
                    {
                        if (
                            outputArray[i].ToLower() == "privmsg" &&
                            i + 3 < outputArray.Length &&
                            outputArray[i+1].StartsWith("#") == false &&
                            outputArray[i+2] == ":" + remotePass
                           )
                        {
                            string remoteInput = output.Replace(outputArray[i-1] + " " + outputArray[i] + " " + outputArray[i+1] + " " + outputArray[i+2] + " ", null);

                            if ( outputArray[i+3].ToLower() != "bot" )
                            {
                                //write remote input command to console
                                ConsoleWriter(isTimePresent, "*" + remoteInput);

                                //write remote input command to log if it's enabled
                                if ( isPathPresent == true )
                                {
                                    LogWriter(isTimePresent, "*" + remoteInput);

                                    logInfo.Refresh();
                                    logSize = logInfo.Length;
                                }
                                //end
                            }

                            if ( outputArray[i+3].ToLower() != "bot" )
                            {
                                ircWriter.WriteLine(remoteInput);
                            }

                            if ( outputArray[i+3].ToLower() == "bot" && variables.IndexExists(outputArray, i+5) == true )
                            {
                                string bCommand = outputArray[i+4].Replace(" ", null);
                                bCommand = bCommand.ToLower();
                                string bValue = outputArray[i+5].Replace(" ", null);
                                bValue = bValue.ToLower();
                                string[] cNickArray = outputArray[0].Split('!');
                                //controller's nick
                                string cNick = cNickArray[0].Replace(":", null);

                                if ( outputArray[i+4].ToLower() == "say" )
                                {
                                    //say logsize
                                    if ( outputArray[i+5].ToLower() == "logsize" )
                                    {
                                        //write to log if it's enabled
                                        if ( isPathPresent == true )
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + logSize/1024 + "KB");
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logSize/1024 + "KB");
                                            LogWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logSize/1024 + "KB");

                                            logInfo.Refresh();
                                            logSize = logInfo.Length;
                                        }
                                        //end
                                        else
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + variables.noLogging);
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + variables.noLogging);
                                        }
                                    }
                                    //end

                                    //say logmaxsize
                                    if ( outputArray[i+5].ToLower() == "logmaxsize" )
                                    {
                                        //write to log if it's enabled
                                        if ( isPathPresent == true )
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + logMaxSize/1024 + "KB");
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logMaxSize/1024 + "KB");
                                            LogWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logMaxSize/1024 + "KB");

                                            logInfo.Refresh();
                                            logSize = logInfo.Length;
                                        }
                                        //end
                                        else
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + variables.noLogging);
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + variables.noLogging);
                                        }
                                    }
                                    //end

                                    //say logpath
                                    if ( outputArray[i+5].ToLower() == "logpath" )
                                    {
                                        //write to log if it's enabled
                                        if ( isPathPresent == true )
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + logPath);
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logPath);
                                            LogWriter(isTimePresent, "*PRIVMSG " + cNick + " " + logPath);

                                            logInfo.Refresh();
                                            logSize = logInfo.Length;
                                        }
                                        //end
                                        else
                                        {
                                            ircWriter.WriteLine("PRIVMSG " + cNick + " " + variables.noLogging);
                                            ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + variables.noLogging);
                                        }
                                    }
                                    //end

                                    //say timestamp
                                    if ( outputArray[i+5].ToLower() == "timestamp" )
                                    {
                                        ircWriter.WriteLine("PRIVMSG " + cNick + " " + showTime);
                                        ConsoleWriter(isTimePresent, "*PRIVMSG " + cNick + " " + showTime);

                                        //write to log if it's enabled
                                        if ( isPathPresent == true )
                                        {
                                            LogWriter(isTimePresent, "*PRIVMSG " + cNick + " " + showTime);

                                            logInfo.Refresh();
                                            logSize = logInfo.Length;
                                        }
                                        //end
                                    }
                                    //end
                                }
                            }

                            //quit message
                            if ( outputArray[i+3].ToLower() == "quit" )
                            {
                                //close sockets
                                tcpClient.Close();
                                networkStream.Close();
                                ircReader.Close();
                                ircWriter.Close();

                                //close logstreams if log is enabled
                                if ( isPathPresent == true )
                                {
                                    logInfo = null;
                                    logWriter.Close();
                                }
                                //end

                                //ask reconnecting
                                if ( variables.Reconnect() == true )
                                {
                                    //reconnect
                                    Console.WriteLine("\n*{0}\n", variables.doReconnect);
                                    Connect(server, port, nick, channelArray, showTime, logPath, logMaxSize, remotePass);
                                }
                                else
                                {
                                    //return to main
                                    Console.WriteLine();
                                    MainClass.Main();
                                }
                                //end
                            }
                            //end
                        }
                    }
                    //end
                }
                //end
            }
            while ( output != null );
        }
        catch ( Exception e )
        {
            //display the error
            Console.WriteLine("*{0} - " + e.Message + "\n", variables.uError);

            //close sockets
            tcpClient.Close();
            networkStream.Close();
            ircReader.Close();
            ircWriter.Close();

            //close logstreams if log is enabled
            if ( isPathPresent == true )
            {
                logWriter.WriteLine();
                logWriter.WriteLine("*{0} - " + e.Message, variables.uError);
                logInfo = null;
                logWriter.Close();
            }
            //end

            //ask reconnecting
            if ( variables.Reconnect() == true )
            {
                //reconnect
                Console.WriteLine("\n*{0}\n", variables.doReconnect);
                Connect(server, port, nick, channelArray, showTime, logPath, logMaxSize, remotePass);
            }
            else
            {
                //return to main
                Console.WriteLine();
                MainClass.Main();
            }
            //end
        }
    }
}


class MainClass
{
    public static void Main()
    {
        Variables variables = new Variables();
        Sockets sockets = new Sockets();

        int logMaxSize = 0;
        int i;

        Console.WriteLine("IRC Bot - v.{0} - Copyright © {1} Orithos\n", variables.version, variables.years);

        Console.WriteLine("C - Connect");
        Console.WriteLine("H - Help");
        Console.WriteLine("Q - Quit\n");

        Console.Write("Action: ");
        string whatNext = Console.ReadLine().ToLower();

        if ( whatNext == "c" )
        {
            Console.WriteLine("\nSettings:");

        //ask server variable and check it
            string server = variables.WhatValue("IRC server").ToString().ToLower();
            if ( server == "" )
            {
                Console.WriteLine("\n*{0} - cannot  be empty\n", variables.values2);
                Main();
            }
        //end

        //ask port variable and check it
            string portString = variables.WhatValue("Server port").ToString();
            if ( portString == "" )
            {
                Console.WriteLine("\n*{0} - cannot  be empty\n", variables.values2);
                Main();
            }
            if ( variables.IsNumeric(portString) != true )
            {
                Console.WriteLine("\n*{0} - no characters allowed\n", variables.values2);
                Main();
            }
            int port = Convert.ToInt32(portString);
        //end

        //ask nick variable and check it
            string nick = variables.WhatValue("Bot's nickname").ToString();
            if ( nick == "" )
            {
                Console.WriteLine("\n*{0} - cannot  be empty\n", variables.values2);
                Main();
            }
            if ( nick != nick.Replace(" ", null) )
            {
                Console.WriteLine("\n*{0} - no spaces allowed\n", variables.values2);
                Main();
            }
        //end

        //ask channels variable and check it
            string channels = variables.WhatValue("Channel(s) (comma-separated)").ToString().Replace(" ", null);
            if ( channels == "" )
            {
                Console.WriteLine("\n*{0} - cannot  be empty\n", variables.values2);
                Main();
            }
            string[] channelArray = channels.Split(',');
            for ( i = 0; i < channelArray.Length; i++ )
            {
                if ( channelArray[i].IndexOf('#') != 0 )
                {
                    channelArray[i] = '#' + channelArray[i];
                }
            }
        //end

        //ask timestamp variable and check it
            string showTime = variables.WhatValue("Show timestamp (ON or OFF)").ToString().ToUpper();
            if ( showTime != "ON" && showTime != "OFF" )
            {
                Console.WriteLine("\n*{0} - only ON or OFF\n", variables.values2);
                Main();
            }
        //end

        //ask log's path variable and check it
            string logPath = variables.WhatValue("Log's path (empty = no log)").ToString();
            if ( File.Exists(logPath) == true )
            {
                Console.WriteLine("\n*{0} - the file cannot exists\n", variables.values2);
                Main();
            }
        //end

        //ask log's max size variable and check it if log path is present
        if ( logPath != "" )
        {
            string logMaxSizeString = variables.WhatValue("Log's max size (in KB)").ToString();
            if ( logMaxSizeString == "" )
            {
                Console.WriteLine("\n*{0} - cannot be empty\n", variables.values2);
                Main();
            }
            if ( variables.IsNumeric(logMaxSizeString) != true )
            {
                Console.WriteLine("\n*{0} - no characters allowed\n", variables.values2);
                Main();
            }
            logMaxSize = Convert.ToInt32(logMaxSizeString);
            if ( logMaxSize == 0 )
            {
                Console.WriteLine("\n*{0} - cannot be zero\n", variables.values2);
                Main();
            }
            if ( logMaxSize < variables.logMinValue )
            {
                Console.WriteLine("\n*{0} - minimum value {1}\n", variables.values2, variables.logMinValue);
                Main();
            }
            logMaxSize = logMaxSize * 1024;
        }
        //end

        //ask remote password variable and check it
            string remotePass = variables.WhatValue("Remote password (empty = no control)").ToString();
            if ( remotePass != remotePass.Replace(" ", null) )
            {
                Console.WriteLine("\n*{0} - no spaces allowed\n", variables.values2);
                Main();
            }
        //end

            //start the connection
            Console.WriteLine("\n*{0}\n", variables.values1);
            sockets.Connect(server, port, nick, channelArray, showTime, logPath, logMaxSize, remotePass);
        }

        if ( whatNext == "h" )
        {
            Console.WriteLine("\nHelp:");

            Console.WriteLine("\t-This is a very small and hopefully a lightweight IRC Bot written in C#.");
            Console.WriteLine("\t-Controlling bot happens by typing a private message to it, method:");

            Console.WriteLine("\n\t\t-PRIVMSG [BOTNAME] [PASSWORD] [COMMAND]");
            Console.WriteLine("\t\t-PRIVMSG mybot mypassword PRIVMSG #mychannel :Hello folks!");

            Console.WriteLine("\n\tNOTE: You have to exclude \"PRIVMSG [BOTNAME]\"");
            Console.WriteLine("\tif you are typing via private message window.");

            Console.WriteLine("\n\tNOTE: Before any message you have to add colon (:)");
            Console.WriteLine("\tlike in the first example, otherwise only last word");
            Console.WriteLine("\twill be counted.");

            Console.WriteLine("\n\t-You can ask bot's start values by typing:");

            Console.WriteLine("\n\t\t-PRIVMSG [B] [P] BOT SAY [LIST]");
            Console.WriteLine("\t\t-LIST: LOGSIZE, LOGMAXSIZE, LOGPATH, TIMESTAMP");
            Console.WriteLine("\t\t-PRIVMSG mybot mypassword BOT SAY LOGSIZE");

            Console.WriteLine("\n\tNOTE: All private messages will be written in the log");
            Console.WriteLine("\t(if logging is enabled).");

            Console.WriteLine("\n*{0}", variables.toMain);
            Console.ReadLine();
            Main();
        }

        if ( whatNext == "q" )
        {
            //close the console
            System.Environment.Exit(0);
        }
        if ( whatNext != "c" && whatNext != "h" && whatNext != "q" )
        {
            Console.WriteLine("\n*{0} - try again\n", variables.values2);
            Main();
        }
    }
}

tesmu [02.07.2005 01:27:42]

#

exe ei toimi

apex [02.07.2005 10:21:22]

#

Oletko asentanut (XP:ssä valmiina) .NET Frameworkin?

maratti [02.07.2005 21:40:49]

#

Kuinkas tämän saa sitte toimimaan? Tartteeko tässä jotakin lisä juttuja, että saa noi C:llä tehdyt jutut toimimaan?

Megant92 [03.07.2005 12:38:28]

#

lainaus:

Kuinkas tämän saa sitte toimimaan? Tartteeko tässä jotakin lisä juttuja, että saa noi C:llä tehdyt jutut toimimaan?

Ei tuo ole C:tä.Se on C#.

maratti [03.07.2005 20:05:00]

#

Jaha nyt sitte tiedän senkin.

peki [03.07.2005 22:46:31]

#

Tuo koodi näkyisi aika useaan otteeseen kutsuvan Main() funktiota uudestaan.
En tiedä C#:stä, mutta ainakin C:ssä Mainin kutsuminen useita kertoja peräkkäin johtaa suureen muistinkulutukseen ja ongelmiin. Tietääkseni se on myös huonoa ohjelmoinityyliä. :P

Firsti [04.07.2005 13:46:30]

#

Tota ei taida saada ihan ehti Linuxilla meneen? :P

apex [04.07.2005 17:31:59]

#

Jaa a, Mono voisi auttaa :)
http://www.mono-project.com/Main_Page

llr [07.07.2005 02:35:49]

#

Ja sitten sama pythonilla säästäen 600 riviä ;) Mutta näyttihän tämä toimivan.

_Pete_ [07.07.2005 23:45:04]

#

lainaus:

Tota ei taida saada ihan ehti Linuxilla meneen? :P

http://machine.homeunix.net/cgi-bin/trac.cgi/wiki/Main

Tuo toimii hyvin linuxilla ja windowsilla ...

teppu [19.07.2005 13:25:09]

#

Onko tuo C#:tä?

Linkku [20.07.2005 19:25:15]

#

lainaus:

Onko tuo C#:tä?

On.

teppu [22.07.2005 18:50:17]

#

Jaa.

miksanos [26.07.2005 16:55:31]

#

Tuossa on kyllä aika perustavanlaatuinen suunnittelumoka, koska kutsut Main() -funktiota tuon tuostakin uudestaan, missä ei ole mitään järkeä. Kun kutsut funktiota, edellinen funktio jää siihen Main() -kohtaan odottamaan sen uuden kutsun valmistumista, mikä ei koskaan tule tapahtumaan, koska jossain joku toinen kohta kutsuu uudestaan Main() -funktiota. Lopulta tarpeeksi monen kerran jälkeen ohjelma kaatuu muistaakseni StackOverflow -poikkeukseen, jota ennen kuitenkin hidastuu merkittävästi kun muisti loppuu eka kesken. Tuota ei kuitenkaan varmaan huomaa, koska muistin loppumiseen vaaditaan satoja tuhansia kutsuja, mutta silti :(

rax [27.05.2008 14:15:29]

#

Deleted text.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta