📄 banlistupdate.cpp
字号:
void TBanlistUpdateForm::UpdateNextFile()
{
// move to next file unless first
if(CurrentFileItr == UpdateFiles.end())
CurrentFileItr = UpdateFiles.begin();
else
++CurrentFileItr;
for(; CurrentFileItr != UpdateFiles.end(); ++CurrentFileItr) {
// is this file selected?
TListItem* Item = FilesListView->FindData(0, (void*)(*CurrentFileItr), true, true);
if(!Item || !Item->Checked)
continue;
// update list view
// TRANSLATOR: list view entry shown when updating banlist file
Item->SubItems->Strings[0] = _("Updating...");
ProgressBar->Position = 0;
// found a file to update
string Url = (*CurrentFileItr)->Url;
Url += (Url.find('?') == -1) ? "?" : "&";
Url += Brand->GetUrlSignature();
// append challenge response to url
if ((*CurrentFileItr)->ChallengeStart >= 0 && (*CurrentFileItr)->ChallengeStop >= 0 &&
(*CurrentFileItr)->ChallengeStart <= (*CurrentFileItr)->ChallengeStop)
{
TKSHA1 Sha1;
if (Sha1.HashFile(Application->ExeName.c_str(), (*CurrentFileItr)->ChallengeStart,
(*CurrentFileItr)->ChallengeStop - (*CurrentFileItr)->ChallengeStart + 1))
{
unsigned char Digest[KSHA_DIGESTSIZE];
char *DigestStr;
Sha1.Final(Digest);
if((DigestStr = Base16Encode(Digest,KSHA_DIGESTSIZE)) != NULL) {
Url += (Url.find('?') == -1) ? "?key=" : "&key=";
Url += DigestStr;
delete[] DigestStr;
}
}
}
// create and start http download
Download = new THttpDownload(this->Handle, WM_DOWNLOAD_CB);
if(Download->Start(Url, TempFilePath)) {
// wait for download to complete / fail
return;
}
Download->Release();
UpdateErrors++;
// TRANSLATOR: list view entry shown when banlist update failed
Item->SubItems->Strings[0] = _("Failed");
}
// we finished
Download = NULL;
// TRANSLATOR: button caption when banlist updates are complete
UpdateBtn->Caption = _("Finish");
UpdateBtn->Enabled = true;
UpdateFinished = true;
// if in automatic mode click finish button to close dialog
if(Automatic)
UpdateBtnClick(NULL);
}
//---------------------------------------------------------------------------
void __fastcall TBanlistUpdateForm::WMDownloadCb(TMessage& Msg)
{
THttpDownload* Dl = (THttpDownload*)Msg.WParam;
switch(Dl->GetState()) {
case HttpDownloadActive:
// update progress bar
if(Dl->GetProgressMax() > 0)
ProgressBar->Position = Dl->GetProgress() * 100 / Dl->GetProgressMax();
else
ProgressBar->Position = 0;
break;
case HttpDownloadCancelling:
break;
case HttpDownloadCancelled:
// remove temp file
::DeleteFile(Dl->GetSavePath().c_str());
// release download
Dl->Release();
// do nothing else since the dialog was already closed by the cancel button
break;
case HttpDownloadFailed: {
// remove temp file
::DeleteFile(Dl->GetSavePath().c_str());
// release download
Dl->Release();
Download = NULL;
// download failed
UpdateErrors++;
TListItem* Item = FilesListView->FindData(0, (void*)(*CurrentFileItr), true, true);
if(Item) {
// TRANSLATOR: list view entry shown when banlist update failed
Item->SubItems->Strings[0] = _("Failed");
}
UpdateNextFile();
break;
}
case HttpDownloadCompleted: {
// remove old file
::DeleteFile((*CurrentFileItr)->SavePath.c_str());
// copy file
TListItem* Item = FilesListView->FindData(0, (void*)(*CurrentFileItr), true, true);
if(CopyDecompressFile(Dl->GetSavePath().c_str(),*CurrentFileItr)) {
// set creation time to now
SetFileCreateTime(*CurrentFileItr);
UpdatedFiles++;
if(Item) {
// TRANSLATOR: list view entry shown when banlist completed successfully
Item->SubItems->Strings[0] = _("Completed");
}
} else {
UpdateErrors++;
if(Item) {
// TRANSLATOR: list view entry shown when banlist update failed
Item->SubItems->Strings[0] = _("Failed");
}
}
// remove temp file
::DeleteFile(Dl->GetSavePath().c_str());
// release download
Dl->Release();
Download = NULL;
UpdateNextFile();
break;
}
}
}
//---------------------------------------------------------------------------
AnsiString TBanlistUpdateForm::GetFileStatus(const TUpdateFile* File)
{
#if 1
WIN32_FILE_ATTRIBUTE_DATA Fad;
// TRANSLATOR: list view entry of last banlist update
AnsiString Status = _("File looks OK");
if(GetFileAttributesEx(File->SavePath.c_str(), GetFileExInfoStandard, &Fad)) {
if(Fad.nFileSizeLow == 0 && Fad.nFileSizeHigh == 0) {
// TRANSLATOR: list view entry of last banlist update
Status = _("File is empty!");
}
} else {
// TRANSLATOR: list view entry of last banlist update
Status = _("File is missing!");
}
return Status;
#else
HANDLE hFile;
FILETIME TimeFT;
SYSTEMTIME TimeST;
ULARGE_INTEGER Time64;
unsigned int Now, CreateTime;
hFile = CreateFile(File->SavePath.c_str(),GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,0,NULL);
if(hFile == INVALID_HANDLE_VALUE)
// TRANSLATOR: list view entry of last banlist update
return _("Unknown");
if(!GetFileTime(hFile,&TimeFT,NULL,NULL)) {
CloseHandle(hFile);
// TRANSLATOR: list view entry of last banlist update
return _("Unknown");
}
CloseHandle(hFile);
// convert to unix time
Time64.LowPart = TimeFT.dwLowDateTime;
Time64.HighPart = TimeFT.dwHighDateTime;
CreateTime = (unsigned int)(Time64.QuadPart / 10000000);
// get current time
GetSystemTime(&TimeST);
if(!SystemTimeToFileTime(&TimeST, &TimeFT))
// TRANSLATOR: list view entry of last banlist update
return _("Unknown");
Time64.LowPart = TimeFT.dwLowDateTime;
Time64.HighPart = TimeFT.dwHighDateTime;
Now = (unsigned int)(Time64.QuadPart / 10000000);
if(File->Type != "nodes" && File->LastUpdate > 0) {
// if we have remote last update check if we are older
if(File->LastUpdate > CreateTime) {
// TRANSLATOR: list view entry of last banlist update
return _("Update available").c_str();
}
// TRANSLATOR: list view entry of last banlist update
return _("Up to date").c_str();
}
// for everything else show days since last update
int Days = ((Now / (60*60)) - (CreateTime / (60*60))) / 24;
if(Days <= 0) {
// TRANSLATOR: list view entry of last banlist update
return _("Updated today").c_str();
}
if(Days == 1) {
// TRANSLATOR: list view entry of last banlist update
return _("Updated yesterday").c_str();
}
// TRANSLATOR: list view entry of last banlist update
return AnsiString::Format(_("Updated %d days ago"),ARRAYOFCONST((Days))).c_str();
#endif
}
// copy temp file to real destination decompressing if necessary
bool TBanlistUpdateForm::CopyDecompressFile(const char* Src,
const TUpdateFile* DstFile)
{
switch (DstFile->Compression)
{
case TUpdateFile::CompressNone:
return ::CopyFile(Src,DstFile->SavePath.c_str(),FALSE);
case TUpdateFile::CompressGzip:
{
gzFile hSrc;
FILE* hDst;
char buf[1024*16];
int len;
if((hSrc = gzopen(Src, "rb")) == NULL)
return false;
if((hDst = fopen(DstFile->SavePath.c_str(), "wb")) == NULL) {
gzclose(hSrc);
return false;
}
while((len = gzread(hSrc,buf,sizeof(buf))) > 0) {
if(fwrite(buf,1,len,hDst) != (size_t)len) {
fclose(hDst);
gzclose(hSrc);
return false; // FIXME: leaves destination file in undetermined state
}
}
fclose(hDst);
gzclose(hSrc);
if(len < 0)
return false; // FIXME: leaves destination file in undetermined state
else
return true;
}
}
return false;
}
// set file create time to now
bool TBanlistUpdateForm::SetFileCreateTime(const TUpdateFile* File)
{
HANDLE hFile;
FILETIME CreationTime;
SYSTEMTIME SystemTime;
GetSystemTime(&SystemTime);
if(!SystemTimeToFileTime(&SystemTime, &CreationTime))
return false;
hFile = CreateFile(File->SavePath.c_str(),GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if(hFile == INVALID_HANDLE_VALUE)
return false;
if(!SetFileTime(hFile,&CreationTime,NULL,NULL)) {
CloseHandle(hFile);
return false;
}
CloseHandle(hFile);
return true;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -