summaryrefslogtreecommitdiff
path: root/plugins/Watrack/proto
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Watrack/proto')
-rw-r--r--plugins/Watrack/proto/i_proto_dlg.inc144
-rw-r--r--plugins/Watrack/proto/i_proto_opt.inc35
-rw-r--r--plugins/Watrack/proto/i_proto_rc.inc17
-rw-r--r--plugins/Watrack/proto/proto.pas564
-rw-r--r--plugins/Watrack/proto/proto.rc36
-rw-r--r--plugins/Watrack/proto/proto.resbin0 -> 2624 bytes
-rw-r--r--plugins/Watrack/proto/wat_context.icobin0 -> 1406 bytes
7 files changed, 796 insertions, 0 deletions
diff --git a/plugins/Watrack/proto/i_proto_dlg.inc b/plugins/Watrack/proto/i_proto_dlg.inc
new file mode 100644
index 0000000000..3c467c79ac
--- /dev/null
+++ b/plugins/Watrack/proto/i_proto_dlg.inc
@@ -0,0 +1,144 @@
+{Misc}
+
+procedure SetAllContactStat(hwndList:HWND);
+var
+ hContact,hItem:THANDLE;
+begin
+ hContact:=CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while hContact<>0 do
+ begin
+ hItem:=SendMessage(hwndList,CLM_FINDCONTACT,hContact,0);
+ if hItem<>0 then
+ begin
+ SendMessage(hwndList,CLM_SETCHECKMARK,hItem,
+ DBReadByte(hContact,strCList,ShareOptText,0));
+ end;
+ hContact:=CallService(MS_DB_CONTACT_FINDNEXT,hContact,0);
+ end;
+end;
+
+procedure SaveAllContactStat(hwndList:HWND);
+var
+ hContact,hItem:THANDLE;
+begin
+ hContact:=CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while hContact<>0 do
+ begin
+ hItem:=SendMessage(hwndList,CLM_FINDCONTACT,hContact,0);
+ if hItem<>0 then
+ begin
+ if SendMessage(hwndList,CLM_GETCHECKMARK,hItem,0)<>0 then
+ DBWriteByte(hContact,strCList,ShareOptText,1)
+ else
+ DBDeleteSetting(hContact,strCList,ShareOptText);
+ end;
+ hContact:=CallService(MS_DB_CONTACT_FINDNEXT,hContact,0);
+ end;
+end;
+
+procedure ResetListOptions(hwndList:HWND);
+var
+ i:integer;
+begin
+ SendMessage(hwndList,CLM_SETBKBITMAP ,0,0);
+ SendMessage(hwndList,CLM_SETBKCOLOR ,GetSysColor(COLOR_WINDOW),0);
+ SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0);
+ SendMessage(hwndList,CLM_SETLEFTMARGIN ,2,0);
+ SendMessage(hwndList,CLM_SETINDENT ,10,0);
+ for i:=0 to FONTID_MAX do
+ SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT));
+ SetWindowLongPtr(hwndList,GWL_STYLE,GetWindowLongPtr(hwndList,GWL_STYLE) or CLS_SHOWHIDDEN);
+end;
+
+procedure SetHistMask(Dlg:HWND);
+begin
+ CheckDlgButton(Dlg,IDC_IN_REQUEST ,ORD((HistMask and hmInRequest )<>0));
+ CheckDlgButton(Dlg,IDC_OUT_REQUEST,ORD((HistMask and hmOutRequest)<>0));
+ CheckDlgButton(Dlg,IDC_IN_INFO ,ORD((HistMask and hmInInfo )<>0));
+ CheckDlgButton(Dlg,IDC_OUT_INFO ,ORD((HistMask and hmOutInfo )<>0));
+ CheckDlgButton(Dlg,IDC_IN_ERROR ,ORD((HistMask and hmInError )<>0));
+ CheckDlgButton(Dlg,IDC_OUT_ERROR ,ORD((HistMask and hmOutError )<>0));
+ CheckDlgButton(Dlg,IDC_IREQUEST ,ORD((HistMask and hmIRequest )<>0));
+ CheckDlgButton(Dlg,IDC_ISEND ,ORD((HistMask and hmISend )<>0));
+end;
+
+procedure SaveHistMask(Dlg:HWND);
+begin
+ HistMask:=0;
+ if IsDlgButtonChecked(Dlg,IDC_IN_REQUEST )<>BST_UNCHECKED then HistMask:=HistMask or hmInRequest;
+ if IsDlgButtonChecked(Dlg,IDC_OUT_REQUEST)<>BST_UNCHECKED then HistMask:=HistMask or hmOutRequest;
+ if IsDlgButtonChecked(Dlg,IDC_IN_INFO )<>BST_UNCHECKED then HistMask:=HistMask or hmInInfo;
+ if IsDlgButtonChecked(Dlg,IDC_OUT_INFO )<>BST_UNCHECKED then HistMask:=HistMask or hmOutInfo;
+ if IsDlgButtonChecked(Dlg,IDC_IN_ERROR )<>BST_UNCHECKED then HistMask:=HistMask or hmInError;
+ if IsDlgButtonChecked(Dlg,IDC_OUT_ERROR )<>BST_UNCHECKED then HistMask:=HistMask or hmOutError;
+ if IsDlgButtonChecked(Dlg,IDC_IREQUEST )<>BST_UNCHECKED then HistMask:=HistMask or hmIRequest;
+ if IsDlgButtonChecked(Dlg,IDC_ISEND )<>BST_UNCHECKED then HistMask:=HistMask or hmISend;
+end;
+
+function DlgProcOptions(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+const
+ Changed:integer=0;
+// hItemAll:THANDLE=0;
+var
+// cii:TCLCINFOITEM;
+ hList:HWND;
+begin
+ result:=0;
+ case hMessage of
+ WM_INITDIALOG: begin
+ TranslateDialogDefault(Dialog);
+ Changed:=DLGED_INIT;
+
+ hList:=GetDlgItem(Dialog,IDC_SHARE);
+ ResetListOptions(hList);
+ SendMessage(hList,CLM_SETUSEGROUPS ,1,0);
+ SendMessage(hList,CLM_SETHIDEEMPTYGROUPS,1,0);
+
+// SendMessage(hList,CLM_SETEXTRACOLUMNS,2,0);
+{
+ FillChar(cii,SizeOf(cii),0);
+ cii.cbSize :=SizeOf(cii);
+ cii.flags :=CLCIIF_GROUPFONT or CLCIIF_CHECKBOX;
+ cii.pszText.w:=TranslateW('** All contacts **');
+ hItemAll:=SendMessage(hList,CLM_ADDINFOITEM,0,dword(@cii));
+}
+ SetAllContactStat(hList);
+ SetHistMask(Dialog);
+
+ SetDlgItemTextW(Dialog,IDC_PROTO_TEXT,ProtoText);
+
+ Changed:=0;
+ end;
+
+ WM_COMMAND: begin
+ if Changed<>DLGED_INIT then
+ begin
+ case wParam shr 16 of
+ BN_CLICKED,EN_CHANGE: SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ if Changed<>DLGED_INIT then
+ begin
+ if PNMHDR(lParam)^.idFrom=IDC_SHARE then
+ if integer(PNMHdr(lParam)^.code)=CLN_CHECKCHANGED then
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+
+ if integer(PNMHdr(lParam)^.code)=PSN_APPLY then
+ begin
+ mFreeMem(ProtoText);
+ ProtoText:=GetDlgText(Dialog,IDC_PROTO_TEXT);
+
+ SaveAllContactStat(GetDlgItem(Dialog,IDC_SHARE));
+ SaveHistMask(Dialog);
+
+ WriteOptions;
+ end;
+ end;
+ end;
+ else
+ {result:=}DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
diff --git a/plugins/Watrack/proto/i_proto_opt.inc b/plugins/Watrack/proto/i_proto_opt.inc
new file mode 100644
index 0000000000..c1e2cbf36d
--- /dev/null
+++ b/plugins/Watrack/proto/i_proto_opt.inc
@@ -0,0 +1,35 @@
+{}
+const
+ defProtoText = '%artist% - %title%';
+const
+ opt_ModStatus:PAnsiChar = 'module/protocol';
+
+ opt_histmask :PAnsiChar = 'historymask';
+ opt_prototext:PAnsiChar = 'prototext';
+
+function GetModStatus:integer;
+begin
+ result:=DBReadByte(0,PluginShort,opt_ModStatus,1);
+end;
+
+procedure SetModStatus(stat:integer);
+begin
+ DBWriteByte(0,PluginShort,opt_ModStatus,stat);
+end;
+
+procedure ReadOptions;
+begin
+ HistMask :=DBReadWord (0,PluginShort,opt_histmask,0);
+ ProtoText:=DBReadUnicode(0,PluginShort,opt_prototext,defProtoText);
+end;
+
+procedure WriteOptions;
+begin
+ DBWriteWord (0,PluginShort,opt_histmask ,HistMask);
+ DBWriteUnicode(0,PluginShort,opt_prototext,ProtoText);
+end;
+
+procedure FreeOptions;
+begin
+ mFreeMem(ProtoText);
+end;
diff --git a/plugins/Watrack/proto/i_proto_rc.inc b/plugins/Watrack/proto/i_proto_rc.inc
new file mode 100644
index 0000000000..f2d56ad329
--- /dev/null
+++ b/plugins/Watrack/proto/i_proto_rc.inc
@@ -0,0 +1,17 @@
+const
+ IDC_EXPORT = 1031;
+ IDC_SHARE = 1033;
+ IDC_IN_REQUEST = 1034;
+ IDC_OUT_REQUEST = 1035;
+ IDC_IN_INFO = 1036;
+ IDC_OUT_INFO = 1037;
+ IDC_IN_ERROR = 1038;
+ IDC_OUT_ERROR = 1039;
+ IDC_IREQUEST = 1040;
+ IDC_ISEND = 1041;
+ IDC_STAT_EXPORT = 1042;
+ IDC_STAT_TEXP = 1043;
+ IDC_STAT_LINE = 1044;
+ IDC_PROTO_TEXT = 1045;
+
+BTN_CONTEXT = 130;
diff --git a/plugins/Watrack/proto/proto.pas b/plugins/Watrack/proto/proto.pas
new file mode 100644
index 0000000000..254a02bac6
--- /dev/null
+++ b/plugins/Watrack/proto/proto.pas
@@ -0,0 +1,564 @@
+{Statistic}
+unit proto;
+{$include compilers.inc}
+interface
+{$Resource proto.res}
+implementation
+
+uses
+ windows,messages,commctrl,
+ common,m_api,mirutils,dbsettings,wrapper,
+ global,wat_api;
+
+{$include i_proto_rc.inc}
+
+const
+ ShareOptText = 'ShareMusic';
+const
+ IcoBtnContext:PAnsiChar='WATrack_Context';
+const
+ MenuUserInfoPos = 500050000;
+
+const
+ wpRequest = 'WAT###0_';
+ wpAnswer = 'WAT###1_';
+ wpError = 'WAT###2_';
+ wpMessage = 'WAT###3_';
+ wpRequestNew = 'ASKWAT';
+
+const
+ SendRequestText:PAnsiChar =
+ 'WATrack internal info - sorry!';
+{
+ 'If you see this message, probably you have no "WATrack" plugin installed or uses old '+
+ 'version. See http://miranda-im.org/download/details.php?action=viewfile&id=2345 or '+
+ 'http://awkward.miranda.im/ (beta versions) for more information and download.';
+}
+const
+ hmInRequest = $0001;
+ hmOutRequest = $0002;
+ hmInInfo = $0004;
+ hmOutInfo = $0008;
+ hmInError = $0010;
+ hmOutError = $0020;
+ hmIRequest = $0040;
+ hmISend = $0080;
+
+var
+ hSRM,
+ hGCI,
+ icchangedhook,
+ hAddUserHook,
+ hContactMenuItem,
+ contexthook:THANDLE;
+ ProtoText:pWideChar;
+ HistMask:cardinal;
+
+{$include i_proto_opt.inc}
+{$include i_proto_dlg.inc}
+
+procedure AddEvent(hContact:THANDLE;atype,flag:integer;data:pointer;size:integer;time:dword=0);
+var
+ dbeo:TDBEVENTINFO;
+begin
+ FillChar(dbeo,SizeOf(dbeo),0);
+ with dbeo do
+ begin
+ cbSize :=SizeOf(dbeo);
+ eventType:=atype;
+ szModule :=PluginShort;
+ if data=nil then
+ begin
+ PAnsiChar(data):='';
+ size:=1;
+ end;
+ pBlob :=data;
+ cbBlob :=size;
+ flags :=flag;
+ if time<>0 then
+ Timestamp:=time
+ else
+ Timestamp:=GetCurrentTime;
+ end;
+ CallService(MS_DB_EVENT_ADD,hContact,lparam(@dbeo));
+end;
+
+{SEND-time text translation}
+(*
+const
+ BufSize = 16384;
+
+function FormatToBBW(src:PWideChar):PWideChar;
+var
+ buf:array [0..32] of WideChar;
+ p:PWideChar;
+ i,j:integer;
+begin
+ result:=src;
+ StrReplaceW(src,'{b}' ,'[b]');
+ StrReplaceW(src,'{/b}' ,'[/b]');
+ StrReplaceW(src,'{u}' ,'[u]');
+ StrReplaceW(src,'{/u}' ,'[/u]');
+ StrReplaceW(src,'{i}' ,'[i]');
+ StrReplaceW(src,'{/i}' ,'[/i]');
+ StrReplaceW(src,'{/cf}','[/color]');
+ StrReplaceW(src,'{/bg}','');
+ StrCopyW(buf,'[color=');
+ repeat
+ i:=StrPosW(src,'{cf');
+ if i=0 then break;
+ j:=i;
+ dec(i);
+ while (src[j]<>#0) and (src[j]<>'}') do inc(j);
+ if src[j]='}' then inc(j);
+ case StrToInt(src+i+3) of
+ 4,10: p:='green]';
+ 5,6: p:='red]';
+ 7,14: p:='magenta]';
+ 3,11,
+ 12,13: p:='blue]';
+ 8,9: p:='yellow]';
+ 2,15: p:='black]';
+ else
+ {1,16:} p:='white]';
+ end;
+ StrCopyW(buf+7,p);
+ StrCopyW(src+i,src+j);
+ StrInsertW(buf,src,i);
+ until false;
+ repeat
+ i:=StrIndex(src,'{bg');
+ if i=0 then break;
+ j:=i;
+ dec(i);
+ while (src[j]<>#0) and (src[j]<>'}') do inc(j);
+ if src[j]='}' then inc(j);
+ StrCopyW(src+i,src+j);
+ until false;
+end;
+
+function SendMessageProcW(wParam:WPARAM; lParam:LPARAM):integer; cdecl;
+var
+ ccs:PCCSDATA;
+ uns,s,ss:pWideChar;
+ p:PAnsiChar;
+ present:boolean;
+ i:integer;
+begin
+ if DisablePlugin<>dsPermanent then
+ begin
+ ccs:=PCCSDATA(lParam);
+ if ccs^.wParam=0 then
+ present:=StrPos('%music%',PAnsiChar(ccs^.lParam))<>nil
+ else // not needed?
+ begin
+ uns:=PWideChar(ccs^.lParam+StrLen(PAnsiChar(ccs^.lParam))+1);
+ present:=StrPos(uns,'%music%')<>nil;
+ end;
+
+ if present then
+ begin
+ if CallService(MS_WAT_GETMUSICINFO,0,0)=WAT_PLS_NOTFOUND then
+ s:=nil
+ else
+ begin
+ if SimpleMode<>BST_UNCHECKED then
+ i:=0
+ else
+ i:=CallService(MS_PROTO_GETCONTACTBASEPROTO,ccs^.hContact,0);
+ s:=GetMacros(TM_MESSAGE,i);
+ end;
+ // if s<>nil then // for empty strings
+ begin
+ mGetMem(ss,BufSize*SizeOf(pWideChar));
+ FillChar(ss^,BufSize*SizeOf(pWideChar),0);
+ if ccs^.wParam=0 then
+ AnsiToWide(PAnsiChar(ccs^.lParam),uns,UserCP);
+ StrCopyW(ss,uns);
+ if ccs^.wParam=0 then
+ mFreeMem(uns);
+ StrReplaceW(ss,'%music%',s);
+ mFreeMem(s);
+ if StrPos(ss,'{')<>nil then
+ FormatToBBW(ss);
+ s:=PWideChar(ccs^.lParam);
+ WideToAnsi(ss,p,UserCP);
+ if ccs^.wParam=0 then
+ begin
+ ccs^.lParam:=dword(p);
+ end
+ else
+ begin
+ move(PAnsiChar(ss)^,(PAnsiChar(ss)+StrLen(p)+1)^,
+ (StrLenW(ss)+1)*SizeOf(WideChar));
+ StrCopy(PAnsiChar(ss),p);
+ ccs^.lParam:=dword(ss);
+ end;
+ result:=CallService(MS_PROTO_CHAINSEND,wParam,lParam);
+ mFreeMem(p);
+ ccs^.lParam:=dword(s);
+ mFreeMem(ss);
+ exit;
+ end;
+ end;
+ end;
+ result:=CallService(MS_PROTO_CHAINSEND,wParam,lParam);
+end;
+*)
+
+function ReceiveMessageProcW(wParam:WPARAM; lParam:LPARAM):integer; cdecl;
+const
+ bufsize = 4096*SizeOf(WideChar);
+var
+ ccs:PCCSDATA;
+ s:pWideChar;
+ buf:PWideChar;
+ base64:TNETLIBBASE64;
+// pos_artist,pos_title,pos_album:PwideChar;
+ pos_template:pWideChar;
+ curpos:pWideChar;
+ encbuf:pWideChar;
+ i:integer;
+ textpos:PWideChar;
+ pc:PAnsiChar;
+ isNewRequest:bool;
+ si:pSongInfo;
+begin
+ ccs:=PCCSDATA(lParam);
+ result:=0;
+ mGetMem(buf,bufsize);
+
+ isNewRequest:=StrCmp(PPROTORECVEVENT(ccs^.lParam)^.szMessage.a,
+ wpRequestNew,Length(wpRequestNew))=0;
+
+ if isNewRequest or
+ (StrCmp(PPROTORECVEVENT(ccs^.lParam)^.szMessage.a,
+ wpRequest,Length(wpRequest))=0) then
+ begin
+ StrCopy(PAnsiChar(buf),PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO,ccs^.hContact,0)));
+ i:=DBReadWord(ccs^.hContact,PAnsiChar(buf),'ApparentMode');
+ StrCat(PAnsiChar(buf),PS_GETSTATUS);
+ if (i=ID_STATUS_OFFLINE) or
+ ((i=0) and (CallService(PAnsiChar(buf),0,0)=ID_STATUS_INVISIBLE)) then
+ begin
+ result:=CallService(MS_PROTO_CHAINRECV,wParam,lParam);
+ end
+ else if DBReadByte(ccs^.hContact,strCList,ShareOptText,0)<>0 then
+// or (NotListedAllow and (DBReadByte(ccs^.hContact,strCList,'NotOnList',0))
+ begin
+ if (HistMask and hmInRequest)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_REQUEST,DBEF_READ,nil,0,
+ PPROTORECVEVENT(ccs^.lParam)^.Timestamp);
+ if GetContactStatus(ccs^.hContact)<>ID_STATUS_OFFLINE then
+ begin
+//!! Request Answer
+ curpos:=nil;
+ if DisablePlugin<>dsPermanent then
+ begin
+ if CallService(MS_WAT_GETMUSICINFO,0,0)=WAT_PLS_NOTFOUND then
+ begin
+ s:=#0#0#0'No player found at this time';
+ textpos:=s+3;
+ end
+ else
+ begin
+ if not isNewRequest then
+ begin
+ FillChar(buf^,bufsize,0);
+ si:=pSongInfo(CallService(MS_WAT_RETURNGLOBAL,0,0));
+ StrCopyW(buf ,si^.artist); curpos:=StrEndW(buf)+1;
+ StrCopyW(curpos,si^.title); curpos:=StrEndW(curpos)+1;
+ StrCopyW(curpos,si^.album); curpos:=StrEndW(curpos)+1;
+ end
+ else
+ curpos:=buf;
+//!! check to DisableTemporary
+
+ s:=PWideChar(CallService(MS_WAT_REPLACETEXT,0,tlparam(ProtoText)));
+ textpos:=StrCopyW(curpos,s);
+ mFreeMem(s);
+ curpos:=StrEndW(curpos)+1;
+ end;
+ end
+ else
+ begin
+ s:=#0#0#0'Sorry, but i don''t use WATrack right now!';
+ textpos:=s+3;
+ end;
+// encode
+ if not isNewRequest then
+ begin
+ if curpos<>nil then
+ begin
+ base64.pbDecoded:=PByte(buf);
+ base64.cbDecoded:=PAnsiChar(curpos)-PAnsiChar(buf);
+ end
+ else
+ begin
+ base64.pbDecoded:=PByte(s);
+ base64.cbDecoded:=(StrLenW(textpos)+3+1)*SizeOf(PWideChar);
+ end;
+ base64.cchEncoded:=Netlib_GetBase64EncodedBufferSize(base64.cbDecoded);
+ mGetMem(encbuf,base64.cchEncoded+1+Length(wpAnswer));
+ base64.pszEncoded:=PAnsiChar(encbuf)+Length(wpAnswer);
+ StrCopy(PAnsiChar(encbuf),wpAnswer);
+ CallService(MS_NETLIB_BASE64ENCODE,0,tlparam(@base64));
+ if (HistMask and hmOutInfo)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_ANSWER,DBEF_SENT,
+ base64.pbDecoded,base64.cbDecoded);
+ CallContactService(ccs^.hContact,PSS_MESSAGE,0,tlparam(encbuf));
+ end
+ else
+ begin
+ i:=WideToCombo(textpos,encbuf,UserCP);
+ if (HistMask and hmOutInfo)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_MESSAGE,DBEF_SENT,encbuf,i);
+// if CallContactService(ccs^.hContact,PSS_MESSAGEW,PREF_UNICODE,dword(encbuf))=
+// ACKRESULT_FAILED then
+ CallContactService(ccs^.hContact,PSS_MESSAGE,PREF_UNICODE,tlparam(encbuf));
+ end;
+ mFreeMem(encbuf);
+ end;
+ end
+ else
+ begin
+ if (HistMask and hmIRequest)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_REQUEST,DBEF_READ,nil,0,
+ PPROTORECVEVENT(ccs^.lParam)^.Timestamp);
+ if (HistMask and hmISend)<>0 then
+ begin
+//!! Request Error Answer
+ if isNewRequest then
+ pc:=PAnsiChar(buf)
+ else
+ begin
+ StrCopy(PAnsiChar(buf),wpError);
+ pc:=PAnsiChar(buf)+Length(wpError);
+ end;
+ StrCopy(pc,'Sorry, but you have no permission to obtain this info!');
+ CallContactService(ccs^.hContact,PSS_MESSAGE,0,tlparam(buf));
+ if (HistMask and hmOutError)<>0 then
+ begin
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_ERROR,DBEF_SENT,nil,0,
+ PPROTORECVEVENT(ccs^.lParam)^.Timestamp);
+ end;
+ end;
+ end;
+ end
+ else if StrCmp(PPROTORECVEVENT(ccs^.lParam)^.szMessage.a,wpAnswer,Length(wpAnswer))=0 then
+ begin
+// decode
+ base64.pszEncoded:=PPROTORECVEVENT(ccs^.lParam)^.szMessage.a+Length(wpAnswer);
+ base64.cchEncoded:=StrLen(base64.pszEncoded);
+ base64.cbDecoded :=Netlib_GetBase64DecodedBufferSize(base64.cchEncoded);
+ mGetMem(base64.pbDecoded,base64.cbDecoded);
+
+ CallService(MS_NETLIB_BASE64DECODE,0,tlparam(@base64));
+
+ curpos:=pWideChar(base64.pbDecoded); // pos_artist:=curpos;
+ while curpos^<>#0 do inc(curpos); inc(curpos); // pos_title :=curpos;
+ while curpos^<>#0 do inc(curpos); inc(curpos); // pos_album :=curpos;
+ while curpos^<>#0 do inc(curpos); inc(curpos);
+ pos_template:=curpos;
+
+ if (HistMask and hmInInfo)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_ANSWER,DBEF_READ,
+ base64.pbDecoded,base64.cbDecoded,
+ PPROTORECVEVENT(ccs^.lParam)^.Timestamp);
+// Action
+
+ StrCopyW(buf,TranslateW('Music Info from '));
+ StrCatW (buf,PWideChar(CallService(MS_CLIST_GETCONTACTDISPLAYNAME,ccs^.hContact,GCDNF_UNICODE)));
+
+ MessageBoxW(0,TranslateW(pos_template),buf,MB_ICONINFORMATION);
+
+ mFreeMem(base64.pbDecoded);
+ end
+ else if StrCmp(PPROTORECVEVENT(ccs^.lParam)^.szMessage.a,wpError,Length(wpError))=0 then
+ begin
+ if (HistMask and hmInError)<>0 then
+ AddEvent(ccs^.hContact,EVENTTYPE_WAT_ERROR,DBEF_READ,nil,0,
+ PPROTORECVEVENT(ccs^.lParam)^.Timestamp);
+{
+ AnsiToWide(PAnsiChar(CallService(MS_CLIST_GETCONTACTDISPLAYNAME,ccs^.hContact,0)),s);
+ StrCopyW(buf,s);
+ StrCatW (buf,TranslateW(' answer you'));
+ mFreeMem(s);
+}
+ MessageBoxA(0,Translate(PPROTORECVEVENT(ccs^.lParam)^.szMessage.a+Length(wpError)),
+ Translate('You Get Error'),MB_ICONERROR);
+ end
+ else
+ result:=CallService(MS_PROTO_CHAINRECV,wParam,lParam);
+ mFreeMem(buf);
+end;
+
+function SendRequest(hContact:WPARAM;lParam:LPARAM):integer; cdecl;
+var
+ buf:array [0..2047] of AnsiChar;
+begin
+ result:=0;
+ StrCopy(buf,wpRequest);
+ StrCopy(buf+Length(wpRequest),SendRequestText);
+ CallContactService(hContact,PSS_MESSAGE,0,tlparam(@buf));
+ if (HistMask and hmOutRequest)<>0 then
+ AddEvent(hContact,EVENTTYPE_WAT_REQUEST,DBEF_SENT,nil,0);
+end;
+
+procedure RegisterContacts;
+var
+ hContact:integer;
+begin
+ hContact:=CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while hContact<>0 do
+ begin
+ if not IsChat(hContact) then
+ CallService(MS_PROTO_ADDTOCONTACT,hContact,lparam(PluginShort));
+ hContact:=CallService(MS_DB_CONTACT_FINDNEXT,hContact,0);
+ end;
+end;
+
+function HookAddUser(hContact:WPARAM;lParam:LPARAM):integer; cdecl;
+begin
+ result:=0;
+ if not IsChat(hContact) then
+ CallService(MS_PROTO_ADDTOCONTACT,hContact,tlparam(PluginShort));
+end;
+
+function OnContactMenu(hContact:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ mi:TCListMenuItem;
+begin
+ FillChar(mi,SizeOf(mi),0);
+ mi.cbSize:=sizeof(mi);
+ if IsMirandaUser(hContact)<=0 then
+ mi.flags:=CMIF_NOTOFFLINE or CMIF_NOTOFFLIST or CMIM_FLAGS or CMIF_HIDDEN
+ else
+ mi.flags:=CMIF_NOTOFFLINE or CMIF_NOTOFFLIST or CMIM_FLAGS;
+ CallService(MS_CLIST_MODIFYMENUITEM,hContactMenuItem,tlparam(@mi));
+ result:=0;
+end;
+
+procedure SetProtocol;
+var
+ desc:TPROTOCOLDESCRIPTOR;
+begin
+ desc.cbSize:=PROTOCOLDESCRIPTOR_V3_SIZE;//SizeOf(desc);
+ desc.szName:=PluginShort;
+ desc._type :=PROTOTYPE_TRANSLATION;
+
+ CallService(MS_PROTO_REGISTERMODULE,0,lparam(@desc));
+// CreateProtoServiceFunction(PluginShort,PSS_MESSAGE ,@SendMessageProcW);
+// CreateProtoServiceFunction(PluginShort,PSS_MESSAGEW,@SendMessageProcW);
+ hSRM:=CreateProtoServiceFunction(PluginShort,PSR_MESSAGE ,@ReceiveMessageProcW);
+// CreateProtoServiceFunction(PluginShort,PSR_MESSAGEW,@ReceiveMessageProcW);
+end;
+
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ mi:TCListMenuItem;
+begin
+ result:=0;
+ FillChar(mi,SizeOf(mi),0);
+ mi.cbSize:=sizeof(mi);
+ mi.flags :=CMIM_ICON;
+
+ mi.hIcon:=CallService(MS_SKIN2_GETICON,0,tlparam(IcoBtnContext));
+ CallService(MS_CLIST_MODIFYMENUITEM,hContactMenuItem,tlparam(@mi));
+end;
+
+procedure RegisterIcons;
+var
+ sid:TSKINICONDESC;
+begin
+ FillChar(sid,SizeOf(TSKINICONDESC),0);
+ sid.cbSize:=SizeOf(TSKINICONDESC);
+ sid.cx:=16;
+ sid.cy:=16;
+ sid.szSection.a:=PluginShort;
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(BTN_CONTEXT),IMAGE_ICON,16,16,0);
+ sid.pszName :=IcoBtnContext;
+ sid.szDescription.a:='Context Menu';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+//!!
+ icchangedhook:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+end;
+
+// ------------ base interface functions -------------
+
+function InitProc(aGetStatus:boolean=false):integer;
+var
+ mi:TCListMenuItem;
+begin
+ if aGetStatus then
+ begin
+ if GetModStatus=0 then
+ begin
+ result:=0;
+ exit;
+ end;
+ end
+ else
+ SetModStatus(1);
+ result:=1;
+
+ ReadOptions;
+ RegisterIcons;
+
+ FillChar(mi, sizeof(mi), 0);
+ mi.cbSize :=sizeof(mi);
+ mi.szPopupName.a:=PluginShort;
+ mi.flags :=CMIF_NOTOFFLINE or CMIF_NOTOFFLIST;
+// mi.popupPosition:=MenuUserInfoPos;
+ mi.hIcon :=CallService(MS_SKIN2_GETICON,0,lparam(IcoBtnContext));
+ mi.szName.a :='Get user''s Music Info';
+ mi.pszService :=MS_WAT_GETCONTACTINFO;
+ hContactMenuItem:=Menu_AddContactMenuItem(@mi);
+
+ SetProtocol;
+ RegisterContacts;
+ hGCI:=CreateServiceFunction(MS_WAT_GETCONTACTINFO,@SendRequest);
+ contexthook :=HookEvent(ME_CLIST_PREBUILDCONTACTMENU,@OnContactMenu);
+ hAddUserHook:=HookEvent(ME_DB_CONTACT_ADDED ,@HookAddUser);
+end;
+
+procedure DeInitProc(aSetDisable:boolean);
+begin
+ if aSetDisable then
+ SetModStatus(0);
+
+ UnhookEvent(hAddUserHook);
+ UnhookEvent(contexthook);
+ UnhookEvent(icchangedhook);
+
+ DestroyServiceFunction(hSRM);
+ DestroyServiceFunction(hGCI);
+ mFreeMem(ProtoText);
+end;
+
+function AddOptionsPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+begin
+ tmpl:='MISC';
+ proc:=@DlgProcOptions;
+ name:='Misc';
+ result:=0;
+end;
+
+var
+ vproto:twModule;
+
+procedure Init;
+begin
+ vproto.Next :=ModuleLink;
+ vproto.Init :=@InitProc;
+ vproto.DeInit :=@DeInitProc;
+ vproto.AddOption :=@AddOptionsPage;
+ vproto.ModuleName:='Protocol';
+ ModuleLink :=@vproto;
+end;
+
+begin
+ Init;
+end.
diff --git a/plugins/Watrack/proto/proto.rc b/plugins/Watrack/proto/proto.rc
new file mode 100644
index 0000000000..dcf5be2faa
--- /dev/null
+++ b/plugins/Watrack/proto/proto.rc
@@ -0,0 +1,36 @@
+#include "i_proto_rc.inc"
+
+LANGUAGE 0,0
+
+MISC DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CONTROL "",IDC_SHARE, "CListControl", WS_TABSTOP | 0x3CA, 4, 4, 144, 180, WS_EX_CLIENTEDGE
+
+ CTEXT "Save events in database",-1, 154, 4, 144, 12, SS_CENTERIMAGE
+ LTEXT "Input" ,-1, 154, 16, 70, 12, SS_CENTERIMAGE
+ RTEXT "Output" ,-1, 226, 16, 70, 12, SS_CENTERIMAGE
+
+ CTEXT "Music Info Request",-1, 170, 30, 112, 14, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_IN_REQUEST , 154, 30, 14, 14, BS_VCENTER | BS_NOTIFY
+ AUTOCHECKBOX "", IDC_OUT_REQUEST , 284, 30, 14, 14, BS_VCENTER | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+
+ CTEXT "Music Info" ,-1, 170, 44, 112, 14, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_IN_INFO , 154, 44, 14, 14, BS_VCENTER | BS_NOTIFY
+ AUTOCHECKBOX "", IDC_OUT_INFO , 284, 44, 14, 14, BS_VCENTER | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+
+ CTEXT "Request Error" ,-1, 170, 58, 112, 14, SS_CENTERIMAGE
+ AUTOCHECKBOX "", IDC_IN_ERROR , 154, 58, 14, 14, BS_VCENTER | BS_NOTIFY
+ AUTOCHECKBOX "", IDC_OUT_ERROR , 284, 58, 14, 14, BS_VCENTER | BS_NOTIFY | BS_RIGHT | BS_LEFTTEXT
+
+ AUTOCHECKBOX "Save ignored requests" , IDC_IREQUEST, 154, 76, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+ AUTOCHECKBOX "Answer to ignored requests", IDC_ISEND , 154, 90, 144, 14, BS_VCENTER | BS_MULTILINE | BS_NOTIFY
+
+ RTEXT "User music info text", -1, 154, 154, 142, 10
+ RTEXT "(%artist%, %title%, %album% and %year% macros can be used only)", -1, 154, 164, 142, 22
+ EDITTEXT IDC_PROTO_TEXT, 4, 186, 296, 36, ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
+}
+
+BTN_CONTEXT ICON "wat_context.ico"
diff --git a/plugins/Watrack/proto/proto.res b/plugins/Watrack/proto/proto.res
new file mode 100644
index 0000000000..7899ef50cc
--- /dev/null
+++ b/plugins/Watrack/proto/proto.res
Binary files differ
diff --git a/plugins/Watrack/proto/wat_context.ico b/plugins/Watrack/proto/wat_context.ico
new file mode 100644
index 0000000000..37d8413c66
--- /dev/null
+++ b/plugins/Watrack/proto/wat_context.ico
Binary files differ