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();
}
}
}exe ei toimi
Oletko asentanut (XP:ssä valmiina) .NET Frameworkin?
Kuinkas tämän saa sitte toimimaan? Tartteeko tässä jotakin lisä juttuja, että saa noi C:llä tehdyt jutut toimimaan?
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#.
Jaha nyt sitte tiedän senkin.
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
Tota ei taida saada ihan ehti Linuxilla meneen? :P
Jaa a, Mono voisi auttaa :)
http://www.mono-project.com/Main_Page
Ja sitten sama pythonilla säästäen 600 riviä ;) Mutta näyttihän tämä toimivan.
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 ...
Onko tuo C#:tä?
lainaus:
Onko tuo C#:tä?
On.
Jaa.
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 :(
Deleted text.
Aihe on jo aika vanha, joten et voi enää vastata siihen.