Browse Source

- Предотвращение добавления в базу сообщений с одинаковыми метами времени

- Доп. проверка для предотвращения добавления в базу дубликатов отправляемых сообщений
- Не показывать окно при ошибках скачивания изображений в чате
- ICQ с недавноего времени присылает ссылки на передаваемые файлы, которые не открыть в браузере. В момент скачивания изображений для отображения в чате и в момент нажатия на подобные ссылки R&Q теперь делает доп. запрос на сервер ICQ для получения рабочих ссылок. Также прямые ссылки на изображения на серверах ICQ теперь не отображаются в браузере, а сразу скачиваются.
master
Mikanoshi 1 year ago
parent
commit
b37045f5c2
11 changed files with 85 additions and 53 deletions
  1. +2
    -1
      .gitignore
  2. +6
    -0
      CHANGELOG
  3. BIN
      Distro/template.zip.sample
  4. +7
    -1
      RnQ/ChatBox.pas
  5. +13
    -7
      RnQ/ICQ/ICQSession.pas
  6. +2
    -2
      RnQ/RnQBuiltTime.inc
  7. BIN
      RnQ/RnQx64.res
  8. +9
    -0
      RnQ/SQLiteDB.pas
  9. +1
    -1
      RnQ/globalLib.pas
  10. +6
    -6
      RnQ/utilLib.pas
  11. +39
    -35
      for.RnQ/RnQNet.pas

+ 2
- 1
.gitignore View File

@ -3,4 +3,5 @@ RnQ/Res/template
*.stat
*.dproj.local
*.mes
*.*cfg*
*.*cfg*
*.dsk

+ 6
- 0
CHANGELOG View File

@ -1,3 +1,9 @@
Изменения в сборке 64 beta
- Предотвращение добавления в базу сообщений с одинаковыми метами времени
- Доп. проверка для предотвращения добавления в базу дубликатов отправляемых сообщений
- Не показывать окно при ошибках скачивания изображений в чате
- ICQ с недавноего времени присылает ссылки на передаваемые файлы, которые не открыть в браузере. В момент скачивания изображений для отображения в чате и в момент нажатия на подобные ссылки R&Q теперь делает доп. запрос на сервер ICQ для получения рабочих ссылок. Также прямые ссылки на изображения на серверах ICQ теперь не отображаются в браузере, а сразу скачиваются.
Изменения в сборке 63 beta
- Определение клиента Miranda NG
- Ассоциация и обработка ссылок с icq: протоколом. Примеры:


BIN
Distro/template.zip.sample View File


+ 7
- 1
RnQ/ChatBox.pas View File

@ -3588,7 +3588,7 @@ var
hash: LongWord;
img: TBytes;
png: TPNGImage;
realurl, fn: String;
realurl, fileurl, fn: String;
response: TStringStream;
pic: TPicName;
origPic: TMemoryStream;
@ -3731,6 +3731,12 @@ begin
realurl := copy(url, 6, Length(url));
if StartsText('www.', realurl) then
realurl := 'http://' + realurl;
if ContainsText(realurl, 'files.icq.net/') then
begin
fileurl := GetRealICQFileLink(realurl);
if not (fileurl = '') then
realurl := fileurl;
end;
openURL(realurl);
ignore := True;
end else if StartsText('mailto:', url) then


+ 13
- 7
RnQ/ICQ/ICQSession.pas View File

@ -5130,7 +5130,7 @@ var
procedure ProcessMsg(Msg: TJSONObject);
var
ID: Integer;
ID, Ack: Integer;
MsgID: TMsgID;
ev, evtmp: Thevent;
hist: Thistory;
@ -5140,6 +5140,7 @@ var
SetLength(eventBinData, 0);
eventFlags := 0;
eventData := '';
eventMsgA := '';
eventEncoding := TEncoding.Default;
@ -5156,12 +5157,17 @@ var
if Msg.GetValueSafe('outgoing', outgoing) then
if outgoing then
begin
// Msg.GetValueSafe('reqId', sTmp);
// if TryStrToInt(sTmp, ID) then
// begin
// eventInt := sID;
// NotifyListeners(IE_serverAck);
// end;
Msg.GetValueSafe('reqId', sTmp);
Ack := Account.acks.FindID(sTmp);
if Ack >= 0 then // Still no ack?!
begin
ODS('Outgoing msg is already in history, but without ack');
eventData := sTmp;
eventMsgA := 'delivered';
NotifyListeners(IE_serverAck);
eventData := '';
eventMsgA := '';
end;
end;
hist := Thistory.Create(c.UID2Cmp);


+ 2
- 2
RnQ/RnQBuiltTime.inc View File

@ -1,2 +1,2 @@
{ 28.12.2019 22:34:47 }
BuiltTime = 43827.9408302893;
{ 05.02.2020 1:03:56 }
BuiltTime = 43866.0443988079;

BIN
RnQ/RnQx64.res View File


+ 9
- 0
RnQ/SQLiteDB.pas View File

@ -434,6 +434,15 @@ end;
txt: String;
bin: TBytes;
begin
qry := TFDQuery.Create(sql);
qry.Connection := sql;
qry.SQL.Text := 'SELECT * FROM "' + dbConv + '" WHERE "Chat" = :chat AND "When" = :when; LIMIT 1';
qry.ParamByName('chat').AsString := chat;
qry.ParamByName('when').AsDateTime := ev.when;
if qry.OpenOrExecute and (qry.RecordCount > 0) then
ev.when := IncMillisecond(ev.when);
qry.Free;
qry := TFDQuery.Create(sql);
qry.Connection := sql;


+ 1
- 1
RnQ/globalLib.pas View File

@ -23,7 +23,7 @@ uses
const
RQversion: Longword = $000A01FF; // remember: it's hex
RnQBuild = 1129;
RnQBuildCustom = 63;
RnQBuildCustom = 64;
DevMode = {$IFDEF DEBUG}True{$ELSE}False{$ENDIF};
PIC_CLIENT_LOGO = TPicName('rnq');


+ 6
- 6
RnQ/utilLib.pas View File

@ -183,7 +183,7 @@ type
function StringFromFile(const FileName: TFileName): RawByteString;
function parseMsgImages(const imgStr: RawByteString): TBytes;
procedure getMsgImages(imgs: TBytes; var imgList: TImgBytes);
procedure CacheType(const url, mime, ctype: RawByteString);
procedure CacheType(const url, ctype: RawByteString);
function CacheImage(var mem: TMemoryStream; const url, ext: RawByteString): Boolean;
procedure GetTrans(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
@ -3718,14 +3718,14 @@ begin
end;
end;
procedure CacheType(const url, mime, ctype: RawByteString);
procedure CacheType(const url, ctype: RawByteString);
begin
try
if not (mime = '') then
imgCacheInfo.WriteString(url, 'mime', mime)
else if not (ctype = '') then
if not (ctype = '') then
begin
imgCacheInfo.WriteString(url, 'mime', ctype);
imgCacheInfo.UpdateFile;
imgCacheInfo.UpdateFile;
end;
except end;
end;


+ 39
- 35
for.RnQ/RnQNet.pas View File

@ -135,6 +135,7 @@ const
function UploadFileMikanoshi(FileStream: TStream; const FileName: String; UploadCallbacks: TCallbacks): String;
function UploadFileRnQ(FileStream: TStream; const FileName: String; UploadCallbacks: TCallbacks): String;
function CreateZip(str: TStringList): TMemoryStream;
function GetRealICQFileLink(lnk: String): String;
function CheckType(const lnk: String): Boolean; overload;
function CheckType(const lnk: String; var sA: RawByteString; var ext: String): Boolean; overload;
function DownloadAndCache(const lnk: String): Boolean;
@ -735,6 +736,8 @@ var
httpCli: TSslHttpCli;
begin
Result := '';
if URL = '' then
Exit;
AvStream := TMemoryStream.Create;
httpCli := TSslHttpCli.Create(nil);
try
@ -975,6 +978,33 @@ begin
Result := UploadFile2MyServer(FileStream, FileName, '---------------MikanoshiServerUpload', 'https://code.highspec.ru/upload.php', UploadCallbacks);
end;
function GetRealICQFileLink(lnk: String): String;
var
JSONObject: TJSONObject;
fileIdStr, imgStr: RawByteString;
buf: TMemoryStream;
fn: String;
begin
Result := '';
fileIdStr := ReplaceText(Trim(lnk), 'files.icq.net/get/', 'files.icq.com/getinfo?file_id=');
fileIdStr := ReplaceText(fileIdStr, 'files.icq.net/files/get?fileId=', 'files.icq.com/getinfo?file_id=');
buf := TMemoryStream.Create;
LoadFromURL(fileIdStr, fn, buf, 0, False, '', False);
SetLength(imgStr, buf.Size);
buf.ReadBuffer(imgStr[1], buf.Size);
buf.Free;
JSONObject := TJSONObject.ParseJSONValue(imgStr) as TJSONObject;
if Assigned(JSONObject) then
try
JSONObject := TJSONObject.ParseJSONValue(TJSONArray(JSONObject.GetValue('file_list')).Items[0].ToJSON) as TJSONObject;
Result := JSONObject.GetValue('dlink').Value;
JSONObject.Free;
except end;
end;
function CheckType(const lnk: String): Boolean;
var
ext: String;
@ -996,15 +1026,14 @@ begin
var
buf: TMemoryStream;
idx: Integer;
ctype: String;
imgStr, mime, fileIdStr: RawByteString;
JSONObject: TJSONObject;
ctype, fn: String;
imgStr: RawByteString;
begin
if EnableVideoLinks and (ContainsText(lnk, 'youtube.com/') or ContainsText(lnk, 'youtu.be/') or ContainsText(lnk, 'vimeo.com/')) then
begin
buf := TMemoryStream.Create;
LoadFromURL(lnk, buf);
LoadFromURL(lnk, fn, buf, 0, False, '', False);
SetLength(imgStr, buf.Size);
buf.ReadBuffer(imgStr[1], buf.Size);
buf.Free;
@ -1013,45 +1042,20 @@ begin
sALocal := copy(imgStr, pos(anchor, imgStr) + length(anchor));
sALocal := copy(sALocal, 1, pos('"', sALocal) - 1);
sALocal := DecodeURL(UnUTF(sALocal));
end
else if ContainsText(lnk, 'files.icq.net/') then
begin
fileIdStr := ReplaceText(Trim(lnk), 'files.icq.net/get/', 'files.icq.com/getinfo?file_id=');
fileIdStr := ReplaceText(fileIdStr, 'files.icq.net/files/get?fileId=', 'files.icq.com/getinfo?file_id=');
buf := TMemoryStream.Create;
LoadFromURL(fileIdStr, buf);
SetLength(imgStr, buf.Size);
buf.ReadBuffer(imgStr[1], buf.Size);
buf.Free;
JSONObject := TJSONObject.ParseJSONValue(imgStr) as TJSONObject;
if Assigned(JSONObject) then
try
JSONObject := TJSONObject.ParseJSONValue(TJSONArray(JSONObject.GetValue('file_list')).Items[0].ToJSON) as TJSONObject;
sALocal := JSONObject.GetValue('dlink').Value + '?no-download=1';
mime := JSONObject.GetValue('mime').Value;
JSONObject.Free;
except end;
end else
end else if ContainsText(lnk, 'files.icq.net/') then
sALocal := GetRealICQFileLink(lnk)
else
sALocal := Trim(lnk);
if not (mime = '') and (pos(';', mime) > 0) then
mime := copy(mime, 1, pos(';', mime) - 1);
ctype := HeaderFromURL(sALocal);
if not (ctype = '') and (pos(';', ctype) > 0) then
ctype := copy(ctype, 1, pos(';', ctype) - 1);
CacheType(lnk, mime, ctype);
if MatchText(mime, ImageContentTypes) or MatchText(ctype, ImageContentTypes) then
CacheType(lnk, ctype);
if MatchText(ctype, ImageContentTypes) then
begin
res := True;
idx := IndexText(mime, ImageContentTypes);
if idx < 0 then
idx := IndexText(ctype, ImageContentTypes);
idx := IndexText(ctype, ImageContentTypes);
if idx >= 0 then
extLocal := ImageExtensions[idx]
else


Loading…
Cancel
Save