Thanks for your reply.
How can I be more specific?
Edit:
-
How should I handle multiple channels for each bot?
Do I have one connection for every channel or just one connection for all of them.
-
What exactly is the use of these chat servers for bots?
I will have to rewrite my code if it works how I think it does (seperate IRC servers). So instead of having a Bot as parent and Channel as child I’d have to reverse that.
I’m just lookiing for guidance on these things, I wonder if I’m doing it correctly, where can things be improved etc.
This is the main code that I use for connecting to IRC and joining channel(s):
public void DoMainWork(object sender, DoWorkEventArgs e)
{
Irc.SendDelay = 200;
Irc.Encoding = Encoding.UTF8;
Irc.AutoRetry = true;
Irc.AutoReconnect = true;
Irc.AutoRelogin = true;
Irc.AutoRejoin = true;
Irc.ActiveChannelSyncing = true;
Irc.OnOp += OnOp;
Irc.OnDeop += OnDeop;
Irc.OnConnected += OnConnected;
Irc.OnConnecting += OnConnecting;
Irc.OnDisconnected += OnDisconnected;
Irc.OnError += OnError;
Irc.OnRawMessage += OnRawMessage;
Irc.OnJoin += OnJoin;
Irc.OnPart += OnPart;
Irc.OnChannelMessage += OnChannelMessage;
Irc.Connect(Config.IrcHost, Config.IrcPort);
AddLogMessage("Authenticating", "");
Irc.Login(Nick, "AccursedNetwork Bot", 0, Nick, "oauth:" + Password);
foreach (var channel in Channels)
{
AddLogMessage("[{0}] joining {1}.".InjectWith(Nick, channel.NamePrefixed));
Irc.RfcJoin(channel.NamePrefixed);
}
while (!_mainWorker.CancellationPending)
{
if (Working)
{
try
{
Irc.ListenOnce(false);
}
catch (ArgumentException)
{
}
Uptime = Uptime + TimeSpan.FromMilliseconds(50);
Iterations++;
}
Thread.Sleep(50);
}
Irc.Disconnect();
}
So basically it hooks all of the events and then processes mostly everything with string comparisons.
OnChannelMessage
private void OnChannelMessage(object s, IrcEventArgs e)
{
if (!Working)
return;
var channel = TwitchChannels.Find(c => c.NamePrefixed == e.Data.Channel);
if (channel == null)
return;
var user = channel.Users.Find(u => u.Name == e.Data.Nick) ?? new User(channel.Id, e.Data.Nick);
if (channel.Mods.Contains(user.Name.Lc()) || Irc.GetChannel(channel.NamePrefixed).Ops.ContainsKey(user.Name.Lc()))
user.AccessLevel = AccessLevel.Operator;
user.AccessLevel = user.Name == channel.Name ? AccessLevel.Owner : user.AccessLevel;
user.MessagesSent++;
user.NeedSave = true;
if (channel.StealthMode)
return;
var message = e.Data.Message;
if (message.IsNullOrEmpty())
return;
string[] parts;
if (channel.Live && (e.Data.Nick == "twitchnotify" && message.Contains("subscribed")))
{
parts = e.Data.Message.Split(' ');
var nick = parts[0];
if (message.Contains("months in a row!"))
{
var months = parts[3];
SendMessage(
"{0} - thank you so much for the continued support with a subscription ({1} months)! <3"
.InjectWith(nick.UcFirst(), months), channel.NamePrefixed);
return;
}
SendMessage("{0} - thank you so much for subscribing! <3".InjectWith(nick.UcFirst()),
channel.NamePrefixed);
return;
}
var isCommand = message.StartsWith("!");
if (!isCommand)
return;
parts = e.Data.MessageArray;
var commandName = parts[0].Lc();
if (commandName == "!{0}".InjectWith(channel.CurrencyName.Lc()))
{
SendMessage("{0} -> you have [{1}] {2}!".InjectWith(user.Name, user.Currency, channel.CurrencyName.UcFirst()), channel.NamePrefixed);
return;
}
if (commandName == "!reload")
{
channel.Load();
SendMessage("{0} -> channel configuration reloaded.".InjectWith(user.Name), channel.NamePrefixed);
return;
}
var command = channel.Commands.Find(cmd => cmd.Name == commandName);
if (command == null)
return;
if (user.AccessLevel < command.AccessLevel)
{
SendMessage("{0} -> you do not have access to this command.".InjectWith(user.Name), channel.NamePrefixed);
return;
}
var commandText = command.Text;
if (commandText.IsNullOrEmpty())
return;
var commandArgsCount = Regex.Matches(commandText, @"\{[0-9]+\}", RegexOptions.Singleline | RegexOptions.IgnoreCase).Count;
var messageArgsCount = 0;
var temp = new string[message.Split(' ').Count()-1];
for (var i = 0; i < temp.Count(); i++)
{
temp[i] = message.Split(' ')[i+1];
}
var messageArgs = temp;
messageArgsCount = messageArgs.Count();
if (messageArgsCount < commandArgsCount)
{
SendMessage("{0} -> incorrect syntax for command {1}.".InjectWith(user.Name, commandName), channel.NamePrefixed);
return;
}
// ReSharper disable once CoVariantArrayConversion
commandText = commandText.InjectWith(messageArgs);
SendMessage(commandText, channel.NamePrefixed);
}
As you can see, every channel is a Channel and every bot is a TwitchBot and every new/existing user is a User.
This is what happens on JOIN/PART (for part in reverse):
private void OnJoin(object s, JoinEventArgs e)
{
var channel = TwitchChannels.Find(c => c.NamePrefixed == e.Data.Channel);
if (channel == null)
return;
var user = channel.Users.Find(u => u.Name == e.Data.Nick);
if (user != null)
return;
user = new User(channel.Id, e.Data.Nick);
AddLogMessage("user {0} joined the channel".InjectWith(user.Name));
channel.Users.Add(user);
}