Parcourir la source

Signed-off-by: lqq <lqq@wswin.cn>

lqq il y a 9 ans
Parent
commit
ce93591b6b

+ 190 - 0
Client/FileTransimt/UploaderTask.pas

@@ -0,0 +1,190 @@
+unit UploaderTask;
+
+interface
+
+uses
+  Windows, IdHTTP, SysUtils, Classes, IdSchedulerOfThreadPool, IdTask, IdThread,
+  IdYarn, IdMultipartFormData;
+
+type
+  TUploaderTask = class(TIdTask)
+  private
+    FThread: TIdThread;
+    FRemote, FLocal: string;
+    FIdHTTP: TIdHTTP;
+    FTime: Integer;
+    FSuccess: Boolean;
+  public
+    constructor Create(ARemote, ALocal: string; AYarn: TIdYarn);
+    destructor Destroy; override;
+    procedure AfterRun; override;
+//    procedure BeforeRun; override;
+    function Run: Boolean; override;
+  end;
+
+  TFacesUploaderTask = class(TIdTask)
+  private
+    FThread: TIdThread;
+    FRemote: string;
+    FFiles: TStrings;
+    FIdHTTP: TIdHTTP;
+    FTime: Integer;
+    FSuccess: Boolean;
+    FOnCompleted: TNotifyEvent;
+    FData: TObject;
+    procedure SetOnCompleted(const Value: TNotifyEvent);
+    procedure SetDate(const Value: TObject);
+  protected
+    procedure DoCompleted;
+  public
+    constructor Create(ARemote: string; const AFiles: TStrings; AYarn: TIdYarn);
+    destructor Destroy; override;
+    procedure AfterRun; override;
+    procedure BeforeRun; override;
+    function Run: Boolean; override;
+    property OnCompleted: TNotifyEvent read FOnCompleted write SetOnCompleted;
+    property Success: Boolean read FSuccess;
+    property Data: TObject read FData write SetDate;
+  end;
+
+implementation
+
+uses
+  ShareUtils, LoggerImport, IdURI, Forms, MainFrm, IdSchedulerOfThread;
+
+{ TUploaderTask }
+
+
+procedure TUploaderTask.AfterRun;
+begin
+  FreeAndNil(Self);
+end;
+
+constructor TUploaderTask.Create(ARemote, ALocal: string; AYarn: TIdYarn);
+begin
+  FRemote := ARemote;
+  FLocal := ALocal;
+  FThread := TIdYarnOfThread(AYarn).Thread;
+  inherited Create(AYarn);
+end;
+
+destructor TUploaderTask.Destroy;
+begin
+
+  inherited;
+end;
+
+function TUploaderTask.Run: Boolean;
+var
+  FileStream: TIdMultiPartFormDataStream;
+begin
+  try
+    Result := False;
+    FileStream := TIdMultiPartFormDataStream.Create;
+    FileStream.AddFile('file1', FLocal, '');
+    FIdHTTP := TIdHTTP.Create(nil);
+    FIdHTTP.Request.ContentType := 'multipart/form-data';
+    FIdHTTP.Post(FRemote, FileStream);
+    Result := True;
+    FSuccess := True;
+  except
+    on E: Exception do
+    begin
+      if (FTime <= 0) and (not FThread.Terminated) then
+        Result := True;
+      Dec(FTime);
+      FileStream.Free;
+      FreeAndNil(FIdHTTP);
+      Error(E.Message, 'TUploaderTask.Run');
+    end;
+  end;
+  FileStream.Free;
+  FreeAndNil(FIdHTTP);
+end;
+
+{ TFacesUploaderTask }
+
+procedure TFacesUploaderTask.AfterRun;
+begin
+  if not FThread.Terminated then
+    FThread.Synchronize(DoCompleted);
+  Free;
+end;
+
+procedure TFacesUploaderTask.BeforeRun;
+begin
+  inherited;
+
+end;
+
+constructor TFacesUploaderTask.Create(ARemote: string; const AFiles: TStrings; AYarn: TIdYarn);
+begin
+  FRemote := ARemote;
+  FFiles := TStringList.Create;
+  if Assigned(AFiles) then
+    FFiles.AddStrings(AFiles);
+  FThread := TIdYarnOfThread(AYarn).Thread;
+  FIdHTTP := TIdHTTP.Create(nil);
+  FIdHTTP.Request.ContentType := 'multipart/form-data';
+  inherited Create(AYarn);
+end;
+
+destructor TFacesUploaderTask.Destroy;
+begin
+  FFiles.Free;
+  FIdHTTP.Free;
+  inherited;
+end;
+
+procedure TFacesUploaderTask.DoCompleted;
+begin
+  if Assigned(FOnCompleted) then
+    FOnCompleted(Self);
+end;
+
+function TFacesUploaderTask.Run: Boolean;
+var
+  FileStream: TIdMultiPartFormDataStream;
+  i: Integer;
+begin
+  try
+    Result := False;       
+    for I := 0 to FFiles.Count - 1 do
+      if FileExists(FFiles[i]) then
+      begin
+        if FThread.Terminated then
+          Exit;
+
+        FileStream := TIdMultiPartFormDataStream.Create;
+        FileStream.AddFile('file1', FFiles[i], '');
+        FIdHTTP.Post(FRemote, FileStream);
+        FreeAndNil(FileStream);
+      end;
+    Result := True;
+    FSuccess := True;
+  except
+    on E: Exception do
+    begin
+      if (FTime <= 0) and (not FThread.Terminated) then
+        Result := True;
+      Dec(FTime);
+      FileStream.Free;
+      Error(E.Message, 'TUploaderTask.Run');
+    end;
+  end;
+  if Assigned(FileStream) then
+    FileStream.Free;
+end;
+
+procedure TFacesUploaderTask.SetDate(const Value: TObject);
+begin
+  FData := Value;
+end;
+
+procedure TFacesUploaderTask.SetOnCompleted(const Value: TNotifyEvent);
+begin
+  FOnCompleted := Value;
+end;
+
+end.
+

+ 9 - 0
Client/Group/GroupConfig.pas

@@ -35,6 +35,7 @@ type
     function GetIP: string;
     function GetPort: Integer;
     function GetGatewayEnable: boolean;
+    function GetImageHost: string;
   public
     constructor Create;
     destructor Destroy; override;
@@ -49,6 +50,7 @@ type
     property GatewayPort: Integer read FGatewayPort write FGatewayPort;
     property GroupVersion: TGroupVersion read FGroupVersion;
     property GatewayEnable: Boolean read GetGatewayEnable;
+    property ImageHost: string read GetImageHost;
   end;
 
   TGroupShareConfig = class
@@ -129,6 +131,13 @@ begin
   Result := FGatewayAddresses.Count <> 0
 end;
 
+function TGroupConfig.GetImageHost: string;
+const
+  UPLOAD_URL: string = 'http://%s:%d/file/upload';
+begin
+  Result := Format(UPLOAD_URL, [FImageIP, FImagePort]);
+end;
+
 function TGroupConfig.GetImageIP: string;
 begin
   RandomImageServer;

+ 157 - 156
Client/Lxtalk.dpr

@@ -1,162 +1,163 @@
 program Lxtalk;
 
 uses
-  FastMM4,
-  mybean.console,
-  ceflib,
-  Windows,
-  IniFiles,
-  Forms,
-  StrUtils,
-  SysUtils,
-  Dialogs,
-  IdSMTP,
-  IdMessage,
-  LoggerImport,
-  AddFaceFrm in 'AddFaceFrm.pas' {AddFaceForm},
-  AddFriendFrm in 'AddFriendFrm.pas' {AddFriendForm},
-  AddFriendRequestFrm in 'AddFriendRequestFrm.pas' {AddFriendRequestForm},
-  AddGroupFrm in 'AddGroupFrm.pas' {AddGroupForm},
-  AddrBookUserFrm in 'AddrBookUserFrm.pas' {AddrBookUserForm},
-  AddUserFrm in 'AddUserFrm.pas' {AddUserForm},
-  AddWebTab in 'AddWebTab.pas' {Form1},
-  AddWebTabFrm in 'AddWebTabFrm.pas' {AddWebTabForm},
-  AlertFrm in 'AlertFrm.pas' {AlertForm},
-  BindTel in 'BindTel.pas' {BindTelFrm},
-  CalcFileCRC32 in 'CalcFileCRC32.pas',
-  CalcFileMD5 in 'CalcFileMD5.pas',
-  ChangePassFrm in 'ChangePassFrm.pas' {ChangePassForm},
-  ConfirmCannotLoadFileFrm in 'ConfirmCannotLoadFileFrm.pas' {ConfirmCannotLoadFileForm},
-  ConfirmReplaceFileFrm in 'ConfirmReplaceFileFrm.pas' {ConfirmReplaceFileForm},
-  ConfirmReplaceNDFileFrm in 'ConfirmReplaceNDFileFrm.pas' {ConfirmReplaceNDFileForm},
-  ConfirmSendOfflineFileFrm in 'ConfirmSendOfflineFileFrm.pas' {ConfirmSendOfflineFileForm},
-  CopyScreenFrm in 'CopyScreenFrm.pas' {CopyScreenForm},
-  CreateTeamFrm in 'CreateTeamFrm.pas' {CreateTeamForm},
-  CustomFacesManagerFrm in 'CustomFacesManagerFrm.pas' {CustomFacesManagerForm},
-  DESUnit in 'DESUnit.pas',
-  GroupManagerFrm in 'GroupManagerFrm.pas' {GroupManagerForm},
-  ImportAddrBookFrm in 'ImportAddrBookFrm.pas' {ImportAddrBookForm},
-  ImportAddrbookUtils in 'ImportAddrbookUtils.pas',
-  ImportGuideFrm in 'ImportGuideFrm.pas' {ImportGuideFrom},
-  Impstringgrid in 'Impstringgrid.pas',
-  LXTConst in 'LXTConst.pas',
-  MainFrm in 'MainFrm.pas' {MainForm},
-  MD5_32 in 'MD5_32.pas',
-  MessageBoxFrm in 'MessageBoxFrm.pas' {MessageBoxForm},
-  AsynActions in 'Actions\AsynActions.pas',
-  AsynRequestUserInfo in 'Actions\AsynRequestUserInfo.pas',
-  AsynRequestUserStatus in 'Actions\AsynRequestUserStatus.pas',
-  AsynResponseUserInfo in 'Actions\AsynResponseUserInfo.pas',
-  CA in 'CA\CA.pas',
-  ConditionConfig in 'Condition\ConditionConfig.pas',
-  LimitCondition in 'Condition\LimitCondition.pas',
-  DownloadFaceWithHttp in 'FileTransimt\DownloadFaceWithHttp.pas',
-  FileDownloaderWithNode in 'FileTransimt\FileDownloaderWithNode.pas',
-  FileStreamTransmitter in 'FileTransimt\FileStreamTransmitter.pas',
-  FileTransferWithNode in 'FileTransimt\FileTransferWithNode.pas',
-  FileTransimt_OldCode in 'FileTransimt\FileTransimt_OldCode.pas',
-  FileTransmitAdapter in 'FileTransimt\FileTransmitAdapter.pas',
-  HttpDownloader in 'FileTransimt\HttpDownloader.pas',
-  HTTPFileDownloader in 'FileTransimt\HTTPFileDownloader.pas',
-  OfflineFileConfig in 'FileTransimt\OfflineFileConfig.pas',
-  TransmiteFileMission in 'FileTransimt\TransmiteFileMission.pas',
-  UploadOrDownloadFileMission in 'FileTransimt\UploadOrDownloadFileMission.pas',
-  MainFormContrller in 'FormController\MainFormContrller.pas',
-  MainFormFooter in 'FormController\MainFormFooter.pas' {MainFrmFooter},
-  OptionFormController in 'FormController\OptionFormController.pas',
-  TalkFormController in 'FormController\TalkFormController.pas',
-  GroupClient in 'Group\GroupClient.pas',
-  GroupConfig in 'Group\GroupConfig.pas',
-  GroupMonitor in 'Group\GroupMonitor.pas',
-  GroupProcess in 'Group\GroupProcess.pas',
-  GroupProtocols in 'Group\GroupProtocols.pas',
-  Groups in 'Group\Groups.pas',
-  GroupService in 'Group\GroupService.pas',
-  GroupUtility in 'Group\GroupUtility.pas',
-  GroupWebSocket in 'Group\GroupWebSocket.pas',
-  IntfTeamTalkForm in 'Group\IntfTeamTalkForm.pas',
-  TeamsAdapter in 'Group\TeamsAdapter.pas',
-  TeamShareAdapter in 'Group\TeamShareAdapter.pas',
-  BranchsProcessor in 'Processor\BranchsProcessor.pas',
-  CommonProcessor in 'Processor\CommonProcessor.pas',
-  CompanyProcessor in 'Processor\CompanyProcessor.pas',
-  FriendsProcessor in 'Processor\FriendsProcessor.pas',
-  TeamsProcessor in 'Processor\TeamsProcessor.pas',
-  UsersProcessor in 'Processor\UsersProcessor.pas',
-  BaseService in 'Services\BaseService.pas',
-  BranchService in 'Services\BranchService.pas',
-  ChromeMessageService in 'Services\ChromeMessageService.pas',
-  ConfigService in 'Services\ConfigService.pas',
-  CurrentContentService in 'Services\CurrentContentService.pas',
-  DirectoryService in 'Services\DirectoryService.pas',
-  FaceService in 'Services\FaceService.pas',
-  FriendsService in 'Services\FriendsService.pas',
-  HtmlService in 'Services\HtmlService.pas',
-  MessagesHander in 'Services\MessagesHander.pas',
-  TeamsService in 'Services\TeamsService.pas',
-  TextMessageService in 'Services\TextMessageService.pas',
-  UserRemarkService in 'Services\UserRemarkService.pas',
-  UsersService in 'Services\UsersService.pas',
-  WorkmatesService in 'Services\WorkmatesService.pas',
-  BaseChromeView in 'Views\BaseChromeView.pas' {BaseChromeViewForm},
-  DevToolChromeFrm in 'Views\DevToolChromeFrm.pas' {DevToolChromeForm},
-  ViewManager in 'Views\ViewManager.pas',
-  EmbeddedView in 'Views\EmbeddedView\EmbeddedView.pas' {EmbeddedViewForm},
-  SettingView in 'Views\SettingViews\SettingView.pas' {SettingViewForm},
-  TalkFormFactory in 'Views\TalkViews\TalkFormFactory.pas',
-  TalkLayout in 'Views\TalkViews\TalkLayout.pas' {TalkLayoutForm},
-  TalkMainView in 'Views\TalkViews\TalkMainView.pas' {TalkMainViewForm},
-  TalkMainViewScope in 'Views\TalkViews\TalkMainViewScope.pas',
-  TalkPersonalToolsView in 'Views\TalkViews\TalkPersonalToolsView.pas' {TalkPersonalToolsViewForm},
-  TalkTeamSideView in 'Views\TalkViews\TalkTeamSideView.pas' {TalkTeamSideViewForm},
-  TalkTeamToolsView in 'Views\TalkViews\TalkTeamToolsView.pas' {TalkTeamToolsViewForm},
-  TalkUserInfoSideView in 'Views\TalkViews\TalkUserInfoSideView.pas' {TalkUserInfoSideViewForm},
-  TalkVideoSideView in 'Views\TalkViews\TalkVideoSideView.pas' {TalkVideoSideViewForm},
-  UITalkFormBase in 'Views\TalkViews\UITalkFormBase.pas',
-  UITalkPersonalForm in 'Views\TalkViews\UITalkPersonalForm.pas',
-  UITalkTeamForm in 'Views\TalkViews\UITalkTeamForm.pas',
-  UserCardView in 'Views\UserViews\UserCardView.pas' {UserCardViewForm},
-  UserCardDetailView in 'Views\UserViews\UserCardDetailView.pas' {UserCardDetailViewForm},
-  Authority in 'Windows\Authority.pas',
-  RealICQUtility in 'Utility\RealICQUtility.pas',
-  SendFolderFrm in 'SendFolderFrm.pas' {SendFolderForm},
-  ShareUtils in 'ShareUtils.pas',
-  SMSFrm in 'SMSFrm.pas' {SMSForm},
-  SystemMessageFrm in 'SystemMessageFrm.pas' {SystemMessageForm},
-  TalkingFrm in 'TalkingFrm.pas' {TalkingForm},
-  TeamOptionsFrm in 'TeamOptionsFrm.pas' {TeamOptionsForm},
-  TestCase in 'TestCase.pas' {Form6},
-  TrueHiddenMainFrm in 'TrueHiddenMainFrm.pas' {TrueHiddenMainForm},
-  U_SnapRect in 'U_SnapRect.pas',
-  MessagesManagerFrm in 'MessagesManagerFrm.pas' {MessagesManagerForm},
-  ModifyFaceFrm in 'ModifyFaceFrm.pas' {ModifyFaceForm},
-  MouseHook in 'MouseHook.pas',
-  MoveFaceFrm in 'MoveFaceFrm.pas' {MoveFaceForm},
-  MultiSendSMSFrm in 'MultiSendSMSFrm.pas' {MultiSendSMSForm},
-  MyInputBoxFrm in 'MyInputBoxFrm.pas' {MyInputBoxForm},
-  NotifyAlertFrm in 'NotifyAlertFrm.pas' {NotifyAlertForm},
-  NotReadMessageBoxFrm in 'NotReadMessageBoxFrm.pas' {NotReadMessageBoxForm},
-  OnlineOfflineAlertFrm in 'OnlineOfflineAlertFrm.pas' {OnlineOfflineAlertForm},
-  OptionsFrm in 'OptionsFrm.pas' {OptionsForm},
-  ProcessingFrm in 'ProcessingFrm.pas' {ProcessingForm},
-  QRCodeFrm in 'QRCodeFrm.pas' {QRCodeForm},
-  QueryIpWry in 'QueryIpWry.pas',
-  RealICQ_TLB in 'RealICQ_TLB.pas',
-  RealICQModel in 'RealICQModel.pas',
-  RealOAMessengerAutoServer in 'RealOAMessengerAutoServer.pas',
-  ReceiveFolderRequestFrm in 'ReceiveFolderRequestFrm.pas' {ReceiveFolderRequestForm},
-  RegFrm in 'RegFrm.pas' {RegForm},
-  AboutFrm in 'AboutFrm.pas' {AboutForm},
-  BaseScope in 'WebApps\BaseScope.pas',
-  BaseWebApp in 'WebApps\BaseWebApp.pas',
-  UserCardScope in 'WebApps\UserCardScope.pas',
-  UserCardWebApp in 'WebApps\UserCardWebApp.pas',
-  SettingWebApp in 'WebApps\SettingWebApp.pas',
-  SettingScope in 'WebApps\SettingScope.pas',
-  SettingService in 'Services\SettingService.pas',
-  TalkPersonalView in 'Views\TalkPersonalView.pas' {TalkPersonalForm},
-  BaseIDView in 'Views\BaseIDView.pas' {BaseIDViewForm};
-
+  FastMM4,
+  mybean.console,
+  ceflib,
+  Windows,
+  IniFiles,
+  Forms,
+  StrUtils,
+  SysUtils,
+  Dialogs,
+  IdSMTP,
+  IdMessage,
+  LoggerImport,
+  AddFaceFrm in 'AddFaceFrm.pas' {AddFaceForm},
+  AddFriendFrm in 'AddFriendFrm.pas' {AddFriendForm},
+  AddFriendRequestFrm in 'AddFriendRequestFrm.pas' {AddFriendRequestForm},
+  AddGroupFrm in 'AddGroupFrm.pas' {AddGroupForm},
+  AddrBookUserFrm in 'AddrBookUserFrm.pas' {AddrBookUserForm},
+  AddUserFrm in 'AddUserFrm.pas' {AddUserForm},
+  AddWebTab in 'AddWebTab.pas' {Form1},
+  AddWebTabFrm in 'AddWebTabFrm.pas' {AddWebTabForm},
+  AlertFrm in 'AlertFrm.pas' {AlertForm},
+  BindTel in 'BindTel.pas' {BindTelFrm},
+  CalcFileCRC32 in 'CalcFileCRC32.pas',
+  CalcFileMD5 in 'CalcFileMD5.pas',
+  ChangePassFrm in 'ChangePassFrm.pas' {ChangePassForm},
+  ConfirmCannotLoadFileFrm in 'ConfirmCannotLoadFileFrm.pas' {ConfirmCannotLoadFileForm},
+  ConfirmReplaceFileFrm in 'ConfirmReplaceFileFrm.pas' {ConfirmReplaceFileForm},
+  ConfirmReplaceNDFileFrm in 'ConfirmReplaceNDFileFrm.pas' {ConfirmReplaceNDFileForm},
+  ConfirmSendOfflineFileFrm in 'ConfirmSendOfflineFileFrm.pas' {ConfirmSendOfflineFileForm},
+  CopyScreenFrm in 'CopyScreenFrm.pas' {CopyScreenForm},
+  CreateTeamFrm in 'CreateTeamFrm.pas' {CreateTeamForm},
+  CustomFacesManagerFrm in 'CustomFacesManagerFrm.pas' {CustomFacesManagerForm},
+  DESUnit in 'DESUnit.pas',
+  GroupManagerFrm in 'GroupManagerFrm.pas' {GroupManagerForm},
+  ImportAddrBookFrm in 'ImportAddrBookFrm.pas' {ImportAddrBookForm},
+  ImportAddrbookUtils in 'ImportAddrbookUtils.pas',
+  ImportGuideFrm in 'ImportGuideFrm.pas' {ImportGuideFrom},
+  Impstringgrid in 'Impstringgrid.pas',
+  LXTConst in 'LXTConst.pas',
+  MainFrm in 'MainFrm.pas' {MainForm},
+  MD5_32 in 'MD5_32.pas',
+  MessageBoxFrm in 'MessageBoxFrm.pas' {MessageBoxForm},
+  AsynActions in 'Actions\AsynActions.pas',
+  AsynRequestUserInfo in 'Actions\AsynRequestUserInfo.pas',
+  AsynRequestUserStatus in 'Actions\AsynRequestUserStatus.pas',
+  AsynResponseUserInfo in 'Actions\AsynResponseUserInfo.pas',
+  CA in 'CA\CA.pas',
+  ConditionConfig in 'Condition\ConditionConfig.pas',
+  LimitCondition in 'Condition\LimitCondition.pas',
+  DownloadFaceWithHttp in 'FileTransimt\DownloadFaceWithHttp.pas',
+  FileDownloaderWithNode in 'FileTransimt\FileDownloaderWithNode.pas',
+  FileStreamTransmitter in 'FileTransimt\FileStreamTransmitter.pas',
+  FileTransferWithNode in 'FileTransimt\FileTransferWithNode.pas',
+  FileTransimt_OldCode in 'FileTransimt\FileTransimt_OldCode.pas',
+  FileTransmitAdapter in 'FileTransimt\FileTransmitAdapter.pas',
+  HttpDownloader in 'FileTransimt\HttpDownloader.pas',
+  HTTPFileDownloader in 'FileTransimt\HTTPFileDownloader.pas',
+  OfflineFileConfig in 'FileTransimt\OfflineFileConfig.pas',
+  TransmiteFileMission in 'FileTransimt\TransmiteFileMission.pas',
+  UploadOrDownloadFileMission in 'FileTransimt\UploadOrDownloadFileMission.pas',
+  MainFormContrller in 'FormController\MainFormContrller.pas',
+  MainFormFooter in 'FormController\MainFormFooter.pas' {MainFrmFooter},
+  OptionFormController in 'FormController\OptionFormController.pas',
+  TalkFormController in 'FormController\TalkFormController.pas',
+  GroupClient in 'Group\GroupClient.pas',
+  GroupConfig in 'Group\GroupConfig.pas',
+  GroupMonitor in 'Group\GroupMonitor.pas',
+  GroupProcess in 'Group\GroupProcess.pas',
+  GroupProtocols in 'Group\GroupProtocols.pas',
+  Groups in 'Group\Groups.pas',
+  GroupService in 'Group\GroupService.pas',
+  GroupUtility in 'Group\GroupUtility.pas',
+  GroupWebSocket in 'Group\GroupWebSocket.pas',
+  IntfTeamTalkForm in 'Group\IntfTeamTalkForm.pas',
+  TeamsAdapter in 'Group\TeamsAdapter.pas',
+  TeamShareAdapter in 'Group\TeamShareAdapter.pas',
+  BranchsProcessor in 'Processor\BranchsProcessor.pas',
+  CommonProcessor in 'Processor\CommonProcessor.pas',
+  CompanyProcessor in 'Processor\CompanyProcessor.pas',
+  FriendsProcessor in 'Processor\FriendsProcessor.pas',
+  TeamsProcessor in 'Processor\TeamsProcessor.pas',
+  UsersProcessor in 'Processor\UsersProcessor.pas',
+  BaseService in 'Services\BaseService.pas',
+  BranchService in 'Services\BranchService.pas',
+  ChromeMessageService in 'Services\ChromeMessageService.pas',
+  ConfigService in 'Services\ConfigService.pas',
+  CurrentContentService in 'Services\CurrentContentService.pas',
+  DirectoryService in 'Services\DirectoryService.pas',
+  FaceService in 'Services\FaceService.pas',
+  FriendsService in 'Services\FriendsService.pas',
+  HtmlService in 'Services\HtmlService.pas',
+  MessagesHander in 'Services\MessagesHander.pas',
+  TeamsService in 'Services\TeamsService.pas',
+  TextMessageService in 'Services\TextMessageService.pas',
+  UserRemarkService in 'Services\UserRemarkService.pas',
+  UsersService in 'Services\UsersService.pas',
+  WorkmatesService in 'Services\WorkmatesService.pas',
+  BaseChromeView in 'Views\BaseChromeView.pas' {BaseChromeViewForm},
+  DevToolChromeFrm in 'Views\DevToolChromeFrm.pas' {DevToolChromeForm},
+  ViewManager in 'Views\ViewManager.pas',
+  EmbeddedView in 'Views\EmbeddedView\EmbeddedView.pas' {EmbeddedViewForm},
+  SettingView in 'Views\SettingViews\SettingView.pas' {SettingViewForm},
+  TalkFormFactory in 'Views\TalkViews\TalkFormFactory.pas',
+  TalkLayout in 'Views\TalkViews\TalkLayout.pas' {TalkLayoutForm},
+  TalkMainView in 'Views\TalkViews\TalkMainView.pas' {TalkMainViewForm},
+  TalkMainViewScope in 'Views\TalkViews\TalkMainViewScope.pas',
+  TalkPersonalToolsView in 'Views\TalkViews\TalkPersonalToolsView.pas' {TalkPersonalToolsViewForm},
+  TalkTeamSideView in 'Views\TalkViews\TalkTeamSideView.pas' {TalkTeamSideViewForm},
+  TalkTeamToolsView in 'Views\TalkViews\TalkTeamToolsView.pas' {TalkTeamToolsViewForm},
+  TalkUserInfoSideView in 'Views\TalkViews\TalkUserInfoSideView.pas' {TalkUserInfoSideViewForm},
+  TalkVideoSideView in 'Views\TalkViews\TalkVideoSideView.pas' {TalkVideoSideViewForm},
+  UITalkFormBase in 'Views\TalkViews\UITalkFormBase.pas',
+  UITalkPersonalForm in 'Views\TalkViews\UITalkPersonalForm.pas',
+  UITalkTeamForm in 'Views\TalkViews\UITalkTeamForm.pas',
+  UserCardView in 'Views\UserViews\UserCardView.pas' {UserCardViewForm},
+  UserCardDetailView in 'Views\UserViews\UserCardDetailView.pas' {UserCardDetailViewForm},
+  Authority in 'Windows\Authority.pas',
+  RealICQUtility in 'Utility\RealICQUtility.pas',
+  SendFolderFrm in 'SendFolderFrm.pas' {SendFolderForm},
+  ShareUtils in 'ShareUtils.pas',
+  SMSFrm in 'SMSFrm.pas' {SMSForm},
+  SystemMessageFrm in 'SystemMessageFrm.pas' {SystemMessageForm},
+  TalkingFrm in 'TalkingFrm.pas' {TalkingForm},
+  TeamOptionsFrm in 'TeamOptionsFrm.pas' {TeamOptionsForm},
+  TestCase in 'TestCase.pas' {Form6},
+  TrueHiddenMainFrm in 'TrueHiddenMainFrm.pas' {TrueHiddenMainForm},
+  U_SnapRect in 'U_SnapRect.pas',
+  MessagesManagerFrm in 'MessagesManagerFrm.pas' {MessagesManagerForm},
+  ModifyFaceFrm in 'ModifyFaceFrm.pas' {ModifyFaceForm},
+  MouseHook in 'MouseHook.pas',
+  MoveFaceFrm in 'MoveFaceFrm.pas' {MoveFaceForm},
+  MultiSendSMSFrm in 'MultiSendSMSFrm.pas' {MultiSendSMSForm},
+  MyInputBoxFrm in 'MyInputBoxFrm.pas' {MyInputBoxForm},
+  NotifyAlertFrm in 'NotifyAlertFrm.pas' {NotifyAlertForm},
+  NotReadMessageBoxFrm in 'NotReadMessageBoxFrm.pas' {NotReadMessageBoxForm},
+  OnlineOfflineAlertFrm in 'OnlineOfflineAlertFrm.pas' {OnlineOfflineAlertForm},
+  OptionsFrm in 'OptionsFrm.pas' {OptionsForm},
+  ProcessingFrm in 'ProcessingFrm.pas' {ProcessingForm},
+  QRCodeFrm in 'QRCodeFrm.pas' {QRCodeForm},
+  QueryIpWry in 'QueryIpWry.pas',
+  RealICQ_TLB in 'RealICQ_TLB.pas',
+  RealICQModel in 'RealICQModel.pas',
+  RealOAMessengerAutoServer in 'RealOAMessengerAutoServer.pas',
+  ReceiveFolderRequestFrm in 'ReceiveFolderRequestFrm.pas' {ReceiveFolderRequestForm},
+  RegFrm in 'RegFrm.pas' {RegForm},
+  AboutFrm in 'AboutFrm.pas' {AboutForm},
+  BaseScope in 'WebApps\BaseScope.pas',
+  BaseWebApp in 'WebApps\BaseWebApp.pas',
+  UserCardScope in 'WebApps\UserCardScope.pas',
+  UserCardWebApp in 'WebApps\UserCardWebApp.pas',
+  SettingWebApp in 'WebApps\SettingWebApp.pas',
+  SettingScope in 'WebApps\SettingScope.pas',
+  SettingService in 'Services\SettingService.pas',
+  TalkPersonalView in 'Views\TalkPersonalView.pas' {TalkPersonalForm},
+  BaseIDView in 'Views\BaseIDView.pas' {BaseIDViewForm},
+  UploaderTask in 'FileTransimt\UploaderTask.pas';
+
 {$R *.res}
 {$R uac.res}
 

+ 1 - 0
Client/Lxtalk.dproj

@@ -114,6 +114,7 @@
     <DCCReference Include="FileTransimt\HTTPFileDownloader.pas" />
     <DCCReference Include="FileTransimt\OfflineFileConfig.pas" />
     <DCCReference Include="FileTransimt\TransmiteFileMission.pas" />
+    <DCCReference Include="FileTransimt\UploaderTask.pas" />
     <DCCReference Include="FileTransimt\UploadOrDownloadFileMission.pas" />
     <DCCReference Include="FormController\MainFormContrller.pas" />
     <DCCReference Include="FormController\MainFormFooter.pas">

+ 3 - 1
Client/Services/MessagesHander.pas

@@ -30,7 +30,8 @@ implementation
 uses
   superobject, FriendsService, WorkmatesService, TeamsService, LoggerImport,
   UsersService, BranchService, MainFrm, UsersProcessor, CompanyProcessor,
-  BranchsProcessor, FriendsProcessor, TeamsProcessor, UserRemarkService;
+  BranchsProcessor, FriendsProcessor, TeamsProcessor, UserRemarkService,
+  TextMessageService;
 
 var
   AMessagesHander: TMessagesHander;
@@ -103,6 +104,7 @@ begin
   TWorkmatesService.GetService.Init;
   TTeamsService.GetService.Init;
   TUserRemarkService.GetService.Init;
+  TTextMessageService.GetService.Init;
 
   AThreadPool := TIdSchedulerOfThreadPool.Create(nil);
   AThreadPool.Init;

+ 461 - 413
Client/Services/TextMessageService.pas

@@ -1,449 +1,497 @@
 unit TextMessageService;
-
-interface
-
-uses
-  BaseService, PerlRegEx, Classes, SysUtils, StrUtils, RealICQModel, Forms;
-
-type
-  TTextMessageService = class(TBaseService)
-  private
-    function GetImageReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
-    function GetMapReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
-    function GetVoiceReplacementStr(AVoiceUrl: string): string;
-    function GetGradeReplacementStr(AGradeUrl: string; AShowForm: Boolean = False): string;
-
-  public
-    procedure HandleAsycTextMessage(AData: Array of Byte);
-
-    function PreProccess(ATalkingForm: TForm; ASender: String; AMessageContent: string; AShowCustomFace: Boolean = True): string;
-    function ContentFilter(AMsg: TRealICQMessage): string;
-    constructor Create;
-    destructor Destroy; override;
-    class function GetService: TTextMessageService; static;
-  end;
-
-implementation
-
-uses
-  Windows, RealICQDBHistory, MainFrm, TalkingFrm, IdURI, ShareUtils,
-  DownloadFaceWithHttp, RealICQClient, MessagesHander, HttpDownloader, MD5, BaseChromeView,
-  UsersService;
-
-var
-  ATextMessageService: TTextMessageService;
-
-const
-  IMAGE_LOADED_TAG: string = '<img oncontextmenu="location.href=''FaceMenu_%s'';return false;" src="%s" align="absBottom" hspace="1" onload="AutoResizeImage(250,250,this)" onclick="openInIE(this)">';
-  IMAGE_LOADING_TAG: string = '<img ID = "%s" oncontextmenu="location.href=''FaceMenu_%s'';return false;" src="%s" align="absBottom" hspace="1" onload="AutoResizeImage(250,250,this)" onclick="openInIE(this)">';
-  VOICE_TAG: string = '<object id="%s" width="300" height="63" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=7.0" align="top" border="0" type="application/x-oleobject">' +
-     '<param name="URL" value="%s">' +
-     '<param name="AUTOSTART" value="0">' +
-     '<param name="uiMode" value="mini">' +
-     '</object>';
+
+interface
+
+uses
+  BaseService, PerlRegEx, Classes, SysUtils, StrUtils, RealICQModel, Forms;
+
+type
+  TTextMessageService = class(TBaseService)
+  private
+    FMessages, FTeamMessages: TStringList;
+    function GetImageReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
+    function GetMapReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
+    function GetVoiceReplacementStr(AVoiceUrl: string): string;
+    function GetGradeReplacementStr(AGradeUrl: string; AShowForm: Boolean = False): string;
+    procedure OnUploaded(ASender: TObject);
+    procedure UploadFaces(AMsg: TObject; AFaces: TStringList);
+  public
+    procedure HandleAsycTextMessage(AData: array of Byte);
+    procedure SendMessage(AMsg: TRealICQMessage; AFaces: TStringList); overload;
+    procedure SendMessage(AMsg: TRealICQTeamMessage; AFaces: TStringList); overload;
+    function CreateMessage: TRealICQMessage;
+    function CreateTeamMessage: TRealICQTeamMessage;
+    function GetMessage(AMessageID: string): TRealICQMessage;
+    function GetTeamMessage(AMessageID: string): TRealICQTeamMessage;
+    function PreProccess(ATalkingForm: TForm; ASender: string; AMessageContent: string; AShowCustomFace: Boolean = True): string;
+    function ContentFilter(AMsg: TRealICQMessage): string;
+    procedure Init;
+    procedure Uninstall;
+    constructor Create;
+    destructor Destroy; override;
+    class function GetService: TTextMessageService; static;
+  end;
+
+implementation
+
+uses
+  Windows, RealICQDBHistory, MainFrm, TalkingFrm, IdURI, ShareUtils,
+  DownloadFaceWithHttp, RealICQClient, MessagesHander, HttpDownloader, MD5,
+  BaseChromeView, UsersService, RealICQUtility;
+
+var
+  ATextMessageService: TTextMessageService;
+
+const
+  IMAGE_LOADED_TAG: string = '<img oncontextmenu="location.href=''FaceMenu_%s'';return false;" src="%s" align="absBottom" hspace="1" onload="AutoResizeImage(250,250,this)" onclick="openInIE(this)">';
+  IMAGE_LOADING_TAG: string = '<img ID = "%s" oncontextmenu="location.href=''FaceMenu_%s'';return false;" src="%s" align="absBottom" hspace="1" onload="AutoResizeImage(250,250,this)" onclick="openInIE(this)">';
+  VOICE_TAG: string = '<object id="%s" width="300" height="63" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=7.0" align="top" border="0" type="application/x-oleobject">' + '<param name="URL" value="%s">' + '<param name="AUTOSTART" value="0">' + '<param name="uiMode" value="mini">' + '</object>';
   MAP_IFRAME_TAG: string = '<iframe src="%s" frameborder="no" border="0" ></iframe>';
 { TTextMessageService }
-
-function TTextMessageService.ContentFilter(AMsg: TRealICQMessage): string;
-var
-  reg: TPerlRegEx;
-begin
-  reg := TPerlRegEx.Create;
-  try
-    reg.Subject := AMsg.MessageStr;
-    reg.RegEx := '\[(\w+)\-src=\"(http://[\w\W]+)\"]';
-    while reg.MatchAgain do
-    begin
-      if CompareText(reg.Groups[1], 'grade') = 0 then
-      begin
-        reg.Replacement := GetGradeReplacementStr(
-          reg.Groups[2],
-          not SameText(TUsersService.GetUsersService.GetMe.LoginName, AMsg.Sender));
-        reg.Subject := reg.Replace();
-      end;
-    end;
-    Result := reg.Subject;
-  finally
-    reg.Free;
-  end;       
-end;
-
-constructor TTextMessageService.Create;
-begin
-  inherited;
-end;
-
-destructor TTextMessageService.Destroy;
-begin
-
-  inherited;
-end;
-
-class function TTextMessageService.GetService: TTextMessageService;
-begin
-  if ATextMessageService = nil then
-    ATextMessageService := TTextMessageService.Create;
-
-  Result := ATextMessageService;
-end;
-
-function TTextMessageService.GetGradeReplacementStr(AGradeUrl: string; AShowForm: Boolean = False): string;
-var
-  AForm: TBaseChromeViewForm;
-begin
-  Result := '请您为我们这次服务给个评分或提个建议,谢谢!';
-  if AShowForm then
-  begin
-    AForm := TBaseChromeViewForm.Create(nil);
-    
-    try
-      AForm.Caption := '评分系统';
-      AForm.ChangeUIColor(MainForm.FormColor);
-      AForm.Width := 720;
-      AForm.Height := 394;
-      AForm.Top := (Screen.Height - 394) div 2;
-      AForm.Left := (Screen.Width - 720) div 2;
-      AForm.URL := AnsiReplaceText(AGradeUrl, '&amp;', '&');
-      AForm.Show;
-    finally
-
-    end;
-  end;           
-end;
-
-function TTextMessageService.GetVoiceReplacementStr(AVoiceUrl: string): string;
-var
-  AMD5String, ALocalPath, AFileName, AFaceID: string;
-  AURL: TIdURI;
-  ATask: THttpDownloader;
-  WaitingFace: TWaitingFace;
-
+
+
+function TTextMessageService.ContentFilter(AMsg: TRealICQMessage): string;
+var
+  reg: TPerlRegEx;
+begin
+  reg := TPerlRegEx.Create;
+  try
+    reg.Subject := AMsg.MessageStr;
+    reg.RegEx := '\[(\w+)\-src=\"(http://[\w\W]+)\"]';
+    while reg.MatchAgain do
+    begin
+      if CompareText(reg.Groups[1], 'grade') = 0 then
+      begin
+        reg.Replacement := GetGradeReplacementStr(reg.Groups[2], not SameText(TUsersService.GetUsersService.GetMe.LoginName, AMsg.Sender));
+        reg.Subject := reg.Replace();
+      end;
+    end;
+    Result := reg.Subject;
+  finally
+    reg.Free;
+  end;
+end;
+
+constructor TTextMessageService.Create;
+begin
+  FMessages := TStringList.Create;
+  FTeamMessages := TStringList.Create;
+  inherited;
+end;
+
+function TTextMessageService.CreateMessage: TRealICQMessage;
+begin
+  Result := TRealICQMessage.Create(MainForm.RealICQClient.LoginName, '', '', '', False);
+
+  with Result do
+  begin
+    MessageID := GetTickCount;
+    while FMessages.IndexOf(IntToStr(MessageID)) >= 0 do
+    begin
+      Sleep(100);
+      MessageID := GetTickCount;
+    end;
+    SendDateTime := Now;
+    FMessages.InsertObject(0, IntToStr(MessageID), Result);
+  end;
+end;
+
+function TTextMessageService.CreateTeamMessage: TRealICQTeamMessage;
+begin
+  Result := TRealICQTeamMessage.Create('', '', '', '', False);
+  with Result do
+  begin
+    MessageID := GetTickCount;
+    while FTeamMessages.IndexOf(IntToStr(MessageID)) >= 0 do
+    begin
+      Sleep(100);
+      MessageID := GetTickCount;
+    end;
+    SendDateTime := Now;
+    FTeamMessages.InsertObject(0, IntToStr(MessageID), Result);
+  end;
+end;
+
+destructor TTextMessageService.Destroy;
+begin
+  TRealICQUtility.FreeStringList(FMessages);
+  TRealICQUtility.FreeStringList(FTeamMessages);
+  inherited;
+end;
+
+class function TTextMessageService.GetService: TTextMessageService;
+begin
+  if ATextMessageService = nil then
+    ATextMessageService := TTextMessageService.Create;
+
+  Result := ATextMessageService;
+end;
+
+function TTextMessageService.GetTeamMessage(AMessageID: string): TRealICQTeamMessage;
+var
+  i: Integer;
+begin
+  i := FMessages.IndexOf(AMessageID);
+  if i > -1 then
+    Result := FMessages.Objects[i] as TRealICQTeamMessage;         
+end;
+
+function TTextMessageService.GetGradeReplacementStr(AGradeUrl: string; AShowForm: Boolean = False): string;
+var
+  AForm: TBaseChromeViewForm;
+begin
+  Result := '请您为我们这次服务给个评分或提个建议,谢谢!';
+  if AShowForm then
+  begin
+    AForm := TBaseChromeViewForm.Create(nil);
+
+    try
+      AForm.Caption := '评分系统';
+      AForm.ChangeUIColor(MainForm.FormColor);
+      AForm.Width := 720;
+      AForm.Height := 394;
+      AForm.Top := (Screen.Height - 394) div 2;
+      AForm.Left := (Screen.Width - 720) div 2;
+      AForm.URL := AnsiReplaceText(AGradeUrl, '&amp;', '&');
+      AForm.Show;
+    finally
+
+    end;
+  end;
+end;
+
+function TTextMessageService.GetVoiceReplacementStr(AVoiceUrl: string): string;
+var
+  AMD5String, ALocalPath, AFileName, AFaceID: string;
+  AURL: TIdURI;
+  ATask: THttpDownloader;
+  WaitingFace: TWaitingFace;
 begin
 //  Result := Format(MAP_IFRAME_TAG, [ExtractFilePath(Application.ExeName) + 'html\mp3.html']);
-  AURL := TIdURI.Create();
-  AURL.URI := AVoiceUrl;
-
-  AMD5String := ChangeFileExt(ExtractFileName(AURL.Document),'');
-  if not (CompareText(ExtractFileExt(AURL.Document), '.mp3') = 0) then
-  begin
-    Result := '对不起,目前只支持MP3音频格式';
-    AURL.Free;
-    Exit;
-  end;
-
-  ALocalPath := TRealICQClient.GetReceivedFaceDir + ExtractFileName(AURL.Document);
+
+
+  AURL := TIdURI.Create();
+  AURL.URI := AVoiceUrl;
+
+  AMD5String := ChangeFileExt(ExtractFileName(AURL.Document), '');
+  if not (CompareText(ExtractFileExt(AURL.Document), '.mp3') = 0) then
+  begin
+    Result := '对不起,目前只支持MP3音频格式';
+    AURL.Free;
+    Exit;
+  end;
+
+  ALocalPath := TRealICQClient.GetReceivedFaceDir + ExtractFileName(AURL.Document);
   AFileName := ReplaceStr(ALocalPath, '\', '/');
 //  Dialog.ShowMessage(Format(VOICE_TAG, ['voice_'+AMD5String, AFileName]));
-  Result := Format(VOICE_TAG, ['voice_'+AMD5String, AFileName]);
-  if not FileExists(ALocalPath) then
-  begin
-    ATask := THttpDownloader.Create(AURL.URI, ALocalPath, AThreadPool.AcquireYarn);
-    AThreadPool.StartYarn(ATask.Yarn, ATask);
-  end;
-
-  AURL.Free;
-end;
-
-procedure TTextMessageService.HandleAsycTextMessage(AData: array of Byte);
-var
-  FontStrLength,
-  SenderLoginNameLength,
-  ReceiverLoginNameLength: Byte;
-
-  nIndex,  IsEncry,
-  MessageStrLength: SmallInt;
-
-  MessageID: Cardinal;
-  SendDateTime: TDateTime;
-
-  SenderLoginName,
-  ReceiverLoginName,
-  FontStr,
-  MessageStr: String;
-
-  RealICQMessage: TRealICQMessage;
-  RealICQUser: TRealICQUser;
-
-  TalkingForm: TTalkingForm;
-begin
-  nIndex := 0;
+
+
+  Result := Format(VOICE_TAG, ['voice_' + AMD5String, AFileName]);
+  if not FileExists(ALocalPath) then
+  begin
+    ATask := THttpDownloader.Create(AURL.URI, ALocalPath, AThreadPool.AcquireYarn);
+    AThreadPool.StartYarn(ATask.Yarn, ATask);
+  end;
+
+  AURL.Free;
+end;
+
+procedure TTextMessageService.HandleAsycTextMessage(AData: array of Byte);
+var
+  FontStrLength, SenderLoginNameLength, ReceiverLoginNameLength: Byte;
+  nIndex, IsEncry, MessageStrLength: SmallInt;
+  MessageID: Cardinal;
+  SendDateTime: TDateTime;
+  SenderLoginName, ReceiverLoginName, FontStr, MessageStr: string;
+  RealICQMessage: TRealICQMessage;
+  RealICQUser: TRealICQUser;
+  TalkingForm: TTalkingForm;
+begin
+  nIndex := 0;
 
   //取 (3)接收人用户名长度            1byte
-  CopyMemory(@ReceiverLoginNameLength, @AData[nIndex], 1);
-  Inc(nIndex, 1);
+  CopyMemory(@ReceiverLoginNameLength, @AData[nIndex], 1);
+  Inc(nIndex, 1);
 
   //取 (4)接收人用户名                动态长度,由(3)指定,接收消息的用户的用户名,如果是服务器中转此处会变成消息的发送人。
-  SetLength(ReceiverLoginName, ReceiverLoginNameLength);
-  CopyMemory(PChar(ReceiverLoginName), @AData[nIndex], ReceiverLoginNameLength);
-  Inc(nIndex, ReceiverLoginNameLength);
+  SetLength(ReceiverLoginName, ReceiverLoginNameLength);
+  CopyMemory(PChar(ReceiverLoginName), @AData[nIndex], ReceiverLoginNameLength);
+  Inc(nIndex, ReceiverLoginNameLength);
 
   //取 (5)发送人用户名长度            1byte
-  CopyMemory(@SenderLoginNameLength, @AData[nIndex], 1);
-  Inc(nIndex, 1);
+  CopyMemory(@SenderLoginNameLength, @AData[nIndex], 1);
+  Inc(nIndex, 1);
 
   //取 (6)发送人用户名                动态长度,由(5)指定。
-  SetLength(SenderLoginName, SenderLoginNameLength);
-  CopyMemory(PChar(SenderLoginName), @AData[nIndex], SenderLoginNameLength);
-  Inc(nIndex, SenderLoginNameLength);
+  SetLength(SenderLoginName, SenderLoginNameLength);
+  CopyMemory(PChar(SenderLoginName), @AData[nIndex], SenderLoginNameLength);
+  Inc(nIndex, SenderLoginNameLength);
 
   
   //取 (7)消息的编号                  4byte,无符号32位整型数据
-  CopyMemory(@MessageID, @AData[nIndex], 4);
-  Inc(nIndex, 4);
+  CopyMemory(@MessageID, @AData[nIndex], 4);
+  Inc(nIndex, 4);
   
   //取 (8)发送消息的时间              8byte,64位浮点类型(double即TDateTime类型)
-  CopyMemory(@SendDateTime, @AData[nIndex], 8);
-  Inc(nIndex, 8);
+  CopyMemory(@SendDateTime, @AData[nIndex], 8);
+  Inc(nIndex, 8);
   
   //取 (9)字体信息长度                1byte,
-  CopyMemory(@FontStrLength, @AData[nIndex], 1);
-  Inc(nIndex, 1);
+  CopyMemory(@FontStrLength, @AData[nIndex], 1);
+  Inc(nIndex, 1);
 
   //取 (10)字体信息                   动态长度,由(9)指定。
-  SetLength(FontStr, FontStrLength);
-  CopyMemory(PChar(FontStr), @AData[nIndex], FontStrLength);
-  Inc(nIndex, FontStrLength);
+  SetLength(FontStr, FontStrLength);
+  CopyMemory(PChar(FontStr), @AData[nIndex], FontStrLength);
+  Inc(nIndex, FontStrLength);
   
   
   //取 (11)消息的长度                 2byte,无符号16位整型。
-  CopyMemory(@MessageStrLength, @AData[nIndex], 2);
-  Inc(nIndex, 2);
+  CopyMemory(@MessageStrLength, @AData[nIndex], 2);
+  Inc(nIndex, 2);
 
   //取 (12)消息内容                   动态长度,由(11)指定。
-  SetLength(MessageStr, MessageStrLength);
-  CopyMemory(PChar(MessageStr), @AData[nIndex], MessageStrLength);
-  Inc(nIndex, MessageStrLength);
+  SetLength(MessageStr, MessageStrLength);
+  CopyMemory(PChar(MessageStr), @AData[nIndex], MessageStrLength);
+  Inc(nIndex, MessageStrLength);
 
    //取(11)是否是私密消息
-  CopyMemory(@IsEncry, @AData[nIndex], 1);
-
-  RealICQMessage := TRealICQMessage.Create(SenderLoginName,
-                                         ReceiverLoginName,
-                                         FontStr,
-                                         MessageStr,IsEncry=1);
+  CopyMemory(@IsEncry, @AData[nIndex], 1);
+
+  RealICQMessage := TRealICQMessage.Create(SenderLoginName, ReceiverLoginName, FontStr, MessageStr, IsEncry = 1);
   RealICQMessage.MessageID := GetTickCount; //设为接收到此消息的时间,以便及时删除无用的消息
-  RealICQMessage.SendDateTime := SendDateTime;
-
-  MainForm.DBHistory.SaveMessage('-1', RealICQMessage.Sender, RealICQMessage.Receiver,
-        RealICQMessage.SendDateTime,
-        RealICQMessage.FontStr,
-        RealICQMessage.MessageStr,RealICQMessage.IsEncryMessage);
-  TalkingForm := GetTalkingForm(ReceiverLoginName, MainForm.RealICQClient);
-  if (TalkingForm <> nil) and (TalkingForm.CanWriteMessage) then
-  begin
-    TalkingForm.ShowMessage(RealICQMessage, false);
-  end;
-end;
-
-function TTextMessageService.PreProccess(ATalkingForm: TForm; ASender: String; AMessageContent: string; AShowCustomFace: Boolean = True): string;
-var
-  Face: TFace;
-  iLoop,
-  iStart,
-  iIndex: Integer;
-  MD5String: String;
-  WaitingFace: TWaitingFace;
-  FaceID,
-  AFileName,
-  ContextMenuStr: String;
-  reg: TPerlRegEx;
-
-  procedure ReplacesTag;
-  begin
-    while reg.MatchAgain do
-    begin
-      MD5String := reg.Groups[1];
-      iIndex := MainForm.FaceList.IndexOf(MD5String);
-      if not AShowCustomFace then
-      begin
-        AFileName := ReplaceStr(FindRecvedFace(MD5String), '\', '/');
-        FaceID := MD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count) + IntToStr(iStart);
-        reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
-        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
-      end
-      else if iIndex >= 0  then
-      begin
-        Face := MainForm.FaceList.Objects[iIndex] as TFace;
-        reg.Replacement := Format(IMAGE_LOADED_TAG, [MD5String, Face.FileName]);
-        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
-      end
-      else if FileExists(FindRecvedFace(MD5String)) then
-      begin
-        AFileName := ReplaceStr(FindRecvedFace(MD5String), '\', '/');
-        reg.Replacement := Format(IMAGE_LOADED_TAG, [MD5String, AFileName]);
-        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
-      end
-      else
-      begin
-        if ATalkingForm <> nil then
-          with (ATalkingForm as TTalkingForm) do
-          begin
-            AFileName := ExtractFilePath(Application.ExeName) + 'Images\progress.gif';
-            AFileName := ReplaceStr(AFileName, '\', '/');
-            FaceID := MD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count) + IntToStr(iStart);
-            reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
-            reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
-
-            if WaitingFaces.IndexOf(MD5String) <> -1 then
-              Continue;
-
-            if Category = tcNormal then
-              FRealICQClient.PleaseSendFaceToMe(Receiver, MD5String)
-            else
-              FRealICQClient.DownloadTeamFace(ASender, MD5String);
-
-            if AShowCustomFace then
-            begin
-              WaitingFace := TWaitingFace.Create;
-              WaitingFace.FFaceMD5Code := MD5String;
-              WaitingFace.FWebBrowser := WebBrowser;
-              WaitingFace.FFaceID := FaceID;
-              WaitingFaces.AddObject(MD5String, WaitingFace);
-            end;
-          end
-        else
-        begin
-          AFileName := ExtractFilePath(Application.ExeName) + 'Images\erre.gif';
-          AFileName := ReplaceStr(AFileName, '\', '/');
-          FaceID := MD5String + IntToStr(GetTickCount);
-          reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
-          reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
-        end;
-      end;
-    end;
-  end;
-begin
-  reg := TPerlRegEx.Create;
-  try
-    reg.Subject := AMessageContent;
-    reg.RegEx   := '\[(\w+)\-src=\"(http://[\w\W]+?)\"\]';
-
-    while reg.MatchAgain do
-    begin
-      if CompareText(reg.Groups[1], 'IMAGE') = 0 then
-      begin
-        reg.Replacement := GetImageReplacementStr(reg.Groups[2], ATalkingForm);
-        reg.Subject := reg.Replace();
-      end
-      else if CompareText(reg.Groups[1], 'MAP') = 0 then
-      begin
-        reg.Replacement := GetMapReplacementStr(reg.Groups[2], ATalkingForm);
-        reg.Subject := reg.Replace();
-      end
-      else if CompareText(reg.Groups[1], 'voice') = 0 then
-      begin
-        reg.Replacement := GetVoiceReplacementStr(reg.Groups[2]);
-        reg.Subject := reg.Replace();
-      end;
-    end;
-    AMessageContent  := reg.Subject;
-  finally
-    reg.Free;
-  end;
-
-  reg := TPerlRegEx.Create;
-  try
-    reg.Subject := AMessageContent;
-    reg.RegEx   := '\[IMG:([\w\W]+?)\]';
-    ReplacesTag;
-
-    reg.RegEx   := '\[image\-src=\"([\w\W]+?)\"\]';
-    ReplacesTag;
-    AMessageContent := reg.Subject;
-  finally
-    reg.Free;
-  end;
+
+
+  RealICQMessage.SendDateTime := SendDateTime;
+
+  MainForm.DBHistory.SaveMessage('-1', RealICQMessage.Sender, RealICQMessage.Receiver, RealICQMessage.SendDateTime, RealICQMessage.FontStr, RealICQMessage.MessageStr, RealICQMessage.IsEncryMessage);
+  TalkingForm := GetTalkingForm(ReceiverLoginName, MainForm.RealICQClient);
+  if (TalkingForm <> nil) and (TalkingForm.CanWriteMessage) then
+  begin
+    TalkingForm.ShowMessage(RealICQMessage, false);
+  end;
+end;
+
+procedure TTextMessageService.Init;
+begin
+  TRealICQUtility.ClearStringList(FMessages);
+  TRealICQUtility.ClearStringList(FTeamMessages);
+end;
+
+function TTextMessageService.PreProccess(ATalkingForm: TForm; ASender: string; AMessageContent: string; AShowCustomFace: Boolean = True): string;
+var
+  Face: TFace;
+  iLoop, iStart, iIndex: Integer;
+  MD5String: string;
+  WaitingFace: TWaitingFace;
+  FaceID, AFileName, ContextMenuStr: string;
+  reg: TPerlRegEx;
+
+  procedure ReplacesTag;
+  begin
+    while reg.MatchAgain do
+    begin
+      MD5String := reg.Groups[1];
+      iIndex := MainForm.FaceList.IndexOf(MD5String);
+      if not AShowCustomFace then
+      begin
+        AFileName := ReplaceStr(FindRecvedFace(MD5String), '\', '/');
+        FaceID := MD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count) + IntToStr(iStart);
+        reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
+        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
+      end
+      else if iIndex >= 0 then
+      begin
+        Face := MainForm.FaceList.Objects[iIndex] as TFace;
+        reg.Replacement := Format(IMAGE_LOADED_TAG, [MD5String, Face.FileName]);
+        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
+      end
+      else if FileExists(FindRecvedFace(MD5String)) then
+      begin
+        AFileName := ReplaceStr(FindRecvedFace(MD5String), '\', '/');
+        reg.Replacement := Format(IMAGE_LOADED_TAG, [MD5String, AFileName]);
+        reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
+      end
+      else
+      begin
+        if ATalkingForm <> nil then
+          with (ATalkingForm as TTalkingForm) do
+          begin
+            AFileName := ExtractFilePath(Application.ExeName) + 'Images\progress.gif';
+            AFileName := ReplaceStr(AFileName, '\', '/');
+            FaceID := MD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count) + IntToStr(iStart);
+            reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
+            reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
+
+            if WaitingFaces.IndexOf(MD5String) <> -1 then
+              Continue;
+
+            if Category = tcNormal then
+              FRealICQClient.PleaseSendFaceToMe(Receiver, MD5String)
+            else
+              FRealICQClient.DownloadTeamFace(ASender, MD5String);
+
+            if AShowCustomFace then
+            begin
+              WaitingFace := TWaitingFace.Create;
+              WaitingFace.FFaceMD5Code := MD5String;
+              WaitingFace.FWebBrowser := WebBrowser;
+              WaitingFace.FFaceID := FaceID;
+              WaitingFaces.AddObject(MD5String, WaitingFace);
+            end;
+          end
+        else
+        begin
+          AFileName := ExtractFilePath(Application.ExeName) + 'Images\erre.gif';
+          AFileName := ReplaceStr(AFileName, '\', '/');
+          FaceID := MD5String + IntToStr(GetTickCount);
+          reg.Replacement := Format(IMAGE_LOADING_TAG, [FaceID, MD5String, AFileName]);
+          reg.Subject := ReplaceStr(reg.Subject, reg.Groups[0], reg.Replacement);
+        end;
+      end;
+    end;
+  end;
+
+begin
+  reg := TPerlRegEx.Create;
+  try
+    reg.Subject := AMessageContent;
+    reg.RegEx := '\[(\w+)\-src=\"(http://[\w\W]+?)\"\]';
+
+    while reg.MatchAgain do
+    begin
+      if CompareText(reg.Groups[1], 'IMAGE') = 0 then
+      begin
+        reg.Replacement := GetImageReplacementStr(reg.Groups[2], ATalkingForm);
+        reg.Subject := reg.Replace();
+      end
+      else if CompareText(reg.Groups[1], 'MAP') = 0 then
+      begin
+        reg.Replacement := GetMapReplacementStr(reg.Groups[2], ATalkingForm);
+        reg.Subject := reg.Replace();
+      end
+      else if CompareText(reg.Groups[1], 'voice') = 0 then
+      begin
+        reg.Replacement := GetVoiceReplacementStr(reg.Groups[2]);
+        reg.Subject := reg.Replace();
+      end;
+    end;
+    AMessageContent := reg.Subject;
+  finally
+    reg.Free;
+  end;
+
+  reg := TPerlRegEx.Create;
+  try
+    reg.Subject := AMessageContent;
+    reg.RegEx := '\[IMG:([\w\W]+?)\]';
+    ReplacesTag;
+
+    reg.RegEx := '\[image\-src=\"([\w\W]+?)\"\]';
+    ReplacesTag;
+    AMessageContent := reg.Subject;
+  finally
+    reg.Free;
+  end;
 
  
   //取系统表情
-  for iLoop := 0 to MainForm.SystemFaceCount - 1 do
-  begin
-    Face := MainForm.FaceList.Objects[iLoop] as TFace;
-    ContextMenuStr := 'oncontextmenu="location.href=''StandardFaceMenu_' + Face.ShortCut + ''';return false;"';
-    AMessageContent := AnsiReplaceStr(AMessageContent,
-                                      Face.ShortCut,
-                                      '<img ' + ContextMenuStr + ' src="' + Face.FileName + '" align="absBottom" hspace="1" >');
-  end;
-
-
-  Result := AMessageContent;
-end;
-
-function TTextMessageService.GetImageReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
-var
-  AMD5String, ALocalPath, AFileName, AFaceID: string;
-  AURL: TIdURI;
-  ATask: TDownloadFaceTask;
-  WaitingFace: TWaitingFace;
-begin
-  AURL := TIdURI.Create();
-  AURL.URI := AImgUrl;
-  AMD5String := ChangeFileExt(ExtractFileName(AURL.Document),'');
-  ALocalPath := TRealICQClient.GetReceivedFaceDir + AMD5String + ExtractFileExt(AURL.Params);
-
-  if FileExists(ALocalPath) then
-  begin
-    AFileName := ReplaceStr(ALocalPath, '\', '/');
-    Result := Format(IMAGE_LOADED_TAG, [AMD5String, AFileName]);
-  end
-  else
-  begin
-    if ATalkingForm <> nil then
-    begin             
-      AFaceID := AMD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count);
-      AFileName := ExtractFilePath(Application.ExeName) + 'Images\progress.gif';
-      Result := Format(IMAGE_LOADING_TAG, [AFaceID, AMD5String, AFileName]);
-
-      WaitingFace := TWaitingFace.Create;
-      WaitingFace.FFaceMD5Code := AMD5String;
-      WaitingFace.FWebBrowser := (ATalkingForm as TTalkingForm).WebBrowser;
-      WaitingFace.FFaceID := AFaceID;
-      WaitingFaces.AddObject(AMD5String, WaitingFace);
-
-      ATask := TDownloadFaceTask.Create(AURL.URI, ALocalPath, AThreadPool.AcquireYarn);
-      AThreadPool.StartYarn(ATask.Yarn, ATask);
-    end
-    else
-    begin
-      AFaceID := AMD5String + IntToStr(GetTickCount);
-      AFileName := ExtractFilePath(Application.ExeName) + 'Images\error.gif';
-      Result := Format(IMAGE_LOADING_TAG, [AFaceID, AMD5String, AFileName]);
-    end;
-  end;
-
-  AURL.Free;
-end;
-
-function TTextMessageService.GetMapReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
-var
-  AMD5String, ALocalPath, AFileName, AFaceID: string;
-  ATask: TDownloadFaceTask;
-  WaitingFace: TWaitingFace;
-begin
-  Result := Format(MAP_IFRAME_TAG, [AnsiReplaceText(AImgUrl, '&amp;', '&')]);
-//  AMD5String := MD5En(AImgUrl);
-//  ALocalPath := TRealICQClient.GetReceivedFaceDir + AMD5String + '.png';
-//
-//  if FileExists(ALocalPath) then
-//  begin
-//    AFileName := ReplaceStr(ALocalPath, '\', '/');
-//    Result := Format(MAP_IFRAME_TAG, [AMD5String, AFileName]);
-//  end
-//  else
-//  begin
-//    AFaceID := AMD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count);
-//    AFileName := ExtractFilePath(Application.ExeName) + 'Images\progress.gif';
-//    Result := Format(IMAGE_LOADING_TAG, [AFaceID, AMD5String, AFileName]);
-//
-//    WaitingFace := TWaitingFace.Create;
-//    WaitingFace.FFaceMD5Code := AMD5String;
-//    WaitingFace.FWebBrowser := (ATalkingForm as TTalkingForm).WebBrowser;
-//    WaitingFace.FFaceID := AFaceID;
-//    WaitingFaces.AddObject(AMD5String, WaitingFace);
-//
-//    ATask := TDownloadFaceTask.Create(AImgUrl, ALocalPath, AThreadPool.AcquireYarn);
-//    AThreadPool.StartYarn(ATask.Yarn, ATask);
-//  end;
-end;
+  for iLoop := 0 to MainForm.SystemFaceCount - 1 do
+  begin
+    Face := MainForm.FaceList.Objects[iLoop] as TFace;
+    ContextMenuStr := 'oncontextmenu="location.href=''StandardFaceMenu_' + Face.ShortCut + ''';return false;"';
+    AMessageContent := AnsiReplaceStr(AMessageContent, Face.ShortCut, '<img ' + ContextMenuStr + ' src="' + Face.FileName + '" align="absBottom" hspace="1" >');
+  end;
+
+  Result := AMessageContent;
+end;
+
+procedure TTextMessageService.OnUploaded(ASender: TObject);
+begin
+
+end;
+
+procedure TTextMessageService.UploadFaces(AMsg: TObject; AFaces: TStringList);
+begin
+
+end;
+
+procedure TTextMessageService.SendMessage(AMsg: TRealICQTeamMessage; AFaces: TStringList);
+begin
+  if Assigned(AFaces) and (AFaces.Count > 0) then
+    UploadFaces(AMsg, AFaces)
+  else    
+  
+end;
+
+procedure TTextMessageService.Uninstall;
+begin
+
+end;
+
+procedure TTextMessageService.SendMessage(AMsg: TRealICQMessage; AFaces: TStringList);
+begin
+
+end;
+
+function TTextMessageService.GetImageReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
+var
+  AMD5String, ALocalPath, AFileName, AFaceID: string;
+  AURL: TIdURI;
+  ATask: TDownloadFaceTask;
+  WaitingFace: TWaitingFace;
+begin
+  AURL := TIdURI.Create();
+  AURL.URI := AImgUrl;
+  AMD5String := ChangeFileExt(ExtractFileName(AURL.Document), '');
+  ALocalPath := TRealICQClient.GetReceivedFaceDir + AMD5String + ExtractFileExt(AURL.Params);
+
+  if FileExists(ALocalPath) then
+  begin
+    AFileName := ReplaceStr(ALocalPath, '\', '/');
+    Result := Format(IMAGE_LOADED_TAG, [AMD5String, AFileName]);
+  end
+  else
+  begin
+    if ATalkingForm <> nil then
+    begin
+      AFaceID := AMD5String + IntToStr(GetTickCount) + IntToStr(WaitingFaces.Count);
+      AFileName := ExtractFilePath(Application.ExeName) + 'Images\progress.gif';
+      Result := Format(IMAGE_LOADING_TAG, [AFaceID, AMD5String, AFileName]);
+
+      WaitingFace := TWaitingFace.Create;
+      WaitingFace.FFaceMD5Code := AMD5String;
+      WaitingFace.FWebBrowser := (ATalkingForm as TTalkingForm).WebBrowser;
+      WaitingFace.FFaceID := AFaceID;
+      WaitingFaces.AddObject(AMD5String, WaitingFace);
+
+      ATask := TDownloadFaceTask.Create(AURL.URI, ALocalPath, AThreadPool.AcquireYarn);
+      AThreadPool.StartYarn(ATask.Yarn, ATask);
+    end
+    else
+    begin
+      AFaceID := AMD5String + IntToStr(GetTickCount);
+      AFileName := ExtractFilePath(Application.ExeName) + 'Images\error.gif';
+      Result := Format(IMAGE_LOADING_TAG, [AFaceID, AMD5String, AFileName]);
+    end;
+  end;
+
+  AURL.Free;
+end;
+
+function TTextMessageService.GetMapReplacementStr(AImgUrl: string; ATalkingForm: TForm): string;
+begin
+  Result := Format(MAP_IFRAME_TAG, [AnsiReplaceText(AImgUrl, '&amp;', '&')]);
+end;
+
+function TTextMessageService.GetMessage(AMessageID: string): TRealICQMessage;
+var
+  i: Integer;
+begin
+  i := FMessages.IndexOf(AMessageID);
+  if i > -1 then
+    Result := FMessages.Objects[i] as TRealICQMessage;
+end;
+
+end.
 
-end.

+ 1 - 1
Client/TalkingFrm.dfm

@@ -9071,7 +9071,7 @@ object TalkingForm: TTalkingForm
     Left = 48
     Top = 312
     Bitmap = {
-      494C010104000900E40110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
+      494C010104000900E80110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
       0000000000003600000028000000400000002000000001002000000000000020
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000

Fichier diff supprimé car celui-ci est trop grand
+ 7756 - 7747
Client/TalkingFrm.pas


+ 1 - 1
Controls/RealICQClient/RealICQClient.pas

@@ -1851,7 +1851,7 @@ begin
     RealICQMessage := SendedMessages.Objects[iLoop] as TRealICQMessage;
     if GetTickCount - RealICQMessage.MessageID >= 60000 then  //等待了60秒还未收到消息反馈,提示消息发送失败
     begin
-      FRealICQClient.Do(RealICQMessage);
+      FRealICQClient.DoSendMessageFailed(RealICQMessage);
       SendedMessages.Delete(iLoop);
     end
     else if GetTickCount - RealICQMessage.MessageID >= 30000 then //等待了30秒未收到消息反馈,转为服务器中转方式发送