[Plugin] IRC Plugin
#1

IRC Plugin

This plugin allows for the creation and management of IRC bots through the SA-MP server. There are many features, including:
  • SSL support and local IP address binding
  • Automatic reconnection attempts with configurable options
  • Bot grouping (built-in support for message distribution to prevent accidental flooding)
  • No limit on number of concurrent bot connections (support for multiple servers)
  • Efficient channel command system (slightly modified zcmd by Zeex)
Changelog

GitHub Commit History

Refer to the CHANGES file the binary package for the full changelog.

Enum

pawn Code:
enum
{
    E_IRC_CONNECT_ATTEMPTS,
    E_IRC_CONNECT_DELAY,
    E_IRC_CONNECT_TIMEOUT,
    E_IRC_RECEIVE_TIMEOUT,
    E_IRC_RESPAWN
}
Natives
  • IRC_Connect(const server[], port, const nickname[], const realname[], const username[], bool:ssl = false, const localip[] = "", const serverpassword[] = "");
    • Connects to an IRC server (returns the botid)
      Note #1: The nickname is the name that everyone will see, the realname will only be visible in a whois, and the username will be in front of the hostname (username@hostname).
      Note #2: SSL connections can be initiated by setting the third-to-last parameter to true and connecting to an SSL-enabled server.
      Note #3: The socket can be optionally bound to a local IP address by entering it in the second-to-last parameter.
      Note #4: A server password can be optionally set by entering it in the last parameter (note that this is NOT the same as a password for an IRC service such as NickServ).

  • IRC_Quit(botid, const message[] = "");
    • Disconnects from an IRC server
      Note: A quit message may be specified, but it is optional.

  • IRC_JoinChannel(botid, const channel[], const key[] = "");
    • Joins a channel
      Note: A channel key may be specified, if necessary.

  • IRC_PartChannel(botid, const channel[], const message[] = "");
    • Parts a channel
      Note: A part message may be specified, but it is optional.

  • IRC_ChangeNick(botid, const nick[]);
    • Changes the bot's current nickname

  • IRC_SetMode(botid, const target[], const mode[]);
    • Sets a user mode or a channel mode
      Note: The target must be either the bot's current nickname or a channel (multiple modes and their parameters may also be set).

  • IRC_Say(botid, const target[], const message[]);
    • Sends a message to a user or a channel

  • IRC_Notice(botid, const target[], const message[]);
    • Sends a notice to a user or a channel

  • IRC_IsUserOnChannel(botid, const channel[], const user[]);
    • Searches for a user in a channel (returns 0 or 1)

  • IRC_InviteUser(botid, const channel[], const user[]);
    • Invites a user to a channel

  • IRC_KickUser(botid, const channel[], const user[], const message[] = "");
    • Kicks a user from a channel
      Note: A kick message may be specified, but it is optional.

  • IRC_GetUserChannelMode(botid, const channel[], const user[], dest[]);
    • Obtains a user's channel mode (voice, halfop, op, protect/admin, or founder/owner)
      Note: This will store "+", "%", "@", "&", "!", "*", "~", ".", or "-" (if the user has no mode) in dest (use the stock functions below to simplify usage).

  • IRC_GetChannelUserList(botid, const channel[], dest[], maxlength = sizeof dest);
    • Obtains a space-delimited list of all users in a channel
      Note: This will store every user's name separated by a single space in dest (make sure that the array size is large enough to fit all of the names).

  • IRC_SetChannelTopic(botid, const channel[], const topic[]);
    • Sets a channel topic
      Note: A blank topic may be set by passing an empty string.

  • IRC_RequestCTCP(botid, const user[], const message[]);
    • Sends a CTCP request to a user

  • IRC_ReplyCTCP(botid, const user[], const message[]);
    • Sends a CTCP reply to a user

  • IRC_SendRaw(botid, const message[]);
    • Sends a raw message to the IRC server

  • IRC_CreateGroup();
    • Creates a group (returns the groupid)

  • IRC_DestroyGroup(groupid);
    • Destroys a group

  • IRC_AddToGroup(groupid, botid);
    • Adds a bot to a group

  • IRC_RemoveFromGroup(groupid, botid);
    • Removes a bot from a group

  • IRC_GroupSay(groupid, const target[], const message[]);
    • Sends a message to a user or a channel using the bot that is next in the group

  • IRC_GroupNotice(groupid, const target[], const message[]);
    • Sends a notice to a user or a channel using the bot that is next in the group

  • IRC_SetIntData(botid, data, value);
    • Adjusts settings for bots (refer to the enum for the data parameter)
Callbacks
  • IRC_OnConnect(botid, ip[], port);
    • Called when a bot successfully connects to the IRC server
      Note: Specifically, this is called when the "001" command is received.

  • IRC_OnDisconnect(botid, ip[], port, reason[]);
    • Called when a bot disconnects from the IRC server

  • IRC_OnConnectAttempt(botid, ip[], port);
    • Called when a bot begins a connection attempt

  • IRC_OnConnectAttemptFail(botid, ip[], port, reason[]);
    • Called when a bot fails a connection attempt

  • IRC_OnJoinChannel(botid, channel[]);
    • Called when a bot joins a channel

  • IRC_OnLeaveChannel(botid, channel[], message[]);
    • Called when a bot parts a channel

  • IRC_OnInvitedToChannel(botid, channel[], invitinguser[], invitinghost[]);
    • Called when a bot is invited to a channel

  • IRC_OnKickedFromChannel(botid, channel[], oppeduser[], oppedhost[], message[]);
    • Called when a bot is kicked from a channel

  • IRC_OnUserDisconnect(botid, user[], host[], message[]);
    • Called when a user in a common channel disconnects from the IRC server

  • IRC_OnUserJoinChannel(botid, channel[], user[], host[]);
    • Called when a user joins a common channel

  • IRC_OnUserLeaveChannel(botid, channel[], user[], host[], message[]);
    • Called when a user parts a common channel

  • IRC_OnUserKickedFromChannel(botid, channel[], kickeduser[], oppeduser[], oppedhost[], message[]);
    • Called when a user is kicked from a common channel

  • IRC_OnUserNickChange(botid, oldnick[], newnick[], host[]);
    • Called when a user in a common channel changes his/her nick

  • IRC_OnUserSetChannelMode(botid, channel[], user[], host[], mode[]);
    • Called when a user in a common channel sets a channel mode

  • IRC_OnUserSetChannelTopic(botid, channel[], user[], host[], topic[]);
    • Called when a user in a common channel sets a channel topic

  • IRC_OnUserSay(botid, recipient[], user[], host[], message[]);
    • Called when a user sends a message to a common channel or a private message to a bot (recpient can be either the bot name or the channel name)
      Note: If the bot is part of a group, only the first member of the group will receive this callback.

  • IRC_OnUserNotice(botid, recipient[], user[], host[], message[]);
    • Called when a user sends a notice to a common channel or to a bot (recpient can be either the bot name or the channel name)

  • IRC_OnUserRequestCTCP(botid, user[], host[], message[]);
    • Called when a user sends a CTCP request to a bot

  • IRC_OnUserReplyCTCP(botid, user[], host[], message[]);
    • Called when a user sends a CTCP reply to a bot

  • IRC_OnReceiveNumeric(botid, numeric, message[]);
    • Called when a bot receives a numeric code from the IRC server

  • IRC_OnReceiveRaw(botid, message[]);
    • Called when a bot receives a raw message from the IRC server
Stock Functions

These functions are used to simplify implementation of IRC_GetChannelUserMode. Note that all of the following will return true if the user is at the requested level or higher. For example, IRC_IsVoice will return true if the user is an op.
  • IRC_IsVoice(botid, channel[], user[]);

  • IRC_IsHalfop(botid, channel[], user[]);

  • IRC_IsOp(botid, channel[], user[]);

  • IRC_IsAdmin(botid, channel[], user[]);

  • IRC_IsOwner(botid, channel[], user[]);
Instructions

Create a directory called "plugins" inside of the server directory if one does not already exist. Place the plugin file (irc.dll or irc.so) inside of this directory.

Add the following line to server.cfg so that the plugin will load the next time the server starts:

Windows:
Code:
plugins irc.dll
Linux:
Code:
plugins irc.so
On Windows, add irc.inc to the pawno\include folder. Include this file in any of the scripts the server is running:

pawn Code:
#include <irc>
Recompile the scripts with any desired natives and callbacks provided by the include file. Start the server.

Channel Command System

The command system is identical to zcmd, but messages are parsed in IRC_OnUserSay rather than in OnPlayerCommandText. The function syntax resembles the following (this can be placed anywhere in the script):

pawn Code:
IRCCMD:command(botid, channel[], user[], host[], params[])
{
    /* ... */
}
Note that if two or more bots are present in the same channel, the bot that needs to process the command must be specified. Otherwise, all of the bots will process it, which is usually undesired. For example:

pawn Code:
new botID = IRC_Connect(/* ... */);

IRCCMD:command(botid, channel[], user[], host[], params[])
{
    if (botid == botID)
    {
        /* ... */
    }
}
This is done automatically for bots in groups (IRC_OnUserSay is called only once).

The command prefix ('!') can be changed by editing the COMMAND_PREFIX constant in irc.inc.

Better examples are in the filterscript.

Notes
  • Although the number of concurrent bot connections is unlimited, nearly all IRC servers do have session limits, and this can result in a network ban if the server is flooded with too many bots under the same address. The main reason for the presence of this feature (other than to prevent accidental message flooding) is to give users the flexibility to connect to multiple servers simultaneously instead of just one.
  • Bots are set to reconnect automatically by default. The default connect attempts is 5, the default connect delay is 20 seconds, and the default connect timeout is 10 seconds. The receive timeout is disabled by default, but it can by set manually.
  • Refer to RFC 1459 and RFC 2812 for more information on raw IRC messages.
Download

The latest compiled binaries will always be here:

GitHub Releases Page

The source can be browsed here. This repository can also be cloned.

The Windows version requires the Microsoft Visual C++ 2015 Redistributable Package.

The OpenSSL library is required for the SSL version of the plugin. If the server is running Windows, download the Win32 OpenSSL Light Installer from Shining Light Productions. If the server is running Linux, install the "openssl" package.
Reply
#2

Woaaaah.

Awesome. About time we got something like this!

Really good stuff man, keep it up!
Reply
#3

Last night I was wondering if there was a more stable script for this!

I'll try it out on my server, and the .3 server too
Reply
#4

Good thing you've really managed to create a proper IRC Plugin for us. Thanks.
Reply
#5

Keep up the good work.
Reply
#6

Great work!

I'm sure a lot of servers will find this extremely useful.
Reply
#7

Very good job! Could you write a plugin to work with sockets?
Reply
#8

Excellent! Using at my server
Reply
#9

Greaaat!!!!
Really Great thanks 100000x
Thanks!!!

EDIT:
if i want to compile this i get a error:
Code:
1>------ Build started: Project: irc, Configuration: Release Win32 ------
1>Compiling...
1>main.cpp
1>h:\irc plugin\source\main.h(37) : fatal error C1083: Cannot open include file: 'boost/algorithm/string.hpp': No such file or directory
1>irc.cpp
1>h:\irc plugin\source\main.h(37) : fatal error C1083: Cannot open include file: 'boost/algorithm/string.hpp': No such file or directory
1>amxplugin.cpp
1>Build log was saved at "file://h:\IRC Plugin\source\Release\BuildLog.htm"
1>irc - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Reply
#10

That's pretty obvious, you'll need the boost library.
Reply
#11

Sounds great!
Will test it these days,if everything works fine I'm going to use this irc plugin for gAdmin.

Suggestion:
IRC_JoinChannel(botid, const channel[], password[] );
Reply
#12

Quote:
Originally Posted by /^We(stie|z+[e|a
r)$/ ]
That's pretty obvious, you'll need the boost library.
yeah how to include it lol?
wich folder/direction?
Reply
#13

I love you! No HOMO!
Reply
#14

Awesome.
Reply
#15

Nice, but the grouping and stuff doesn't seem to work too nice. It might just be me but I've been testing and what I get is:


Quote:

[20:38:08] <TESTIE_03> - Server Information -
[20:38:08] <TESTIE_03> Players: 0/16
[20:38:08] <TESTER_03> IP Address: 95.211.6.150:7777

While I call this code:
pawn Code:
IRC_GroupSay(ircGroup, channel, "7- Server Information -");

format(str, sizeof(str), "4IP Address:17 %s:%s", SERVER_IP, SERVER_PORT);
IRC_GroupSay(ircGroup, channel, str);

format(str, sizeof(str), "4Players:17 %d/%d", GetOnlinePlayers(), maxPlayers);
IRC_GroupSay(ircGroup, channel, str);
And my IRC connections are this:
pawn Code:
ircBot[0] = IRC_Connect(IRC_SERVER, IRC_PORT, ircName[0], IRC_REALNAME, IRC_HOSTNAME);
ircBot[1] = IRC_Connect(IRC_SERVER, IRC_PORT, ircName[1], IRC_REALNAME, IRC_HOSTNAME);
ircGroup = IRC_CreateGroup();
IRC_AddToGroup(ircGroup, ircBot[0]);
IRC_AddToGroup(ircGroup, ircBot[1]);
So... shouldn't it be:
Quote:

[20:38:08] <TESTIE_03> - Server Information -
[20:38:08] <TESTER_03> IP Address: 95.211.6.150:7777
[20:38:08] <TESTIE_03> Players: 0/16

I had the same issues with Jacob's IRC plugin and my only solution was to make one bot send the commands.
Am I doing something wrong or what's going on? I would appreciate help!

By the way, it is great to see a new IRC plugin. Thanks a lot Incognito, you're great.
I love the RAW message parsing you've added as OnReceiveRaw... also all the groups and efficiency.

Please help!
Reply
#16

Great work
Reply
#17

Thanks!

InstabiC: Make sure that you are not adding bots to the group twice. It is best to add them in IRC_OnConnect and remove them in IRC_OnDisconnect to ensure that this does not happen.

Gijs: Try commenting out IRC_OnReceiveRaw. The connect message is probably too big to write to a file. I will fix this in my example filterscript now.
Reply
#18

Quote:
Originally Posted by Incognito
InstabiC: Make sure that you are not adding bots to the group twice. It is best to add them in IRC_OnConnect and remove them in IRC_OnDisconnect to ensure that this does not happen.
Thank you for the reply.

I now assign the bots into groups under IRC_OnConnect. It seems a little better but when I type the command like 5 times in a row, pretty fast (a second interval?) it still messes up it atleast once. But this is certainly better than it was with Jacob's plugin so thanks a bunch!
Reply
#19

Very nice, I will have to test this out later!
Reply
#20

Good work! Thank you so much for this.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)