libIrcClient

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

libIrcClient

Postby voodooattack » May 03, 2006 11:10

libircclient is a small but powerful library, which implements client-server IRC protocol. It is designed to be small, fast, portable and compatible to RFC standards, and most IRC clients. libircclient features include:

* Full multi-threading support.
* Single threads handles all the IRC processing.
* Support for single-threaded applications, and socket-based applications, which use select()
* Synchronous and asynchronous interfaces.
* CTCP support with optional build-in reply code.
* Flexible DCC support, including both DCC chat, and DCC file transfer.
* Can both initiate and react to initiated DCC.
* Can accept or decline DCC sessions asynchronously.
* Plain C interface and implementation (possible to use from C++ code, obviously)
* Compatible with RFC 1459 and most IRC clients.
* Free, licensed under LGPL license.
* Good documentation and examples available.


Website: http://libircclient.sourceforge.net/

FB package: http://voodooattack.sitesled.com/FB/lircc.zip

[extract to FB folder, the dll is included along with the static lib]

I didn't bother finishing the example since i got caugh in other projects.. the only thing missing in the example is DCC functionality..

the example is almost a typical translation of the C example supplied with the library, so it shouldn't be hard to understand the C example..

also note, once you call irc_run(session), you're not controlling the application execution any more, the function will not return until the session terminates, a good strategy would be creating threads to deal with multiple sessions(if you plan to create more than one session)..

I'll be writing a Win32 Service, demonstrating an IRC bot with a scripting interface, based on the 'FBServ Framework' i posted earlier:
http://www.freebasic.net/forum/viewtopic.php?t=3708 (i'll update it soon enough)

that'll be a good example of using both components, along the chaos of the multi-threading salad that'll follow.. :P

good luck, and i hope you find it useful.. :-)
jofers
Posts: 1525
Joined: May 27, 2005 17:18
Contact:

Postby jofers » May 03, 2006 13:43

Cool :) Great contribution!
v1ctor
Site Admin
Posts: 3799
Joined: May 27, 2005 8:08
Location: SP / Bra[s]il
Contact:

Postby v1ctor » May 03, 2006 19:27

Nice, it didn't know an OSS lib like that existed - btw, there's a small mistake in lircc.bi, #include once "lircc\libircclient.bi" must come before the other headers because it defines irc_session_t.

I played with it a bit and added user input: http://rafb.net/paste/results/zO4TKG14.html, basic (no pun) stuff, pretty much untested.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » May 04, 2006 10:44

works very well v1c... :-)

I've fixed the includes.. should work fine now.
peck
Posts: 24
Joined: Aug 04, 2005 1:12
Location: Sweden

Postby peck » May 18, 2006 1:27

If I'm not mistaking (at least this worked on my machine).
In libircclient.bi:

#ifndef LIRCC_STATIC
#IncLib "libircclient"
#else
#inclib "libircclient-static"
#endif

should be:

#ifndef LIRCC_STATIC
#IncLib "ircclient"
#else
#inclib "ircclient-static"
#endif

Anyone except me who doesn't manage to compile with the "static" lib?

Anyone that could bother to fix the DCC-stuff? Would be really useful.

Thanks anyways voodoo. Will be using this one frequently I suspect.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » May 26, 2006 0:08

peck wrote:Anyone except me who doesn't manage to compile with the "static" lib?

Anyone that could bother to fix the DCC-stuff? Would be really useful.

Thanks anyways voodoo. Will be using this one frequently I suspect.


you're welcome.. and sorry about that lil mistake.. :)
works OK here, but maybe the recent .16 modifications changed something :D

I'll get to the DCC stuff soon, when i start working on that bot again :#)

[edit]
OMG... i just noticed this post!!!!!!!!!! :-O

Code: Select all

peck            PostPosted: May 18, 2006 3:27
voodooattack    PostPosted: May 26, 2006 2:08


rofl

sorry for the waay late reply mate...
i have this problem using firefox, when it terminates unexpectedly, i lose all the "new post" highlights, something with the forum cookie i guess.. :)

[/edit]
peck
Posts: 24
Joined: Aug 04, 2005 1:12
Location: Sweden

Postby peck » Jul 21, 2006 15:02

i'm still eagerly waiting for the dcc-issue to be resolved (since my own attempts only resulted in the exampleprogram repeatedly crashing) as well as someone to tell me how the hell i compile the static library-version so that it won't crash when i try to use it, due to me prolly being too stupid to realize how to do it.

voodooattack: hope you haven't forgot about this one mate, since fbirclib is prolly never going to be finished, everyone has to rely on you ;)
Tox
Posts: 6
Joined: Jul 26, 2006 6:57
Location: Queensland, Australia. The marshes.
Contact:

Postby Tox » Jul 27, 2006 9:07

Okay, I'm new and particularly stupid when it comes to FB, but I keep getting the error "c:\.....\ld.exe: cannot find -llibircclient" when I try to compile. I've extracted this into my FB directory and everything seems to be in order, so uh... someone tell me what I'm doing wrong? o_o

For reference, I've been poking about with a grand project in the form of several little experiments, one of which is an online world framework based on IRC protocol. A library like this would help. Erm, a lot. :P
peck
Posts: 24
Joined: Aug 04, 2005 1:12
Location: Sweden

Postby peck » Jul 27, 2006 22:30

Extract everything into one directory (don't miss the dll :P ), and move the lircc.bi file into the include file under your freebasic directory.
Worked like a charm for me. As long as I didn't try to use the static library.

Tox wrote:Okay, I'm new and particularly stupid when it comes to FB, but I keep getting the error "c:\.....\ld.exe: cannot find -llibircclient" when I try to compile. I've extracted this into my FB directory and everything seems to be in order, so uh... someone tell me what I'm doing wrong? o_o

For reference, I've been poking about with a grand project in the form of several little experiments, one of which is an online world framework based on IRC protocol. A library like this would help. Erm, a lot. :P
Tox
Posts: 6
Joined: Jul 26, 2006 6:57
Location: Queensland, Australia. The marshes.
Contact:

Postby Tox » Jul 28, 2006 5:05

...have my babies. :D
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » Jul 28, 2006 19:09

ah, sorry again it took me a while ^_^

i was actually rewriting FBServ (the win32 service platform) to be .16 compatible, in part of a bigger plan to make an irc bot that works as a win32 service :D

then i got involved in other projects, and totally forgot.. :(

as long as people are still interested.. expect a new fully-fledged example in a few hours :)
Tox
Posts: 6
Joined: Jul 26, 2006 6:57
Location: Queensland, Australia. The marshes.
Contact:

Postby Tox » Jul 29, 2006 3:54

I love you too. *sends out a basket of muffins with heart-shaped sprinkles*

Wait, muffins with sprinkles? <.<
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » Jul 31, 2006 22:53

alright, here goes:

Code: Select all

   
    Option Explicit
   
    '#define LIRCC_STATIC

    #include "lircc.bi"
    #include "crt.bi"
   
    #macro identify(session, password)
        scope
            dim cmd as string =  "identify " & password
            irc_cmd_msg (session, "nickserv", strptr(cmd))
        end scope
    #endmacro
   
   
    type irc_ctx_t
        channel as zstring ptr
        nick    as zstring ptr
    end type
   
    sub logevent(text as string)
       
        print #1, text
       
    end sub
   
   
    Sub dump_event cdecl(byval session as irc_session_t ptr, byval event as zstring ptr, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        if origin then
            logevent "Event: '" & *event & "', Origin '" & *origin & "'"
        else
            logevent "Event: '" & *event & "'"
        end if
       
        if count then
            dim i
            for i = 0 to count -1
                logevent "param" & i & ": " & *cast(zstring ptr,params[i])
            next
        end if
    End Sub


    sub dcc_recv_callback (byval session as irc_session_t ptr, byval id as irc_dcc_t, byval status as integer, byval ctx as any ptr, byval bdata as ubyte ptr, byval length as uinteger)

        static count    as integer = 1
        dim buf         as zstring * 30
       
        select case as const (status)
       
            case LIBIRC_ERR_CLOSED
                print using "DCC ##: chat closed"; id
           
            case 0
                if bdata <> 0 then
                   
                    print using "DCC ##: chat connected"; id
                    irc_dcc_msg   (session, id, "Hehe")
               
                else
               
                    print using "DCC ##: &"; id; *cast(zstring ptr, bdata)
                    count += 1
                    sprintf (buf, "DCC [%i]: %i", id, count)
                    irc_dcc_msg   (session, id, buf)
                   
                end if
            case else:
                print using  "DCC ##: error &"; id; *irc_strerror(status)
            end select

    end sub
   
    sub dcc_file_recv_callback (byval session as irc_session_t ptr, byval id as irc_dcc_t, byval status as integer , byval ctx as integer, byval bdata as ubyte ptr, byval length as uinteger)
       
        if  status = 0 and length = 0 then
           
            print "File sent successfully."

            if ctx then
                close #ctx
           end if
           
        elseif status then
   
            print using "File sent error: ####"; status
       
            if ctx then
                close #ctx
           end if
        else
   
            if ctx then
                dim i
                for i = 0 to length - 1
                    put #ctx, , bdata[i]
                    print using "File sent progress: ####"; length
                next
            end if
           
        end if
       
    end sub
   
    Sub event_connect cdecl(byval session as irc_session_t ptr, byval event as zstring ptr, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        Dim ctx as irc_ctx_t ptr = irc_get_ctx(session)
       
        dump_event (session, event, origin, params, count)
       
        print " Connected."
       
        dim schan as string = *ctx->channel
       
        identify (session, "password") 'most networks will not allow pms for
        'unregistered users..
       
        print using "Joining Channel: &"; schan
       
        irc_cmd_join (session, ctx->channel, 0)
       
       
    End Sub
   
    Sub event_join cdecl(byval session as irc_session_t ptr, byval event as zstring ptr, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        dim schan as string = *params[0]
       
        print using "Now talking in channel: &"; schan
       
        dump_event (session, event, origin, params, count)
       
        irc_cmd_user_mode (session, "+i")
        'irc_cmd_msg (session, params[0], "Hi all")
       
       
       
    End Sub
   
   
    Sub event_dcc_send cdecl(byval session as irc_session_t ptr, byval nick as zstring ptr, byval addr as zstring ptr, byval filename as zstring ptr, byval size as uinteger, byval dccid as irc_dcc_t)
        'you can display sending progress, etc here...
    End Sub
   
    Sub event_channel cdecl(byval session as irc_session_t ptr, byval event as zstring ptr, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        Dim nickbuf as zstring * 128
       
        if count <> 2 then exit sub
       
        dim sname as string
        dim schan as string
        dim smsg  as string
        dim dccid as irc_dcc_t
       
        if origin then
            sname = *origin
        else
            sname = "someone"
        end if
       
        schan = *params[0]       
       
        if params[1] then smsg = *params[1]
       
        print using "'&' said in channel &: &"; sname, schan, smsg
       
        if origin = 0 then exit sub
       
        irc_target_get_nick(origin, @nickbuf, sizeof(nickbuf))
       
        select case TRIM(lCASE(smsg))
            case "!quit"
                if *origin = "voodooattack" then
                    irc_cmd_quit (session, "of course, Master!")
                else
                    dim txt as string = "no " & sname & ", you loser!"
                    irc_cmd_msg (session, params[0], strptr(txt) )
                end if
            case "!help"
                irc_cmd_msg (session, params[0], "!quit, !help, !dccc (dcc chat), !dccs (dcc send), !ctcp")
            case "!ctcp"
                irc_cmd_ctcp_request (session, nickbuf, "PING 223")
                irc_cmd_ctcp_request (session, nickbuf, "FINGER")
                irc_cmd_ctcp_request (session, nickbuf, "VERSION")
                irc_cmd_ctcp_request (session, nickbuf, "TIME")
            case "!list"
                Dim lf as string
                dim msg as string
               
                print "!list query from '" & sname & "'"
                msg = chr(2) & "Listing shared files:" & chr(2)
                irc_cmd_msg (session, origin, strptr(msg))
               
                lf = Dir("*.*")
               
                if lf <> "" then
                    do while lf <> ""
                        irc_cmd_msg (session, origin, strptr(lf))
                        lf = Dir()
                    loop
                else
                    irc_cmd_msg (session, origin, "No files found.")
                end if
               
                msg = chr(2) & "End of file listing." & chr(2)
               
                irc_cmd_msg (session, origin, strptr(msg))
               
            case "!dccc"
                irc_dcc_chat (session, 0, nickbuf, cast(irc_dcc_callback_t, @dcc_recv_callback), @dccid)
                Print using "DCC chat ID: #"; dccid
            case "!dccs"
                irc_dcc_sendfile (session, 0, nickbuf, "dcctest.txt", cast(irc_dcc_callback_t, @event_dcc_send), @dccid)
                Print using "DCC send ID: #"; dccid
            case "!topic"
                irc_cmd_topic (session, params[0], 0)
            case else
                if left(lCASE(smsg),7) = "!topic " then
                    dim s as string = mid(smsg,8)
                    irc_cmd_topic (session, params[0], params[1] + 8)
                elseif left(lCASE(smsg),6) = "!mode " then
                    dim s as string = mid(smsg,7)
                    irc_cmd_channel_mode (session, params[0], strptr(s))
                elseif left(lCASE(smsg),6) = "!nick " then
                    dim s as string = mid(smsg,7)
                    irc_cmd_nick (session, strptr(s))
                elseif left(lCASE(smsg),7) = "!whois " then
                    dim s as string = mid(smsg,8)
                    irc_cmd_whois (session, strptr(s))
                elseif left(lCASE(smsg),6) = "!stab " then
                    dim s as string = "stabs " & mid(smsg,7)
                    irc_cmd_me (session, params[0], strptr(s))
                elseif left(lCASE(smsg),6) = "!send " then
                    dim s as string = trim(mid(smsg,7))
                    if dir(exepath & "\" & s) = "" then
                        dim msg as string = "File not found: " & s
                        irc_cmd_msg (session, origin, strptr(msg))
                    else
                        print "(" & sname & ") sending file: " & s
                        irc_dcc_sendfile (session, 0, origin, strptr(s), cast(irc_dcc_callback_t, @event_dcc_send), @dccid)
                    end if
                elseif left(lCASE(smsg),6) = "!join " then
                    dim s as string = trim(mid(smsg,7))
                    print "Joining channel: " & s
                    irc_cmd_join (session, strptr(s), 0)
                elseif left(lCASE(smsg),5) = "!part" then
                    dim s as string = trim(mid(smsg,7))
                    if s = "" then s = schan
                    print "Leaving channel: " & s
                    irc_cmd_part (session, strptr(s))
                end if
        end select
    End Sub
   
    Sub event_privmsg cdecl(byval session as irc_session_t ptr, byval event as zstring ptr, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        dump_event (session, event, origin, params, count)
       
        dim sname as string
        dim snick as string
        dim smsg  as string
        dim dccid as irc_dcc_t
       
        if origin then
            sname = *origin
        else
            sname = "someone"
        end if
       
        snick = *params[0]
       
        if params[1] then smsg = *params[1]
       
        print using "'&' said to me (&): &"; sname ; snick; smsg
       
        if left(lCASE(smsg),6) = "!send " then
            dim s as string = trim(mid(smsg,7))
            if dir(exepath & "\" & s) = "" then
                dim msg as string = "File not found: " & s
                irc_cmd_msg (session, origin, strptr(msg))
            else
                print "(" & sname & ") sending file: " & s
                irc_dcc_sendfile (session, 0, origin, strptr(s), cast(irc_dcc_callback_t, @event_dcc_send), @dccid)
            end if
        end if

       
    End Sub
   
   
    Sub event_numeric cdecl(byval session as irc_session_t ptr, byval event as uinteger, byval origin as zstring ptr, byval params as byte ptr ptr, byval count as uinteger)
       
        dim buf as string
       
        buf = str(event)
       
        dump_event (session, buf, origin, params, count)
       
    End Sub
   
    Sub event_dcc_chat cdecl(byval session as irc_session_t ptr, byval nick as zstring ptr, byval addr as zstring ptr, byval dccid as irc_dcc_t)
       
        print using "DCC chat [##] requested from '&' (&)"; dccid; *nick; *addr
       
        irc_dcc_accept (session, dccid, 0, cast(irc_dcc_callback_t, @dcc_recv_callback))
       
    End Sub
   

   
 
   
    extern Argc alias "fb_argc" as uinteger
    extern Argv alias "fb_argv" as zstring ptr ptr
   
    Function InitIRC() As Integer
       
        Dim callbacks   as irc_callbacks_t
        Dim ctx         as irc_ctx_t
        Dim s           as irc_session_t ptr
       
        if Argc <> 4 then
            Print Using "Usage: & <server> <nick> <channel>"; COMMAND$(0)
            Return 1
        end if
       
        memset (byval @callbacks, 0, sizeof(irc_callbacks_t))
       
        with callbacks
           
            .event_connect = @event_connect
            .event_join = @event_join
            .event_channel = @event_channel
            .event_privmsg = @event_privmsg
            .event_numeric = @event_numeric
            .event_dcc_chat_req = @event_dcc_chat
            .event_dcc_send_req = @event_dcc_send
           
            .event_nick = @dump_event
            .event_quit = @dump_event
            .event_part = @dump_event
            .event_mode = @dump_event
            .event_topic = @dump_event
            .event_kick = @dump_event
            .event_notice = @dump_event
            .event_invite = @dump_event
            .event_umode = @dump_event
            .event_ctcp_rep = @dump_event
            .event_ctcp_action = @dump_event
            .event_unknown = @dump_event
           
        end with
        cls
        s = irc_create_session (@callbacks)
       
        if s = 0 then
            Print "Could not create session."
            Return 1
        end if
       
        ctx.channel = argv[3]
        ctx.nick = argv[2]
       
        open "irclog.txt" for output as #1
       
        irc_option_set (s, LIBIRC_OPTION_STRIPNICKS)    'strip nicknames..
       
        print using "Connecting to '&' as '&':"; *argv[1]; *argv[2];
       
        irc_set_ctx(s, @ctx)
       
        if irc_connect(s, argv[1], 6667, 0, argv[2], 0, 0) then
            Print " error!"
            print using "Could not connect: &"; *irc_strerror(irc_errno(s))
            return 1
        end if
       
        irc_run (s)
       
        close #1
       
        return 0
       
    End Function
   
    End InitIRC


a kinda dirty example, but it does the trick.. :)

also, take a look here:
http://libircclient.sourceforge.net/modules.html

the full docs.. can be really useful if you feel lost in this callback salad :)

EDIT:

removed my own nickserv password.. ahm... :P
Mike Chambers
Posts: 85
Joined: Jun 18, 2006 19:48

Postby Mike Chambers » Aug 09, 2006 18:54

dangit... i was going to program an IRC client from scratch. now i would feel like i'm wasting my time since you already wrote a client library lol.

nice job, though!
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Postby voodooattack » Aug 09, 2006 18:56

Mike Chambers wrote:dangit... i was going to program an IRC client from scratch. now i would feel like i'm wasting my time since you already wrote a client library lol.

nice job, though!


well, thanks, but i didn't write the library my self, i just translated the headers over to FB ;)

good luck with your client :)

Return to “Libraries”

Who is online

Users browsing this forum: No registered users and 1 guest