Z
zero
First a short discription of my program. I have a bot that connects to
an internet chess server. Whenever the bot logs on, it loads certain
information from file, and puts it in STL containers (specifically sets &
maps). When disconnecting for any reason, the containers are converted
to strings, and saved to disk, so they can be loaded again when the bot
logs back on. Periodically (triggered by a timer event), the bot mails a
log to addresses contained in two of the maps. The same timer is used to
send the output buffer to the server (such a buffer is needed because if
you send too much data at once, the server closes the connection as a
security precaution). There is also a mechanism that automatically re-
connects the bot if it is disconnected.
Now the problem. If the bot disconnects a few times, the log gets mailed
normally the first time, but the next time it should be sent, all the
containters are empty! This of course means the log can't be sent,
'cause it gets the mail addresses from two of the containers. I have no
idea how or why this happens.
I'd appreciate any ideas on how to fix this.
Here are some parts of the code:
typedef std::map<AnsiString, int, myless> guideMap;
typedef std::map<AnsiString, AnsiString, myless> adrMap;
typedef std::set<AnsiString> headSet;
class GuideBot ublic CNBot
{
private:
int assistsAsked;
int unansweredAssists;
int guestAssists;
guideMap theGuides;
guideMap theAdmins;
headSet theTDHeads;
adrMap theAAdr;
adrMap theGAdr;
void handleLevel1Block();
void processTell(AnsiString tellFrom, AnsiString theTell, UINT type);
void findGAlias(AnsiString tellFrom, AnsiString theTell);
void findTDAlias(AnsiString tellFrom, AnsiString theTell);
void findAAlias(AnsiString tellFrom, AnsiString theTell);
void loadAll();
bool isHead(AnsiString user);
bool isGHead(AnsiString user);
bool isAHead(AnsiString user);
bool isTDHead(AnsiString user);
public:
GuideBot():CNBot() {}
GuideBot(AnsiString asHandle, AnsiString asPassword):CNBot(asHandle,
asPassword) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection):CNBot
(asFileName, tcsConnection) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection,
AnsiString asSection):CNBot(asFileName, tcsConnection, asSection) {}
~GuideBot() {}
void onConnect(TCustomWinSocket *Socket);
void saveAll();
void mailDump();
int countingSince;
};
void __fastcall TForm1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Bot->onConnect(Socket);
HandleEdit->Enabled = false;
PasswordEdit->Enabled = false;
CommandEdit->Enabled = true;
if(Application->ShowMainForm)
CommandEdit->SetFocus();
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Output->Lines->Add("**** DISCONNECTED ****");
HandleEdit->Enabled = true;
PasswordEdit->Enabled = true;
CommandEdit->Enabled = false;
Bot->saveAll();
if(Bot->stayConnected)
{
reconnectValue = 4000;
reconnectTimer = 0;
}
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
Bot->saveAll();
ErrorCode = 0;
ClientSocket->Close();
reconnectValue = 4000;
reconnectTimer = 0;
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::SendTimer(TObject *Sender)
{
reconnectTimer++;
if(reconnectTimer == reconnectValue)
{
reconnectValue = -1;
Connect1Click(Sender);
}
myCounter++;
if(Bot != NULL)
{
Bot->sendoBuffer(ClientSocket->Socket);
}
if(myCounter%120000 == 0) // every hour
{
Bot->saveAll();
Output->Clear();
}
// if(myCounter == 20160000) // every 7 days
if(myCounter == 2000)
{
Bot->mailDump();
myCounter = 0;
Bot->countingSince = myCounter;
Bot->saveAll();
}
}
void GuideBot:nConnect(TCustomWinSocket *Socket)
{
stayConnected = true;
AnsiString command;
command = setDGLevel();
Socket->SendText(command + char(10));
Socket->SendText(getHandle() + char(10));
Socket->SendText(getPassword() + char(10));
if(theGuides.begin() == theGuides.end())
int lalala = 0;
loadAll();
if(theGuides.begin() == theGuides.end())
int lalala = 0;
countingSince = Form1->myCounter;
}
void GuideBot::loadAll()
{
int iPos, answered;
AnsiString theLine, guideName;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
strList->LoadFromFile("guides.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theGuides.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("admins.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theAdmins.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("gheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theGAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("aheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theAAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("tdheads.ini");
for(int i = 0; i < strList->Count; i++)
theTDHeads.insert(strList->Strings);
}
__finally
{
delete strList; // destroy the list object
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
assistsAsked = times->ReadInteger("assists", "assistsAsked", 0);
guestAssists = times->ReadInteger("assists", "guestAssists", 0);
unansweredAssists = times->ReadInteger("assists", "unansweredAssists",
0);
delete times;
}
void GuideBot::saveAll()
{
AnsiString aLine;
int sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
times->WriteInteger("guides", "sec", sec);
times->WriteInteger("guides", "min", min);
times->WriteInteger("guides", "hour", hour);
times->WriteInteger("guides", "day", day);
times->WriteInteger("assists", "assistsAsked", assistsAsked);
times->WriteInteger("assists", "guestAssists", guestAssists);
times->WriteInteger("assists", "unansweredAssists",
unansweredAssists);
delete times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"settings.ini");
times->WriteInteger("Program", "myCounter", Form1->myCounter);
delete times;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("guides.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theAdmins.begin(); itr != theAdmins.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
strList->SaveToFile("admins.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theGAdr.begin(); itr != theGAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("gheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theAAdr.begin(); itr != theAAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("aheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
headSet::iterator itr;
for(itr = theTDHeads.begin(); itr != theTDHeads.end(); itr++)
strList->Add(*itr);
// if(strList->Count > 0)
strList->SaveToFile("tdheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
}
void GuideBot::mailDump()
{
if(theGuides.begin() == theGuides.end())
{
loadAll();
return;
}
TIniFile *times;
int total = 0;
int guides = 0;
int sec;
AnsiString ending1, ending2, aLine;
guideMap::iterator itr1;
adrMap::iterator itr2;
TStringList *strList;
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
sec += times->ReadInteger("guides", "sec", 0);
min += times->ReadInteger("guides", "min", 0);
hour += times->ReadInteger("guides", "hour", 0);
day += times->ReadInteger("guides", "day", 0);
delete times;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
ending1.sprintf("Counting since %i days, %i hours, %i minutes and %i
seconds.", day, hour, min, sec);
ending2.sprintf("%i assists were asked, of which %i (%2.1f%%) were
guest assists. %i assists were left unanswered (%2.1f%%)", assistsAsked,
guestAssists, ((assistsAsked == 0) ? 0.0 : ((float)guestAssists/(float)
assistsAsked)*100), unansweredAssists, ((assistsAsked == 0) ? 0.0 :
((float)unansweredAssists/(float)assistsAsked)*100));
strList = new TStringList();
try
{
for(itr1 = theGuides.begin(); itr1 != theGuides.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Guides answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Guide assist stats";
for(itr2 = theGAdr.begin(); itr2 != theGAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
guides = 0;
total = 0;
for(itr1 = theAdmins.begin(); itr1 != theAdmins.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Admins answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Admin assist stats";
for(itr2 = theAAdr.begin(); itr2 != theAAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
strList->SaveToFile("dump.txt");
}
__finally
{
delete strList;
}
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
(*itr).second = 0;
theAdmins.clear();
assistsAsked = 0;
guestAssists = 0;
unansweredAssists = 0;
}
an internet chess server. Whenever the bot logs on, it loads certain
information from file, and puts it in STL containers (specifically sets &
maps). When disconnecting for any reason, the containers are converted
to strings, and saved to disk, so they can be loaded again when the bot
logs back on. Periodically (triggered by a timer event), the bot mails a
log to addresses contained in two of the maps. The same timer is used to
send the output buffer to the server (such a buffer is needed because if
you send too much data at once, the server closes the connection as a
security precaution). There is also a mechanism that automatically re-
connects the bot if it is disconnected.
Now the problem. If the bot disconnects a few times, the log gets mailed
normally the first time, but the next time it should be sent, all the
containters are empty! This of course means the log can't be sent,
'cause it gets the mail addresses from two of the containers. I have no
idea how or why this happens.
I'd appreciate any ideas on how to fix this.
Here are some parts of the code:
typedef std::map<AnsiString, int, myless> guideMap;
typedef std::map<AnsiString, AnsiString, myless> adrMap;
typedef std::set<AnsiString> headSet;
class GuideBot ublic CNBot
{
private:
int assistsAsked;
int unansweredAssists;
int guestAssists;
guideMap theGuides;
guideMap theAdmins;
headSet theTDHeads;
adrMap theAAdr;
adrMap theGAdr;
void handleLevel1Block();
void processTell(AnsiString tellFrom, AnsiString theTell, UINT type);
void findGAlias(AnsiString tellFrom, AnsiString theTell);
void findTDAlias(AnsiString tellFrom, AnsiString theTell);
void findAAlias(AnsiString tellFrom, AnsiString theTell);
void loadAll();
bool isHead(AnsiString user);
bool isGHead(AnsiString user);
bool isAHead(AnsiString user);
bool isTDHead(AnsiString user);
public:
GuideBot():CNBot() {}
GuideBot(AnsiString asHandle, AnsiString asPassword):CNBot(asHandle,
asPassword) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection):CNBot
(asFileName, tcsConnection) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection,
AnsiString asSection):CNBot(asFileName, tcsConnection, asSection) {}
~GuideBot() {}
void onConnect(TCustomWinSocket *Socket);
void saveAll();
void mailDump();
int countingSince;
};
void __fastcall TForm1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Bot->onConnect(Socket);
HandleEdit->Enabled = false;
PasswordEdit->Enabled = false;
CommandEdit->Enabled = true;
if(Application->ShowMainForm)
CommandEdit->SetFocus();
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Output->Lines->Add("**** DISCONNECTED ****");
HandleEdit->Enabled = true;
PasswordEdit->Enabled = true;
CommandEdit->Enabled = false;
Bot->saveAll();
if(Bot->stayConnected)
{
reconnectValue = 4000;
reconnectTimer = 0;
}
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
Bot->saveAll();
ErrorCode = 0;
ClientSocket->Close();
reconnectValue = 4000;
reconnectTimer = 0;
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::SendTimer(TObject *Sender)
{
reconnectTimer++;
if(reconnectTimer == reconnectValue)
{
reconnectValue = -1;
Connect1Click(Sender);
}
myCounter++;
if(Bot != NULL)
{
Bot->sendoBuffer(ClientSocket->Socket);
}
if(myCounter%120000 == 0) // every hour
{
Bot->saveAll();
Output->Clear();
}
// if(myCounter == 20160000) // every 7 days
if(myCounter == 2000)
{
Bot->mailDump();
myCounter = 0;
Bot->countingSince = myCounter;
Bot->saveAll();
}
}
void GuideBot:nConnect(TCustomWinSocket *Socket)
{
stayConnected = true;
AnsiString command;
command = setDGLevel();
Socket->SendText(command + char(10));
Socket->SendText(getHandle() + char(10));
Socket->SendText(getPassword() + char(10));
if(theGuides.begin() == theGuides.end())
int lalala = 0;
loadAll();
if(theGuides.begin() == theGuides.end())
int lalala = 0;
countingSince = Form1->myCounter;
}
void GuideBot::loadAll()
{
int iPos, answered;
AnsiString theLine, guideName;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
strList->LoadFromFile("guides.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theGuides.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("admins.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theAdmins.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("gheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theGAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("aheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings;
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theAAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("tdheads.ini");
for(int i = 0; i < strList->Count; i++)
theTDHeads.insert(strList->Strings);
}
__finally
{
delete strList; // destroy the list object
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
assistsAsked = times->ReadInteger("assists", "assistsAsked", 0);
guestAssists = times->ReadInteger("assists", "guestAssists", 0);
unansweredAssists = times->ReadInteger("assists", "unansweredAssists",
0);
delete times;
}
void GuideBot::saveAll()
{
AnsiString aLine;
int sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
times->WriteInteger("guides", "sec", sec);
times->WriteInteger("guides", "min", min);
times->WriteInteger("guides", "hour", hour);
times->WriteInteger("guides", "day", day);
times->WriteInteger("assists", "assistsAsked", assistsAsked);
times->WriteInteger("assists", "guestAssists", guestAssists);
times->WriteInteger("assists", "unansweredAssists",
unansweredAssists);
delete times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"settings.ini");
times->WriteInteger("Program", "myCounter", Form1->myCounter);
delete times;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("guides.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theAdmins.begin(); itr != theAdmins.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
strList->SaveToFile("admins.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theGAdr.begin(); itr != theGAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("gheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theAAdr.begin(); itr != theAAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("aheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
headSet::iterator itr;
for(itr = theTDHeads.begin(); itr != theTDHeads.end(); itr++)
strList->Add(*itr);
// if(strList->Count > 0)
strList->SaveToFile("tdheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
}
void GuideBot::mailDump()
{
if(theGuides.begin() == theGuides.end())
{
loadAll();
return;
}
TIniFile *times;
int total = 0;
int guides = 0;
int sec;
AnsiString ending1, ending2, aLine;
guideMap::iterator itr1;
adrMap::iterator itr2;
TStringList *strList;
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"times.ini");
sec += times->ReadInteger("guides", "sec", 0);
min += times->ReadInteger("guides", "min", 0);
hour += times->ReadInteger("guides", "hour", 0);
day += times->ReadInteger("guides", "day", 0);
delete times;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
ending1.sprintf("Counting since %i days, %i hours, %i minutes and %i
seconds.", day, hour, min, sec);
ending2.sprintf("%i assists were asked, of which %i (%2.1f%%) were
guest assists. %i assists were left unanswered (%2.1f%%)", assistsAsked,
guestAssists, ((assistsAsked == 0) ? 0.0 : ((float)guestAssists/(float)
assistsAsked)*100), unansweredAssists, ((assistsAsked == 0) ? 0.0 :
((float)unansweredAssists/(float)assistsAsked)*100));
strList = new TStringList();
try
{
for(itr1 = theGuides.begin(); itr1 != theGuides.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Guides answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Guide assist stats";
for(itr2 = theGAdr.begin(); itr2 != theGAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
guides = 0;
total = 0;
for(itr1 = theAdmins.begin(); itr1 != theAdmins.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Admins answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Admin assist stats";
for(itr2 = theAAdr.begin(); itr2 != theAAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
strList->SaveToFile("dump.txt");
}
__finally
{
delete strList;
}
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
(*itr).second = 0;
theAdmins.clear();
assistsAsked = 0;
guestAssists = 0;
unansweredAssists = 0;
}