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.
RnQ/RnQ/iniLib.pas

1971 lines
62 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit iniLib;
{$I RnQConfig.inc}
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Winapi.Messages, Forms, IniFiles, SciterLib, ICQCommon, SQLiteDB, RnQZip, RQCodes;
{$I NoRTTI.inc}
procedure BeforeWindowsCreation;
procedure AfterWindowsCreation;
procedure ChangeOrAddUser;
procedure StartUser(const UID: TUID = '');
procedure Quit;
procedure QuitFinish;
procedure QuitUser;
procedure ReStart;
procedure ResetCFG;
procedure UpdateProperties;
procedure LoadCFG(zp: TZipFile);
function GetCommonCFG: AnsiString;
procedure LoadCommonCFG;
procedure SaveCommonCFG;
procedure old_LoadMacros(zp: TZipFile);
var
ImgCacheInfo: TMemIniFile;
CacheDir: String;
implementation
uses
Windows, Graphics, Classes, SysUtils, Menus, ShellAPI, Controls, Types, StrUtils, SysConst, SciterApi, ZSTDLib,
RnQDialogs, RnQLangs, RnQNet, RnQTrayLib, RnQGlobal, RnQPrefsLib, RDUtils, RnQMacros, RnQStrings, RnQCrypt, RnQSysUtils,
RQUtil, RDGlobal, RQThemes, RDFileUtil, RnQGraphics32, RnQ_Avatars, RnQTips,
roasterlib, usersDlg,
utilLib, events, HistAllSearch, globalLib, themesLib,
RQlog, pluginLib, outboxLib, uinlistlib,
mainDlg, prefSheet, groupsLib, hook,
{$IFDEF UNICODE}
AnsiStrings,
{$ENDIF UNICODE}
Protocols_All, Protocol_ICQ,
ICQContacts, ICQConsts, ICQSession,
SpellCheck, HiddenForm, CLBox;
var
initOnce: boolean;
uin2Bstarted: TUID;
Previous: HWND;
procedure ResetCFG;
var
i: integer;
begin
rosterTitle := '%uin% %displayed%';
ShowMainBorder := True;
NoBorderWithShadow := True;
ShowUINDelimiter := True;
ResetThemePaths;
UseContactThemes := False;
sendOnEnter := 0;
skipSplash := False;
autoSwitchKL := False;
// resetTheme;
sortBy := SB_event;
FillChar(OnStatusDisable, sizeOf(OnStatusDisable), 0);
if Assigned(Account.AccProto) then
Account.AccProto.ResetPrefs;
EnableIgnoreList := True;
IgnoreList.Clear;
EnableQuietList := False;
QuietList.Clear;
NotInList.Clear;
RecentList.Clear;
connectOnConnection := False;
InitMacroses;
with transparency do
begin
forRoster := False;
forChat := False;
active := 200;
inactive := 86;
chgOnMouse := True;
forTray := False;
tray := 220;
end;
splitX := 100;
splitY := -1;
TempBlinkTime := 8000;
useLastStatus := True;
lastStatusUserSet := byte(SC_UNK);
RnQStartingStatus := -1; // Last used
RnQStartingVisibility := Byte(VI_normal);
quoting.cursorBelow := False;
quoting.width := 300;
quoting.quoteselected := True;
inactivehide := False;
inactivehideTime := 50;
InactiveTrim := False;
HandleICQLinks := False;
focusOnChatPopup := True;
AlertTopMost := False;
CheckUpdate.Betas := False;
CheckUpdate.Enabled := False;
CheckUpdate.Every := 24;
prefHeight := 390;
minOnOff := False;
minOnOffTime := 30;
for i := 0 to byte(High(TRnQCLIconsSet)) do
begin
TO_SHOW_ICON[TRnQCLIconsSet(i)] := True;
SHOW_ICONS_ORDER[i] := TRnQCLIconsSet(i);
end;
TO_SHOW_ICON[CNT_ICON_AVT] := False;
XStatusInTray := False;
SetLength(spamfilter.Quests, 0);
showXStatusMnu := True;
showNewXStatuses := False;
blinkWithStatus := True;
{$IFDEF USE_BALOONS}
showBalloons := True;
{$ELSE USE_BALOONS}
showBalloons := False;
{$ENDIF USE_BALOONS}
usePlugPanel := True;
rosterbarOnTop := True;
optimizeDB := True;
AnimateWindows := True;
blinkSpeed := 5;
userCharSet := -1;
logpref.writehistory := True;
logpref.pkts.onWindow := False;
logpref.pkts.onFile := False;
logpref.pkts.clear := False;
logpref.evts.onWindow := False;
logpref.evts.onFile := False;
logpref.evts.clear := False;
incomingOnAway := False;
showOnlyOnline := False;
OnlOfflInOne := False;
showUnkAsOffline := True;
closeAuthAfterReply := True;
CloseFTWndAuto := False;
autoConsumeEvents := True;
DsblEvnt4ClsdGrp := False;
showStatusOnTabs := True;
indentRoster := True;
collapseGroups := True;
NILdoWith := 0;
ScreenshotFormat := 0;
dontSavePwd := True;
clearPwdOnDSNCT := False;
askPassOnBossKeyOn := False;
MakeBackups := False;
startMinimized := False;
autoReconnect := True;
QuitConfirmation := False;
ShowHintsInCL := True;
ShowHintsInChat := True;
ShowSmartReplies := False;
ShowReactions := True;
closeChatOnSend := True;
ClosePageOnSingle := False;
RelativeTimeInChat := False;
RelativeTimeInChatDays := 7;
RelativeTimeInChatHours := 6;
lockOnStart := False;
autocopyhist := True;
bViewTextWrap := True;
useSmiles := True;
ShowSmileCaption := False;
EnableImgLinksIn := True;
EnableImgLinksOut := True;
LimitMaxChatImgWidth := True;
LimitMaxChatImgHeight := True;
EnableStickers := True;
ChatImageQuality := 0;
PreferredResolution := 0;
EnableVideoLinks := True;
ChatSmoothFontRendering := True;
TrimMsgNewLines := True;
AnimatedScroll := True;
EnableSpellCheck := False;
MaxChatImgWidthVal := 512;
MaxChatImgheightVal := 512;
PreviewResolution := 2;
ServerToUpload := 0;
ChatLoadBuffer := 20;
BarPos := 0;
FilterPos := 2;
MenuDrawExt := True;
showIncomingDlg := False;
autoSizeRoster := False;
autosizeFullRoster := False;
autosizeUp := False;
snapToScreenEdges := False;
ShowDisconnectedDlg := True;
ShowTempConnectErrors := True;
fontstylecodes.enabled := True;
playSounds := True;
SoundReset;
Autoconnect := False;
ShowGroups := True;
ShowEmptyGroups := False;
alwaysOnTop := True;
chatAlwaysOnTop := False;
avatarShowInChat := True;
avatarShowInHint := True;
avatarShowInTray := True;
avatarShowInTaskBar := False;
avatarUsePalette := False;
useSingleClickTray := True;
wheelVelocity := 3;
useDefaultBrowser := True;
browserCmdLine := '';
trayIconGuid := GUID_NULL;
with spamfilter do
begin
ignoreNIL := False;
warn := False;
addToHist := True;
ignoreauthNIL := False; // By Rapid D
UseBot := False;
UseBotFromFile := False;
BotTriesCount := 3;
notNIL := False;
notEmpty := False;
nobadwords := False;
multisend := False;
badwords := '';
uingt := 0;
end;
autoaway.autoexit := True;
autoaway.away := True;
autoaway.na := True;
autoaway.ss := True;
autoaway.boss := True;
autoaway.awayTime := 15 * (10 * 60);
autoaway.naTime := 30 * (10 * 60);
autoaway.setxstatus := True;
autoaway.xstatus := 7;
behaviour[EK_incoming].trig := [BE_tray, BE_sound, BE_tip, BE_history];
behaviour[EK_outgoing].trig := [BE_history, BE_tip];
behaviour[EK_msg].trig := [BE_tray, BE_openchat, BE_save, BE_sound, BE_history, BE_tip, BE_FLASHCHAT];
behaviour[EK_contacts] := behaviour[EK_msg];
behaviour[EK_auth] := behaviour[EK_msg];
behaviour[EK_authDenied] := behaviour[EK_msg];
behaviour[EK_authreq] := behaviour[EK_msg];
behaviour[EK_addedyou] := behaviour[EK_msg];
behaviour[EK_statuschange].trig := [BE_history];
{$IFDEF USE_BALOONS}
behaviour[EK_typingBeg].trig := [BE_tip, BE_BALLOON];
behaviour[EK_typingFin].trig := [BE_tip, BE_BALLOON];
{$ELSE not USE_BALOONS}
behaviour[EK_typingBeg].trig := [BE_tip];
behaviour[EK_typingFin].trig := [BE_tip];
{$ENDIF USE_BALOONS}
behaviour[EK_XstatusMsg].trig := [BE_history];
behaviour[EK_buzz].trig := [BE_OPENCHAT, BE_HISTORY, BE_TIP, BE_FLASHCHAT, BE_SOUND];
for i := 1 to EK_last do
begin
behaviour[i].tiptimes := False;
behaviour[i].tiptime := 50;
behaviour[i].tiptimeplus := 50;
end;
behaviour[EK_msg].tiptimes := True;
behaviour[EK_msg].tiptime := 1;
behaviour[EK_typingBeg].tiptime := 20;
behaviour[EK_typingFin].tiptime := 20;
TipsMaxCnt := 20;
TipsBtwSpace := 2;
TipsAlign := alBottomRight;
TipVerIndent := 0;
TipHorIndent := 0;
TipsMaxAvtSizeUse := True;
TipsMaxAvtSize := 100;
FreeAndNil(spellLanguages);
spellLanguages := TStringList.Create;
spellLanguages.Delimiter := ',';
spellLanguages.StrictDelimiter := True;
spellLanguageMain := '';
spellErrorColor := clRed;
spellErrorStyle := 0;
end;
procedure UpdateProperties;
var
pp: TRnQPref;
sU: String;
i: integer;
MyInf, StartInf: TICQContact;
mainRect: TRect;
WinRect: TRect;
begin
pp := MainPrefs;
pp.addPrefBool('sqlite-config', True);
if Assigned(Account.AccProto) and not (Account.AccProto.MyAccNum = '') then
begin
MyInf := Account.AccProto.GetMyInfo;
StartInf := Account.AccProto.GetStartInfo;
if Assigned(StartInf) then
MainPrefs.addPrefStr('account-id', StartInf.UID)
else if Assigned(MyInf) then
MainPrefs.addPrefStr('account-id', MyInf.UID);
if Assigned(MyInf) then
MainPrefs.addPrefStr('account-name', MyInf.Displayed);
end;
pp.addPrefInt('version', RnQBuild);
pp.DeletePref('history-crypt-enabled');
pp.DeletePref('history-crypt-save-password');
pp.DeletePref('history-crypt-password');
pp.DeletePref('history-crypt-password64');
for i := 1 to EK_last do
begin
sU := String(event2str[i]) + '-behaviour';
pp.addPrefStr(sU, beh2str(i));
end;
if Assigned(UI.CL) then
mainRect := UI.CL.GetBounds
else
mainRect := Rect(0, 0, 0, 0);
WinRect := screen.DesktopRect;
sU := '-' + IntToStr(WinRect.Width) + 'x' + IntToStr(WinRect.Height);
pp.addPrefInt('window-top' + sU, mainRect.Top);
pp.addPrefInt('window-height' + sU, mainRect.Height);
pp.addPrefInt('window-left' + sU, mainRect.Left);
pp.addPrefInt('window-width' + sU, mainRect.Width);
pp.addPrefInt('window-top', mainRect.Top);
pp.addPrefInt('window-height', mainRect.Height);
pp.addPrefInt('window-left', mainRect.Left);
pp.addPrefInt('window-width', mainRect.Width);
pp.addPrefInt('chat-top', ChatXY.Top);
pp.addPrefInt('chat-height', ChatXY.Height);
pp.addPrefInt('chat-left', ChatXY.Left);
pp.addPrefInt('chat-width', ChatXY.Width);
pp.addPrefBool('chat-maximized', ChatXY.Maximized);
pp.addPrefInt('search-top', SearchXY.Top);
pp.addPrefInt('search-height', SearchXY.Height);
pp.addPrefInt('search-left', SearchXY.Left);
pp.addPrefInt('search-width', SearchXY.Width);
pp.addPrefBool('search-maximized', SearchXY.Maximized);
pp.addPrefInt('settings-top', PrefsXY.Top);
pp.addPrefInt('settings-height', PrefsXY.Height);
pp.addPrefInt('settings-left', PrefsXY.Left);
pp.addPrefInt('settings-width', PrefsXY.Width);
pp.addPrefBool('settings-maximized', PrefsXY.maximized);
pp.addPrefBool('transparency', transparency.forRoster);
pp.addPrefBool('transparency-chat', transparency.forChat);
pp.addPrefBool('transparency-tray', transparency.forTray);
pp.addPrefBool('transparency-chgonmouse', transparency.chgOnMouse);
pp.addPrefInt('transparency-active', transparency.active);
pp.addPrefInt('transparency-inactive', transparency.inactive);
pp.addPrefInt('transparency-vtray', transparency.tray);
pp.addPrefStr('proxy-name', MainProxy.name);
pp.addPrefStr('proxy-host', MainProxy.addr.host);
pp.addPrefInt('proxy-port', MainProxy.addr.port);
pp.addPrefBool('proxy-auth', MainProxy.auth);
pp.addPrefStr('proxy-user', MainProxy.user);
pp.addPrefBlob64('proxy-pass64', PassCrypt(UTF(MainProxy.pwd)));
pp.addPrefBool('proxy-NTLM', MainProxy.NTLM);
pp.addPrefStr('proxy-proto', proxyproto2str[MainProxy.proto]);
pp.addPrefBool('auto-size', autoSizeRoster);
pp.addPrefBool('auto-size-full', autosizeFullRoster);
pp.addPrefBool('auto-size-up', autosizeUp);
pp.addPrefBool('snap-to-screen-edges', snapToScreenEdges);
pp.addPrefBool('reopen-chats-on-start', reopenchats);
pp.addPrefBool('skip-splash', skipSplash);
pp.addPrefBool('optimize-database', optimizeDB);
pp.addPrefBool('start-minimized', startMinimized);
pp.addPrefBool('auto-reconnect', autoReconnect);
pp.addPrefBool('use-last-status', useLastStatus);
pp.addPrefBool('close-auth-after-reply', closeAuthAfterReply);
pp.addPrefBool('close-ft-after-end', CloseFTWndAuto);
pp.addPrefBool('inactive-hide', inactivehide);
pp.addPrefBool('inactive-trim', InactiveTrim);
pp.addPrefBool('check-betas', checkupdate.betas);
pp.addPrefBool('roaster-bar-on-top', rosterbarOnTop);
pp.addPrefBool('filter-bar-on-top', filterbarOnTop);
pp.addPrefBool('handle-icq-links', HandleICQLinks);
pp.addPrefBool('dont-save-password', dontSavePwd);
pp.addPrefBool('clear-password-on-disconnect', clearPwdOnDSNCT);
pp.addPrefBool('ask-password-after-bossmode', askPassOnBossKeyOn);
pp.addPrefBool('make-bakups-on-save', MakeBackups);
pp.addPrefBool('oncoming-on-away', incomingOnAway);
pp.addPrefTime('last-update-check-time', checkupdate.last);
pp.addPrefInt('wheel-velocity', wheelVelocity);
pp.addPrefInt('inactive-hide-time', inactivehideTime);
pp.addPrefBool('auto-connect', autoconnect);
pp.addPrefBool('connect-on-connection', connectOnConnection);
pp.addPrefBool('quit-confirmation', QuitConfirmation);
pp.addPrefBool('min-on-off', minOnOff);
pp.addPrefInt('min-on-off-time', minOnOffTime);
pp.addPrefInt('sound-volume', Soundvolume);
pp.addPrefBool('play-sounds', playSounds);
pp.addPrefBool('lock-on-start', lockOnStart);
pp.addPrefBool('auto-check-update', checkupdate.enabled);
pp.addPrefBool('show-only-online-contacts', showOnlyOnline);
pp.addPrefBool('show-all-contacts-in-one', OnlOfflInOne);
pp.addPrefBool('show-unk-as-offline', showUnkAsOffline);
pp.addPrefBool('show-oncoming-dialog', showIncomingDlg);
pp.addPrefBool('always-on-top', alwaysOnTop);
pp.addPrefBool('chat-always-on-top', chatAlwaysOnTop);
pp.addPrefBool('chat-show-avatars-chat', avatarShowInChat);
pp.addPrefBool('chat-show-avatars-hint', avatarShowInHint);
pp.addPrefBool('chat-show-avatars-tray', avatarShowInTray);
pp.addPrefBool('chat-show-avatars-taskbar', avatarShowInTaskBar);
pp.addPrefBool('chat-use-avatar-palette', avatarUsePalette);
pp.addPrefBool('use-single-click-tray', useSingleClickTray);
pp.addPrefInt('split-x', splitX);
pp.addPrefInt('split-y', splitY);
pp.addPrefInt('blink-speed', blinkSpeed);
// pp.addPrefInt('temp-blink-time', tempBlinkTime);
pp.addPrefInt('show-tips-count', TipsMaxCnt);
pp.addPrefInt('show-tips-align', byte(TipsAlign));
pp.addPrefInt('show-tips-btw-space', TipsBtwSpace);
pp.addPrefInt('show-tips-ver-indent', TipVerIndent);
pp.addPrefInt('show-tips-hor-indent', TipHorIndent);
pp.addPrefBool('show-tips-use-avt-size', TipsMaxAvtSizeUse);
pp.addPrefInt('show-tips-avt-size', TipsMaxAvtSize);
pp.addPrefInt('not-in-list-do', NILdoWith);
pp.addPrefBool('animate-windows', AnimateWindows);
pp.addPrefBool('show-groups', ShowGroups);
pp.addPrefBool('show-empty-groups', ShowEmptyGroups);
for i := 0 to byte(High(TRnQCLIconsSet)) do
if TRnQCLIconsSet(i) <> CNT_TEXT then
pp.addPrefBool(RnQCLIcons[TRnQCLIconsSet(i)].PrefText, TO_SHOW_ICON[TRnQCLIconsSet(i)]);
pp.addPrefStr('show-cl-icons-order', ICON_ORDER_PREF);
pp.addPrefBool('show-xstatus-in-menu-flag', showXStatusMnu);
pp.addPrefBool('show-new-xstatuses', showNewXStatuses);
pp.addPrefBool('show-balloons-flag', showBalloons);
pp.addPrefBool('use-plugin-panel', usePlugPanel);
pp.addPrefBool('use-smiles', useSmiles);
pp.addPrefBool('smiles-captions', ShowSmileCaption);
pp.addPrefBool('menu-draw-ext', MenuDrawExt);
pp.addPrefInt('send-on-enter', sendOnEnter);
pp.addPrefBool('chat-parse-image-links-in', EnableImgLinksIn);
pp.addPrefBool('chat-parse-image-links-out', EnableImgLinksOut);
pp.addPrefBool('chat-images-limit-width', LimitMaxChatImgWidth);
pp.addPrefBool('chat-images-limit-height', LimitMaxChatImgHeight);
pp.addPrefInt('chat-images-width-value', MaxChatImgWidthVal);
pp.addPrefInt('chat-images-height-value', MaxChatImgheightVal);
pp.addPrefInt('chat-images-resample-preset', ChatImageQuality);
pp.addPrefInt('chat-video-preferred-resolution', PreferredResolution);
pp.addPrefBool('chat-video-links-thumbnails', EnableVideoLinks);
pp.addPrefBool('chat-font-rendering', ChatSmoothFontRendering);
pp.addPrefBool('chat-trim-newlines', TrimMsgNewLines);
pp.addPrefBool('chat-animated-scroll', AnimatedScroll);
pp.addPrefBool('chat-spellcheck', EnableSpellCheck);
pp.addPrefBool('chat-images-enable-stickers', EnableStickers);
pp.addPrefInt('chat-images-preview-size', PreviewResolution);
pp.addPrefInt('file-transfer-upload-server', ServerToUpload);
pp.addPrefStr('disabled-plugins', disabledPlugins);
pp.addPrefBool('show-status-on-tabs', showStatusOnTabs);
pp.addPrefBool('single-message-by-default', singledefault);
pp.addPrefBool('auto-copy', autocopyhist);
pp.addPrefBool('hist-msg-view-wrap', bViewTextWrap);
pp.addPrefBool('indent-contact-list', indentRoster);
pp.addPrefBool('collapse-some-groups', collapseGroups);
pp.addPrefBool('auto-consume-events', autoConsumeEvents);
pp.addPrefBool('disable-events-on-closed-groups', DsblEvnt4ClsdGrp);
pp.addPrefBool('show-disconnected-dialog', ShowDisconnectedDlg);
pp.addPrefBool('show-temporary-connection-errors', ShowTempConnectErrors);
pp.addPrefBool('focus-on-chat-popup', focusOnChatPopup);
pp.addPrefBool('bring-info-frgd', AlertTopMost);
pp.addPrefBool('enable-ignore-list', enableIgnoreList);
pp.addPrefBool('enable-quiet-list', enableQuietlist);
pp.addPrefBool('use-contacts-themes', UseContactThemes);
pp.addPrefInt('preferences-height', prefHeight);
pp.addPrefBool('autoaway-exit', autoaway.autoexit);
pp.addPrefBool('autoaway-away', autoaway.away);
pp.addPrefInt('autoaway-away-time', autoaway.awayTime);
pp.addPrefBool('autoaway-na', autoaway.na);
pp.addPrefBool('autoaway-ss', autoaway.ss);
pp.addPrefBool('autoaway-boss', autoaway.boss);
pp.addPrefInt('autoaway-na-time', autoaway.naTime);
pp.addPrefBool('autoaway-set-xstatus', autoaway.setxstatus);
pp.addPrefInt('autoaway-xstatus', autoaway.xstatus);
pp.addPrefBool('ignore-not-in-list', spamfilter.ignoreNIL);
pp.addPrefBool('ignore-authreq-notinlist', spamfilter.ignoreauthNIL);
pp.addPrefBool('spam-ignore-not-in-list', spamfilter.notNIL);
pp.addPrefBool('spam-ignore-empty-history', spamfilter.notEmpty);
pp.addPrefBool('spam-ignore-bad-words', spamfilter.nobadwords);
pp.addPrefBool('spam-ignore-multisend', spamfilter.multisend);
pp.addPrefBool('spam-warn', spamfilter.warn);
pp.addPrefBool('spam-add-history', spamfilter.addToHist);
pp.addPrefInt('spam-uin-greater-than', spamfilter.uingt);
pp.addPrefBool('spam-use-bot', spamfilter.useBot);
pp.addPrefBool('spam-use-bot-file', spamfilter.UseBotFromFile);
pp.addPrefInt('spam-bot-tries', spamfilter.BotTriesCount);
pp.addPrefBool('cl-hints-show', ShowHintsInCL);
pp.addPrefBool('chat-hints-show', ShowHintsInChat);
pp.addPrefBool('chat-smart-replies', ShowSmartReplies);
pp.addPrefBool('chat-message-reactions', ShowReactions);
pp.addPrefBool('chat-close-on-send', closeChatOnSend);
pp.addPrefBool('chat-close-page-on-single', ClosePageOnSingle);
pp.addPrefBool('chat-relative-time', RelativeTimeInChat);
pp.addPrefInt('chat-relative-time-days', RelativeTimeInChatDays);
pp.addPrefInt('chat-relative-time-hours', RelativeTimeInChatHours);
pp.addPrefInt('chat-load-buffer', ChatLoadBuffer);
pp.addPrefInt('cl-bar-position', BarPos);
pp.addPrefInt('cl-filter-position', FilterPos);
pp.addPrefBool('use-default-browser', useDefaultBrowser);
pp.addPrefStr('browser-command-line', browserCmdLine);
pp.addPrefGuid('tray-icon-guid', trayIconGuid);
pp.addPrefStr('sort-by', sortby2str[sortBy]);
pp.addPrefBool('xstatus-in-tray', XStatusInTray);
pp.addPrefBool('blink-with-status', blinkWithStatus);
pp.addPrefBool('log-events-file', logpref.evts.onFile);
pp.addPrefBool('log-events-window', logpref.evts.onWindow);
pp.addPrefBool('log-events-clear', logpref.evts.clear);
pp.addPrefBool('log-packets-file', logpref.pkts.onFile);
pp.addPrefBool('log-packets-window', logpref.pkts.onWindow);
pp.addPrefBool('log-packets-clear', logpref.pkts.clear);
pp.addPrefBool('font-style-codes', fontstylecodes.enabled);
pp.addPrefBool('write-history', logpref.writehistory);
pp.addPrefBool('quote-selected', quoting.quoteselected);
pp.addPrefInt('quoting-width', quoting.width);
pp.addPrefBool('quoting-cursor-below', quoting.cursorBelow);
pp.addPrefBool('show-main-border', ShowMainBorder);
pp.addPrefBool('no-border-with-shadow', NoBorderWithShadow);
pp.addPrefBool('show-uin-delimiter', ShowUINDelimiter);
pp.addPrefBool('auto-switch-keyboard-layout', autoSwitchKL);
pp.addPrefStr('roaster-title', rosterTitle);
pp.addPrefStr('spam-bad-words', spamfilter.badwords);
pp.addPrefStr('theme', theme.ThemePath.fn);
pp.addPrefStr('theme-sub', theme.ThemePath.subfn);
pp.addPrefStr('theme-smiles', RQSmilesPath.fn);
pp.addPrefStr('theme-smiles-sub', RQSmilesPath.subfn);
pp.addPrefStr('theme-emojis', RQEmojisPath.fn);
pp.addPrefStr('theme-emojis-sub', RQEmojisPath.subfn);
pp.addPrefStr('theme-sounds', RQSoundsPath.fn);
pp.addPrefStr('theme-sounds-sub', RQSoundsPath.subfn);
pp.addPrefStrList('spellcheck-languages', spellLanguages);
pp.addPrefStr('spellcheck-language-main', spellLanguageMain);
pp.addPrefStr('spellcheck-error-color', ColorToString(spellErrorColor));
pp.addPrefInt('spellcheck-error-style', spellErrorStyle);
pp.addPrefStr('custom-css-main', MainCSS);
pp.addPrefStr('custom-css-chat', ChatCSS);
if Assigned(Account.AccProto) then
Account.AccProto.GetPrefs(pp);
plugins.castEv(PE_PROPERTIES_CHANGED);
end;
procedure SetCommonCfg(cfg: RawByteString);
var
l, h, v: RawByteString;
function yesno: boolean;
begin
Result := l = 'yes'
end;
function int: integer;
var
bb: integer;
begin
Val(l, Result, bb);
if bb <> 0 then
Result := 0;
end;
begin
if cfg = '' then
exit;
while cfg > '' do
begin
l := chop(CRLF, cfg);
h := LowerCase(Trim(chop(AnsiString('='), l)));
v := Trim(l);
l := LowerCase(v);
try
if h = 'auto-start-uin' then
autostartUIN := UnUTF(l)
else if h = 'last-user' then
lastUser := UnUTF(l)
else if h = 'users-path' then
usersPath := UnUTF(v)
else if h = 'main-path' then
RnQMainPath := UnUTF(v)
else if h = 'langs-filename' then
gLangFile := UnUTF(v)
else if h = 'langs-sub-filename' then
gLangSubFile := UnUTF(v);
except
end
end;
end;
function GetCommonCFG: AnsiString;
begin
Result :=
'auto-start-uin=' + UTF(autostartUIN) + CRLF +
'users-path=' + UTF(usersPath) + CRLF +
'main-path=' + UTF(RnQMainPath) + CRLF +
'last-user=' + UTF(lastUser) + CRLF +
'langs-filename=' + UTF(gLangFile) + CRLF +
'langs-sub-filename=' + UTF(gLangSubFile) + CRLF;
end;
procedure ResetCommonCFG;
begin
autostartUIN := '';
lastUser := '';
usersPath := cmdLinePar.userPath;
RnQMainPath := cmdLinePar.mainPath;
gLangFile := '';
gLangSubFile := '';
end;
procedure SetCFG(pp: TRnQPref);
begin
pp.getPrefBool('start-minimized', StartMinimized);
end;
procedure SetCFGFromDB(pp: TRnQPref);
var
I: Integer;
L, sU, sR: String;
WinRect: TRect;
FormPos: TFormDimen;
begin
// lastVersion:=0;
pp.getPrefStr('theme', theme.ThemePath.fn);
pp.getPrefStr('theme-sub', theme.ThemePath.subfn);
pp.getPrefStr('theme-smiles', RQSmilesPath.fn);
pp.getPrefStr('theme-smiles-sub', RQSmilesPath.subfn);
pp.getPrefStr('theme-emojis', RQEmojisPath.fn);
pp.getPrefStr('theme-emojis-sub', RQEmojisPath.subfn);
pp.getPrefStr('theme-sounds', RQSoundsPath.fn);
pp.getPrefStr('theme-sounds-sub', RQSoundsPath.subfn);
pp.getPrefBool('use-contacts-themes', UseContactThemes);
pp.getPrefStr('roaster-title', rosterTitle);
pp.getPrefBool('show-main-border', ShowMainBorder);
pp.getPrefBool('no-border-with-shadow', NoBorderWithShadow);
pp.getPrefBool('show-uin-delimiter', ShowUINDelimiter);
pp.getPrefBool('optimize-database', optimizeDB);
pp.getPrefBool('reopen-chats-on-start', reopenchats);
pp.getPrefBool('connect-on-connection', connectOnConnection);
pp.getPrefBool('use-default-browser', useDefaultBrowser);
pp.getPrefStr('browser-command-line', browserCmdLine);
pp.getPrefGuid('tray-icon-guid', trayIconGuid);
pp.getPrefStr('disabled-plugins', disabledPlugins);
pp.getPrefInt('wheel-velocity', wheelVelocity);
pp.getPrefInt('split-x', splitX);
pp.getPrefInt('split-y', splitY);
pp.getPrefBool('auto-switch-keyboard-layout', autoSwitchKL);
pp.getPrefDateTime('last-update-check-time', checkupdate.last);
pp.getPrefBool('skip-splash', skipSplash);
pp.getPrefBool('auto-reconnect', autoReconnect);
pp.getPrefBool('auto-check-update', checkupdate.enabled);
pp.getPrefBool('lock-on-start', lockOnStart);
pp.getPrefBool('cl-hints-show', ShowHintsInCL);
pp.getPrefBool('chat-hints-show', ShowHintsInChat);
pp.getPrefBool('chat-smart-replies', ShowSmartReplies);
pp.getPrefBool('chat-message-reactions', ShowReactions);
pp.getPrefBool('chat-close-on-send', closeChatOnSend);
pp.getPrefBool('chat-close-page-on-single', ClosePageOnSingle);
pp.getPrefBool('chat-relative-time', RelativeTimeInChat);
pp.getPrefInt('chat-relative-time-days', RelativeTimeInChatDays);
pp.getPrefInt('chat-relative-time-hours', RelativeTimeInChatHours);
pp.getPrefInt('chat-load-buffer', ChatLoadBuffer);
pp.getPrefInt('cl-bar-position', BarPos);
pp.getPrefInt('cl-filter-position', FilterPos);
pp.getPrefBool('animate-windows', AnimateWindows);
pp.getPrefBool('inactive-hide', inactivehide);
pp.getPrefBool('inactive-trim', InactiveTrim);
pp.getPrefBool('font-style-codes', fontstylecodes.enabled);
pp.getPrefBool('roaster-bar-on-top', rosterbarOnTop);
pp.getPrefBool('filter-bar-on-top', filterbarOnTop);
pp.getPrefBool('oncoming-on-away', incomingOnAway);
pp.getPrefBool('use-last-status', useLastStatus);
pp.getPrefBool('handle-icq-links', HandleICQLinks);
for i := 1 to EK_last do
begin
sU := event2str[i] + '-behaviour';
sR := beh2str(i);
pp.getPrefStr(sU, sR);
behaviour[i] := str2beh(sR)
end;
pp.getPrefInt('inactive-hide-time', inactivehideTime);
pp.getPrefInt('blink-speed', blinkSpeed);
pp.getPrefBool('dont-save-password', dontSavePwd);
pp.getPrefBool('clear-password-on-disconnect', clearPwdOnDSNCT);
pp.getPrefBool('ask-password-after-bossmode', askPassOnBossKeyOn);
pp.getPrefBool('make-bakups-on-save', MakeBackups);
pp.getPrefBool('always-on-top', alwaysOnTop);
pp.getPrefBool('chat-always-on-top', chatAlwaysOnTop);
pp.getPrefBool('chat-show-avatars-chat', avatarShowInChat);
pp.getPrefBool('chat-show-avatars-hint', avatarShowInHint);
pp.getPrefBool('chat-show-avatars-tray', avatarShowInTray);
pp.getPrefBool('chat-show-avatars-taskbar', avatarShowInTaskBar);
pp.getPrefBool('chat-use-avatar-palette', avatarUsePalette);
pp.getPrefBool('use-single-click-tray', useSingleClickTray);
pp.getPrefBool('check-betas', checkupdate.betas);
pp.getPrefBool('show-groups', ShowGroups);
pp.getPrefBool('show-empty-groups', ShowEmptyGroups);
pp.getPrefInt('show-tips-count', TipsMaxCnt);
TipsAlign := TtipsAlign(byte(pp.getPrefIntDef('show-tips-align', byte(TipsAlign))));
pp.getPrefInt('show-tips-btw-space', TipsBtwSpace);
pp.getPrefInt('show-tips-ver-indent', TipVerIndent);
pp.getPrefInt('show-tips-hor-indent', TipHorIndent);
pp.getPrefBool('show-tips-use-avt-size', TipsMaxAvtSizeUse);
pp.getPrefInt('show-tips-avt-size', TipsMaxAvtSize);
pp.getPrefBool('close-auth-after-reply', closeAuthAfterReply);
pp.getPrefBool('close-ft-after-end', CloseFTWndAuto);
pp.getPrefBool('quoting-cursor-below', quoting.cursorBelow);
pp.getPrefBool('quote-selected', quoting.quoteselected);
pp.getPrefInt('quoting-width', quoting.width);
pp.getPrefBool('quit-confirmation', QuitConfirmation);
pp.getPrefBool('log-events-file', logpref.evts.onFile);
pp.getPrefBool('log-events-window', logpref.evts.onWindow);
pp.getPrefBool('log-events-clear', logpref.evts.clear);
pp.getPrefBool('log-packets-file', logpref.pkts.onFile);
pp.getPrefBool('log-packets-window', logpref.pkts.onWindow);
pp.getPrefBool('log-packets-clear', logpref.pkts.clear);
pp.getPrefBool('write-history', logpref.writehistory);
pp.getPrefBool('indent-contact-list', indentRoster);
pp.getPrefBool('collapse-some-groups', collapseGroups);
pp.getPrefBool('auto-consume-events', autoConsumeEvents);
pp.getPrefBool('disable-events-on-closed-groups', DsblEvnt4ClsdGrp);
pp.getPrefBool('focus-on-chat-popup', focusOnChatPopup);
pp.getPrefBool('bring-info-frgd', AlertTopMost);
pp.getPrefBool('show-status-on-tabs', showStatusOnTabs);
pp.getPrefBool('show-disconnected-dialog', ShowDisconnectedDlg);
pp.getPrefBool('show-temporary-connection-errors', ShowTempConnectErrors);
pp.getPrefBool('use-smiles', useSmiles);
pp.getPrefBool('smiles-captions', ShowSmileCaption);
pp.getPrefBool('chat-parse-image-links-in', EnableImgLinksIn);
pp.getPrefBool('chat-parse-image-links-out', EnableImgLinksOut);
pp.getPrefBool('chat-images-limit-width', LimitMaxChatImgWidth);
pp.getPrefBool('chat-images-limit-height', LimitMaxChatImgHeight);
pp.getPrefInt('chat-images-width-value', MaxChatImgWidthVal);
pp.getPrefInt('chat-images-height-value', MaxChatImgheightVal);
pp.getPrefInt('chat-images-resample-preset', ChatImageQuality);
pp.getPrefInt('chat-video-preferred-resolution', PreferredResolution);
pp.getPrefBool('chat-video-links-thumbnails', EnableVideoLinks);
pp.getPrefBool('chat-font-rendering', ChatSmoothFontRendering);
pp.getPrefBool('chat-trim-newlines', TrimMsgNewLines);
pp.getPrefBool('chat-animated-scroll', AnimatedScroll);
pp.getPrefBool('chat-spellcheck', EnableSpellCheck);
pp.getPrefBool('chat-images-enable-stickers', EnableStickers);
pp.getPrefInt('chat-images-preview-size', PreviewResolution);
pp.getPrefInt('file-transfer-upload-server', ServerToUpload);
pp.getPrefBool('menu-draw-ext', MenuDrawExt);
NILdoWith := pp.getPrefIntDef('not-in-list-do', 0);
pp.getPrefBool('auto-copy', autocopyhist);
pp.getPrefBool('hist-msg-view-wrap', bViewTextWrap);
for i := 0 to byte(High(TRnQCLIconsSet)) do
if TRnQCLIconsSet(i) <> CNT_TEXT then
pp.getPrefBool(RnQCLIcons[TRnQCLIconsSet(i)].PrefText, TO_SHOW_ICON[TRnQCLIconsSet(i)]);
pp.getPrefStr('show-cl-icons-order', sR);
ICON_ORDER_PREF_parse(sR);
pp.getPrefBool('show-xstatus-in-menu-flag', showXStatusMnu);
pp.getPrefBool('show-new-xstatuses', showNewXStatuses);
pp.getPrefBool('show-balloons-flag', showBalloons);
pp.getPrefBool('use-plugin-panel', usePlugPanel);
pp.getPrefBool('single-message-by-default', singledefault);
pp.getPrefBool('show-oncoming-dialog', showIncomingDlg);
pp.getPrefBool('min-on-off', minOnOff);
pp.getPrefInt('min-on-off-time', minOnOffTime);
pp.getPrefBool('enable-ignore-list', enableIgnoreList);
pp.getPrefBool('enable-quiet-list', enableQuietlist);
pp.getPrefBool('ignore-not-in-list', spamfilter.ignoreNIL);
pp.getPrefBool('ignore-authreq-notinlist', spamfilter.ignoreauthNIL);
pp.getPrefBool('spam-warn', spamfilter.warn);
pp.getPrefBool('spam-add-history', spamfilter.addToHist);
pp.getPrefBool('spam-ignore-not-in-list', spamfilter.notNIL);
pp.getPrefBool('spam-ignore-empty-history', spamfilter.notEmpty);
pp.getPrefBool('spam-ignore-bad-words', spamfilter.nobadwords);
pp.getPrefBool('spam-ignore-multisend', spamfilter.multisend);
spamfilter.badwords := ansiReplaceStr(pp.getPrefStrDef('spam-bad-words'), CRLF, AnsiChar(';'));
pp.getPrefInt('spam-uin-greater-than', spamfilter.uingt);
pp.getPrefBool('spam-use-bot', spamfilter.useBot);
pp.getPrefBool('spam-use-bot-file', spamfilter.UseBotFromFile);
pp.getPrefInt('spam-bot-tries', spamfilter.BotTriesCount);
boundInt(spamfilter.BotTriesCount, 2, 6);
WinRect := screen.DesktopRect;
sU := '-' + IntToStr(WinRect.Width) + 'x' + IntToStr(WinRect.Height);
FormPos.Top := pp.getPrefIntDef('window-top' + sU);
FormPos.Left := pp.getPrefIntDef('window-left' + sU);
FormPos.Width := pp.getPrefIntDef('window-width' + sU);
FormPos.Height := pp.getPrefIntDef('window-height' + sU);
WinRect := UI.CL.GetBounds;
if (FormPos.Top = -1) or (FormPos.Left = -1) then
begin
FormPos.Top := pp.getPrefIntDef('window-top', WinRect.Top);
FormPos.Left := pp.getPrefIntDef('window-left', WinRect.Left);
end;
if (FormPos.Width = -1) or (FormPos.Height = -1) then
begin
FormPos.Width := pp.getPrefIntDef('window-width', WinRect.Width);
FormPos.Height := pp.getPrefIntDef('window-height', WinRect.Height);
end;
UI.CL.SetBounds(FormPos);
UI.CL.SavePositionForCurrentMonitorCount;
pp.getPrefBool('auto-size-up', autosizeUp);
pp.getPrefBool('auto-size', autoSizeRoster);
pp.getPrefBool('auto-size-full', autosizeFullRoster);
pp.getPrefBool('snap-to-screen-edges', snapToScreenEdges);
pp.getPrefInt('preferences-height', prefHeight);
pp.getPrefInt('chat-top', ChatXY.Top);
pp.getPrefInt('chat-height', ChatXY.Height);
pp.getPrefInt('chat-left', ChatXY.Left);
pp.getPrefInt('chat-width', ChatXY.Width);
pp.getPrefBool('chat-maximized', ChatXY.Maximized);
pp.getPrefInt('search-top', SearchXY.Top);
pp.getPrefInt('search-height', SearchXY.Height);
pp.getPrefInt('search-left', SearchXY.Left);
pp.getPrefInt('search-width', SearchXY.Width);
pp.getPrefBool('search-maximized', SearchXY.Maximized);
pp.getPrefInt('settings-top', PrefsXY.Top);
pp.getPrefInt('settings-height', PrefsXY.Height);
pp.getPrefInt('settings-left', PrefsXY.Left);
pp.getPrefInt('settings-width', PrefsXY.Width);
pp.getPrefBool('settings-maximized', PrefsXY.Maximized);
pp.getPrefBool('auto-connect', autoconnect);
pp.getPrefBool('play-sounds', playSounds);
pp.getPrefInt('sound-volume', Soundvolume);
pp.getPrefBool('show-only-online-contacts', showOnlyOnline);
pp.getPrefBool('show-all-contacts-in-one', OnlOfflInOne);
pp.getPrefBool('show-unk-as-offline', showUnkAsOffline);
L := pp.getPrefStrDef('sort-by');
sortBy := str2sortby(l);
// pp.getPrefInt('temp-blink-time', tempBlinkTime);
pp.getPrefBool('transparency', transparency.forRoster);
pp.getPrefBool('transparency-chat', transparency.forChat);
pp.getPrefBool('transparency-tray', transparency.forTray);
pp.getPrefBool('transparency-chgonmouse', transparency.chgOnMouse);
pp.getPrefInt('transparency-active', transparency.active);
pp.getPrefInt('transparency-inactive', transparency.inactive);
pp.getPrefInt('transparency-vtray', transparency.tray);
pp.getPrefBool('autoaway-exit', autoaway.autoexit);
pp.getPrefBool('autoaway-away', autoaway.away);
pp.getPrefInt('autoaway-away-time', autoaway.awayTime);
pp.getPrefBool('autoaway-na', autoaway.na);
pp.getPrefInt('autoaway-na-time', autoaway.naTime);
pp.getPrefBool('autoaway-set-xstatus', autoaway.setxstatus);
pp.getPrefInt('autoaway-xstatus', autoaway.xstatus);
pp.getPrefBool('autoaway-ss', autoaway.ss);
pp.getPrefBool('autoaway-boss', autoaway.boss);
pp.getPrefBool('xstatus-in-tray', XStatusInTray);
pp.getPrefBool('blink-with-status', blinkWithStatus);
pp.getPrefStr('proxy-host', MainProxy.addr.host);
pp.getPrefInt('proxy-port', MainProxy.addr.port);
// if pp.getPrefBoolDef('proxy-ver5', True) then
// MainProxy.proto := PP_SOCKS5
// else
// MainProxy.proto := PP_SOCKS4;
if not pp.getPrefBoolDef('proxy', False) then
MainProxy.proto := PP_NONE;
pp.getPrefStr('proxy-name', MainProxy.name);
pp.getPrefBool('proxy-auth', MainProxy.auth);
pp.getPrefBool('proxy-ntlm', MainProxy.NTLM);
pp.getPrefStr('proxy-user', MainProxy.user);
if pp.prefExists('proxy-pass64') then
L := pp.getPrefBlob64Def('proxy-pass64')
else
L := pp.getPrefBlobDef('proxy-pass');
MainProxy.pwd := UnUTF(PassDecrypt(L));
L := pp.getPrefStrDef('proxy-proto');
I := IndexStr(L, proxyproto2str);
if I < 0 then
MainProxy.proto := PP_NONE
else
MainProxy.proto := TProxyProto(I);
pp.getPrefInt('send-on-enter', sendOnEnter);
sU := '';
pp.getPrefStrList('spellcheck-languages', spellLanguages);
pp.getPrefStr('spellcheck-language-main', spellLanguageMain);
pp.getPrefInt('spellcheck-error-style', spellErrorStyle);
pp.getPrefStr('spellcheck-error-color', sU);
try
if not (sU = '') then
spellErrorColor := StringToColor(sU)
else
spellErrorColor := clRed;
except
spellErrorColor := clRed;
end;
boundInt(inactivehideTime, 0, 60 * 60 * 10);
boundInt(blinkSpeed, 1, 15);
boundInt(transparency.active, 0, 255);
boundInt(transparency.inactive, 0, 255);
ApplyTransparency;
end;
procedure LoadCFG(zp: TZipFile);
var
fn: String;
s: RawByteString;
i: integer;
begin
i := -1;
if Assigned(zp) then
try
i := zp.IndexOf(configFileName);
if i >= 0 then
s := zp.data[i];
except
i := -1;
s := '';
end;
if i < 0 then
begin
if FileExists(AccPath + configFileName) then
fn := AccPath + configFileName
else
fn := AccPath + oldconfigFileName;
if not FileExists(fn) then
fn := myPath + defaultsConfigFileName;
s := loadfileA(fn);
end;
if not (s = '') then
MainPrefs.Load(s);
s := loadfileA(cmdLinePar.extraini);
MainPrefs.Load(s);
s := '';
end;
procedure LoadCommonCFG;
begin
SetCommonCfg(loadfileA(myPath + commonFileName))
end;
procedure SaveCommonCFG;
begin
savefile2(myPath + commonFileName, GetCommonCFG, True, MakeBackups)
end;
function EnumWindowsCallback(Handle: HWND; Param: LPARAM): Boolean; stdcall;
var
ClassName: array[0..257] of Char;
begin
GetClassName(Handle, ClassName, Length(ClassName));
Result := True;
if not (StrIComp(ClassName, 'THiddenForm') = 0) then
Exit;
if (SendMessage(Handle, WM_FINDINSTANCE, 0, 0) <> 1337) or (Handle = Hidden.Handle) then
Exit;
Previous := Handle;
Result := False;
end;
procedure EmergencyExit(Code: Integer = 0);
begin
FreeAndNil(UI);
Halt(Code);
end;
procedure BeforeWindowsCreation;
procedure ParseCmdLineParams;
var
i, m: Integer;
s: String;
UIN: TUID;
begin
MyPath := ExtractFilePath(paramStr(0));
StickerPath := MyPath + 'Cache\Stickers\';
cmdLinePar.extraini := '';
cmdLinePar.startUser := '';
cmdLinePar.mainPath := '';
cmdLinePar.userPath := '';
cmdLinePar.logpath := '';
logpath := myPath;
cmdLinePar.useproxy := '';
{$IFDEF LANGDEBUG}
lang_debug := False;
xxx := False;
{$ENDIF LANGDEBUG}
i := 0;
while i < paramCount() do
begin
inc(i);
s := paramStr(i);
if s = '--add-ini' then
begin
inc(i);
cmdLinePar.extraini := paramStr(i);
end
else if s = '--nosound' then
masterMute := True
else
{$IFDEF LANGDEBUG}
if s = '--lang' then
lang_debug := True
else
{$ENDIF}
if s = '--icqlink' then
begin
Inc(i);
Previous := 0;
EnumWindows(@EnumWindowsCallback, 0);
if Previous = 0 then
cmdLinePar.icqlink := paramStr(i)
else
begin
PostMessage(Previous, WM_HANDLEICQLINK, GlobalAddAtom(PChar(ParamStr(i))), 0);
//Application.Terminate;
Halt;
end;
end else if s = '--mainpath' then
begin
inc(i);
cmdLinePar.mainPath := paramStr(i);
cmdLinePar.mainPath := includeTrailingPathDelimiter(cmdLinePar.mainPath);
if not DirectoryExists(cmdLinePar.mainPath) then
begin
m := MessageDlg(GetTranslation('Directory "%s" does not exist. Do you want to create it?', [cmdLinePar.mainPath]), mtConfirmation, [mbYes, mbIgnore, mbAbort]);
if m = mrAbort then
EmergencyExit;
if m = mrYes then
CreateDir(cmdLinePar.mainPath)
else
cmdLinePar.mainPath := '';
end;
end else if s = '--userpath' then
begin
inc(i);
cmdLinePar.userPath := paramStr(i);
cmdLinePar.userPath := includeTrailingPathDelimiter(cmdLinePar.userPath);
if not DirectoryExists(cmdLinePar.userPath) then
begin
m := MessageDlg(GetTranslation('Directory "%s" does not exist. Do you want to create it?', [cmdLinePar.userPath]), mtConfirmation, [mbYes, mbIgnore, mbAbort]);
if m = mrAbort then
EmergencyExit;
if m = mrYes then
CreateDir(cmdLinePar.userPath)
else
cmdLinePar.userPath := '';
end;
end else if s = '--logpath' then
begin
inc(i);
cmdLinePar.logpath := paramStr(i);
cmdLinePar.logpath := includeTrailingPathDelimiter(cmdLinePar.logpath);
if not DirectoryExists(cmdLinePar.logpath) then
cmdLinePar.logpath := '';
end else if s = '--proxy' then
begin
inc(i);
cmdLinePar.useproxy := paramStr(i);
// cmdLinePar.useproxy := includeTrailingPathDelimiter(cmdLinePar.useproxy);
// if not DirectoryExists(cmdLinePar.logpath) then
// cmdLinePar.logpath := '';
end else
// is it an UIN ?
try
UIN := s;
if TICQSession._isProtoUid(UIN) then
cmdLinePar.startUser := UIN;
except end;
end
end;
var
s: String;
i: integer;
begin
if initOnce then
Exit;
initOnce := True;
startTime := now;
ParseCmdLineParams;
Application.Initialize;
Application.HintHidePause := 60000;
Application.Title := 'R&Q';
WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');
timeformat.chat := FormatSettings.shortdateformat + ' hh:nn:ss';
timeformat.info := FormatSettings.shortdateformat + ' hh:nn';
timeformat.clock := 'hh:nn';
timeformat.log := FormatSettings.shortdateformat + ' hh:nn:ss.zzz';
timeformat.automsg := 'hh:nn';
supportedBehactions[EK_msg] := allBehactions;
supportedBehactions[EK_incoming] := allBehactions;
supportedBehactions[EK_outgoing] := allBehactions;
supportedBehactions[EK_contacts] := allBehactions;
supportedBehactions[EK_addedyou] := allBehactions;
supportedBehactions[EK_auth] := allBehactions;
supportedBehactions[EK_authreq] := allBehactions;
supportedBehactions[EK_authDenied] := allBehactions;
supportedBehactions[EK_statuschange] := allBehactions;
supportedBehactions[EK_typingBeg] := mtnBehactions;
supportedBehactions[EK_typingFin] := mtnBehactions;
supportedBehactions[EK_XstatusMsg] := allBehactions;
supportedBehactions[EK_buzz] := [BE_OPENCHAT, BE_HISTORY, BE_TIP, BE_FLASHCHAT, BE_SOUND];
ResetCommonCFG;
LoadCommonCFG;
DefineISOCountries;
UI := TUI.Create(Hidden);
UI.LoadTemplate('template', 'init.htm');
UI.ApplySystemColor;
LoadSomeLanguage;
AllProxies := nil;
uin2Bstarted := GetUserAutoStart(AccPass);
if uin2Bstarted = '' then
uin2Bstarted := ShowUsers;
if uin2Bstarted = '' then
EmergencyExit(0)
else
AccPass := NewAccPass;
repeat
s := 'R&Q' + uin2Bstarted;
Mutex := OpenMutex(MUTEX_MODIFY_STATE, False, PChar(s));
if Mutex <> 0 then
begin
CloseHandle(Mutex);
uin2Bstarted := ShowUsers(True);
if uin2Bstarted = '' then
EmergencyExit(0)
else
AccPass := NewAccPass;
end;
until Mutex = 0;
i := FindInAvailableUsers(uin2Bstarted);
if i < 0 then
begin
MsgDlg('StartUser: Bad UIN', True, mtError);
EmergencyExit(1);
end;
SQLDB := TSQLDatabase.Create;
Account.acks := TOutbox.Create;
Account.outbox := TOutbox.Create;
RecentList := TRnQCList.Create;
NotInList := TRnQCList.Create;
IgnoreList := TRnQCList.Create;
QuietList := TRnQCList.Create;
UpdateViewInfoQ := TRnQCList.Create;
groups := TGroups.Create;
theme.fBasePath := RnQMainPath;
uinlists := TUINLists.Create;
retrieveQ := TRnQCList.Create;
reqAvatarsQ := TRnQCList.Create;
LoadTranslit;
childWindows := TList.Create;
locked := False;
autoaway.time := 0;
UserStartTime := 0;
eventQ := TEventQ.Create;
HotkeysEnabled := True;
plugins := TPlugins.Create;
end;
procedure ChangeOrAddUser;
var
S: String;
VMutex: Cardinal;
UIN2Start: TUID;
begin
UIN2Start := ShowUsers;
if (UIN2Start = '') and not Assigned(Account.AccProto) then
begin
if Running then
QuitFinish;
Exit;
end;
if (UIN2Start = '') or (Assigned(Account.AccProto) and Account.AccProto.GetStartInfo.equals(UIN2Start)) then
Exit;
repeat
S := 'R&Q' + UIN2Start;
VMutex := OpenMutex(MUTEX_MODIFY_STATE, False, PChar(s));
if VMutex <> 0 then
begin
CloseHandle(VMutex);
UIN2Start := ShowUsers(True);
if (UIN2Start = '') or (Assigned(Account.AccProto) and Account.AccProto.GetStartInfo.Equals(UIN2Start)) then
Exit;
end;
until VMutex = 0;
if UIN2Start = '' then
Exit;
if Assigned(Account.AccProto) then
if not Account.AccProto.IsOffline then
begin
if MessageDlg(GetTranslation('This is gonna disconnect you. Proceed?'), mtConfirmation, [mbYes, mbNo]) <> mrYes then
Exit;
Account.AccProto.Disconnect;
end;
try
UI.CL.Hide;
if Assigned(Account.AccProto) then
QuitUser;
AccPass := NewAccPass;
StartUser(UIN2Start);
finally
if Assigned(UI) and Assigned(UI.CL) then
if StartMinimized = UI.CL.Visible then
if not UI.CL.Visible then
UI.CL.ToggleVisible;
end;
end;
procedure StartUser(const UID: TUID = '');
const
maxProg = 17;
var
i: Integer;
thisUser: TRnQUser;
s, dbpath: String;
dbZip: TZipFile;
zipPrefs, DBEncrypted: Boolean;
MyInf: TICQContact;
AccUID: TUID;
Pages: String;
begin
UserStarting := True;
if not (UID = '') then
uin2Bstarted := UID;
i := findInAvailableUsers(uin2Bstarted);
if i < 0 then
begin
msgDlg('StartUser: Bad UIN', True, mtError);
halt(1);
end;
s := 'R&Q' + uin2Bstarted;
// there is no previous Mutex so create new one
Mutex := CreateMutex(nil, False, PChar(s));
// take ownership of our mutex
WaitForSingleObject(Mutex, INFINITE);
thisUser := availableusers[i];
AccPath := thisUser.path + thisUser.SubPath + PathDelim;
logpref.evts.onWindow := True;
if cmdLinePar.logpath > '' then
logpath := cmdLinePar.logpath
else
logpath := myPath;
LogEvent('User: (ICQ)' + thisUser.UIN + ' starting');
SetProgBar(nil, 1 / maxProg);
MainPrefs := TRnQPref.create;
FantomWork := not DirectoryExists(AccPath); // New <20><> 2007.10.09
helpExists := FileExists(myPath + docsPath + getTranslation(helpFilename));
zipPrefs := False;
dbZip := nil;
s := AccPath + dbFilename + '5';
if not FileExists(s) then
s := AccPath + dbFilename + '4';
if not FileExists(s) then
begin // Trying to find saved files
s := AccPath + dbFilename + '5.new';
if not FileExists(s) then
begin
s := AccPath + dbFilename + '5.bak';
if not FileExists(s) then
s := '';
end
end;
if not (s = '') then
begin
dbZip := TZipFile.create;
try
dbZip.LoadFromFile(s);
zipPrefs := dbZip.Count > 0;
dbZip.Password := AccPass;
except
MsgDlg('Error while opening DB archive', True, mtError);
end;
if not zipPrefs then
begin
FreeAndNil(dbZip);
end;
end;
LoadCFG(dbZip);
LogEvent('CFG: loaded');
AccUID := MainPrefs.getPrefStrDef('account-id');
if AccUID = '' then
AccUID := uin2Bstarted;
with thisUser do
begin
Account.ProtoPath := AccPath;
Account.AccProto := TICQSession.Create(AccUID);
RnQUser := AccUID + ' "' + name + '"';
if pwd > '' then
Account.AccProto.pwd := pwd;
end;
// mainfrm.SetProgBar(2/maxProg); // <20><> <20><> <20><>, <20>.<2E>. <20><>
StayConnected := False;
CleanDisconnect := True;
UserStartTime := Now;
Account.AccProto.SetListener(Protocols_All.ProtoEvent);
ResetCFG;
SetCFG(MainPrefs);
SQLDB.NeedToConvertDB := not MainPrefs.getPrefBoolDef('sqlite-config', False);
if SQLDB.NeedToConvertDB then
SetCFGFromDB(MainPrefs);
dbpath := AccPath + accountFilename;
DBEncrypted := SQLDB.ManageSecurity(SA_CHECK);
if not SQLDB.Connect(IfThen(DBEncrypted, AccPass)) then
begin
if DBEncrypted then
MessageDlg(GetTranslation('You have to provide a valid password for encrypted account!'), mtError, [mbOK])
else
MessageDlg(GetTranslation('Failed to open account database'), mtError, [mbOK]);
if Assigned(Account.AccProto) then
begin
Account.AccProto.Clear;
try
FreeAndNil(Account.AccProto);
except
Account.AccProto := nil;
end;
end;
if Assigned(dbZip) then
FreeAndNil(dbZip);
FreeAndNil(MainPrefs);
try
CloseHandle(Mutex);
Mutex := 0;
except end;
ChangeOrAddUser;
Exit;
end;
if not SQLDB.NeedToConvertDB then
begin
SQLDB.LoadConfig;
SetCFGFromDB(MainPrefs);
end;
SetICQLinksHandler(HandleICQLinks);
// reset log files
if logpref.evts.clear then
deletefile(logpath + eventslogFilename);
if logpref.pkts.clear then
deletefile(logpath + requestslogFilename);
if logpref.evts.onFile and not fileIsWritible(logpath + eventslogFilename) then
begin
logpref.evts.onFile := False;
MsgDlg(GetTranslation('Can''t write to file: "%s"', [eventslogFilename]), False, mtError);
end;
if logpref.pkts.onFile and not fileIsWritible(logpath + requestslogFilename) then
begin
logpref.pkts.onFile := False;
MsgDlg(GetTranslation('Can''t write to file: "%s"', [requestslogFilename]), False, mtError);
end;
if SQLDB.NeedToConvertHistory then
SQLDB.ConvertHistory;
LogEvent('R&Q: ' + IntToStr(RnQBuild) + ' starting');
if SQLDB.NeedToConvertDB then
begin
MainCSS := LoadFromZipOrFile(dbZip, Account.ProtoPath, MainCSSFileName);
ChatCSS := LoadFromZipOrFile(dbZip, Account.ProtoPath, ChatCSSFileName);
end
else
begin
MainCSS := MainPrefs.getPrefStrDef('custom-css-main');
ChatCSS := MainPrefs.getPrefStrDef('custom-css-chat');
end;
UI.InitSettings;
UI.CL.Init;
UI.Chat.Init;
UI.Tips.InitSettings;
LogEvent('Theme: loading');
ReloadCurrentTheme;
picDrawFirstLtr := theme.ThemePath.fn = '';
LogEvent('Theme: loaded');
if not skipsplash then
theme.PlaySound('start');
SetProgBar(nil, 3 / maxProg);
ToggleMainFormBorder(True, ShowMainBorder);
if not StartMinimized then
begin
UI.CL.Show;
Application.ProcessMessages;
end;
SetProgBar(nil, 4 / maxProg);
if SQLDB.NeedToConvertDB then
begin
LogEvent('Proxies: converting to SQLite');
old_LoadProxies(dbZip);
LogEvent('Proxies: ' + IntToStr(Length(AllProxies)) + ' total');
SQLDB.SaveProxies;
LogEvent('Proxies: conversion completed');
LogEvent('Macros: converting to SQLite');
old_LoadMacros(dbZip);
LogEvent('Macros: ' + IntToStr(Length(macros)) + ' total');
SQLDB.SaveMacros;
LogEvent('Macros: conversion completed');
end
else
begin
LogEvent('Proxies: loading');
SQLDB.LoadProxies;
LogEvent('Proxies: loaded');
LogEvent('Hotkeys: loading');
SQLDB.LoadMacros;
LogEvent('Hotkeys: loaded');
end;
SetProgBar(nil, 5 / maxProg);
UpdateSWHotkeys;
LogEvent('DB: loading');
if SQLDB.NeedToConvertDB then
begin
LogEvent('Groups: converting to SQLite');
groups.old_FromString(LoadFromZipOrFile(dbZip, Account.ProtoPath, groupsFilename));
LogEvent('Groups: ' + IntToStr(groups.Count) + ' total');
SQLDB.SaveGroups;
LogEvent('Groups: conversion completed');
groups.RecalculateOrder;
LogEvent('Contacts DB: converting to SQLite');
old_LoadDB(dbZip);
LogEvent('Contacts DB: ' + IntToStr(TICQSession.ContactsDB.Count) + ' total');
SQLDB.SaveContactsDB;
LogEvent('Contacts DB: conversion completed');
end
else
begin
SQLDB.LoadGroups;
groups.RecalculateOrder;
SQLDB.LoadContactsDB;
end;
LogEvent('DB: loaded');
SetProgBar(nil, 6 / maxProg);
if Assigned(Account.AccProto) then
Account.AccProto.SetPrefs(MainPrefs);
UI.CL.UpdateStatusGlyphs;
UI.CL.UpdateVisibilityImage;
// mainfrm.SetProgBar(4/maxProg);
InitTimers;
SetProgBar(nil, 7 / maxProg);
if cmdLinePar.useproxy > '' then
begin
for i := 0 to length(AllProxies) - 1 do
if (AllProxies[i].name = cmdLinePar.useproxy) or ('"' + AllProxies[i].name + '"' = cmdLinePar.useproxy) then
begin
CopyProxy(MainProxy, AllProxies[i]);
Break;
end;
end;
SetProgBar(nil, 8 / maxProg);
lastUser := uin2Bstarted;
if RnQStartingStatus < 0 then
lastStatus := lastStatusUserSet
else
begin
lastStatusUserSet := byte(SC_UNK);
lastStatus := RnQStartingStatus;
end;
SetProgBar(nil, 9 / maxProg);
if SQLDB.NeedToConvertDB then
begin
LogEvent('XStatuses: converting to SQLite');
old_LoadExtSts(dbZip);
LogEvent('XStatuses: ' + IntToStr(Length(ExtStsStrings)) + ' total');
SQLDB.SaveXStatuses;
LogEvent('XStatuses: conversion completed');
LogEvent('SpamQuests: converting to SQLite');
old_LoadSpamQuests(dbZip);
LogEvent('SpamQuests: ' + IntToStr(Length(SpamFilter.Quests)) + ' total');
SQLDB.SaveSpamQuests;
LogEvent('SpamQuests: conversion completed');
LogEvent('Lists: converting to SQLite');
old_LoadLists(Account.AccProto, dbZip, Account.ProtoPath);
LogEvent('UINLists: ' + IntToStr(UINLists.Count) + ' total');
SQLDB.SaveUINLists;
LogEvent('Lists: conversion completed');
end
else
begin
LogEvent('Lists: loading');
SQLDB.LoadXStatuses;
SQLDB.LoadSpamQuests;
SQLDB.LoadUINLists;
SQLDB.LoadReactions;
LogEvent('Lists: loaded');
end;
SetProgBar(nil, 10 / maxProg);
RnQUser := Account.AccProto.MyAccNum;
MyInf := Account.AccProto.GetMyInfo;
if Assigned(MyInf) then
RnQUser := MyInf.Displayed;
LogEvent('Various lists: loading');
SetProgBar(nil, 11 / maxProg);
if SQLDB.NeedToConvertDB then
begin
LogEvent('InOutbox: converting to SQLite');
old_LoadOutInbox(dbZip);
LogEvent('Inbox: ' + IntToStr(eventQ.Count) + ' total');
LogEvent('Outbox: ' + IntToStr(Account.outbox.Count) + ' total');
SQLDB.SaveInbox;
SQLDB.SaveOutbox;
LogEvent('InOutbox: conversion completed');
end
else
begin
SQLDB.LoadInbox;
SetProgBar(nil, 12 / maxProg);
SQLDB.LoadOutbox;
end;
SetProgBar(nil, 14 / maxProg);
LogEvent('Various lists: loaded');
UI.CL.UpdateCaption;
IOresult;
if not DirectoryExists(AccPath + avtPath) then
ForceDirectories(AccPath + avtPath);
IOresult;
LogEvent('Avatars: loading');
loadAvatars(Account.AccProto, AccPath + avtPath);
LogEvent('Avatars: loaded');
UserStarting := False;
roasterLib.RebuildCL;
StatusIcon := TStatusIcon.Create(UI.CL.Window);
StatusIcon.OnGetPicTip := Protocols_All.GetTrayIconTip;
StatusIcon.TrayIcon.OnEvent := UI.CL.OnTrayEvent;
eventQ.onNewTop := StatusIcon.Update;
StatusIcon.TrayIcon.Show;
StatusIcon.Update;
contactsPnlStr := IntToStr(TList(Account.AccProto.ReadList(LT_ROSTER)).Count);
UI.CL.UpdateContactCount;
Account.acks.clear;
SetProgBar(nil, 15 / maxProg);
plugins.Load;
SetProgBar(nil, 16 / maxProg);
if SQLDB.NeedToConvertDB then
begin
Pages := LoadFromZipOrFile(dbZip, Account.ProtoPath, reopenchatsFileName);
SQLDB.SaveConfig;
end else
Pages := MainPrefs.getPrefStrDef('reopen-list');
FreeAndNil(dbZip);
// All loaded!
try // If exists old type files - delete them all
RenameFile(AccPath + dbFilename + '4', AccPath + dbFilename + '4.bak');
deletefile(AccPath + dbFilename + '4');
deletefile(AccPath + dbFilename + '3');
deletefile(AccPath + dbFilename);
deletefile(AccPath + rosterFileName1);
deletefile(AccPath + groupsFilename);
deletefile(AccPath + ignoreFileName1);
deletefile(AccPath + nilFilename1);
deletefile(AccPath + retrieveFilename1);
deletefile(AccPath + configFileName);
deletefile(AccPath + inboxFilename);
deletefile(AccPath + outboxFilename);
deletefile(AccPath + macrosFileName);
deletefile(AccPath + uinlistFilename);
deletefile(AccPath + reopenchatsFileName);
deletefile(AccPath + SpamQuestsFilename);
deletefile(AccPath + extstatusesFilename);
deletefile(AccPath + proxiesFileName);
except
MsgDlg('Error on deleting old lists', True, mtError);
end;
if lockOnStart then
begin
startingLock := True;
if not doLock then
exit;
enD;
ForceForegroundWindow(UI.CL.Window);
SetProgBar(nil, 0);
// Bug with Sciter debug enabled
{$IFDEF DEBUG}
TThread.CreateAnonymousThread(procedure
begin
Sleep(1000);
TThread.Synchronize(nil, procedure
begin
if ReopenChats and not (Pages = '') then
UI.Chat.LoadPages(Pages);
end);
end).Start;
{$ELSE}
if ReopenChats and not (Pages = '') then
UI.Chat.LoadPages(Pages);
{$ENDIF DEBUG}
if AutoConnect then
DoConnect
else
CheckAutoconnect;
LogEvent('User: started');
CheckBDays;
if not (cmdLinePar.icqlink = '') then
begin
ProcessICQLink(cmdLinePar.icqlink);
cmdLinePar.icqlink := '';
end;
end;
procedure QuitUser;
begin
if UserStartTime = 0 then
Exit;
UserStartTime := 0;
LogEvent('Quit user');
if Assigned(plugins) then
try
plugins.unload;
except end;
UninitTimers;
UI.Tips.RemoveAll;
UI.Chat.CloseAllPages(True);
{ if notInList.empty or (NILdoWith = 1)
or ((NILdoWith = 0) and (messageDlg(getTranslation('You have some not-in-list contact.\nDo you want to see them next time?'),mtConfirmation,[mbyes,mbNo],0, mbYes, 30) = mrNo)) then
deleteFile(userPath+nilFileName1)
else
if not saveFile(userPath+nilFileName1, notinlist.toString) then
msgDlg(getTranslation('Error saving not-in-list'),mtError);
}
if (NILdoWith = 1) or ((NILdoWith = 0) and not notinlist.empty and
(MessageDlg(GetTranslation('You have some not-in-list contact.\nDo you want to see them next time?'), mtConfirmation,
[mbYes, mbNo], 30) = mrNo)) then
notinlist.clear;
// theme.PlaySound('quit');
FlushLogPktFile;
FlushLogEvFile;
roasterLib.Clear;
if not (StartingLock or FantomWork) then
begin
UpdateProperties;
SaveCommonCFG;
SaveAccountSync;
end;
SQLDB.Disconnect;
LogEvent('Properties saved');
AccPass := '';
UI.Chat.PagesEnumStr := '';
trayIconGuid := GUID_NULL;
FreeAndNil(MainPrefs);
FreeAndNil(StatusIcon);
FreeAndNil(spellLanguages);
SetLength(SpamFilter.Quests, 0);
Groups.Clear;
UINLists.Clear;
MonPositions.Clear;
Account.outbox.Clear;
eventQ.onNewTop := nil;
eventQ.Clear;
CloseAllChildWindows;
Account.AccProto.Clear;
RecentList.Clear;
NotInList.Clear;
RetrieveQ.Clear;
ReqAvatarsQ.Clear;
ClearDB(TICQSession.ContactsDB);
try
FreeAndNil(Account.AccProto);
except
Account.AccProto := nil;
end;
theme.ClearThemelist;
if Assigned(ContactsTheme) then
ContactsTheme.Clear(tsc_all);
theme.clear(tsc_all);
// destroy our mutex
try
CloseHandle(Mutex);
Mutex := 0;
except end;
LogEvent('User quit');
end;
procedure ReStart;
begin
try
QuitUser;
if Assigned(StatusIcon) then
begin
if Assigned(StatusIcon.TrayIcon) then
StatusIcon.TrayIcon.Hide;
StatusIcon.Empty;
end;
except end;
RestartApp;
end;
procedure old_LoadMacros(zp: TZipFile);
var
s: RawByteString;
i: integer;
begin
i := -1;
if Assigned(zp) then
try
i := zp.IndexOf(macrosFileName);
if i >= 0 then
s := zp.data[i];
except
i := -1;
s := '';
end;
if i < 0 then
s := loadfileA(Account.ProtoPath + macrosFileName);
str2macros(s, macros)
end;
procedure Quit;
begin
if not initOnce then
Exit;
InitOnce := False;
plugins.castEv(PE_QUIT); // Added For Test Purpose
SoundUnInit;
DisableSounds := True;
StayConnected := False;
CleanDisconnect := True;
try
Account.AccProto.Disconnect;
except end;
Running := False;
UninstallHook;
StopSpellTask;
UI.Chat.Hide;
UI.CL.Hide;
QuitUser;
QuitFinish;
end;
procedure QuitFinish;
begin
QuitConfirmation := False;
UnLoadTranslit;
FreeAndNil(plugins);
FreeAndNil(uinlists);
ClearLanguage;
ClearAvailableUsers;
ClearPrefPages;
try
FreeAndNil(Account.AccProto);
except
Account.AccProto := nil;
end;
FreeAndNil(SQLDB);
FreeAndNil(RecentList);
FreeAndNil(NotInList);
FreeAndNil(IgnoreList);
FreeAndNil(QuietList);
FreeAndNil(UpdateViewInfoQ);
FreeAndNil(ChildWindows);
FreeAndNil(ReqAvatarsQ);
FreeAndNil(RetrieveQ);
FreeAndNil(Groups);
FreeAndNil(Account.outbox);
FreeAndNil(Account.acks);
FreeAndNil(eventQ);
FreeAndNil(UI.CL);
FreeAndNil(UI.Chat);
FreeAndNil(UI.Log);
FreeAndNil(UI.Tips);
FreeAndNil(UI.Prefs);
LogEvent('Shutdown', '', True);
FlushLogPktFile;
FlushLogEvFile;
Application.Terminate;
end;
procedure AfterWindowsCreation;
begin
Application.OnActivate := UI.AppActivate;
Application.OnDeactivate := UI.AppDeactivate;
Application.OnHint := UI.Chat.DisplayHint;
Running := True;
MainFormHandleUpdate;
ApplyTransparency;
SoundInit;
end;
initialization
initOnce := False;
onContactCreation := ContactCreation;
onContactDestroying := contactDestroying;
cacheDir := ExtractFilePath(paramStr(0)) + 'Cache\';
ForceDirectories(cacheDir);
imgCacheInfo := TMemIniFile.Create(cacheDir + 'Images.ini');
SCITER_DLL_DIR := ModulesPath;
SCITER_DLL_SKIP_FREE := True;
ZSTDDllName := ModulesPath + 'libzstd.dll';
finalization
if Assigned(imgCacheInfo) then
imgCacheInfo.Free;
end.