Last active
December 28, 2015 15:29
-
-
Save TLMcode/7522378 to your computer and use it in GitHub Desktop.
maestrith's ahk for irc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; http://files.maestrith.com/irc/irc.ahk | |
| #SingleInstance,Force | |
| v:=[],settings:=new xml("settings") | |
| if !FileExist("scilexer.dll"){ | |
| SplashTextOn,200,50,Downloading required files,Please wait... | |
| urldownloadtofile,http://www.maestrith.com/files/AHKStudio/SciLexer.dll,SciLexer.dll | |
| SplashTextOff | |
| } | |
| CoordMode,ToolTip,Screen | |
| chan:=new xml("channels"),messages:=new xml("messages") | |
| global v,chan,settings,main,input,messages | |
| username:=settings.ssn("//username").text | |
| username:=username?username:"Guest" %a_now% | |
| v.username:=username | |
| gui() | |
| strsplit(data,delim,omit=""){ | |
| stringsplit,data,data,%delim%,%omit% | |
| list:=[] | |
| loop,% data0 | |
| list.insert(data%a_index%) | |
| return list | |
| } | |
| return | |
| GuiClose: | |
| ExitApp | |
| return | |
| ; Sockets library by Bentschi http://www.autohotkey.com/board/topic/94376-socket-class-%C3%BCberarbeitet/ | |
| class Socket{ | |
| static __eventMsg := 0x9987 | |
| __New(s=-1){ | |
| static init | |
| if (!init){ | |
| DllCall("LoadLibrary", "str", "ws2_32", "ptr") | |
| VarSetCapacity(wsadata, 394+A_PtrSize) | |
| DllCall("ws2_32\WSAStartup", "ushort", 0x0000, "ptr", &wsadata) | |
| DllCall("ws2_32\WSAStartup", "ushort", NumGet(wsadata, 2, "ushort"), "ptr", &wsadata) | |
| OnMessage(Socket.__eventMsg, "SocketEventProc") | |
| init := 1 | |
| } | |
| this.socket := s | |
| } | |
| __Delete(){ | |
| this.disconnect() | |
| } | |
| __Get(k, v){ | |
| if (k="size") | |
| return this.msgSize() | |
| } | |
| connect(host, port){ | |
| if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port)))) | |
| return 0 | |
| while (next) | |
| { | |
| sockaddrlen := NumGet(next+0, 16, "uint") | |
| sockaddr := NumGet(next+0, 16+(2*A_PtrSize), "ptr") | |
| if ((this.socket := DllCall("ws2_32\socket", "int", NumGet(next+0, 4, "int"), "int", this.__socketType, "int", this.__protocolId, "ptr"))!=-1) | |
| { | |
| if ((r := DllCall("ws2_32\WSAConnect", "ptr", this.socket, "ptr", sockaddr, "uint", sockaddrlen, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", 0, "int"))=0) | |
| { | |
| DllCall("ws2_32\freeaddrinfo", "ptr", faddr) | |
| return Socket.__eventProcRegister(this, 0x21) | |
| } | |
| this.disconnect() | |
| } | |
| next := NumGet(next+0, 16+(3*A_PtrSize), "ptr") | |
| } | |
| this.lastError := DllCall("ws2_32\WSAGetLastError") | |
| return 0 | |
| } | |
| bind(host, port){ | |
| if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port)))) | |
| return 0 | |
| while (next){ | |
| sockaddrlen := NumGet(next+0, 16, "uint") | |
| sockaddr := NumGet(next+0, 16+(2*A_PtrSize), "ptr") | |
| if ((this.socket := DllCall("ws2_32\socket", "int", NumGet(next+0, 4, "int"), "int", this.__socketType, "int", this.__protocolId, "ptr"))!=-1){ | |
| if (DllCall("ws2_32\bind", "ptr", this.socket, "ptr", sockaddr, "uint", sockaddrlen, "int")=0){ | |
| DllCall("ws2_32\freeaddrinfo", "ptr", faddr) | |
| return Socket.__eventProcRegister(this, 0x29) | |
| } | |
| this.disconnect() | |
| } | |
| next := NumGet(next+0, 16+(3*A_PtrSize), "ptr") | |
| } | |
| this.lastError := DllCall("ws2_32\WSAGetLastError") | |
| return 0 | |
| } | |
| listen(backlog=32){ | |
| return (DllCall("ws2_32\listen", "ptr", this.socket, "int", backlog)=0) ? 1 : 0 | |
| } | |
| accept(){ | |
| if ((s := DllCall("ws2_32\accept", "ptr", this.socket, "ptr", 0, "int", 0, "ptr"))!=-1){ | |
| newsock := new Socket(s) | |
| newsock.__protocolId := this.__protocolId | |
| newsock.__socketType := this.__socketType | |
| Socket.__eventProcRegister(newsock, 0x21) | |
| return newsock | |
| } | |
| return 0 | |
| } | |
| disconnect(){ | |
| Socket.__eventProcUnregister(this) | |
| DllCall("ws2_32\closesocket", "ptr", this.socket, "int") | |
| this.socket := -1 | |
| return 1 | |
| } | |
| msgSize(){ | |
| VarSetCapacity(argp, 4, 0) | |
| if (DllCall("ws2_32\ioctlsocket", "ptr", this.socket, "uint", 0x4004667F, "ptr", &argp)!=0) | |
| return 0 | |
| return NumGet(argp, 0, "int") | |
| } | |
| send(addr, length){ | |
| if ((r := DllCall("ws2_32\send", "ptr", this.socket, "ptr", addr, "int", length, "int", 0, "int"))<=0) | |
| return 0 | |
| return r | |
| } | |
| sendText(msg,encoding="UTF-8"){ | |
| msg.="`r`n" | |
| VarSetCapacity(buffer, length := (StrPut(msg, encoding)*(((encoding="utf-16")||(encoding="cp1200")) ? 2 : 1))) | |
| StrPut(msg, &buffer, encoding) | |
| return this.send(&buffer, length-1) | |
| } | |
| recv(byref buffer, wait=1){ | |
| while ((wait) && ((length := this.msgSize())=0)) | |
| sleep, 100 | |
| if (length){ | |
| VarSetCapacity(buffer, length) | |
| if ((r := DllCall("ws2_32\recv", "ptr", this.socket, "ptr", &buffer, "int", length, "int", 0))<=0) | |
| return 0 | |
| return r | |
| } | |
| return 0 | |
| } | |
| recvText(wait=1, encoding="UTF-8"){ | |
| if (length := this.recv(buffer, wait)) | |
| return StrGet(&buffer, length, encoding) | |
| return | |
| } | |
| __getAddrInfo(host, port){ | |
| a := ["127.0.0.1", "0.0.0.0", "255.255.255.255", "::1", "::", "FF00::"] | |
| conv := {localhost:a[1], addr_loopback:a[1], inaddr_loopback:a[1], addr_any:a[2], inaddr_any:a[2], addr_broadcast:a[3] | |
| , inaddr_broadcast:a[3], addr_none:a[3], inaddr_none:a[3], localhost6:a[4], addr_loopback6:a[4], inaddr_loopback6:a[4] | |
| , addr_any6:a[5], inaddr_any:a[5], addr_broadcast6:a[6], inaddr_broadcast6:a[6], addr_none6:a[6], inaddr_none6:a[6]} | |
| if (conv[host]) | |
| host := conv[host] | |
| VarSetCapacity(hints, 16+(4*A_PtrSize), 0) | |
| NumPut(this.__socketType, hints, 8, "int") | |
| NumPut(this.__protocolId, hints, 12, "int") | |
| if ((r := DllCall("ws2_32\getaddrinfo", "astr", host, "astr", port, "ptr", &hints, "ptr*", next))!=0){ | |
| this.lastError := DllCall("ws2_32\WSAGetLastError") | |
| return 0 | |
| } | |
| return next | |
| } | |
| __eventProcRegister(obj, msg){ | |
| a := SocketEventProc(0, 0, "register", 0) | |
| a[obj.socket] := obj | |
| return (DllCall("ws2_32\WSAAsyncSelect", "ptr", obj.socket, "ptr", A_ScriptHwnd, "uint", Socket.__eventMsg, "uint", msg)=0) ? 1 : 0 | |
| } | |
| __eventProcUnregister(obj){ | |
| a := SocketEventProc(0, 0, "register", 0) | |
| a.remove(obj.socket) | |
| return (DllCall("ws2_32\WSAAsyncSelect", "ptr", obj.socket, "ptr", A_ScriptHwnd, "uint", 0, "uint", 0)=0) ? 1 : 0 | |
| } | |
| } | |
| SocketEventProc(wParam, lParam, msg, hwnd){ | |
| global Socket | |
| static a := [] | |
| Critical | |
| if (msg="register") | |
| return a | |
| if (msg=Socket.__eventMsg){ | |
| if (!isobject(a[wParam])) | |
| return 0 | |
| if ((lParam & 0xFFFF) = 1) | |
| return a[wParam].onRecv(a[wParam]) | |
| else if ((lParam & 0xFFFF) = 8) | |
| return a[wParam].onAccept(a[wParam]),m("here") | |
| else if ((lParam & 0xFFFF) = 32){ | |
| a[wParam].socket := -1 | |
| return a[wParam].onDisconnect(a[wParam]) | |
| } | |
| return 0 | |
| } | |
| return 0 | |
| } | |
| class SocketTCP extends Socket | |
| { | |
| static __protocolId := 6 ;IPPROTO_TCP | |
| static __socketType := 1 ;SOCK_STREAM | |
| } | |
| class SocketUDP extends Socket{ | |
| static __protocolId := 17 ;IPPROTO_UDP | |
| static __socketType := 2 ;SOCK_DGRAM | |
| enableBroadcast(){ | |
| VarSetCapacity(optval, 4, 0) | |
| NumPut(1, optval, 0, "uint") | |
| if (DllCall("ws2_32\setsockopt", "ptr", this.socket, "int", 0xFFFF, "int", 0x0020, "ptr", &optval, "int", 4)=0) | |
| return 1 | |
| return 0 | |
| } | |
| disableBroadcast(){ | |
| VarSetCapacity(optval, 4, 0) | |
| if (DllCall("ws2_32\setsockopt", "ptr", this.socket, "int", 0xFFFF, "int", 0x0020, "ptr", &optval, "int", 4)=0) | |
| return 1 | |
| return 0 | |
| } | |
| } | |
| t(x*){ | |
| for a,b in x | |
| list.=b "`n" | |
| ToolTip,%list% | |
| } | |
| m(x*){ | |
| for a,b in x | |
| list.=b "`n" | |
| MsgBox,% list | |
| } | |
| hwnd(win,hwnd=0){ | |
| static windows:=[] | |
| if win&&hwnd | |
| return windows[win]:=hwnd | |
| if win.rem | |
| return windows[win.rem]:=0 | |
| if win.1 | |
| return "ahk_id" windows[win.1] | |
| return windows[win] | |
| } | |
| gui(){ | |
| static | |
| DllCall("LoadLibrary","str","scilexer.dll") | |
| Gui,+hwndhwnd | |
| hwnd(1,hwnd) | |
| Gui,Add,ListView,w150 r20 gg vchangechan AltSubmit -Multi,Channels | |
| OnMessage(0x06,"Focus"),OnMessage(0x4E,"notify") | |
| main:=new s(1,"w700 x+10 r25") | |
| v.main:=main | |
| set() | |
| main.2268(1) | |
| main.2403(0x15,10),v.msrvr:=[] | |
| main.2051(1,0xff00ff) | |
| main.2409(1,1) | |
| newdoc:=main.2375 | |
| v.chandoc[v.msrvr]:=newdoc | |
| main.2358(0,newdoc) | |
| main.2171(1),main.2240(1,4) | |
| main.2242(1,65) | |
| input:=new s(1,"w500 r1") | |
| input.2130(0) | |
| input.2115(1) | |
| input.2112(0,":") | |
| Gui,Add,TreeView,w150 h360 ym x880 AltSubmit gg vnicklist | |
| Gui,Add,Button,xm gconnect,Connect | |
| Gui,Add,Button,x+10 gg vdownload_update,Download Update | |
| Gui,Add,button,x+10 gsrvr,Server Messages | |
| Gui,Add,Text,xm,Username: | |
| Gui,Add,Edit,x+5 w200 gusername,% v.username | |
| Gui,Show,y0 | |
| ControlFocus,Scintilla2,% hwnd([1]) | |
| ;goto connect | |
| return | |
| username: | |
| ControlGetText,username,Edit1,% hwnd([1]) | |
| settings.add({path:"username",text:username}) | |
| ;v.username:=username | |
| settings.save(1) | |
| return | |
| srvr: | |
| main.2358(0,v.chandoc[v.msrvr]) | |
| main.2629 | |
| return | |
| connect: | |
| ControlGetText,username,Edit1,% hwnd([1]) | |
| v.username:=username | |
| sock:=new SocketTCP() | |
| sock.onRecv:=Func("onrecv") | |
| sock.connect("irc.freenode.net",6667) | |
| username:=v.username | |
| sock.Sendtext("NICK " username) | |
| sock.Sendtext("USER " username " 0 * :" username) | |
| WinSetTitle,%A_ScriptName%,,AHK IRC - %username% | |
| v.sock:=sock | |
| return | |
| } | |
| focus(){ | |
| ControlFocus,Scintilla2,% hwnd([1]) | |
| } | |
| onrecv(socket){ | |
| static store | |
| store.=socket.recvText() | |
| pos:=InStr(store,"`r`n",0,0) | |
| ;sort(SubStr(store,1,pos)) | |
| next(SubStr(store,1,pos)) | |
| store:=SubStr(store,pos) | |
| } | |
| d(info){ | |
| win:=info.w?info.w:1 | |
| type:=info.t?"TreeView":"ListView" | |
| control:=info.t?"SysTreeView32":"SysListView32" | |
| con:=info.t?info.t:info.l | |
| Gui,%win%:Default | |
| Gui,%win%:%type%,% control con | |
| } | |
| changechan(){ | |
| d({l:1}) | |
| LV_GetText(channel,LV_GetNext()) | |
| GuiControl,-Redraw,Scintilla1 | |
| if !(nick){ | |
| clear:=chan.sn("//@tv") | |
| while,cc:=clear.item(a_index-1) | |
| cc.text:="" | |
| TV_Delete() | |
| mm:=chan.search("//channel/@name",channel) | |
| for a,b in ["Operator","Voice","Normal"]{ | |
| root:=TV_Add(b),top:=ssn(mm,b) | |
| top.SetAttribute("tv",root) | |
| list:=sn(mm,b "/*") | |
| while,ll:=list.item(a_index-1){ | |
| user:=TV_Add(ssn(ll,"@user").text,root,"Sort") | |
| ll.SetAttribute("tv",user) | |
| userlist.=ssn(ll,"@user").text " " | |
| } | |
| TV_Modify(root,"Expand") | |
| } | |
| TV_Modify(TV_GetNext(),"VisFirst Focus") | |
| } | |
| Sort,userlist,D%A_Space% | |
| v.userlist:=userlist | |
| GuiControl,+Redraw,Scintilla1 | |
| if v.chandoc[channel] | |
| main.2358(0,v.chandoc[channel]) | |
| } | |
| updatechan(sel=""){ | |
| d({l:1}),LV_Delete() | |
| list:=chan.sn("//channel/@name") | |
| while,cc:=list.item(a_index-1){ | |
| Select:=cc.text=sel?"Select Vis Focus":"" | |
| LV_Add(select,cc.text) | |
| } | |
| if IsObject(sel) | |
| LV_Modify(sel.1,"Select Vis Focus") | |
| } | |
| class s{ | |
| static ctrl:=[],lc:="" | |
| __New(win=1,pos=""){ | |
| static count=1 | |
| Gui,%win%:Add,custom,classScintilla hwndsc %pos% +1387331584 | |
| this.sc:=sc,s.ctrl[sc]:=this,t:=[] | |
| for a,b in {fn:2184,ptr:2185} | |
| this[a]:=DllCall("SendMessageA","UInt",sc,"int",b,int,0,int,0) | |
| ;controllist(),arrange(),color(this) | |
| v.focus:=sc | |
| this.2460(3) | |
| for a,b in [[2563,1],[2565,1],[2614,1],[2402,0x15,75]]{ | |
| b.2:=b.2?b.2:0,b.3:=b.3?b.3:0 | |
| this[b.1](b.2,b.3) | |
| } | |
| return this | |
| } | |
| __Delete(){ | |
| m("should not happen") | |
| } | |
| __Get(x*){ | |
| return DllCall(this.fn,"Ptr",this.ptr,"UInt",x.1,int,0,int,0,"Cdecl") | |
| } | |
| __Call(code,lparam=0,wparam=0){ | |
| if (code="getseltext"){ | |
| VarSetCapacity(text,this.2161),length:=this.2161(0,&text) | |
| return StrGet(&text,length,"cp0") | |
| } | |
| if (code="textrange"){ | |
| VarSetCapacity(text,abs(lparam-wparam)),VarSetCapacity(textrange,12,0),NumPut(lparam,textrange,0),NumPut(wparam,textrange,4),NumPut(&text,textrange,8) | |
| this.2162(0,&textrange) | |
| return strget(&text,"","cp0") | |
| } | |
| if (code="gettext"){ | |
| cap:=VarSetCapacity(text,vv:=this.2182),this.2182(vv,&text),t:=strget(&text,vv,"cp0") | |
| return t | |
| } | |
| wp:=(wparam+0)!=""?"Int":"AStr" | |
| if wparam.1 | |
| wp:="AStr" | |
| if wparam=0 | |
| wp:="int" | |
| return DllCall(this.fn,"Ptr",this.ptr,"UInt",code,int,lparam,wp,wparam,"Cdecl") | |
| } | |
| } | |
| class xml{ | |
| keep:=[] | |
| __New(param*){ | |
| root:=param.1,file:=param.2 | |
| file:=file?file:root ".xml" | |
| temp:=ComObjCreate("MSXML2.DOMDocument"),temp.setProperty("SelectionLanguage","XPath") | |
| this.xml:=temp | |
| SplitPath,file,,dd | |
| IfNotExist,%dd% | |
| FileCreateDir,%dd% | |
| ifexist %file% | |
| temp.load(file),this.xml:=temp | |
| else | |
| this.xml:=this.CreateElement(temp,root) | |
| this.file:=file | |
| xml.keep[ref]:=this | |
| } | |
| CreateElement(doc,root){ | |
| return doc.AppendChild(this.xml.CreateElement(root)).parentnode | |
| } | |
| under(info){ | |
| new:=info.under.appendchild(this.xml.createelement(info.node)) | |
| for a,b in info.att | |
| new.SetAttribute(a,b) | |
| new.text:=info.text | |
| return new | |
| } | |
| add(info){ | |
| path:=info.path,p:="/",dup:=this.ssn("//" path)?1:0 | |
| if next:=this.ssn("//" path)?this.ssn("//" path):this.ssn("//*") | |
| Loop,Parse,path,/ | |
| last:=A_LoopField,p.="/" last,next:=this.ssn(p)?this.ssn(p):next.appendchild(this.xml.CreateElement(last)) | |
| if (info.dup&&dup) | |
| next:=next.parentnode.appendchild(this.xml.CreateElement(last)) | |
| for a,b in info.att | |
| next.SetAttribute(a,b) | |
| if info.text!="" | |
| next.text:=info.text | |
| return next | |
| } | |
| ssn(node,find=""){ | |
| if (find) | |
| return this.xml.SelectSingleNode(node "[contains(.,'" RegExReplace(find,"'","')][contains(.,'") "')]..") | |
| return this.xml.SelectSingleNode(node) | |
| } | |
| sn(node){ | |
| return this.xml.SelectNodes(node) | |
| } | |
| __Get(x=""){ | |
| return this.xml.xml | |
| } | |
| transform(){ | |
| static | |
| if !IsObject(xsl){ | |
| xsl:=ComObjCreate("MSXML2.DOMDocument") | |
| style= | |
| ( | |
| <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
| <xsl:output method="xml" indent="yes" encoding="UTF-8"/> | |
| <xsl:template match="@*|node()"> | |
| <xsl:copy> | |
| <xsl:apply-templates select="@*|node()"/> | |
| <xsl:for-each select="@*"> | |
| <xsl:text></xsl:text> | |
| </xsl:for-each> | |
| </xsl:copy> | |
| </xsl:template> | |
| </xsl:stylesheet> | |
| ) | |
| xsl.loadXML(style),style:=null | |
| } | |
| this.xml.transformNodeToObject(xsl,this.xml) | |
| } | |
| save(x*){ | |
| if x.1=1 | |
| this.Transform() | |
| filename:=this.file?this.file:x.1.1 | |
| file:=fileopen(filename,"rw") | |
| file.seek(0) | |
| file.write(this.xml.xml) | |
| file.length(file.position) | |
| } | |
| easyatt(path){ | |
| list:=[] | |
| if nodes:=path.nodename | |
| nodes:=path.SelectNodes("@*") | |
| else if path.text | |
| nodes:=this.sn("//*[text()='" path.text "']/@*") | |
| else | |
| for a,b in path | |
| nodes:=this.sn("//*[@" a "='" b "']/@*") | |
| while,n:=nodes.item(A_Index-1) | |
| list[n.nodename]:=n.text | |
| return list | |
| } | |
| search(node,find){ | |
| found:=this.xml.SelectNodes(node "[contains(.,'" RegExReplace(find,"'","')][contains(.,'") "')]") ;.. at end | |
| while,ff:=found.item(a_index-1) | |
| if (ff.text=find) | |
| return ssn(ff,"..") | |
| } | |
| removeall(node,find){ | |
| found:=this.xml.SelectNodes(node "[contains(.,'" RegExReplace(find,"'","')][contains(.,'") "')]") ;.. at end | |
| while,ff:=found.item(a_index-1){ | |
| if (ff.text=find){ | |
| ff:=ssn(ff,"..") | |
| ff.ParentNode.RemoveChild(ff) | |
| } | |
| } | |
| } | |
| } | |
| ssn(node,path){ | |
| return node.SelectSingleNode(path) | |
| } | |
| sn(node,path){ | |
| return node.SelectNodes(path) | |
| } | |
| search(node,path,find){ | |
| found:=node.SelectNodes(path "[contains(.,'" RegExReplace(find,"'","')][contains(.,'") "')]") | |
| while,ff:=found.item(a_index-1) | |
| if (ff.text=find) | |
| return ssn(ff,"..") | |
| } | |
| send(message="",channel=""){ | |
| edit:=trim(input.gettext(),"`r`n") | |
| if !edit | |
| return input.2004 | |
| input.2004 | |
| d({l:1}),LV_GetText(channel,LV_GetNext()) | |
| StringSplit,edit,edit,%A_Space% | |
| if (v.main.2357=v.chandoc[v.msrvr]&&SubStr(edit,1,1)!="/") | |
| return v.sock.Sendtext(edit),display(edit) | |
| ;#sjc_bot | |
| ;add /msg whois....hell look at the site with the irc commands and add em | |
| info:=msg(Edit) | |
| if (info.1="/quit"||info.1="/q") | |
| mm:="QUIT :" msg(edit,1).2 | |
| else if (info.1="/c"||info.1="/chanserv") | |
| mm:="PRIVMSG CHANSERV :" msg(edit,1).2 | |
| else if (info.1="me") | |
| mm:="PRIVMSG " info.2 " :" chr(1) msg(edit,1).2 chr(1) | |
| else if (info.1="/i"||info.1="/ident") | |
| mm:="PRIVMSG NICKSERV :IDENTIFY " msg(edit,1).2 | |
| else if (info.1="/away") | |
| mm:="AWAY :" msg(edit,1).2 | |
| else if (info.1="/n"||info.1="/nickserv") | |
| mm:="PRIVMSG NICKSERV :" msg(edit,1).2 | |
| else if (info.1="/raw"||info.1="/r"||info.1="/") | |
| mm:=msg(edit,1).2 | |
| else if (info.1="/msg"||info.1="/m") | |
| mm:="PRIVMSG " info.2 " :" msg(edit,2).3 | |
| else if (info.1="/part"){ | |
| currentchan(channel) | |
| info.2:=info.2?info.2:channel | |
| mm:="PART " out:=InStr(info.2,"#")?info.2:"#" info.2 " :" msg(edit,2).3 | |
| } | |
| else if (info.1="/j"||info.1="/join"),info:=msg(edit,1) | |
| mm:="JOIN " out:=InStr(info.2,"#")?info.2:"#" info.2 | |
| else | |
| mm:="PRIVMSG " channel " :" edit | |
| if mm | |
| v.sock.Sendtext(mm) | |
| if !InStr(info.1,"/") | |
| display(edit,channel,v.username ":") | |
| if (info.1="/me") | |
| display("***" v.username " " msg(edit,1).2,channel) | |
| input.2004 | |
| ;ControlSetText,Edit1,,% hwnd([1]) | |
| return | |
| g: | |
| %A_GuiControl%() | |
| return | |
| } | |
| msg(edit,count=0){ | |
| if !(count){ | |
| StringSplit,Edit,edit,%a_space% | |
| return [edit1,edit2,edit3] | |
| } | |
| loop,%count% | |
| search.="\W(.+)" | |
| RegExMatch(edit,"OU)(.+)" search "$",info) | |
| return info | |
| } | |
| next(message){ | |
| static pl:={"@":"Operator","+":"Voice","":"Normal"} | |
| GuiControl,-Redraw,Scintilla1 | |
| LV_GetText(curchan,LV_GetNext()) | |
| currentpage:=main.2357 | |
| Loop,Parse,message,`r`n,`r`n | |
| { | |
| if !A_LoopField | |
| continue | |
| in:=strsplit(A_LoopField," ") | |
| ;change this | |
| if (in.2=353) | |
| v.lastline.=SubStr(A_LoopField,InStr(A_LoopField,":",0,1,2)+1) " " | |
| if (in.2=366){ ;going to get rid of this one | |
| cc:=chan.search("//channel/@name",curchan) | |
| out:=strsplit(v.lastline," ") | |
| for a,user in out{ | |
| if !user | |
| continue | |
| if search(cc,"*/*/@user",user) | |
| continue | |
| if RegExMatch(SubStr(user,1,1),"\W",prefix) | |
| user:=SubStr(user,2) | |
| under:=ssn(cc,pl[prefix]) | |
| chan.under({under:under,node:"user",att:{user:user}}) | |
| } | |
| v.catch:=0 | |
| v.chan[in.4]:=1 | |
| updatechan(in.4) | |
| newdoc:=main.2375 | |
| v.chandoc[in.4]:=newdoc | |
| v.lastline:="" | |
| main.2358(0,newdoc) | |
| set() | |
| } | |
| ;--------------- | |
| regexmatch(in.1,"A):(.+)!",user) | |
| if (in.1="ping") | |
| v.sock.Sendtext("PONG " in.2) | |
| if (in.2="JOIN"&&v.username=user1){ | |
| if !cc:=ssn(chan.search("//channel/@name",in.3),".."){ | |
| cc:=chan.add({path:"channel",att:{name:in.3},dup:1}) | |
| for a,b in ["Operator","Voice","Normal"] | |
| chan.under({under:cc,node:b}) | |
| } | |
| updatechan(in.3) | |
| } | |
| if (in.2="JOIN"&&v.username!=user1){ | |
| ;working | |
| user:=user1 | |
| if RegExMatch(SubStr(user,1,1),"\W",prefix) | |
| user:=SubStr(user,2) | |
| cc:=chan.search("//channel/@name",in.3) | |
| under:=ssn(cc,pl[prefix]) | |
| newusr:=chan.under({under:under,node:"user",att:{user:user}}) | |
| id:=ssn(under,"@tv").text | |
| new:=TV_Add(user,id,"Sort") | |
| newusr.SetAttribute("tv",new) | |
| updatenicks(in.3),display(user " has joined the channel",in.3) | |
| } | |
| if (in.2="QUIT"){ | |
| found:=chan.sn("//@user[contains(.,'" RegExReplace(user1,"'","')][contains(.,'") "')]") | |
| while,ff:=found.item(a_index-1){ | |
| if (ff.text=user1){ | |
| top:=ssn(ff,"..") | |
| if tv:=ssn(top,"@tv").text | |
| TV_Delete(tv) | |
| top.ParentNode.RemoveChild(top) | |
| } | |
| } | |
| } | |
| if (in.2="PART"){ | |
| user:=user1 | |
| cc:=chan.search("//channel/@name",in.3) | |
| if (v.username=user) | |
| cc.ParentNode.RemoveChild(cc),updatechan([1]) | |
| else if uu:=search(cc,"*/*/@user",user) | |
| tv:=ssn(uu,"@tv").text,uu.ParentNode.RemoveChild(uu) | |
| if tv | |
| TV_Delete(tv) | |
| updatenicks(in.3),display(user " has left the channel",in.3) | |
| } | |
| if (in.2="MODE"){ | |
| cc:=chan.search("//channel/@name",in.3) | |
| uu:=search(cc,"*/*/@user",in.5) | |
| if tv:=ssn(uu,"@tv").text | |
| TV_Delete(tv) | |
| prefix:=uu.ParentNode.nodename | |
| if (InStr(in.4,"-o")&&prefix="Operator")||(InStr(in.4,"-v")&&prefix="Voice") | |
| uu:=ssn(cc,"Normal").AppendChild(uu) | |
| if InStr(in.4,"+o") | |
| uu:=ssn(cc,"Operator").AppendChild(uu) | |
| if InStr(in.4,"+v") | |
| uu:=ssn(cc,"Voice").AppendChild(uu) | |
| tv:=ssn(uu.ParentNode,"@tv").text | |
| newtv:=TV_Add(in.5,tv,"Sort") | |
| uu.SetAttribute("tv",newtv) | |
| TV_Modify(tv,"Expand") | |
| } | |
| if (in.2="NICK"){ | |
| newnick:=SubStr(in.3,2) | |
| if (user1=v.username) | |
| v.username:=user1 | |
| found:=chan.sn("//@user[contains(.,'" RegExReplace(user1,"'","')][contains(.,'") "')]") | |
| while,ff:=found.item(a_index-1){ | |
| if (ff.text=user1){ | |
| top:=ssn(ff,"..") | |
| if tv:=ssn(top,"@tv").text | |
| TV_Modify(tv,"",newnick) | |
| ff.text:=newnick | |
| } | |
| } | |
| } | |
| if (in.2="PRIVMSG"){ | |
| cc:=if InStr(in.3,"#")?in.3:user1 | |
| msg:=SubStr(A_LoopField,InStr(A_LoopField,":",0,1,2)) | |
| display(msg,cc,user1) | |
| if !WinActive(hwnd([1])) | |
| if InStr(msg,v.username) | |
| TrayTip,AHK IRC,% SubStr(A_LoopField,InStr(A_LoopField,":",0,1,2)+1),3 | |
| } | |
| display(A_LoopField) | |
| } | |
| lines:=main.2370 | |
| first:=main.2152 | |
| total:=main.2154 | |
| current:=main.2235(total-1) | |
| if !((lines+first+current+2)<total) | |
| main.2629 | |
| main.2358(0,currentpage) | |
| main.2171(1) | |
| GuiControl,+Redraw,Scintilla1 | |
| } | |
| currentchan(byref channel){ | |
| if !LV_GetNext() | |
| channel:="" | |
| else | |
| LV_GetText(channel,LV_GetNext()) | |
| } | |
| notify(wp,info,c,d){ | |
| Critical | |
| sc:=NumGet(info+0) | |
| if (main.sc!=sc&&input.sc!=sc) | |
| return | |
| static last | |
| fn:=[] | |
| ;,2:"id",4:"position",5:"ch",6:"modifiers",7:"modType",8:"text",9:"length",10:"linesAdded",11:"macMessage",12:"macwParam",13:"maclParam",14:"line",15:"foldLevelNow",16:"foldLevelPrev",17:"margin",18:"listType",19:"x",20:"y",21:"token",22:"annotLinesAdded",23:"updated"} | |
| for a,b in {0:"Obj",2:"Code",4:"ch",7:"text",6:"modType",9:"linesadded",3:"position",13:"line",8:"length"} | |
| fn[b]:=NumGet(Info+(A_PtrSize*a)) | |
| if (fn.code=2008){ | |
| move:=main.2370+main.2152<=main.2166(main.2006)?0:1 | |
| if move | |
| main.2629 | |
| } | |
| if (fn.code=2027){ | |
| start:=end:=main.2008 | |
| while,main.2010(start)=1 | |
| start-- | |
| while,main.2010(end)=1 | |
| end++ | |
| url:=main.textrange(start+1,end) | |
| url:=RegExMatch(url,"Ai)http")?url:"http://" url | |
| Run,% url | |
| } | |
| if (fn.code=2004) | |
| ControlFocus,Scintilla2,% hwnd([1]) | |
| if (fn.code=2001){ | |
| if fn.ch=10 | |
| return send() | |
| cp:=input.2008 | |
| word:=input.textrange(input.2266(cp-1,1),input.2267(cp-1,1)) | |
| li:="" | |
| if (StrLen(word)>1&&input.2102=0){ | |
| ;ll:=v.keywords[SubStr(word,1,1)] | |
| ll:=v.userlist | |
| Loop,Parse,ll,%a_space% | |
| if RegExMatch(A_LoopField,"Ai)" word) | |
| li.=A_LoopField " " | |
| if li | |
| input.2100(StrLen(word),Trim(li)) | |
| } | |
| } | |
| } | |
| stripurl(text){ | |
| urls:=[],pos:=0,start:=0 | |
| offset:=InStr(Text,":",0,1,1) | |
| tt:=SubStr(text,offset+1) | |
| Loop,Parse,tt,%A_Space% | |
| { | |
| if A_LoopField contains http,ftp,.com,.net,.gov,.org,mailto | |
| urls[start++]:={url:A_LoopField,pos:pos+offset} | |
| pos+=StrLen(A_LoopField)+1 | |
| } | |
| return urls | |
| } | |
| download_update(){ | |
| FileMove,%A_ScriptName%,backup_%a_now%_%A_ScriptName% | |
| ext:=A_IsCompiled?".exe":".ahk" | |
| URLDownloadToFile,http://www.maestrith.com/files/irc/irc%ext%,%A_ScriptName% | |
| MsgBox,17,Reload now?,Reload now? will kick you offline. | |
| IfMsgBox,Ok | |
| { | |
| reload | |
| ExitApp | |
| } | |
| } | |
| updatenicks(curchan){ | |
| mm:=chan.search("//channel/@name",curchan) | |
| for a,b in ["Operator","Voice","Normal"]{ | |
| list:=sn(mm,b "/*") | |
| while,ll:=list.item(a_index-1) | |
| userlist.=ssn(ll,"@user").text " " | |
| } | |
| Sort,userlist,D%A_Space% | |
| v.userlist:=userlist | |
| } | |
| compile(info,index=1){ | |
| for a,b in info | |
| if (A_Index>index) | |
| msg.=b " " | |
| return msg | |
| } | |
| display(edit,win="",user=""){ | |
| static pos:=[] | |
| currentwindow:=main.2357 | |
| pos[currentwindow]:=main.2152 | |
| window:=!win?v.chandoc[v.msrvr]:v.chandoc[win] | |
| if !window | |
| { | |
| window:=main.2375 | |
| v.chandoc[win]:=window | |
| root:=chan.ssn("//*") | |
| chan.under({under:root,node:"channel",att:{name:win}}) | |
| updatechan() | |
| } | |
| main.2358(0,window) | |
| main.2613(pos[window]) | |
| end:=main.2006 | |
| if InStr(edit,Chr(1) "ACTION"){ | |
| edit:=RegExReplace(edit,"Ui)" Chr(1) "ACTION") | |
| StringReplace,edit,edit,% Chr(1),,All | |
| edit:="***" user " " edit | |
| } | |
| else | |
| edit:=user?user edit:edit | |
| edit:=end?"`r`n" edit:edit | |
| main.2051(2,0xff0000) | |
| main.2052(2,0) | |
| main.2171(0) | |
| if win | |
| main.2003(end,edit) | |
| else | |
| main.2003(end,edit) | |
| if win | |
| url:=stripurl(edit) | |
| for a,b in url{ | |
| main.2409(1,1) | |
| main.2051(1,0xff00ff) | |
| main.2032(end+b.pos,0x1f) | |
| main.2033(StrLen(b.url),1) | |
| } | |
| main.2171(1) | |
| line:=main.2166(main.2006) | |
| main.2530(line,"["A_Hour ":" A_Min ":" A_Sec "]") | |
| main.2532(line,2) | |
| main.2358(0,currentwindow) | |
| main.2613(pos[currentwindow]) | |
| } | |
| set(){ | |
| main.2052(32,0) | |
| main.2051(32,0x0000FF) | |
| main.2050 | |
| main.2052(33,0) ;has to be after 2050 to keep the timestamp colors right | |
| } | |
| nicklist(){ | |
| if (A_GuiEvent="rightclick"&&TV_GetParent(A_EventInfo)&&LV_GetNext()){ | |
| TV_GetText(user,A_EventInfo),LV_GetText(channel,LV_GetNext()) | |
| v.sock.Sendtext("chanserv :op " channel " " user) | |
| } | |
| ;t(A_GuiEvent,A_EventInfo) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment