1,594
社区成员




type
TUser = class(TObject)
private
FIP, FUserName: string;
FPort: Integer;
FSelected: Boolean;
FContext: TIdContext;
FLock: TCriticalSection;
FCommandQueues: TThreadList;
FListItem: TListItem;
FWorkSize: Int64;
procedure SetContext(const Value: TIdContext);
procedure SetListItem(const Value: TListItem);
protected
procedure DoWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
public
constructor Create(const AIP, AUserName: string; APort: Integer;
AContext: TIdContext); reintroduce;
destructor Destroy; override;
procedure Lock;
procedure Unlock;
property IP: string read FIP;
property Port: Integer read FPort;
property UserName: string read FUserName;
property Selected: Boolean read FSelected write FSelected;
property Context: TIdContext read FContext write SetContext;
property CommandQueues: TThreadList read FCommandQueues;
property ListItem: TListItem read FListItem write SetListItem;
end;
implementation
{$R *.dfm}
function GetPercentFrom(Int, Total: Int64): Double;
begin
if (Int = 0) or (Total = 0) then
Result := 0
else if Int = Total then
Result := 100
else
begin
Result := Int / (Total / 100);
end;
end;
{ TUser }
constructor TUser.Create(const AIP, AUserName: string; APort: Integer;
AContext: TIdContext);
begin
FLock := TCriticalSection.Create;
FIP := AIP;
FPort := APort;
FUserName := AUserName;
Context := AContext;
FCommandQueues := TThreadList.Create;
end;
destructor TUser.Destroy;
begin
FCommandQueues.Free;
FLock.Free;
inherited;
end;
procedure TUser.DoWork(ASender: TObject; AWorkMode: TWorkMode;
AWorkCount: Int64);
var
NewPercent: string;
begin
if ListItem <> nil then
begin
NewPercent := IntToStr(Trunc(GetPercentFrom(AWorkCount, FWorkSize))) + '%';
if ListItem.SubItems[1] <> NewPercent then
ListItem.SubItems[1] := NewPercent;
end;
end;
procedure TUser.Lock;
begin
FLock.Enter;
end;
procedure TUser.Unlock;
begin
FLock.Leave;
end;
procedure TUser.SetContext(const Value: TIdContext);
begin
if FContext <> nil then
FContext.Data := nil;
if Value <> nil then
Value.Data := Self;
FContext := Value;
end;
procedure TUser.SetListItem(const Value: TListItem);
begin
if FListItem <> Value then
FListItem := Value;
if Value <> nil then
Value.Data := Self;
end;
procedure TFIndex.IdTCPServerConnect(AContext: TIdContext);
var
Client: TUser;
AUserName: string;
lst: TList;
I: Integer;
begin
AUserName := AContext.Connection.IOHandler.ReadLn;
if AUserName = '' then
begin
AContext.Connection.IOHandler.WriteLn('NO_USER_NAME');
AContext.Connection.Disconnect;
Exit;
end;
lst := FUsers.LockList;
try
for I := 0 to lst.Count - 1 do
if SameText(TUser(lst[I]).UserName, AUserName) then
begin
AContext.Connection.IOHandler.WriteLn('USER_ALREADY_LOGINED');
AContext.Connection.Disconnect;
Exit;
end;
Client := TUser.Create(AContext.Binding.PeerIP, AUserName,
AContext.Binding.PeerPort, AContext);
lst.Add(Client);
Client.Lock;
try
Client.Context.Connection.IOHandler.WriteLn('LOGINED');
finally
Client.Unlock;
end;
finally
FUsers.UnlockList;
end;
SendMessage(FormHanlde, WM_REFRESH_USERS, Ord(rpAppendItem), Integer(Client));
end;
procedure TFIndex.IdTCPServerDisconnect(AContext: TIdContext);
var
Client: TUser;
begin
Client := TUser(AContext.Data);
if Client <> nil then
begin
Client.Lock;
try
Client.Context := nil;
finally
Client.Unlock;
end;
FUsers.Remove(Client);
SendMessage(FormHanlde, WM_REFRESH_USERS, Ord(rpDeleteItem),
Integer(Client));
Client.Free;
end;
end;
procedure TFIndex.IdTCPServerExecute(AContext: TIdContext);
var
Client: TUser;
Msg, Cmd: string;
cmds: TList;
CmdRec: PCmdRec;
begin
Client := TUser(AContext.Data);
if Client <> nil then
begin
Client.Lock;
try
AContext.Connection.IOHandler.CheckForDataOnSource(250);
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
Msg := AContext.Connection.IOHandler.ReadLn;
if FormHanlde <> 0 then
begin
LockUI;
try
Memo.Lines.Add(Format('IP:%s的%s用户说:"%s"', [Client.IP,
Client.UserName, Msg]));
finally
UnlockUI;
end;
end;
end;
cmds := Client.CommandQueues.LockList;
try
if cmds.Count > 0 then
begin
CmdRec := cmds[0];
Cmd := CmdRec.Cmd;
cmds.Delete(0);
Dispose(CmdRec);
end
else
Cmd := '';
finally
Client.CommandQueues.UnlockList;
end;
if Cmd = '' then
Exit;
if Pos('SENDF', Cmd) = 1 then
begin
if FormHanlde <> 0 then
begin
LockUI;
try
Memo.Lines.Add(Format('发送文件到%s(IP:%s)', [Client.UserName,
Client.IP]));
finally
UnlockUI;
end;
end;
// SendFileToUser(Client,Trim(Copy(Cmd,6,Length(Cmd))));
end
else if Pos('SENDT', Cmd) = 1 then
begin
if FormHanlde <> 0 then
begin
LockUI;
try
Memo.Lines.Add(Format('发送文本信息到%s(IP:%s),文本内容:"%s"',
[Client.UserName, Client.IP,
Trim(Copy(Cmd, 6, Length(Cmd)))]));
finally
UnlockUI;
end;
end;
SendTextToUser(Client, Trim(Copy(Cmd, 6, Length(Cmd))));
end;
finally
Client.Unlock;
end;
end;
end;