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



Pastebėjimas dėl kodo - kadangi ciklas yra amžinas, tai šitos eilutės
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
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
Gal kas gali padeti? man meta stai tokias 3 klaidas..papastinau visa info errora ir 3 lines. http://paste2.org/p/1059742