C# ir .NET pamokėlės #8. IRC prisijungimas. Praktinė pamoka

Sveiki, turbūt retas nežinos mIRC programos. Seniau buvo užėjus populiarumo banga, tačiau greit Skype nuslopino ją. Tačiau, anais niūrais laikais klestėjo ir pats programavimas mIRC aplinkoj, taip vadinamų script'ų kurimai, tuo pačiu ir į vieną ar kitą event'ą reaguojantys botai. Taigi, botai, apie juos šį kart ir kalbėsiu. mes būsim kietesni ir sukursim jį ne mIRC aplinkoj, o C#, tad mums nereikės jokių pašalinių programų, kad botas puikiai veiktų :) Ilgai netempęs gumos pristatau kodą su komentarais:

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

class Klase
{
    static void Main()
    {
        try
        {
             // Jungiames į serverį
            TcpClient client = new TcpClient("irc.data.lt", 6667);
            NetworkStream stream = client.GetStream();
            // Skaitysime serverio pranešimus
            StreamReader reader = new StreamReader(stream);
            // Siųsime serveriui pranešimus
            StreamWriter writer = new StreamWriter(stream);
            // Saugomas nuskaitytas serverio atsiųstas tekstas
            string inputLine; 

            // Serveriui nusiunčiam savo nick'ą
            writer.WriteLine("NICK Botukas222");
            writer.Flush(); // Išvalom buffer'į
            while (true)
            {
                // Nagrinėjam serverio atsiųstą tekstą
                while ((inputLine = reader.ReadLine()) != null)
                {
                    // Sau į console atvaizduojam atsiųstą tekstą
                    Console.WriteLine(inputLine);
                    // Jei tai buvo parašyta žinutė?
                    if (inputLine.Contains("PRIVMSG"))
                    {
                        // Susiskaidom žinutę, kad lengviau angrinėt būtų
                        string[] txt = inputLine.Split(' ');
                        // Jei tai mums į privatą parašė?
                        if (txt[2] == "Botukas222")
                        {
                            // Susižinom rašytojo nick'ą
                            string kasRase = inputLine.Substring(1, inputLine.IndexOf('!') - 1);
                            // Siunčiam jam atgal žinutę.
                            // kasRase - aukščiau rastas nickas
                            // toliau seka parašytos žinutės radimas:
                            // inputLine.LastIndexOf(':') + 1 - iš pavadinimo matyt, kad randa paskutinio : simbolio vietą. +1, nes mums nereiks jo atvaizduot, tai imame sekančią vietą
                            // inputLine.Length - inputLine.LastIndexOf(':') - 1 - taigi paimame visą atėjusio teksto ilgį, bei atimame tą rastą paskutinyjį :. -1, nes skaičiuojama nuo 0, tad programa lūžtų, jei to neparašytume.
                            writer.WriteLine("PRIVMSG {0} Jusu zinute: {1}", kasRase, inputLine.Substring(inputLine.LastIndexOf(':') + 1, inputLine.Length - inputLine.LastIndexOf(':') - 1));
                            writer.Flush();
                        }
                        else
                        {
                            // Analogiškai anam, tik čia jau kanalo žinutės
                            string kasRase = inputLine.Substring(1, inputLine.IndexOf('!') - 1);
                            writer.WriteLine("PRIVMSG #test22 {0} parase zinute: {1}", kasRase, inputLine.Substring(inputLine.LastIndexOf(':') + 1, inputLine.Length - inputLine.LastIndexOf(':') - 1));
                            writer.Flush();
                        }
                    }
                    // Jei mūsų prašo servas identifikavimo.. savo galim pasirašyt, tik palikt struktūrą: USER nick server server: tekstas
                    else if (inputLine.Contains("Checking ident..."))
                    {
                        writer.WriteLine("USER Botukas222 irc.data.lt irc.data.lt: botasgalvass4");
                        writer.Flush();
                    }
                    // jei atvaizdavo serveris visą savo pateikiamą info, jungiames į kanalą
                    else if (inputLine.Contains("End of /MOTD command."))
                    {
                        writer.WriteLine("JOIN #test22");
                        writer.Flush();
                    }
                    // Jei mus pingina, siunčiam atgal
                    else if (inputLine.Contains("PING"))
                    {
                        writer.WriteLine("PONG irc.data.lt");
                        writer.Flush();
                    }

                }
            }
            // viską uždarom
            stream.Close();
            client.Close();
            reader.Close();
            writer.Close();
        }
        catch (SocketException e)
        {
            Console.WriteLine(e);
        }
    }
}

Tai tik pats elementariausias variantas. Botas sėdės kanale ir reaguos į privačią bei kanalo žinutes. Jei turėsit ryžto tobulint jį, neapseisit be, taip vadinamo, IRC protocol'o aprašymo, kurį rasite čia. Jei turit klausimų, prašom rašykit į komentarus. Sėkmės kūrybiniame procese!

Susiję įrašai:

  1. C# ir .NET pamokėlės #7. String Sveiki. Kadangi dažnai įvairiose programose reikia atlikti įvairius veiksmus su...
  2. C# ir .NET pamokėlės #5. Metodai Tai vienas iš naudingiausių įrankių kuriant programas. Jei esate dirbę...
  3. C# ir .NET pamokėlės #3. Sąlygos sakiniai Sąlygos sakinys, tai if...else formuluotė. Jeigu esate programavę su kokia...
  4. C# ir .NET pamokėlės #6. Masyvai Masyvas (angl. Array) – rinkinys vienodo tipo informacijos, kuri yra...
  5. C# ir .NET pamokėlės #2. Kintamieji Vienas iš dalykų, be kurių nei vienas programuotojas negalėtų apsieiti...
Topix Rokit Twitter Facebook Digg Delicious Stumbleupon

apie įrašą „C# ir .NET pamokėlės #8. IRC prisijungimas. Praktinė pamoka“

  1. Pastebėjimas dėl kodo - kadangi ciklas yra amžinas, tai šitos eilutės

    stream.Close();
    client.Close();
    reader.Close();
    writer.Close();
    

    niekada nebus įvygdytos, nes ciklas bus nutraukiamas vieninteliu būdu - exception, tai reiškia, kad vygdymas peršoks iškart į catch, bet tavo catch gaudo tik SocketException, reiškias niekada neuždarysi connection'o. Turėtum apskritai padaryt kažkokį išėjimą naturalų (ant Esc ar pan). Be to TcpClient klasė yra IDisposable, todėl turėtum daryt

    using(TcpClient client = new TcpClient("irc.data.lt", 6667))
    {
    // <tavo_kodas>
    } 

    arba bet kokiu atveju po panaudojimo naudoti client.Dispose();, net jei šauna exception'as. Taipogi visos klasės paveldėtos iš Stream bei reader'iai ir writer'iai yra IDisposable, todėl ten irgi turėtum naudoti using, nes kitaip nepaleisi Dispose metodo ir liks šiukšlių, kurių nesurinks GC ( garbage collector ). Taipogi dėl writer.Flush(); writer turi property AutoFlush, taigi reiktų padaryt writer.AutoFlush = true; ir nebereikėtų kartoti po kiekvieno Write'o tos nesamonės. Apskritai - kiekvieną kartą, kai sukasi ciklas, paskelbinėt kintamuosius - žudantis dalykas. Iškelk virš ciklo, neprarasi performance'o. Šiaip client'as super pavyzdys, kaip paprastai dirbti su tinklu. Mažas pastebėjimas dėl kintamųjų - jei angliškai, tai visus angliškai, jei lietuviškai - tai visus lietuviškai :) Ir dar - klasės pavadinimas turi atspindėt, ką ji daro, tai siūlyčiau vietoj Klase pavadinti kad ir IrcBot. Bet čia jau tikriausiai kabinėjimasis :D

  2. nėra tobulas. šiaip reiktų padaryt išeidinėjant dar, kad IRC protocol'ui nusiųstu exit'ą, nes dabar serveris mato, kaip kliento nulūžimą. šiaip čia daug pavyzdžių yra kaip su string'ais dirbt. Dėl AutoFlush tai nežinojau tokio, dėkui :D

  3. Gal kas gali padeti? man meta stai tokias 3 klaidas..papastinau visa info errora ir 3 lines. http://paste2.org/p/1059742

Palikti atsakymą