Basically i'm trying to serialize a dictionary<string, string>
object into a file, and load it back later. I know I'm probably doing something wrong here. (and yes this is an irc bot
). The issue is that the full contents of the dictionary isn't saving to the file and in my debug window i'm getting the "didn't save" text which means It probably hasn't.
It also crashes sometimes (leaves chat then returns)
That's all I can really say on the matter.. if there's something I"m doing wrong i think it's probably to do with my nested statements or a file handler not being dealt with in the correct manner.
I do have two parent functions, save and load, but the compiler doesn't like me calling them from within the IRCBOT
CLASS
Here is the full code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
/*
* This program establishes a connection to irc server and joins a channel. Thats it.
*
* Coded by Pasi Havia 17.11.2001 http://koti.mbnet.fi/~curupted
*
* Updated / fixed by Blake 09.10.2010
*/
class IrcBot
{
//Save the file
public bool SaveFile(string fullpath = Filename)
{
try
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = File.Create(fullpath);
formatter.Serialize(stream, C);
stream.Close();
}
catch
{
return false;
}
return true;
}
//Load a file
public bool LoadFile(string fullpath = Filename)
{
try
{
if (!File.Exists(fullpath))
return false;
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = File.OpenRead(fullpath);
C = (Dictionary<string, string>)formatter.Deserialize(stream);
stream.Close();
}
catch
{
return false;
}
return true;
}
// Irc server to connect
public static string SERVER = "irc.caffie.net";
// Irc server's port (6667 is default port)
private static int PORT = 6667;
// User information defined in RFC 2812 (Internet Relay Chat: Client Protocol) is sent to irc server
private static string USER = "USER IrcBot 0 * :IrcBot";
// Bot's nickname
private static string NICK = "Pinkbot";
// Channel to join
private static string CHANNEL = "#testingbots";
//The dictionary for messages
// private Dictionary<int, string> D = new Dictionary<int, string>();
public static Dictionary<string, string> C = new Dictionary<string, string>();
public const string fullpath = "bot_knowledge.txt";
public const string Filename = "bot_knowledge.txt";
public static StreamWriter writer;
static bool responded;
static bool shutup;
private static void Add_Response(string a, string b)
{
C.Add(a, b);
}
public static void Main(string[] args)
{
NetworkStream stream;
TcpClient irc;
string inputLine;
StreamReader reader;
try
{
//C.Add("what's up?", "nothing much");
// C.Add("meep", "mope");
// C.Add("hey", "what?");
// C.Add("what is", "it's two. ");
// C.Add("This", "that");
// C.Add("okay", "it is okay.");
// C.Add("is it?", "yeah..");
// C.Add("who are you", "I'm a bot");
// C.Add("Who are you?", "I am a bot");
// C.Add("not you", "oh I'm sorry");
// C.Add("what?", "nothing... just processing");
// C.Add("What?", "nothing just you know. :3");
// C.Add("help", "With ? ");
// C.Add("help me", "I can't I'm a bot.");
//C.Add("hm", "thinking deeply about something are we?");
// C.Add("yes", "oh no. ");
// C.Add("no", "OHHHH YESSS");
// C.Add("super mario world", "yes");
// C.Add("SMWC", "That's this place.. isn't it?");
// C.Add("smwc", "on our website!");
// C.Add("lol", "AHAHAHAHAHAHAHA!");
// C.Add("lel", "It's LOL");
// C.Add("!help", "use '!'shutup or '!'reset to change states omit '' see help2 for more");
// C.Add("!help2", "usage of '!'add is '!add' <yourphrasehere> '!'and <yoursecond phrase here> omit the ' ' ");
irc = new TcpClient(SERVER, PORT);
stream = irc.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
writer.WriteLine("NICK " + NICK);
writer.Flush();
writer.WriteLine(USER);
writer.Flush();
while (true)
{
while ((inputLine = reader.ReadLine()) != null)
{
if (inputLine.Contains("!shutup"))
{
shutup = true;
}
Console.WriteLine("<-" + inputLine);
//=======Here data is saved or loaded manually======//
if (inputLine.Contains("!load"))
{
try
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream st = File.OpenRead(fullpath);
C = (Dictionary<string, string>)formatter.Deserialize(st);
st.Close();
}
catch
{
Console.WriteLine("Didn't load");
}
writer.WriteLine("PRIVMSG " + CHANNEL + " :Data was loaded, presumably." + "\r\n");
writer.Flush();
}
if (inputLine.Contains("!save"))
{
try
{
BinaryFormatter formatter = new BinaryFormatter();
if (File.Exists(fullpath))
{
FileStream sa = File.OpenWrite(fullpath);
formatter.Serialize(sa, C);
sa.Close();
}
else
File.Delete(fullpath);
FileStream sc = File.Create(fullpath);
formatter.Serialize(sc, C);
sc.Close();
}
catch
{
Console.WriteLine("Wasn't saved...");
}
writer.WriteLine("PRIVMSG " + CHANNEL + " :Data was saved, presumably." + "\r\n");
writer.Flush();
}
//==============================================//
if (inputLine.Contains("!add"))
{
string[] parts = inputLine.Split(new Char[] { ' ' });
int x = parts.Count();
int splitstart = 0;
string a = "";
string b = "";
for (int t = 4; t < x; t++)
{
if (parts[t] == "!and")
{
splitstart = t;
break;
}
if (t == 4)
{
a = a + parts[t];
}
else
a = a + " " + parts[t];
}
//now that i found splitstart i can do this
if (splitstart > 0)
{
for (int tt = splitstart+1; tt<x; tt++)
{
if (tt == splitstart + 1)
{
b = b + parts[tt];
}
else
b = b + " " + parts[tt];
}
Add_Response(a, b);
writer.WriteLine("PRIVMSG " + CHANNEL + " :added " +a+" ->"+b+" to my dictionary"+ "\r\n");
writer.Flush();
}
}
if (responded == true)
{
responded = false;
}
// Split the lines sent from the server by spaces. This seems the easiest way to parse them.
string[] splitInput = inputLine.Split(new Char[] { ' ' });
foreach (string it in splitInput)
{
if (it.Contains("!reset"))
{
if (responded == true)
{
writer.WriteLine("PRIVMSG " + CHANNEL + " :variable 'responded' was set to true" + "\r\n");
writer.Flush();
}
if (responded == false)
{
writer.WriteLine("PRIVMSG " + CHANNEL + " :variable 'responded' was set to false" + "\r\n");
writer.Flush();
}
responded = false;
shutup = false;
}
//if (it.Contains("hello"))
//{
// writer.WriteLine("PRIVMSG " + CHANNEL + " :hey" + "\r\n");
//writer.Flush();
// }
if (responded == false)
{
if (!shutup)
{
foreach (KeyValuePair<string, string> entry in C)
{
// Console.WriteLine("<- was split to part " + it);
if (it.StartsWith(entry.Key))
{
string output = entry.Value;
writer.WriteLine("PRIVMSG " + CHANNEL + " :" + output + "\r\n");
writer.Flush();
responded = true;
}
else
if (inputLine.Contains(entry.Key))
{
string output = entry.Value;
writer.WriteLine("PRIVMSG " + CHANNEL + " :" + output + "\r\n");
writer.Flush();
responded = true;
}
}
}
}
}
if (splitInput[0] == "PING")
{
string PongReply = splitInput[1];
//Console.WriteLine("->PONG " + PongReply);
writer.WriteLine("PONG " + PongReply);
writer.Flush();
continue;
}
switch (splitInput[1])
{
// This is the 'raw' number, put out by the server. Its the first one
// so I figured it'd be the best time to send the join command.
// I don't know if this is standard practice or not.
case "001":
string JoinString = "JOIN " + CHANNEL;
writer.WriteLine(JoinString);
writer.Flush();
break;
case "002":
break;
default:
break;
}
}
// Close all streams
writer.Close();
reader.Close();
irc.Close();
}
}
catch (Exception e)
{
// Show the exception, sleep for a while and try to establish a new connection to irc server
Console.WriteLine(e.ToString());
Thread.Sleep(5000);
string[] argv = { };
Main(argv);
}
}
}