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/usersDlg.pas

547 lines
14 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit usersDlg;
{$I RnQConfig.inc}
interface
uses
Winapi.Windows, System.SysUtils, System.Classes, System.UITypes,
SciterJS, SciterJSAPI, RnQDialogs, ICQCommon, ICQSession;
{$I PubRTTI.inc}
type
PRnQUser = ^TRnQUser;
TRnQUser = record
uin: TUID;
name, // uinStr,
SubPath, path, prefix: string;
pwd: String;
encr: boolean;
end;
{$I NoRTTI.inc}
TUsersMethods = class(TNativeMethods)
class procedure RegisterMethods(var ReturnValue: TSciterValue); override;
class procedure GetUsersData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
class procedure OpenICQReg(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
class procedure ChangeOrAddUser(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
class procedure CheckAccountPass(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
class procedure CreateAccount(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
class procedure DeleteAccount(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
end;
function FindInAvailableUsers(const uin: TUID): integer;
procedure ClearAvailableUsers;
procedure RefreshAvailableUsers;
function GetUserAutoStart(var Pass: String): TUID;
var
AvailableUsers: array of TRnQUser;
implementation
uses
Winapi.ShlObj,
{$IFDEF UNICODE}
System.AnsiStrings,
{$ENDIF UNICODE}
SciterLib, GlobalLib, UtilLib, IniLib, ICQContacts,
RnQZip, RDUtils, RnQSysUtils, RnQGlobal, RnQLangs, RQUtil, RDGlobal, RDFileUtil;
const
Have2Sel = 'You have to select a user to delete it';
function FindInAvailableUsers(const uin: TUID): integer;
begin
for Result := 0 to Length(AvailableUsers) - 1 do
if AvailableUsers[result].uin = uin then
Exit;
Result := -1;
end;
procedure ClearAvailableUsers;
var
i: Integer;
begin
for i := 0 to Length(availableUsers)-1 do
begin
SetLength(availableUsers[i].name, 0);
// SetLength(availableUsers[i].uinStr, 0);
SetLength(availableUsers[i].SubPath, 0);
SetLength(availableUsers[i].path, 0);
SetLength(availableUsers[i].uin, 0);
SetLength(availableUsers[i].Prefix, 0);
end;
SetLength(availableUsers, 0);
end;
procedure RefreshAvailableUsers;
function getNick_SSI(const path: string; const uid: TUID;
var nick: String; var isEncripted: Boolean): Boolean;
function yesno(const l: String): boolean;
begin result := LowerCase(l)='yes' end;
var
db: TRnQCList;
ini: TStrings;
zf: TZipFile;
s: AnsiString;
cf: String;
i: Integer;
// cnt: TRnQcontact;
save: Boolean;
begin
Result := False;
nick := '';
save := False;
isEncripted := False;
ini := TStringList.create;
db := nil;
cf := path + PathDelim + dbFileName + '5';
if not FileExists(cf) then
cf := path + PathDelim + dbFileName + '4';
if FileExists(cf) then
begin
zf := TZipFile.Create;
try
zf.LoadFromFile(cf);
i := zf.IndexOf('about.txt');
if i >= 0 then
begin
isEncripted := zf.IsEncrypted(i);
Result := True;
if not isEncripted then
begin
ini.Text := zf.data[i];
s := ini.values['account-name'];
nick := UnUTF(s);
end;
end;
if not Result then
begin
i := zf.IndexOf(configFileName);
if i >=0 then
begin
isEncripted := zf.IsEncrypted(i);
Result := True;
if not isEncripted then
begin
ini.Text := zf.data[i];
s := ini.values['account-name'];
nick := UnUTF(s);
end;
end;
end;
{
if not Result then
begin
i := zf.IndexOf(dbFileName);
if i >=0 then
begin
isEncripted := zf.IsEncrypted(i);
Result := True;
if not isEncripted then
begin
s := zf.data[i];
db := str2db(protoClass._getContactClass, s);
cnt := db.get(protoClass._getContactClass, uid);
if Assigned(cnt) then
nick := cnt.nick;
freeDB(db);
end;
end;
end;
}
except
s := '';
end;
zf.Free;
end;
if not Result then
begin
cf := path + PathDelim + configFileName;
if fileExists(cf) then
begin
save := True;
Result := True;
try
ini.LoadFromFile(cf);
except
ini.Clear;
end;
nick := UnUTF(ini.values['account-name']);
end
else
begin
cf := path + PathDelim +OldconfigFileName;
if fileExists(cf) then
begin
Result := True;
save := True;
ini.LoadFromFile(cf);
nick := ini.values['account-name'];
end
end;
end;
if not Result then
begin
// loadDB(path+ PathDelim, db)
begin
zf := TZipFile.Create;
try
if FileExists(path + PathDelim + dbFileName + '3') then
zf.LoadFromFile(path + PathDelim + dbFileName + '3');
i := zf.IndexOf(dbFileName);
if i >=0 then
s := zf.data[i];
except
s := '';
end;
zf.Free;
end;
if s = '' then
s := loadFileA(path+ PathDelim +dbFileName);
{
if s > '' then
begin
Result := True;
db:=str2db(protoClass._getContactClass, s);
cnt := db.get(protoClass._getContactClass, uid);
if Assigned(cnt) then
nick := cnt.nick;
end;
}
// if not result then
// nick := ' ';
if save then
begin
ini.values['account-name']:= UTF(nick);
ini.saveToFile(cf);
end;
FreeDB(db);
end;
ini.free;
end; // getNick
procedure addAvailableUser(const UID: TUID; const pPath, pPrefix: String);
var
n: Integer;
begin
n := length(availableUsers);
setlength(availableUsers, n + 1);
// with availableUsers[n] do
begin
// availableUsers[n].uinStr:=extractFileName(pPath);
with availableUsers[n] do
begin
// if copy(uinStr, 1, 4) = AIMprefix then
// uinStr := copy(uinStr, 5, length(uinStr));
// uinStr:=extractFileName(pPath);
SubPath := extractFileName(pPath);
// uinStr := UID;
uin := UID;
// uid := uinStr;
getNick_SSI(pPath, UID, name, encr);
Prefix := pPrefix;
path:= ExtractFilePath(pPath);
end;
end;
end; // addAvailableUser
procedure searchIn(path: String; const Prefix: String = '');
var
sr: TsearchRec;
s: String;
s2: TUID;
begin
path := includeTrailingPathDelimiter(path);
ZeroMemory(@sr.FindData, SizeOf(TWin32FindData));
if FindFirst(path + '*', faDirectory, sr) = 0 then
repeat
if (sr.Attr and faDirectory > 0) and (sr.name <> '.')and (sr.name <> '..') then
begin
s := ExtractFileName(sr.name);
s2 := s;
if TICQSession._isProtoUid(s2) then
addAvailableUser(s2, path + sr.name, Prefix);
end;
until FindNext(sr) > 0;
FindClose(sr);
end;
var
s: String;
i, j, n: Integer;
found: Boolean;
ss: TUID;
// uid: AnsiString;
begin
ClearAvailableUsers;
searchIn(myPath);
if RnQMainPath > '' then
searchIn(myPath + RnQMainPath);
// s := getSpecialFolder('AppData') + 'R&Q\';
s := getSpecialFolder(CSIDL_APPDATA) + 'R&Q\';
searchIn(s, 'App\');
if (cmdLinePar.userPath > '') and not AnsiSameText(cmdLinePar.userPath, usersPath) then
if LowerCase(s) <> LowerCase(cmdLinePar.userPath) then
searchIn(cmdLinePar.userPath, 'User\');
s := usersPath;
while s > '' do
searchIn(chop(';',s), 'Users path\');
s := mypath + accountsPath;
if s <> usersPath then
while s>'' do
searchIn(chop(';',s));
if cmdLinePar.startUser > '' then
begin
found := False;
for n := 0 to length(availableUsers) - 1 do
begin
ss := cmdLinePar.startUser;
if TICQSession._isProtoUid(ss) and (availableUsers[n].uin = ss) then
found := True;
end;
if not found then
begin
// fantomWork := True;
//addAvailableUser(cmdLinePar.startUser, myPath + cmdLinePar.startUser, 'CMD\');
end;
end;
n := length(availableUsers);
for i := 0 to n - 2 do
for j := i + 1 to n - 1 do
swap4(availableUsers[i], availableUsers[j], sizeOf(availableUsers[i]), availableUsers[i].uin > availableUsers[j].uin);
end; // refreshAvailableUsers
function GetUserAutoStart(var Pass: String): TUID;
var
I: Integer;
begin
RefreshAvailableUsers;
Result := '';
Pass := '';
if not (CmdLinePar.StartUser = '') then
Result := ExtractFileName(CmdLinePar.StartUser)
else
begin
I := FindInAvailableUsers(autostartUIN);
if I >= 0 then
Result := autostartUIN
else if Length(AvailableUsers) = 1 then
Result := AvailableUsers[0].uin;
end;
if not (Result = '') then
begin
I := FindInAvailableUsers(Result);
if I >= 0 then
begin
with AvailableUsers[i] do
if encr and not CheckAccPass(uin, path + SubPath + PathDelim + dbFilename + '5', Pass) then
Result := ''
else
NewAccPass := Pass;
end else
Result := '';
end;
end;
class procedure TUsersMethods.RegisterMethods(var ReturnValue: TSciterValue);
begin
AddMethod('GetUsersData', GetUsersData);
AddMethod('OpenICQReg', OpenICQReg);
AddMethod('ChangeOrAddUser', ChangeOrAddUser);
AddMethod('CheckAccountPass', CheckAccountPass);
AddMethod('CreateAccount', CreateAccount);
AddMethod('DeleteAccount', DeleteAccount);
inherited;
end;
class procedure TUsersMethods.GetUsersData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
RnQVer: String;
I: Integer;
UsersVar: TParams;
Data: TParams;
begin
RnQVer := IntToStr(RnQBuild) + ' ' + GetTranslation('Build %d', [RnQBuildCustom]);
{$IFDEF CPUX64}
RnQVer := RnQVer + ' x64';
{$ENDIF CPUX64}
RefreshAvailableUsers;
SetLength(UsersVar, Length(AvailableUsers));
for I := 0 to Length(AvailableUsers) - 1 do
UsersVar[I] := UI.RecordToVar(AvailableUsers[I]);
SetLength(Data, 4);
Data[0] := LastUser;
if Assigned(Account.AccProto) then
Data[1] := String(Account.AccProto.StartAccountNum)
else
Data[1] := '';
Data[2] := UsersVar;
Data[3] := RnQVer;
V2S(Data, retval);
end;
class procedure TUsersMethods.OpenICQReg(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
OpenURL('https://icq.com/join/');
end;
class procedure TUsersMethods.ChangeOrAddUser(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
iniLib.ChangeOrAddUser
end;
class procedure TUsersMethods.CheckAccountPass(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
I: Integer;
Res: Boolean;
Pass: String;
UID: PWideChar;
StrLen: Cardinal;
begin
UID := '';
API.ValueStringData(argv, UID, StrLen);
if UID = '' then
begin
V2S(False, retval);
Exit;
end;
Res := False;
I := FindInAvailableUsers(UID);
if I >= 0 then
begin
with AvailableUsers[I] do
if encr then
begin
Res := CheckAccPass(uin, path + SubPath + PathDelim + dbFilename + '5', Pass);
NewAccPass := Pass;
end;
end;
V2S(Res, retval);
end;
class procedure TUsersMethods.CreateAccount(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UID: PWideChar;
UIDOnly: TUID;
StrLen: Cardinal;
UserPath: String;
IsProto: Boolean;
begin
UID := '';
API.ValueStringData(argv, UID, StrLen);
if CmdLinePar.UserPath > '' then
UserPath := CmdLinePar.UserPath
else
UserPath := MyPath + AccountsPath;
UIDOnly := UID;
IsProto := TICQSession._IsProtoUid(UIDOnly);
if TICQSession._IsValidUid(UIDOnly) then
UIDOnly := TICQContact.TrimUID(UIDOnly);
if not IsProto then
begin
MsgDlg('Not a valid user identifier', True, mtError);
Exit;
end;
if FindInAvailableUsers(UIDOnly) > -1 then
begin
MsgDlg(GetTranslation('%s already exists', [UID]), False, mtError);
Exit;
end;
UserPath := UserPath + UIDOnly + PathDelim;
IOresult;
ForceDirectories(UserPath);
IOresult;
LastUser := UIDOnly;
UI.ReloadUsers;
end;
class procedure TUsersMethods.DeleteAccount(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UIN: PWideChar;
UINToDelete: TUID;
StrLen: Cardinal;
I: Integer;
Path: String;
ItsMe, Continue: Boolean;
begin
UIN := '';
API.ValueStringData(argv, UIN, StrLen);
UINToDelete := UIN;
if UINToDelete = '' then
MsgDlg(Have2Sel, True, mtInformation)
else
begin
I := FindInAvailableUsers(UINToDelete);
if I = -1 then
begin
MsgDlg('Error deleting this user!', True, mtError);
Exit;
end;
UINToDelete := AvailableUsers[I].uin;
Path := AvailableUsers[I].path + AvailableUsers[I].SubPath;
if UINToDelete = '' then
begin
MsgDlg(Have2Sel, True, mtInformation);
Exit;
end;
ItsMe := Assigned(Account.AccProto) and (Account.AccProto.GetStartInfo <> nil) and (Account.AccProto.GetStartInfo.Equals(UINToDelete));
if ItsMe then
begin
Continue := MessageDlg(
GetTranslation('The user you are trying to delete is the one in use right now.\nIt will be closed to be deleted. Continue?', [UINToDelete]),
mtConfirmation, [mbYes, mbNo]) = mrYes;
if Continue then
begin
UI.CL.Hide;
QuitUser;
end;
end else
Continue := MessageDlg(GetTranslation('Are you sure you want to delete %s ?', [UINToDelete]), mtConfirmation, [mbYes, mbNo]) = mrYes;
if Continue then
//if DelSubTree(UINToDelete) then
if DelTree(Path) then
begin
UI.ReloadUsers;
MsgDlg('User deleted!', True, mtInformation);
end else
MsgDlg('Error deleting this user!', True, mtError);
end
end;
end.