You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
317 lines
8.2 KiB
Plaintext
317 lines
8.2 KiB
Plaintext
library SEOInclude;
|
|
|
|
uses
|
|
Classes,
|
|
Windows,
|
|
Messages,
|
|
plugin,
|
|
pluginutil,
|
|
Graphics,
|
|
SysUtils,
|
|
FWURLPosition,
|
|
IniFiles,
|
|
CallExec,
|
|
System.AnsiStrings;
|
|
|
|
{$I NoRTTI.inc}
|
|
{$R SEOInclude.res}
|
|
{$R 'icons.res' 'Icons\icons.rc'}
|
|
|
|
type
|
|
TPOSTThread = class(TThread)
|
|
private
|
|
isMsgGot: boolean;
|
|
protected
|
|
procedure Execute; override;
|
|
end;
|
|
|
|
var
|
|
MsgToCheck, MsgCheck, userPath, andrqPath, msg: AnsiString;
|
|
delimpos, uin, flags, vApiVersion, currentUIN: Integer;
|
|
When: TDateTime;
|
|
ini: TIniFile;
|
|
State: boolean = false;
|
|
ressent: pointer;
|
|
|
|
ba: Integer;
|
|
hico: TIcon;
|
|
URLPosition: TFWURLPosition;
|
|
|
|
POST: TPOSTThread;
|
|
|
|
type
|
|
TDynByteArray = array of Byte;
|
|
|
|
TAdvancedInteger = record
|
|
LowPart, HighPart: Integer;
|
|
end;
|
|
|
|
const
|
|
namepl = 'SEO Include 1.1';
|
|
descpl = namepl + ' © Mikanoshi' + #13#10 + 'Îòîáðàæåíèå ßíäåêñ òÈÖ è Google PR äëÿ ñàéòîâ â ÷àòå';
|
|
|
|
function FirstDelimiter(s: RawByteString): Integer;
|
|
var
|
|
spacepos, crpos, lfpos, tabpos: Integer;
|
|
begin
|
|
spacepos := pos(' ', s);
|
|
crpos := pos(#13, s);
|
|
lfpos := pos(#10, s);
|
|
tabpos := pos(#9, s);
|
|
result := 0;
|
|
|
|
if (spacepos > 0) then
|
|
result := spacepos
|
|
else if (crpos > 0) then
|
|
result := crpos
|
|
else if (lfpos > 0) then
|
|
result := lfpos
|
|
else if (tabpos > 0) then
|
|
result := tabpos;
|
|
end;
|
|
|
|
function UTF8CharLength(const c: Byte): Integer;
|
|
begin
|
|
if ((c and $80) = $00) then
|
|
result := 1
|
|
else if ((c and $E0) = $C0) then
|
|
result := 2
|
|
else if ((c and $F0) = $E0) then
|
|
result := 3
|
|
else if ((c and $F8) = $F0) then
|
|
result := 4
|
|
else
|
|
result := -1;
|
|
end;
|
|
|
|
function UTF8IsTrailChar(const c: Byte): boolean;
|
|
begin
|
|
result := ((c and $C0) = $80);
|
|
end;
|
|
|
|
function IsUTF8Memory(AMem: PBYTE; ASize: Int64): boolean;
|
|
var i: Int64;
|
|
c: Integer;
|
|
begin
|
|
result := TRUE;
|
|
|
|
i := 0;
|
|
while (i < ASize) do
|
|
begin
|
|
c := UTF8CharLength(AMem^);
|
|
if ((c >= 1) and (c <= 4) and ((i + c - 1) < ASize)) then
|
|
begin
|
|
inc(i, c);
|
|
inc(AMem);
|
|
while (c > 1) do
|
|
begin
|
|
if (not UTF8IsTrailChar(AMem^)) then
|
|
begin
|
|
result := false;
|
|
break;
|
|
end
|
|
else
|
|
begin
|
|
dec(c);
|
|
inc(AMem);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
result := false;
|
|
end;
|
|
|
|
if (not result) then
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function ParseStats(messg: RawByteString): RawByteString;
|
|
var
|
|
msgtmp, msgseo, url, tic, tic_text, pr: RawByteString;
|
|
begin
|
|
msgtmp := messg;
|
|
msgseo := messg;
|
|
delimpos := 0;
|
|
URLPosition := TFWURLPosition.Create;
|
|
if (pos('www.', msgtmp) > 0) or (pos('http://', msgtmp) > 0) then
|
|
try
|
|
repeat
|
|
if (pos('www.', msgtmp) > 0) and (pos('http://', msgtmp) > 0) then
|
|
begin
|
|
if (pos('www.', msgtmp) < pos('http://', msgtmp)) then
|
|
msgtmp := copy(msgtmp, pos('www.', msgtmp), length(msgtmp))
|
|
else
|
|
msgtmp := copy(msgtmp, pos('http://', msgtmp), length(msgtmp));
|
|
end
|
|
else if pos('www.', msgtmp) > 0 then
|
|
msgtmp := copy(msgtmp, pos('www.', msgtmp), length(msgtmp))
|
|
else if (pos('http://', msgtmp) > 0) then
|
|
msgtmp := copy(msgtmp, pos('http://', msgtmp), length(msgtmp));
|
|
|
|
delimpos := FirstDelimiter(msgtmp);
|
|
if delimpos = 0 then
|
|
delimpos := length(msgtmp)
|
|
else
|
|
dec(delimpos);
|
|
|
|
if pos('www.', msgtmp) = 1 then
|
|
begin
|
|
url := copy(msgtmp, pos('www.', msgtmp), delimpos);
|
|
msgtmp := copy(msgtmp, pos('www.', msgtmp) + length(url), length(msgtmp));
|
|
end
|
|
else
|
|
begin
|
|
url := copy(msgtmp, pos('http://', msgtmp), delimpos);
|
|
msgtmp := copy(msgtmp, pos('http://', msgtmp) + length(url), length(msgtmp));
|
|
end;
|
|
|
|
if (url = 'http://') or (url = 'www.') then
|
|
continue
|
|
else
|
|
begin
|
|
URLPosition := TFWURLPosition.Create;
|
|
URLPosition.GetURLPosition(AnsiReplaceStr(url, 'http://', ''), [ucYandex, ucGoogle]);
|
|
if URLPosition.YandexTIC = -1 then
|
|
tic := '?'
|
|
else
|
|
tic := '*' + inttostr(URLPosition.YandexTIC) + '*';
|
|
if URLPosition.GooglePR = -1 then
|
|
pr := '?'
|
|
else
|
|
pr := '*' + inttostr(URLPosition.GooglePR) + '*';
|
|
|
|
tic_text := ' [òÈÖ: ';
|
|
if IsUTF8Memory(PByte(PAnsiChar(msgseo)), length(msgseo)) then
|
|
tic_text := UTF8Encode(' [òÈÖ: ');
|
|
|
|
msgseo := AnsiReplaceStr(msgseo, url, url + tic_text + tic + ' | PR: ' + pr + ']');
|
|
end;
|
|
until ((pos('www.', msgtmp) = 0) and (pos('http://', msgtmp) = 0)) or (url = '');
|
|
finally
|
|
URLPosition.Free;
|
|
end;
|
|
|
|
result := msgseo;
|
|
end;
|
|
|
|
procedure TPOSTThread.Execute;
|
|
begin
|
|
MsgCheck := ParseStats(MsgToCheck);
|
|
if (isMsgGot) then
|
|
ressent := str2comm(char(PM_DATA) + _istring(MsgCheck))
|
|
else
|
|
ressent := str2comm(char(PM_DATA) + _istring(MsgToCheck) + _istring(MsgCheck));
|
|
POST.Terminate;
|
|
end;
|
|
|
|
procedure OnButtonClick(iButton: Integer);
|
|
begin
|
|
case iButton of
|
|
0:
|
|
begin
|
|
ini := TIniFile.Create(RQ_GetUserPath + 'SEOInclude.ini');
|
|
if State = TRUE then
|
|
begin
|
|
State := false;
|
|
hico.Handle := LoadIcon(HInstance, 'SEO_2');
|
|
ini.WriteString('Main', 'State', 'Off');
|
|
end
|
|
else
|
|
begin
|
|
State := TRUE;
|
|
hico.Handle := LoadIcon(HInstance, 'SEO_1');
|
|
ini.WriteString('Main', 'State', 'On');
|
|
end;
|
|
RQ_ChangeChatButton(ba, hico.Handle, namepl);
|
|
ini.Free;
|
|
end;
|
|
1, 2:
|
|
messagebox(0, PWideChar(descpl), 'About', 0);
|
|
end;
|
|
end;
|
|
|
|
function pluginFun(data: pointer): pointer; stdcall;
|
|
begin
|
|
result := NIL;
|
|
if (data = NIL) or (_int_at(data) = 0) then
|
|
Exit;
|
|
case _byte_at(data, 4) of
|
|
PM_EVENT:
|
|
case _byte_at(data, 5) of
|
|
PE_INITIALIZE:
|
|
begin
|
|
RQ__ParseInitString(data, callback, vApiVersion, andrqPath, userPath, currentUIN);
|
|
|
|
hico := TIcon.Create;
|
|
hico.Handle := LoadIcon(HInstance, 'SEO_2');
|
|
if fileexists(RQ_GetUserPath + 'SEOInclude.ini') then
|
|
begin
|
|
ini := TIniFile.Create(RQ_GetUserPath + 'SEOInclude.ini');
|
|
if ini.ReadString('Main', 'State', 'Off') = 'On' then
|
|
begin
|
|
hico.Handle := LoadIcon(HInstance, 'SEO_1');
|
|
State := TRUE;
|
|
end
|
|
else
|
|
begin
|
|
hico.Handle := LoadIcon(HInstance, 'SEO_2');
|
|
State := false;
|
|
end;
|
|
ini.Free;
|
|
end;
|
|
|
|
ba := RQ_CreateChatButton(@OnButtonClick, hico.Handle, namepl);
|
|
result := str2comm(char(PM_DATA) + _istring(namepl) + _int(APIversion));
|
|
end;
|
|
|
|
PE_FINALIZE:
|
|
begin
|
|
if ba <> 0 then
|
|
RQ_DeleteChatButton(ba);
|
|
if hico <> nil then
|
|
hico.Free;
|
|
end;
|
|
|
|
PE_MSG_SENT:
|
|
if State = TRUE then
|
|
begin
|
|
RQ__ParseMsgSentString(data, uin, flags, msg);
|
|
MsgToCheck := msg;
|
|
POST := TPOSTThread.Create(TRUE);
|
|
POST.isMsgGot := false;
|
|
POST.Start;
|
|
case WaitForSingleObject(POST.Handle, INFINITE) of
|
|
WAIT_OBJECT_0:
|
|
result := ressent;
|
|
end;
|
|
POST.Free;
|
|
end;
|
|
|
|
PE_MSG_GOT:
|
|
if State = TRUE then
|
|
begin
|
|
RQ__ParseMsgGotString(data, uin, flags, When, msg);
|
|
MsgToCheck := msg;
|
|
POST := TPOSTThread.Create(TRUE);
|
|
POST.isMsgGot := TRUE;
|
|
POST.Start;
|
|
case WaitForSingleObject(POST.Handle, INFINITE) of
|
|
WAIT_OBJECT_0:
|
|
result := ressent;
|
|
end;
|
|
POST.Free;
|
|
end;
|
|
|
|
PE_PREFERENCES:
|
|
messagebox(0, PWideChar(descpl), 'About', 0);
|
|
|
|
end; // case
|
|
end; // case
|
|
end; // pluginFun
|
|
|
|
exports pluginFun;
|
|
|
|
end.
|