What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

[Plugin - Monitoring] QuickIRC - An IRC Monitoring and Control by Apoc & wired420

Apoc

Well-Known Member
Joined
Jan 16, 2010
Messages
2,790
Reaction score
94
This is still in early development! If you come here to bitch, go somewhere else!

QuickIRC was written to give wired420 and myself some decent IRC-based control over Honorbuddy.

It is written using Smartirc4net as the base IRC implementation; so it is a stable plugin as far as IRC connections go.

What it does

It is an all-around monitoring, and controller for Honorbuddy, all via IRC.

There are currently 23 commands, some of which with multiple 'switches' available, bringing the total up to over 30 in the current version. Commands are *very* easy to add, so new ones will most likely be coming as this plugin matures.

It will 'say' any useful chat messages received from WoW, in IRC. (Where it says it is configurable, see the settings section below)

It currently supports certain 'events' to be said in IRC as well. (Leveling, deaths, etc)

What are the commands it supports?

The following is a short-list of commands, which may not always be up to date! Please download the latest version if you want to see the newest list of commands.

Code:
---- Command list - All commands are prefixed with the '!' character unless otherwise stated ----
list - Lists the available commands
w - Sends a whisper to a player. Syntax: !w name message
s - Sends a say message in game. Syntax: !s message
p - Sends a party message in game. Syntax: !p message
r - Sends a raid message in game. Syntax: !r message
bg - Sends a battleground message in game. Syntax: !bg message
g - Sends a guild message in game. Syntax: !g message
start - Starts the currently selected bot.
stop - Stops the currently selected bot.
die - Kills the bot, and optionally the WoW it is associated with. Specify -a to kill WoW as well.
restart - Restarts the entire Honorbuddy process. Don't use this if you are not using a relogger, or cannot manually hit the login button!
listplugins - Lists the current plugins loaded, and whether they are enabled.
listprofiles - Lists the profiles found in the specified directory. Syntax: !listprofiles C:\Path\To\Profiles
listbots - Lists the current bots loaded.
changebot - Changes the currently loaded bot. [Note: this can cause issues, as it does zero state checking!]
switchprofile - Changes the current profile. [Requires a bot 'restart'] Syntax: !switchprofile C:\Path\To\Profile.xml
toggleplugin - Toggles a plugin on and off. Syntax: !toggleplugin name of plugin
level - Displays the current character's level
xphr - Displays the current character's XP/hr
loots - Displays the current character's total loot count. Add '-h' to get the per-hour value.
kills - Displays the current character's total kill count. Add '-h' to get the per-hour value.
deaths - Displays the current character's total death count. Add '-h' to get the per-hour value.
bgstats - Displays current character's wins and losses in battlegrounds.
cash - Displays the current characters cash.
screenshot - Takes a screenshot and prints the ImageShack link.
mapname - No description
version - No description
runtime - Displays the bots current running time.
status - Displays the current status. Available switches: -p (POI) -g (GOAL) -a (ACTIVITY). Syntax example: !status -pga

The '!' prefix is configurable.

How do I add a command?

You'll need to know at least a little C#, and have some knowledge of writing plugins/CCs for Honorbuddy.

The following is an example of the 'level' command:

Code:
    class LevelCommand : IrcCommand
    {
        public override string Trigger { get { return "level"; } }

        public override string Description
        {
            get { return "Displays the current character's level"; }
        }

        public override void HandleCommand(string fullText, params string[] args)
        {
            Send("Current level is: " + StyxWoW.Me.Level);
        }
    }

As you can see, it is very simple to add new commands.

We highly recommend that you use the 'Send(message)' function when outputting text to IRC. This will automatically select the user's defined message type.

After you create your command, we suggest you either a) put it in one of the already supplied files in the /Commands folder, or create a new file (with proper C# namespaces and whatnot) in the /Commands folder. They will automatically be loaded at runtime.

Configuration

QuickIRC lets you configure quite a few things, some of which you MUST change for it to function properly.

QuickIRCSettings.png

SendType - Allows you to change where messages are sent. By default, this is 'Channel'. Other supported modes are PrivateMessage, and Notice. Unless you know what you are doing, we suggest you do not use the 'Notice' option. (Advanced IRC users may find it useful)
CommandPrefix - Allows you to change the prefix the bot looks for, when reading commands. Very useful if you have multiple bots running in the same channel, and don't want to private message a specific one to issue a command.
Channel - The channel the bot will join upon connection.
ChannelPassword - If your channel is password-protected, enter the password here.
LoginAtStart - QuickIRC can automatically login to IRC when Honorbuddy is loaded. By default, this behavior is turned off, and you must manually hit 'Start' in the settings window to login to IRC.
OwnerNick - This is the nickname of the person that the bot will respond to. Commands given by anyone other than this nickname, will be ignored. (Set this to your IRC nick)
Port - If you need to connect on a non-standard port, change this to the port you wish to use. (If you don't know what this means, just leave the setting as it is.)
Server - The IRC network that the bot will connect to. By default, it is the unofficial HB IRC. Set this to the IRC network you want to use. (e.g. Undernet, EFNet, QuakeNet, etc)
Username - The name of the bot when connected to IRC.

Changes

v1.0.0.0 - Initial release. Hooray!

Credits

All the people in #honorbuddy that kept giving us commands to add

Download

You'll need SVN to download, please see Google for how to do this. (I can't help explain, sorry)

SVN URL:

http://svn.apocdev.com/quickirc/trunk/QuickIRC2/


If you want to request new commands, or functionality, please, feel free to do so!
 
Last edited:
I'm loving the look of this! Great work guys can't wait to try it out.
 
Why does this come out the day after i brick my iphone...

QQ

But I'm very excited to see this

thank you guys for all your hard work, I'm constantly impressed by what this community comes up with.
 
If you have an android phone I suggest the YAAIC (Yet another android irc client). Works perfect with this and is free. Doesn't kill battery life as some android apps do. If you got an iphone your on your own with finding one that allows passworded channels as I'll never even consider owning one :P

Also if you need a secure server to place you bot on we have the unofficial honorbuddy channel at irc.rootswitch.net. You are more than welcome to make your own channel there. Ip's are fully encrypted to all four decimals and not stored. Any bots found in the main channels will be kicked so make sure to make your own channel. If you wish to password your channel heres the way to do so.

/quote cs register <channelname> <password> <description> - I put random crap in description

then you can

/quote cs set <channelname> mlock +ntsk <password>

+s makes your channel not show up for the public.
+k is for a key or password.

The second command will make it so even if your not there people can't be in your channel.

If you need any further help you can find me on IRC most hours of the day.
 
Last edited:
oh I had a good irc app, just need to get the damn thing to restore...
 
As per requested; here is a !screenshot command. It will take an SS, and upload it to imageshack, then post the link in IRC.

Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;

using Microsoft.Win32;

using Styx.Helpers;
using Styx.Plugins;
using Styx.WoWInternals;

namespace ApocDev.Plugins.QuickIrc.Commands
{
    class ScreenshotCommand : IrcCommand
    {
        public override string Trigger { get { return "screenshot"; } }

        public override string Description { get { return "Takes a screenshot and prints the ImageShack link."; } }

        public override void HandleCommand(string fullText, params string[] args)
        {
            try
            {
                PluginManager.Plugins.Find(p => p.Plugin.PluginName == QuickIrc.Instance.Name).Enabled = true;
                var mte = new MainThreadExecution();
                mte.Invoker = TakeScreenshot;
                mte.Args = new object[0];
                QuickIrc.MainThreadExecutions.Enqueue(mte);
            }
            catch (Exception e)
            {
                Logging.WriteException(e);
                Send("Exception: " + e.Message);
            }
        }

        private object TakeScreenshot(params object[] args)
        {
            try
            {
                Lua.DoString("TakeScreenshot()");
                ThreadPool.QueueUserWorkItem(UploadWorkerThread);
            }
            catch (Exception e)
            {
                Logging.WriteException(e);
                Send("Exception1: " + e.Message);
            }
            return true;
        }

        private void UploadWorkerThread(object state)
        {
            try
            {
                // Wait 1s to let the file system update
                Thread.Sleep(1000);
                string directory = Path.GetDirectoryName(ObjectManager.WoWProcess.MainModule.FileName) + "\\Screenshots";
                var di = new DirectoryInfo(directory);
                FileInfo file = di.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
                Send("Uploading " + file.Name);
                string link = Upload(file.FullName);
                Send("Link: " + link);
            }
            catch (Exception e)
            {
                Logging.WriteException(e);
                Send("Exception2: " + e.Message);
            }
        }

        #region Uploader code

        private static string Upload(string filename)
        {
            byte[] fileData = File.ReadAllBytes(filename);
            var postParams = new Dictionary<string, object>();
            postParams["fileupload"] = fileData;
            postParams["key"] = "ZMWC3P1Hbc72a424f2538cbe8cb128a597989790";

            HttpWebResponse resp = MultipartFormDataPost("http://www.imageshack.us/upload_api.php", "QIRC", filename, postParams);
            string respString = new StreamReader(resp.GetResponseStream()).ReadToEnd();

            using (var reader = new XmlTextReader(new MemoryStream(Encoding.UTF8.GetBytes(respString))))
            {
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == "image_link")
                        {
                            return reader.ReadString();
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Post the data as a multipart form
        /// postParameters with a value of type byte[] will be passed in the form as a file, and value of type string will be
        /// passed as a name/value pair.
        /// </summary>
        private static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, string fileName, Dictionary<string, object> postParameters)
        {
            const string formDataBoundary = "-----------------------------28947758029299";
            const string contentType = "multipart/form-data; boundary=" + formDataBoundary;

            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary, fileName);

            return PostForm(postUrl, userAgent, contentType, formData);
        }

        /// <summary>
        /// Post a form
        /// </summary>
        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
        {
            var request = WebRequest.Create(postUrl) as HttpWebRequest;

            if (request == null)
            {
                throw new NullReferenceException("request is not a http request");
            }

            // Add these, as we're doing a POST
            request.Method = "POST";
            request.ContentType = contentType;
            request.UserAgent = userAgent;
            request.CookieContainer = new CookieContainer();

            // We need to count how many bytes we're sending. 
            request.ContentLength = formData.Length;

            using (Stream requestStream = request.GetRequestStream())
            {
                // Push it out there
                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            return request.GetResponse() as HttpWebResponse;
        }

        /// <summary>
        /// Turn the key and value pairs into a multipart form.
        /// See http://www.ietf.org/rfc/rfc2388.txt for issues about file uploads
        /// </summary>
        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary, string fileName)
        {
            Stream formDataStream = new MemoryStream();

            foreach (var param in postParameters)
            {
                if (param.Value is byte[])
                {
                    var fileData = param.Value as byte[];

                    // Add just the first part of this param, since we will write the file data directly to the Stream
                    string header = string.Format(
                        "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: " + MimeType(fileName) + "\r\n\r\n", boundary, param.Key, param.Key);
                    formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, header.Length);

                    // Write the file data directly to the Stream, rather than serializing it to a string.  This 
                    formDataStream.Write(fileData, 0, fileData.Length);
                }
                else
                {
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", boundary, param.Key, param.Value);
                    formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, postData.Length);
                }
            }

            // Add the end of the request
            string footer = "\r\n--" + boundary + "--\r\n";
            formDataStream.Write(Encoding.UTF8.GetBytes(footer), 0, footer.Length);

            // Dump the Stream into a byte[]
            formDataStream.Position = 0;
            var formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }

        private static string MimeType(string filename)
        {
            string mime = "application/octetstream";
            string ext = Path.GetExtension(filename).ToLower();
            RegistryKey rk = Registry.ClassesRoot.OpenSubKey(ext);
            if (rk != null && rk.GetValue("Content Type") != null)
                mime = rk.GetValue("Content Type").ToString();
            return mime;
        }

        #endregion
    }
}
 
Could someone recommend a good place to create my own channel for an IRC nub, or is just any network fine?
 
Could someone recommend a good place to create my own channel for an IRC nub, or is just any network fine?

The default server setup in the settings is fine. wired420 offers the server out of the kindness of his heart :) (And me making him create it!)
 
i'm not really the pro with C+ thing are people willing to share there proper results? or is this too much to ask^^?
 
haha doesn't make any sence, never mind ill figure;)
 
Alright I am connected but a little confused, I am using an IRC client on my itouch and I am connected to irc.rootswitch.net, now I am confused on how to send the commands to my bot and get the status back.
 
Alright I am connected but a little confused, I am using an IRC client on my itouch and I am connected to irc.rootswitch.net, now I am confused on how to send the commands to my bot and get the status back.

If you left the settings as default, it won't work. We did it specifically so you would be forced to do at least a little bit of work on your end to set it up properly.

Once you set it up (set your owner name, the type of message to reply with, etc) you can use !list (or whatever prefix you had chosen) to get a list of commands. (You can private message the IRC bot, or just say it in the channel)
 
If you left the settings as default, it won't work. We did it specifically so you would be forced to do at least a little bit of work on your end to set it up properly.

Once you set it up (set your owner name, the type of message to reply with, etc) you can use !list (or whatever prefix you had chosen) to get a list of commands. (You can private message the IRC bot, or just say it in the channel)

I already set my own owner name, and it is set to send as a private message, in my IRC App I added a chatroom and for the connection it is: irc.rootswitch.net, the name is #honorbuddy-quickirc
and no pass, did I do that right?
 
Been testing it the last few hours, and I'm impressed. Thanks :D

I've noticed one small problem though. If I write !msg (character name with ? in it, haven't tested with other special characters) I get an error in WoW saying "No player named '(rest of the name)ü' is currently playing."
So it seems to have some troubles with special characters. Running the English EU client. Not sure about HB version though - should be latest stable.
 
Been testing it the last few hours, and I'm impressed. Thanks :D

I've noticed one small problem though. If I write !msg (character name with ? in it, haven't tested with other special characters) I get an error in WoW saying "No player named '(rest of the name)ü' is currently playing."
So it seems to have some troubles with special characters. Running the English EU client. Not sure about HB version though - should be latest stable.

This is actually a limitation on IRC itself. Not much we can do about it tbh.
 
If anyone wants to see it running sit in #wired420 for a while and you'll eventually see me use it or it talk.
 
Back
Top