Multihunters Analysis tool v1.93

From Planetarion Wiki
Jump to navigationJump to search

This is the second 'major' version of the multihunters analysis tool. It is also coded in c++ , but features improvements over the old version. It has more refined detection algorithms - as well as a pre-cache ability in order to speed up the analysis process. It is also susceptible to buffer overflows as arrays are still used - this was corrected in the next major version of the analysis tool ( v2 ) - which was coded in java to give a GUI interface rather then a command line one.


Multihunter.cpp

// Includes

#include <string.h>
#include <math.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <windows.h>

// Custom Includes
#include "Textcolours.h"
#include "tokens.h"

using namespace std;

// Prototypes
int Menu();
int ShowPlanetMenu();
int ShowPlanetMenu2(int c);
void AddPlanet();
void ShowPlanet();
void DeletePlanet();
void Investigate(bool automatic);
void DoInvestigate(int Planet1, int Planet2);
void Log(string Line);
string StripNum(string Line);
void ParseFile(string filename);
void AddAll(bool automatic);
void DelAll();
long unsigned int DatetoSec(string Date);
int Percentage(int num, int total);
string Progress(int num,int total);
string DeHTML(string in);
void htmltotxt(string filename);


// Class Definitions
class LOGINS {
public:
	LOGINS::LOGINS();
	string Line[5000]; // 5k lines 
	int Lines;
};
class LAUNCHES {
public:
	LAUNCHES::LAUNCHES();
	string Line[2000]; // 2k lines
	int Lines;
};
class INCOMINGS {
public:
	INCOMINGS::INCOMINGS();
	string Line[2000]; // 2k lines
	int Lines;
};
class ALLIANCES {
public:
	ALLIANCES::ALLIANCES();
	string Line[500]; // 500 lines
	int Lines;
};
class UPGRADES {
public:
	UPGRADES::UPGRADES();
	string Line[500]; // 500 lines
	int Lines;
};
class PASSWORD {
public:
	PASSWORD::PASSWORD();
	string Pass[100];
	int Items;
};

class REPORT {
public:
	REPORT::REPORT();
	string Line[2000000]; // 2000k lines
	int Lines;
	void Add(string Line);
	void Dump(char* Filename);
	void Clear(char* Filename);
};

class STATS {
public:
	int Logins;
	int TotalLaunches;
	int TotalIncs;
	int TotalAlliances;
	int PlanetsUpgraded;
};
class GLOBALSTATS {
public:
	int Dodgypoints;
	int LinesParsed;
	int LinesAnalysed;
	int MatchingIP;
	int MatchingPass;
};

class INVLOGINS {
public:
	INVLOGINS::INVLOGINS();
	string Subnet[500]; // up to 500 different subnets
	string UniqueIP[2000]; //up to 2000 different IPs
	int count[500];
	int ipcount[2000]; 
	int Items;
	int ipitems;
	void Add(string IP,string Raw);
	void Reset();
};

class INITS {
public:
	INITS::INITS();
	string line[1000];
	int lines;
};

class TARGETS {
public:
	TARGETS::TARGETS();
	string Target[1000];
	int Count[1000];
	int Targets;
	void Add(string Target);
};

class PLANET {
public:
	PLANET::PLANET();
	string Coords;
	int UserID;
	string Username;
	string Password;
	string AccountStatus;
	int Upgraded_By;
	int Credits;
	int Alliance_ID;
	int Alliance_Status;
	string Fname;
	string Lname;
	string City;
	string Country;
	string Phone;
	string Email;
	string RegisterIP;
	string LastIP;
	string Rulername;
	string Planetname;
	bool ClosedBefore;
	string Filename;
	LOGINS Logins;
	LAUNCHES Launches;
	INCOMINGS Incomings;
	ALLIANCES Alliances;
	UPGRADES Upgrades;
	STATS Stats;
	INVLOGINS Ips;
	INITS Roid_Init;
};

class DB {
public:
	DB::DB();
	PLANET Planet[200]; // up to 200 planets to be done at once
	GLOBALSTATS Stats;
	REPORT Report;
	int Planets;
	void DelPlanet(int Number);
};



// Text Colour Functions

void ColText() {
	SetColour(BDEFAULT,TURQUOISE);
}
void ColError() {
	SetColour(BDEFAULT,RED);
}
void ColQuery() {
	SetColour(BDEFAULT,GREEN);
}
void ColInput() {
	SetColour(BDEFAULT,YELLOW);
}

// Class Constructors

LOGINS::LOGINS() {
	Lines = 0;
}
LAUNCHES::LAUNCHES() {
	Lines = 0;
}
INCOMINGS::INCOMINGS() {
	Lines = 0;
}
ALLIANCES::ALLIANCES() {
	Lines = 0;
}
UPGRADES::UPGRADES() {
	Lines = 0;
}
REPORT::REPORT() {
	Lines = 0;
}
PLANET::PLANET() {
}
PASSWORD::PASSWORD() {
	Items = 0;
}
INITS::INITS() {
	lines = 0;
}


DB::DB() {
	Planets = 0;
	ofstream fout("Report.txt");
}

INVLOGINS::INVLOGINS() {
	Items = 0;
	ipitems = 0;
}

TARGETS::TARGETS() {
	Targets = 0;
}

// Global Definitions

DB Database;
ofstream fout;
string GlobalSummary;

// Main Program Core

int main(int argc, char* argv[]) {
	std::cout << "Multihunter tool v1.93 coded by Phil^" << endl;
	std::cout << "=====================================" << endl;
	Database.Report.Clear("html.txt");
	Database.Report.Clear("Report.txt");
	bool exit = false;
	bool automatic = false;
	int choice;
	while (exit != true) {
		choice = Menu();
		switch (choice) {
			case (1): 
				// Do adding of planet
				AddPlanet();
				break;
			case (2): 
				// Do deletion of planet
				DeletePlanet();
				break;
			case (3):
				// Add All .txt to investigation
				AddAll(false);
				break;
			case (4):
				// Delete ALL planets from investigation
				DelAll();
				break;
			case (5):
				// Display Planets
				ShowPlanet();
				break;
			case (6): 
				// Do investigation
				Investigate(false);
				break;
			case (7):
				// Do All Auto
				AddAll(true);
				Investigate(true);
				exit = true;
				system("Report.txt");
				automatic = true;
				break;
			case (8):
				// Quit
				ColText();
				cout << "Exiting Program" << endl;
				ResetColour();
				exit = true;
				break;
			default:
				// Do Default settings
				ColError();
				cout << "Unknown Option!" << endl;
				ResetColour();
				break;
		}
	}
	if ( automatic == false ) { system("PAUSE"); }
	system("cls");
	ResetColour();
	return 0;
}


// Additional Functions


int Menu() {
	string menuin;
	cout << "Options" << endl;
	ColQuery();
	cout << "1) Add Planet to investigation\n";
	cout << "2) Delete Planet from investigation\n";
	cout << "3) Add ALL files to investigation\n";
	cout << "4) Delete all planets from investigation\n";
	cout << "5) Show Planets in Investigation\n";
	cout << "6) Start Investigation\n";
	cout << "7) Automatic Mode\n";
	cout << "8) Quit" << endl;
	ResetColour(); // reset colours to default
	cout << "Select your choice : ";
	ColInput();
	cin >> menuin;
	ResetColour();
	system("cls");
	int menucheck = atoi(menuin.c_str());
	if ( ( menucheck < 0 ) || ( menucheck > 8 )) { menucheck = 0; } 
	return menucheck;
	
}

void DelAll() {
	ColInput();
	cout << "ARE YOU SURE? enter Y to confirm or anything else to cancel : ";
	string in;
	cin >> in;
	if ( ( in == "Y" ) || ( in == "y" ) ) {
		ColText();
		cout << "Erasing all planets from investigation...\n";
		
		int c = 0;
		while ( c < Database.Planets ) {
			// Bugfix
			Database.Planet[c].Incomings.Lines = 0;
			Database.Planet[c].Launches.Lines = 0;
			Database.Planet[c].Logins.Lines = 0;
			c++;
		}

		Database.Planets = 0;
		Database.Planet[0].Filename = ""; // Bugfix
		cout << "Done\n\n\n";
	}
}

void AddAll(bool automatic) {
	
	ColInput();
	string in;
	if ( automatic == false ) { 
		cout << "ARE YOU SURE? enter Y to confirm or anything else to cancel : "; 
		cin >> in;
	}
	if ( automatic == true ) { in = "Y"; }

	if ( ( in == "Y" ) || ( in == "y" ) ) {

		ColText();
		cout << "Adding Planets\n";
		WIN32_FIND_DATA FindFileData;
		HANDLE hFind = NULL;
		hFind = FindFirstFile("*.txt", &FindFileData); // make a find thing
		if (hFind != INVALID_HANDLE_VALUE) {
			ColQuery();
			cout << "\nAdding all .txt files in current directory not already parsed... \n";
			// Special Case for 1st file, then get rest.
			int county = 0;
			bool add = true;
			while (county <= Database.Planets) {
				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
					// File Exists
					add = false;
				}
				county++;
			}
			if ( add == true ) {
				// Add File
				ParseFile(FindFileData.cFileName); 
			} 
			while (FindNextFile(hFind, &FindFileData) != 0) {
				int county = 0;
				add = true;
				while (county <= Database.Planets) {
					if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
						add = false;
					}
					county++;
				}
				if ( add == true ) {
					// Add File
					ParseFile(FindFileData.cFileName); 
				} 
			}
			FindClose(hFind); // close the find thing		
		}
		
		// do HTM files
		hFind = NULL;
		hFind = FindFirstFile("*.htm", &FindFileData); // make a find thing
		if (hFind != INVALID_HANDLE_VALUE) {
			ColQuery();
			cout << "\nAdding all .htm files in current directory not already parsed... \n";
			// Special Case for 1st file, then get rest.
			int county = 0;
			bool add = true;
			while (county <= Database.Planets) {
				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
					// File Exists
					add = false;
				}
				county++;
			}
			if ( add == true ) {
				// Add File
				ParseFile(FindFileData.cFileName); 
			} 
			while (FindNextFile(hFind, &FindFileData) != 0) {
				int county = 0;
				add = true;
				while (county <= Database.Planets) {
					if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
						add = false;
					}
					county++;
				}
				if ( add == true ) {
					// Add File
					ParseFile(FindFileData.cFileName); 
				} 
			}
			FindClose(hFind); // close the find thing
		}


		// DO HTML FILES
		hFind = NULL;
		hFind = FindFirstFile("*.html", &FindFileData); // make a find thing
		if (hFind != INVALID_HANDLE_VALUE) {
			ColQuery();
			cout << "\nAdding all .html files in current directory not already parsed... \n";
			// Special Case for 1st file, then get rest.
			int county = 0;
			bool add = true;
			while (county <= Database.Planets) {
				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
					// File Exists
					add = false;
				}
				county++;
			}
			if ( add == true ) {
				// Add File
				ParseFile(FindFileData.cFileName); 
			} 
			while (FindNextFile(hFind, &FindFileData) != 0) {
				int county = 0;
				add = true;
				while (county <= Database.Planets) {
					if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
						add = false;
					}
					county++;
				}
				if ( add == true ) {
					// Add File
					ParseFile(FindFileData.cFileName); 
				} 
			}	
			FindClose(hFind); // close the find thing
		}
		
		cout << "Finished Adding Files\n\n\n";
		if ( automatic == false ) { system("pause"); }
		system("cls");

		}
	}




void AddPlanet() {
	// Display the files with a .txt extention in current dir
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind = NULL;
	hFind = FindFirstFile("*.txt", &FindFileData); // make a find thing
	if (hFind != INVALID_HANDLE_VALUE) {
		ColText();
		cout << "\nListing all .txt files in current directory... \n";
		ColQuery();
		int county = 0;
		while (county <= Database.Planets) {
			if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
				ColInput();
			}
			county++;
		}
		cout << FindFileData.cFileName << "\t"; // First File
		ColQuery();
		while (FindNextFile(hFind, &FindFileData) != 0) {
			int county = 0;
			while (county <= Database.Planets) {
				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
					ColInput();
				}
				county++;
			}
			cout << FindFileData.cFileName << "\t"; // For the rest of the files
			ColQuery();
		}
		FindClose(hFind); // close the find thing
		hFind = NULL;
	}

	hFind = FindFirstFile("*.htm", &FindFileData); // make a find thing
	if (hFind != INVALID_HANDLE_VALUE) {
		ColText();
		cout << "\nListing all .htm files in current directory... \n";
		ColQuery();
		int county = 0;
		while (county <= Database.Planets) {
			if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
				ColInput();
			}
			county++;
		}
		cout << FindFileData.cFileName << "\t"; // First File
		ColQuery();
		while (FindNextFile(hFind, &FindFileData) != 0) {
			int county = 0;
			while (county <= Database.Planets) {
				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
					ColInput();
				}
				county++;
			}
			cout << FindFileData.cFileName << "\t"; // For the rest of the files
			ColQuery();
		}
		FindClose(hFind); // close the find thing
		hFind = NULL;
	}

	hFind = FindFirstFile("*.html", &FindFileData); // make a find thing
	if (hFind != INVALID_HANDLE_VALUE) {
		ColText();
		cout << "\nListing all .html files in current directory... \n";
		ColQuery();
		int county = 0;
		while (county <= Database.Planets) {
			if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
				ColInput();
			}
			county++;
		}
		cout << FindFileData.cFileName << "\t"; // First File
		ColQuery();
 		while (FindNextFile(hFind, &FindFileData) != 0) {
 			int county = 0;
 			while (county <= Database.Planets) {
 				if ( FindFileData.cFileName == Database.Planet[county].Filename ) {
 					ColInput();
 				}
 				county++;
 			}
 			cout << FindFileData.cFileName << "\t"; // For the rest of the files
 			ColQuery();
 		}
 		FindClose(hFind); // close the find thing
 		hFind = NULL;
 	}
	cout << "\n";
	
	// Finish Displaying Files

	ColText();
	cout << "Enter the filename of the datafile containing the planet in question" << endl << ": " ;
	string filename;
	ColInput();
	cin >> filename;
	ColText();
	int	county = 0;
	bool Alreadythere = false;
	while (county <= Database.Planets) {
		if ( filename == Database.Planet[county].Filename ) {
			Alreadythere = true;
		}
		county++;
	}
	if ( Alreadythere == false ) {
		// Not already added file - Parse it
		ParseFile(filename);
		ColQuery();
		cout << "Completed\n";
		ResetColour();
		system("Pause");
		system("cls");
	}
	else {
		ColError(); 
		cout << "Already Parsed that file!\n";
		ResetColour();
		system("pause");
		system("cls");
	}
}


int ShowPlanetMenu() {
	string menuin;
	cout << "Select Planet" << endl;
	ColQuery();
	int c = 0;
	while (c <= (Database.Planets - 1)) {
		cout << (c+1) << ") " << Database.Planet[c].Coords << endl;
		c++;
	}
	cout << "0) Back to Main Menu" << endl;
	ResetColour(); // reset colours to default
	cout << "Select Planet to view data on : ";
	ColInput();
	cin >> menuin;
	ResetColour();
	system("cls");
	int menucheck = atoi(menuin.c_str());
	if ( ( menucheck < 0 ) || ( menucheck > (Database.Planets) )) { menucheck = 0; } 
	return menucheck;
}

int ShowPlanetMenu2(int c) {
	string menuin;
	cout << "Options" << endl;
	ColQuery();
	cout << "1) View Misc Planet Info" << endl;
	cout << "2) View Fleet Launches" << endl;
	cout << "3) View Attacks on this Planet" << endl;
	cout << "4) View Alliance History" << endl;
	cout << "5) View Login History" << endl;
	cout << "6) View Upgrades History" << endl;
	cout << "7) View Roid Initiation History" << endl;
	cout << "0) Back to Main Menu" << endl;
	ResetColour(); // reset colours to default
	cout << "Select type of data to view : ";
	ColInput();
	cin >> menuin;
	ResetColour();
	system("cls");
	int menucheck = atoi(menuin.c_str());
	if ( ( menucheck < 0 ) || ( menucheck > 7 )) { menucheck = 0; } 
	return menucheck;
}
int ShowPlanetDelMenu() {
	string menuin;
	ColQuery();
	int c = 0;
	while (c <= (Database.Planets - 1)) {
		cout << (c+1) << ") " << Database.Planet[c].Coords << endl;
		c++;
	}
	cout << "0) Back to Main Menu" << endl;
	ResetColour(); // reset colours to default
	cout << "Select Planet to Erase : ";
	ColInput();
	cin >> menuin;
	int menucheck = atoi(menuin.c_str());
	if ( ( menucheck < 0 ) || ( menucheck > (Database.Planets) )) { menucheck = 0; } 
	return menucheck;
}
void ShowPlanet () {
	ColText();
	int Planetchoice = ShowPlanetMenu();
	int Datachoice;
	bool exiting = false;
	if ( Planetchoice <= 0 ) {
		exiting = true;
	}
	if ( Planetchoice > 0 ) {
		Planetchoice--;
		Datachoice = ShowPlanetMenu2(Planetchoice);
	}
	if ( Datachoice >= 0 ) {
		switch (Datachoice) {
				case (1): {
				// Misc Planet Info
				ColQuery();
				cout << "Planet Info\n\n";
				cout << "User ID: ";
				ColText();
				cout << Database.Planet[Planetchoice].UserID << "\n";
				ColQuery();
				cout << "Username: ";
				ColText();
				cout << Database.Planet[Planetchoice].Username << "\n";
				ColQuery();
				cout << "Password: ";
				ColText();
				cout << Database.Planet[Planetchoice].Password << "\n";
				ColQuery();
				cout << "Account Status: ";
				ColText();
				cout << Database.Planet[Planetchoice].AccountStatus << "\n";
				ColQuery();
				cout << "Rulername: ";
				ColText();
				cout << Database.Planet[Planetchoice].Rulername << "\n";
				ColQuery();
				cout << "Planetname: ";
				ColText();
				cout << Database.Planet[Planetchoice].Planetname << "\n";
				ColQuery();
				cout << "Coordinates: ";
				ColText();
				cout << Database.Planet[Planetchoice].Coords << "\n";
				ColQuery();
				cout << "Upgraded by UserID: ";
				ColText();
				cout << Database.Planet[Planetchoice].Upgraded_By << "\n";
				ColQuery();
				cout << "Remaining Credits: ";
				ColText();
				cout << Database.Planet[Planetchoice].Credits << "\n";
				ColQuery();
				cout << "Closed Before: ";
				ColText();
				cout << Database.Planet[Planetchoice].ClosedBefore << "\n";
				ColQuery();
				cout << "Alliance ID: ";
				ColText();
				cout << Database.Planet[Planetchoice].Alliance_ID << "\n";
				ColQuery();
				cout << "Alliance Status: ";
				ColText();
				cout << Database.Planet[Planetchoice].Alliance_Status << "\n";
				ColQuery();
				cout << "First Name: ";
				ColText();
				cout << Database.Planet[Planetchoice].Fname << "\n";
				ColQuery();
				cout << "Last Name: ";
				ColText();
				cout << Database.Planet[Planetchoice].Lname << "\n";
				ColQuery();
				cout << "City: ";
				ColText();
				cout << Database.Planet[Planetchoice].City << "\n";
				ColQuery();
				cout << "Country: ";
				ColText();
				cout << Database.Planet[Planetchoice].Country << "\n";
				ColQuery();
				cout << "Phone Number: ";
				ColText();
				cout << Database.Planet[Planetchoice].Phone << "\n";
				ColQuery();
				cout << "Email Address: ";
				ColText();
				cout << Database.Planet[Planetchoice].Email << "\n";
				ColQuery();
				cout << "Registered from IP: ";
				ColText();
				cout << Database.Planet[Planetchoice].RegisterIP << "\n";
				ColQuery();
				cout << "Last Login IP: ";
				ColText();
				cout << Database.Planet[Planetchoice].LastIP << "\n";
				ResetColour();
				system("pause");
				system("cls");
				break;
			}
			case (2): {
				// Show Fleet Launches
				ColQuery();
				cout << "Fleet Launches\n\n";
				ColText();
				int c2 = 0;
				while (c2 < Database.Planet[Planetchoice].Launches.Lines) {
					cout << Database.Planet[Planetchoice].Launches.Line[c2] << endl;
					c2++;
				}
				cout << endl;
				ResetColour();
				system("pause");
				system("cls");
				break;
			}
			case (3): {
				// Show Attacks On Planet
				ColQuery();
				cout << "Attacks On Planet\n\n";
				ColText();
				int c2 = 0;
				while (c2 < Database.Planet[Planetchoice].Incomings.Lines) {
					cout << Database.Planet[Planetchoice].Incomings.Line[c2] << endl;
					c2++;
				}
				cout << endl;
				ResetColour();
				system("pause");
				system("cls");
				break;
			}
			case (4): {
				// Show Alliance History
				ColQuery();
				cout << "Alliance History\n\n";
				ColText();
				int c2 = 0;
				while (c2 < Database.Planet[Planetchoice].Alliances.Lines) {
					cout << Database.Planet[Planetchoice].Alliances.Line[c2] << endl;
				c2++;
				}
				cout << endl;
				ResetColour();
				system("pause");
				system("cls");
				break;
			}
			case (5): {
				// Show Login History
				ColQuery();
				cout << "Login History\n\n";
				ColText();
				int c2 = 0;
				while (c2 < Database.Planet[Planetchoice].Logins.Lines) {
					cout << Database.Planet[Planetchoice].Logins.Line[c2] << endl;
					c2++;
				}
				cout << endl;
				ResetColour();
				system("pause");
				system("cls");
				break;
			}
 			case (6): {
 				// Show Upgrades History
 				ColQuery();
 				cout << "Upgrades History\n\n";
 				ColText();
 				int c2 = 0;
 				while (c2 < Database.Planet[Planetchoice].Upgrades.Lines) {
 					cout << Database.Planet[Planetchoice].Upgrades.Line[c2] << endl;
 					c2++;
 				}
 				cout << endl;
 				ResetColour();
 				system("pause");
				system("cls");
				break;
			}
			case (7): {
				// Show roid initiation history
				ColQuery();
				cout << "Roid Initiation History\n\n";
				ColText();
				int c2 = 0;
				while ( c2 < Database.Planet[Planetchoice].Roid_Init.lines) {
					cout << Database.Planet[Planetchoice].Roid_Init.line[c2] << endl;
 					c2++;
 				}
 				ResetColour();
 				system("pause");
 				system("cls");
 				break;
			}
			case (0): {
				exiting = true;
				break;
			}
			default: {
				ColError();
				cout << "Not a Menu Choice\n";
				ColText();
				break;
			}
		}
	}
	ResetColour();
	system("cls");
}

void DeletePlanet() {
	ColQuery();
	int Selected = ShowPlanetDelMenu();
	if ( Selected > 0 ) {
		Selected--; 
		cout << "ARE YOU SURE? enter Y to confirm or anything else to cancel : ";
		string in;
		ColInput();
		cin >> in;
		if ( ( in == "Y" ) || ( in == "y" ) ) {
			ColText();
			cout << "Erased Planet\n";
			Database.DelPlanet(Selected);
		}
	}
	ResetColour();
	system("Pause");
	system("cls");
}

void Investigate(bool automatic) {
	GlobalSummary = "";
	Database.Report.Clear("Report.txt");
	// this is the function which prepares the combinations of planets for investigation
	ColQuery();
	cout << "Beginning Investigation on Planets\n";
	Log("Multihunter Investigation Tool 1.93 - Coded by Phil^\n\n");
	ColText();
	// this is the loop which generates ALL permutations. soo simple its artistic :D
	int c = 0;
	if ( Database.Planets <= 1) {
		// Not enough to investigate
		ColError();
		cout << "Not enough Planets Added to investigate\n";
		ColText();
	}
	else {

		for (int i=0; i<Database.Planets; i++) {
			for (int j=(i+1);j<Database.Planets;j++) {
				cout << "\n\n\nChecking: " << Database.Planet[i].Coords << " and " << Database.Planet[j].Coords << "\n\n";
				Log("\n\n\nInvestigating: " + Database.Planet[i].Coords + " and " + Database.Planet[j].Coords + "\n\n");
				DoInvestigate(i,j);
			}
		}
	}
	
	// Dump the Unique IPs
	
	Log("\n\nIP Database dump");
	Log("\n================");
	for ( c = 0; c<Database.Planets; c++ ) {
		ColQuery();
		cout << "\nDumping IP database of " << Database.Planet[c].Coords << "... ";
		ColText();
		Log("\n\nIP data for " + Database.Planet[c].Coords);
		Log("\n=========================");
		cout << "[----------] 000%";
		for ( int d = 0; d < Database.Planet[c].Ips.Items; d++ ) {
			cout << Progress(d,Database.Planet[c].Ips.Items );
			Log("\n" + Database.Planet[c].Ips.Subnet[d] + ".x.x");
			for ( int e = 0; e < Database.Planet[c].Ips.ipitems ; e++) {
				string subnet = Database.Planet[c].Ips.Subnet[d];
				string ip = Database.Planet[c].Ips.UniqueIP[e];
				if (( Gettok(subnet,1,".") == Gettok(ip,1,".")) && ( Gettok(subnet,2,".") == Gettok(ip,2,".") )) {
					Log("\n\t" + ip);
				}
			}
		}
	}
	// Do global summary
	cout << "\n\n";
	Log("\n\n===================================================================================");
	Log("\n\nGlobal Case Summary\n");
	Log(GlobalSummary);
	// Dump the report to a file
	Database.Report.Dump("Report.txt");
	cout << "Report Generated.\n";
	// Reset Report.
	Database.Report.Lines = 0; 
	ResetColour();
	if ( automatic == false ) { system("Pause"); }
	system("cls");
}

void DoInvestigate(int Planet1,int Planet2) {
	// this is the function that ACTUALLY investigates them.
	// 
	string Line;
	string Summary = "";
	bool samealliance = false;
	Summary = "Investigating Planets " + Database.Planet[Planet1].Coords + " And " + Database.Planet[Planet2].Coords + "\n";


    // ---------------------------------------------------------------------------------
	// SAME ALLIANCE CHECK
	ColQuery();
	cout << "Alliance Check... ";
	Log("\nAlliance Check : \n");
	Log("============================================\n");
	ColText();
	if (( Database.Planet[Planet1].Alliance_ID == Database.Planet[Planet2].Alliance_ID ) && ( Database.Planet[Planet1].Alliance_ID != 0 ) ) {
		Log("!!! Planets are in Same Alliance !!!\n");
		Summary = Summary + "\nPlanets are in the Same Alliance";
		samealliance = true;
	}
	else {
		Log("NO EVIDENCE - Planets are NOT in the same Alliance\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// SAME REGISTERED IP CHECK
	ColQuery();
	cout << "Register IP Check... ";
	Log("\nRegistration IP Check : \n");
	Log("============================================\n");
	ColText();
	if ( Database.Planet[Planet1].RegisterIP == Database.Planet[Planet2].RegisterIP ) {
		Log("!!! Planets signed up from the same IP Address !!!\n");
		Summary = Summary + "\nPlanets signed up from the same IP address";
	}
	else {
		Log("NO EVIDENCE - Planets did NOT sign up from the same IP address\n");
	}
	cout << "[**********] 100%\n";
	// ---------------------------------------------------------------------------------
	// SAME PASSWORD CHECK
	ColQuery();
	cout << "Password Check... ";
	Log("\nSame Password Check : \n");
	Log("============================================\n");
	ColText();
	if ( Database.Planet[Planet1].Password == Database.Planet[Planet2].Password ) {
		Log("!!! Planets have the same Password !!!\n");
		Summary = Summary + "\nPlanets have the same Password";
	}
	else {
		Log("NO EVIDENCE - Planets do NOT have the same Password\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// SAME FIRST/LAST NAME CHECK
	ColQuery();
	cout << "Name Check... ";
	Log("\nSame Name Check : \n");
	Log("============================================\n");
	ColText();
	if (( Database.Planet[Planet1].Fname == Database.Planet[Planet2].Fname ) || ( Database.Planet[Planet1].Lname == Database.Planet[Planet2].Lname )) {
		Log("!!! Planets have the same First/Last Name !!!\n");
		Summary = Summary + "\nPlanets have the same First/Last Name";
	}
	else {
		Log("NO EVIDENCE - Planets do NOT have the same last name\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// SAME PHONE NUMBER CHECK
	ColQuery();
	cout << "Phone Check... ";
	Log("\nSame Phone Number Check : \n");
	Log("============================================\n");
	ColText();
	if (( Database.Planet[Planet1].Phone == Database.Planet[Planet2].Phone) && ( Database.Planet[Planet1].Phone != "" ) ) {
		Log("!!! Planets have the same Phone Number !!!\n");
		Summary = Summary + "\nPlanets have the same Phone Number";
	}
	else {
		Log("NO EVIDENCE - Planets do NOT have the same Phone Number\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// SAME CITY CHECK
	ColQuery();
	cout << "City Check... ";
	Log("\nSame City Check : \n");
	Log("============================================\n");
	ColText();
	if ( Database.Planet[Planet1].City == Database.Planet[Planet2].City ) {
		Log("!!! Planets have the same City !!!\n");
		Summary = Summary + "\nPlanets Have the same City";
	}
	else {
		Log("NO EVIDENCE - Planets do NOT have the same City\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// SAME COUNTRY CHECK
	ColQuery();
	cout << "Country Check... ";
	Log("\nSame Country Check : \n");
	Log("============================================\n");
	ColText();
	if ( Database.Planet[Planet1].Country == Database.Planet[Planet2].Country ) {
		Log("!!! Planets have the same Country !!!\n");
		Summary = Summary + "\nPlanets have the same Country";
	}
	else {
		Log("NO EVIDENCE - Planets do NOT have the same Country\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// PREVIOUS CLOSURE CHECK
	ColQuery();
	cout << Database.Planet[Planet1].Coords << " Closure check... ";
	Log("\n" + Database.Planet[Planet1].Coords + " Previous Closure Check : \n");
	Log("============================================\n");
	ColText();
	if ( Database.Planet[Planet1].ClosedBefore == true ) {
		Log("!!! " + Database.Planet[Planet1].Coords + " has been closed before!!!\n");
		Summary = Summary + "\n" + Database.Planet[Planet1].Coords + " has been closed before";
	}
	else { 
		Log("NO EVIDENCE - " + Database.Planet[Planet1].Coords + " has NOT been closed before\n");
	}

	cout << "[**********] 100%\n";

	ColQuery();
	cout << Database.Planet[Planet2].Coords << " Closure check... ";
	Log("\n" + Database.Planet[Planet2].Coords + " Previous Closure Check : \n");
	ColText();
	if ( Database.Planet[Planet2].ClosedBefore == true ) {
		Log("!!! " + Database.Planet[Planet2].Coords + " has been closed before!!!\n");
		Summary = Summary + "\n" + Database.Planet[Planet2].Coords + " Has been closed before";
	}
	else { 
		Log("NO EVIDENCE - " + Database.Planet[Planet2].Coords + " has NOT been closed before\n");
	}
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// PLANET UPGRADE CHECK
	ColQuery();
	cout << "Planet Upgrade check... ";
	Log("\nPlanet Upgrade Check : \n");
	Log("============================================\n");
	ColText();
	int Upgrades = 0;
	if ( Database.Planet[Planet1].Upgraded_By == Database.Planet[Planet2].UserID ) {
		Log(Database.Planet[Planet1].Coords + " Was Upgraded by " + Database.Planet[Planet2].Coords + "\n");
		Summary = Summary + "\n" + Database.Planet[Planet1].Coords + " Was Upgraded by " + Database.Planet[Planet2].Coords;
		Upgrades++;
	}
	if ( Database.Planet[Planet2].Upgraded_By == Database.Planet[Planet1].UserID ) {
		Log(Database.Planet[Planet2].Coords + " Was Upgraded by " + Database.Planet[Planet1].Coords + "\n");
		Summary = Summary + "\n" + Database.Planet[Planet2].Coords + " Was Upgraded by " + Database.Planet[Planet1].Coords;
		Upgrades++;
	}
	if (( Database.Planet[Planet1].Upgraded_By == Database.Planet[Planet2].Upgraded_By ) && ( Database.Planet[Planet1].Upgraded_By != 0)) {
		Log(Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords + " Were upgraded by the same person : UserID " + IntToString(Database.Planet[Planet1].Upgraded_By) + "\n");
		Summary = Summary + "\n" + Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords + " Were upgraded by the same person : UserID " + IntToString(Database.Planet[Planet1].Upgraded_By);
		Upgrades++;
	}
	Log(IntToString(Upgrades) + " Upgrades detected between the planets\n");
	cout << "[**********] 100%\n";
    // ---------------------------------------------------------------------------------
	// LOGIN CORRELATIONS CHECKING
	int LoginCorrelations = 0;
	int LoginMatchCorrelations = 0;
	ColQuery();
	cout << "Checking for Login Correlations... ";
	Log("\nLogin Correlations\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	int c = 0;
	int d = 0;
	while ( c < Database.Planet[Planet1].Logins.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Logins.Lines);
		while ( d < Database.Planet[Planet2].Logins.Lines ) {
			string month1 = Gettok(Database.Planet[Planet1].Logins.Line[c],2," ");
			string month2 = Gettok(Database.Planet[Planet2].Logins.Line[d],2," ");
			string day1 = Gettok(Database.Planet[Planet1].Logins.Line[c],3," ");
			string day2 = Gettok(Database.Planet[Planet2].Logins.Line[d],3," ");
			string ip1 = Gettok(Database.Planet[Planet1].Logins.Line[c],6," ");
			string ip2 = Gettok(Database.Planet[Planet2].Logins.Line[d],6," ");
			int hour1 = atoi(Gettok(Gettok(Database.Planet[Planet1].Logins.Line[c],4," "),1,":").c_str());
			int hour2 = atoi(Gettok(Gettok(Database.Planet[Planet2].Logins.Line[d],4," "),1,":").c_str());
			int min1 = atoi(Gettok(Gettok(Database.Planet[Planet1].Logins.Line[c],4," "),2,":").c_str());
			int min2 = atoi(Gettok(Gettok(Database.Planet[Planet2].Logins.Line[d],4," "),2,":").c_str());
			if ((abs((hour1 * 60 + min1) - (hour2 * 60 + min2)) <= 10 ) && ( month1 == month2 ) && ( day1 == day2 )) {
				// If they are within 10 mins of each other on the same Day on the same Month
				Line = Database.Planet[Planet1].Coords + " : " + Database.Planet[Planet1].Logins.Line[c];
				Log( Line + "\n");
				Line = Database.Planet[Planet2].Coords + " : " + Database.Planet[Planet2].Logins.Line[d];
				Log( Line + "\n");
				int mindiff = abs((hour1 * 60 + min1) - (hour2 * 60 + min2));
				Line = IntToString(mindiff) + " Minutes Difference";
				if ( ip1 == ip2 ) {
					Line = Line + ",IP Match!! - " + ip1 ; // Doesnt matter which if they`re equal
					LoginMatchCorrelations++;
				}
				Log( Line + "\n\n");
				LoginCorrelations++;
			}
			d++;
		}
		d = 0;
		c++;
	}
	Log(IntToString(LoginCorrelations) + " Login Correlations Detected\n");
	Log(IntToString(LoginMatchCorrelations) + " Login Correlations from the same IP Detected\n");

	if ( LoginCorrelations > 0 ) {
		Summary = Summary + "\n" + IntToString(LoginCorrelations) + " Login Correlations detected";
		Summary = Summary + "\n" + IntToString(LoginMatchCorrelations) + " Login Correlations from the same IP Detected";
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";
    // ---------------------------------------------------------------------------------
	// FLEET LAUNCH CORRELATION CHECKING
	int FleetLaunchCorrelations = 0;
	int AllianceInteractions = 0;
	int IngalInteractions = 0;
	int InteractionsFromSameIP = 0;
	int InteractionsToOthersGal = 0;
	int InteractionsToSameGal = 0;
	ColQuery();
	cout << "Checking for Fleet Launch Correlations... ";
	Log("\nFleet Launch Correlations\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	c = 0;
	d = 0;
	while ( c < Database.Planet[Planet1].Launches.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Launches.Lines);
		while ( d < Database.Planet[Planet2].Launches.Lines ) {
			string line1 = Database.Planet[Planet1].Launches.Line[c];
			string line2 = Database.Planet[Planet2].Launches.Line[d];
			string coord1 = Gettok(line1,(Numtok(line1," ") - 1)," ");
			string coord2 = Gettok(line2,(Numtok(line2," ") - 1)," ");
			string galcheck1 = Gettok(coord1,1,":") + Gettok(coord1,2,":");
			string galcheck2 = Gettok(coord2,1,":") + Gettok(coord2,2,":");
			string pgal1 = Gettok(Database.Planet[Planet1].Coords,1,":") + Gettok(Database.Planet[Planet1].Coords,2,":");
			string pgal2 = Gettok(Database.Planet[Planet2].Coords,1,":") + Gettok(Database.Planet[Planet2].Coords,2,":");
			string mission1 = Gettok(line1,4," ");
			string mission2 = Gettok(line2,4," ");
			// with the variable eta we really wanna get the LANDING tick
			int Tick1 = atoi(Gettok(line1,3," ").c_str());
			int Tick2 = atoi(Gettok(line2,3," ").c_str());
			// if fleets launched within x ticks of each other are going to the same galaxy - dump report
			if (( abs( Tick1 - Tick2 ) <= 3 ) && ( galcheck1 == galcheck2 )) { 

				// check to see if they were on the same IP when it happened
				int g;
				g = 0;
				string Fleetdate1 = Righttok(line1,6," ");
				long int MyDiff1 = 999999999;
				string MyLogin1, MyIP1, Logindate1;
				while ( g < Database.Planet[Planet1].Logins.Lines ) {
					Logindate1 = Lefttok(Database.Planet[Planet1].Logins.Line[g],5," ");
					long int Diff = ( DatetoSec(Fleetdate1) - DatetoSec(Logindate1) );
					if (( Diff > 0 ) && ( Diff < MyDiff1 )) {
						MyDiff1 = Diff;
						MyLogin1 = Database.Planet[Planet1].Logins.Line[g];
						MyIP1 = Gettok(MyLogin1,6," ");

					}
					g++;
				}
				// closest login for planet1 is in mylogin1 now

				g = 0;
				string Fleetdate2 = Righttok(line2,6," ");
				long int MyDiff2 = 999999999;
				string MyLogin2, MyIP2, Logindate2;
				while ( g < Database.Planet[Planet2].Logins.Lines ) {
					Logindate2 = Lefttok(Database.Planet[Planet2].Logins.Line[g],5," ");
					long int Diff = ( DatetoSec(Fleetdate2) - DatetoSec(Logindate2) );
					if (( Diff > 0 ) && ( Diff < MyDiff2 )) {
						MyDiff2 = Diff;
						MyLogin2 = Database.Planet[Planet2].Logins.Line[g];
						MyIP2 = Gettok(MyLogin2,6," ");
					}
					g++;
				}

				// closest login for planet2 is in mylogin2 now
				if (( MyLogin1 != "" ) && ( MyLogin2 != "" )) {
					Line = Database.Planet[Planet1].Coords + " : " + line1;
					Log(Line + "\n");
					Line = Database.Planet[Planet2].Coords + " : " + line2;
					Log(Line + "\n");

					Line = "Closest login of " + Database.Planet[Planet1].Coords + " - " + MyLogin1 + "\n";
					Line = Line + "Closest login of " + Database.Planet[Planet2].Coords + " - " + MyLogin2 + "\n";
				}
				Line = Line + IntToString(abs( Tick1 - Tick2 )) + " Tick Difference ";

				if (( MyIP1 == MyIP2 ) && (MyIP1 != "") ) {
					Line = Line + ", SAME IP!!";
					InteractionsFromSameIP++;
				}

				if ( coord1 == coord2 ) {
					Line = Line + ", SAME TARGET!!";
				}

				if (( samealliance == true ) && ( galcheck1 == galcheck2 ) && ( mission1 == mission2 ) && (( mission1 == "Defend" ) || ( mission1 == "Recall"))) {
					Line = Line + ", POSSIBLE ALLIANCE ACTIVITY!!";
					AllianceInteractions++;
				}

				if (( galcheck1 == galcheck2 ) && ( pgal1 == pgal2 ) && ( pgal1 == galcheck1) ) {
					IngalInteractions++;
					Line = Line + ", INGAL INTERACTION";
				}

				if ((( pgal1 != galcheck1 ) && ( pgal2 == galcheck1)) || (( pgal1 != galcheck2 ) && ( pgal2 == galcheck2))) {
					InteractionsToOthersGal++;
					Line = Line + " , INTERACTION TO EACH OTHERS GALAXY";
				}
				
				Log(Line + "\n\n");
				FleetLaunchCorrelations++;
			}
			d++;
		}
		d = 0;
		c++;
	}
	Log(IntToString(FleetLaunchCorrelations) + " Total Fleet Launch Correlations Detected\n");
	Log(IntToString(AllianceInteractions) + " Potential Alliance Interactions Detected\n");
	Log(IntToString(IngalInteractions) + " Ingal Interactions Detected\n");
	Log(IntToString(InteractionsToOthersGal) + " Interactions to each others galaxy Detected\n");
	Log(IntToString(InteractionsFromSameIP) + " Fleet Launch Correlations from the same IP address Detected\n");


	if ( FleetLaunchCorrelations > 0 ) {
		Summary = Summary + "\n" + IntToString(FleetLaunchCorrelations) + " Total Fleet Launch Correlations";
		Summary = Summary + "\n" + IntToString(AllianceInteractions) + " Potential Alliance Interactions";
		Summary = Summary + "\n" + IntToString(IngalInteractions) + " Ingal Interactions";
		Summary = Summary + "\n" + IntToString(InteractionsToOthersGal) + " Interactions to each others galaxy Detected";
		Summary = Summary + "\n" + IntToString(InteractionsFromSameIP) + " Fleet Launch Correlations from same IP";
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";
    // ---------------------------------------------------------------------------------
	// COMMON INCOMINGS
	ColQuery();
	cout << "Checking for Incoming Correlations... ";
	Log("\nIncoming Correlations\n");
	Log("============================================\n");
	ColText();
	cout << "\n[----------] 000%";
	c = 0;
	d = 0;
	int ComDef = 0;
	int ComAtt = 0;
	int Interact = 0;
	cout << Progress(-1,1);
	while ( c < Database.Planet[Planet1].Incomings.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Incomings.Lines);
		while ( d < Database.Planet[Planet2].Incomings.Lines ) {
			string line1 = Database.Planet[Planet1].Incomings.Line[c];
			string line2 = Database.Planet[Planet2].Incomings.Line[d];
			string coords1 = Gettok(line1,5," ");
			string coords2 = Gettok(line2,5," ");
			
			if ( coords1 == coords2 ) {
				if ((Gettok(line1,4," ") == "Attack") || (Gettok(line2,4," ") == "Attack")) {
					// Common Attacker
					Log(Database.Planet[Planet1].Coords + " : " + line1 + "\n");
					Log(Database.Planet[Planet2].Coords + " : " + line2 + "\n");
					Log("Common Attacker\n\n");
					ComAtt++;
					c++;
				}
				else if ((Gettok(line1,4," ") == "Defend") || (Gettok(line2,4," ") == "Defend")) {
					// Common Defender
					Log(Database.Planet[Planet1].Coords + " : " + line1 + "\n");
					Log(Database.Planet[Planet2].Coords + " : " + line2 + "\n");
					Log("Common Defender\n\n");
					ComDef++;
					c++;
				}
			}
			d++;
		}
		d = 0;
		c++;
	}
	cout << Progress(1,1) << " , ";
	// check Interactions now
	c = 0;
	cout << "[----------] 000%";
	while ( c < Database.Planet[Planet1].Incomings.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Incomings.Lines);
		string coordscheck = Gettok(Database.Planet[Planet1].Incomings.Line[c],5," ");
		if ( coordscheck == Database.Planet[Planet2].Coords ) {
				// Interaction between the accounts ( attacking / defending each other )
				Log(Database.Planet[Planet1].Coords + " : " + Database.Planet[Planet1].Incomings.Line[c] + "\n");
				Log("Interaction Between the accounts\n\n");
				Interact++;
				c++;
			}
		c++;
	}

	cout << Progress(1,1) << " , ";
	// check Interactions now
	c = 0;
	cout << "[----------] 000%";
	while ( c < Database.Planet[Planet2].Incomings.Lines ) {
		cout << Progress(c,Database.Planet[Planet2].Incomings.Lines);
		string coordscheck = Gettok(Database.Planet[Planet2].Incomings.Line[c],5," ");
		if (coordscheck == Database.Planet[Planet1].Coords ) {
				// Interaction between the accounts ( attacking / defending each other )
				Log(Database.Planet[Planet2].Coords + " : " + Database.Planet[Planet2].Incomings.Line[c] + "\n");
				Log("Interaction Between the accounts\n\n");
				Interact++;
				
			}
		c++;
	}
	cout << Progress(1,1);

	Log("Totals :\n");
	Log("Number of Common Attackers : " + IntToString(ComAtt) + "\n");
	Log("Number of Common Defenders : " + IntToString(ComDef) + "\n");
	Log("Number of Interactions between the accounts : " + IntToString(Interact) + "\n");
	if ( ComAtt > 0 ) {
		Summary = Summary + "\n" + "Number of Common Attackers : " + IntToString(ComAtt);
	}
	if ( ComDef > 0 ) {
		Summary = Summary + "\n" + "Number of Common Defenders : " + IntToString(ComDef);
	}
	if ( Interact > 0 ) {
		Summary = Summary + "\n" + "Number of Interactions between the accounts : " + IntToString(Interact);
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";

    // ---------------------------------------------------------------------------------
	// INTERESTING LOGINS
	INVLOGINS Ldata;
	ColQuery();
	cout << "Checking for Interesting Logins... ";
	Log("\nInteresting Logins\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	// Go through Planet 1 's logins for subnets
	c = 0;
	while ( c < Database.Planet[Planet1].Logins.Lines ) {
		string Ip = Database.Planet[Planet1].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Ldata.Add(Ip2,Ip);
		c++;
	}
	Log(Database.Planet[Planet1].Coords + " :\n");
	c = 0;
	int Susp = 0;
	while ( c < Ldata.Items ) {
		cout << Progress(c,Ldata.Items);
		if ( Ldata.count[c] <= 30  ) {
			Log(Ldata.Subnet[c] + ".x.x : " + IntToString(Ldata.count[c]) + " Times\n");
			Susp++;
		}
		c++;
	}
	Log(IntToString(Susp) + " Interesting IP Subnet Logins Found\n");
	if ( Susp > 0 ) {
		Summary = Summary + "\n" + IntToString(Susp) + " Interesting IP Subnet Logins Found on " + Database.Planet[Planet1].Coords;
	}
	// Lets look for Fleet launches for the interesting logins


	// Go through Planet 2 's logins for subnets
	c = 0;
	cout << Progress(0,0); // Bugfix
	cout << " , ";
	Ldata.Reset(); // reset this.
	cout << "[----------] 000%";

	while ( c < Database.Planet[Planet2].Logins.Lines ) {
		string Ip = Database.Planet[Planet2].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Ldata.Add(Ip2,Ip);
		c++;
	}
	Log(Database.Planet[Planet2].Coords + " :\n");
	c = 0;
	Susp = 0;
	while ( c < Ldata.Items ) {
		cout << Progress(c,Ldata.Items);
		if ( Ldata.count[c] <= 30  ) {
			Log(Ldata.Subnet[c] + ".x.x : " + IntToString(Ldata.count[c]) + " Times\n");
			Susp++;
		}
		c++;
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";
	Log(IntToString(Susp) + " Interesting IP Subnet Logins Found\n");
	if ( Susp > 0 ) {
		Summary = Summary + "\n" + IntToString(Susp) + " Interesting IP Subnet Logins Found on " + Database.Planet[Planet2].Coords;
	}
	Ldata.Reset(); // reset this


    // ---------------------------------------------------------------------------------
	// EMAIL AND USERNAME CHECK
	int EmailPassAndUsername = 0;
	ColQuery();
	cout << "Email, Pass and Username Check... ";
	Log("\nEmail, Pass and Username Check\n");
	Log("============================================\n");
	ColText();
	// Check Planet 1
	cout << "[----------] 000%";

	// Username of P1 > email of P2
	cout << Progress(1,7);
	if (( StripNum(Database.Planet[Planet1].Username) == StripNum(Gettok(Database.Planet[Planet2].Email,1,"@")))) {
		// Match
		Log("Possible Match found between " + Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords + "\n");
		Log(Database.Planet[Planet1].Coords + " , UN : " + Database.Planet[Planet1].Username + " Email : " + Database.Planet[Planet1].Email + "\n");
		Log(Database.Planet[Planet2].Coords + " , UN : " + Database.Planet[Planet2].Username + " Email : " + Database.Planet[Planet2].Email + "\n");
		EmailPassAndUsername++;
	}

	// Username of P2 > email of P1
	cout << Progress(2,7);
	if (( StripNum(Database.Planet[Planet2].Username) == StripNum(Gettok(Database.Planet[Planet1].Email,1,"@")))) {
		// Match
		Log("Possible Match found between " + Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords + "\n");
		Log(Database.Planet[Planet1].Coords + " , UN : " + Database.Planet[Planet1].Username + " Email : " + Database.Planet[Planet1].Email + "\n");
		Log(Database.Planet[Planet2].Coords + " , UN : " + Database.Planet[Planet2].Username + " Email : " + Database.Planet[Planet2].Email + "\n");
		EmailPassAndUsername++;
	}

	// Username of P1 > Username of P2
	cout << Progress(3,7);
	if ( StripNum(Database.Planet[Planet1].Username) == StripNum(Database.Planet[Planet2].Username)) {
		// Usernames Match
		Log("Usernames Appear Similar : " + Database.Planet[Planet1].Coords + " , UN : " + Database.Planet[Planet1].Username + " , " + Database.Planet[Planet2].Coords + " , UN : " + Database.Planet[Planet2].Username + "\n");
		EmailPassAndUsername++;
	}
	
	// Username of P1 > Pass of P2
	cout << Progress(4,7);
	if ( StripNum(Database.Planet[Planet1].Username) == StripNum(Database.Planet[Planet2].Password)) {
		// Match
		Log("Usernames/Passes Appear Similar : " + Database.Planet[Planet1].Coords + " , UN : " + Database.Planet[Planet1].Username + " , " + Database.Planet[Planet2].Coords + " , PW : " + Database.Planet[Planet2].Password + "\n");
		EmailPassAndUsername++;
	}

	// Username of P2 > Pass of P1
	cout << Progress(5,7);
	if ( StripNum(Database.Planet[Planet2].Username) == StripNum(Database.Planet[Planet1].Password)) {
		// Match
		Log("Usernames/Passes Appear Similar : " + Database.Planet[Planet2].Coords + " , UN : " + Database.Planet[Planet2].Username + " , " + Database.Planet[Planet1].Coords + " , PW : " + Database.Planet[Planet1].Password + "\n");
		EmailPassAndUsername++;
	}

	// Pass of P1 > Email of P2
	cout << Progress(6,7);
	if ( StripNum(Database.Planet[Planet1].Password) == StripNum(Gettok(Database.Planet[Planet2].Email,1,"@"))) {
		// Match
		Log("Pass/Email Appears Similar : " + Database.Planet[Planet1].Coords + " , PW : " + Database.Planet[Planet1].Password + " , " + Database.Planet[Planet2].Coords + " , Email : " + Database.Planet[Planet2].Email + "\n");
		EmailPassAndUsername++;
	}

	// Pass of P2 > Email of P1
	cout << Progress(7,7);
	if ( StripNum(Database.Planet[Planet2].Password) == StripNum(Gettok(Database.Planet[Planet1].Email,1,"@"))) {
		// Match
		Log("Pass/Email Appears Similar : " + Database.Planet[Planet2].Coords + " , PW : " + Database.Planet[Planet2].Password + " , " + Database.Planet[Planet1].Coords + " , Email : " + Database.Planet[Planet1].Email + "\n");
		EmailPassAndUsername++;
	}

	Log(IntToString(EmailPassAndUsername) + " Email/Username Correlations Detected\n");

	if ( EmailPassAndUsername > 0 ) {
		Summary = Summary + "\n" + IntToString(EmailPassAndUsername) + " Email/Pass/Username Correlations Detected";
	}
	cout << "\n";
	//
    // ---------------------------------------------------------------------------------
	// Suspicious Fleet Movements
	ColQuery();
	cout << "Suspicious Fleet Movements Check... ";
	Log("\nSuspicious Fleet Movements Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	int Movements = 0;
	c = 0;

	Ldata.Reset(); // reset this.
	while ( c < Database.Planet[Planet1].Logins.Lines ) {
		string Ip = Database.Planet[Planet1].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Ldata.Add(Ip2,Ip);
		c++;
	}

	c = 0;
	d = 0;
	while ( c < Database.Planet[Planet1].Launches.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Launches.Lines);
 		string Fleetdate = Righttok(Database.Planet[Planet1].Launches.Line[c],6," ");
		long int MyDiff = 999999999;
		string MyLogin, MyIP, Logindate;
		while ( d < Database.Planet[Planet1].Logins.Lines ) {
			Logindate = Lefttok(Database.Planet[Planet1].Logins.Line[d],5," ");
			long int Diff = ( DatetoSec(Fleetdate) - DatetoSec(Logindate) );
			if (( Diff > 0 ) && ( Diff < MyDiff )) {
				MyDiff = Diff;
				MyLogin = Database.Planet[Planet1].Logins.Line[d];
				MyIP = Gettok(MyLogin,6," ");

			}
			d++;
		}
		// the closest matching login for the fleet launch is now in MyLogin
		int e = 0;
		while ( e < Ldata.Items ) {
			if (( Ldata.count[e] <= 30  ) && ( Ldata.Subnet[e] == Gettok(MyIP,1,".") + "." + Gettok(MyIP,2,".") ) ) {
				// That IP subnet appears less then 30 times
				Log("Planet - " + Database.Planet[Planet1].Coords + "\nMovement : " + Database.Planet[Planet1].Launches.Line[c] + "\nClosest Login On : " + MyLogin + "\nFrom IP subnet : " + Ldata.Subnet[e] + ".x.x , Seen " + IntToString(Ldata.count[e]) + " Times \n\n");
				Movements++;
			}
			e++;
		}
		d =0;
		c++;
	}

	Log(IntToString(Movements) + " Suspicious Fleet Movements Detected on " + Database.Planet[Planet1].Coords + "\n");
	if ( Movements > 0 ) {
		Summary = Summary + "\n" + IntToString(Movements) + " Suspicious Fleet Movements Detected on " + Database.Planet[Planet1].Coords;
	}
	cout << Progress(0,0); // Bugfix
	cout << " , ";
	cout << "[----------] 000%";
	c = 0;
	Ldata.Reset(); // reset this.
	while ( c < Database.Planet[Planet2].Logins.Lines ) {
		string Ip = Database.Planet[Planet2].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Ldata.Add(Ip2,Ip);
		c++;
	}

	c = 0;
	d = 0;
	Movements = 0;
	while ( c < Database.Planet[Planet2].Launches.Lines ) {
		cout << Progress(c,Database.Planet[Planet1].Launches.Lines);
		string Fleetdate = Righttok(Database.Planet[Planet2].Launches.Line[c],6," ");
		long int MyDiff = 999999999;
		string MyLogin, MyIP, Logindate;
		while ( d < Database.Planet[Planet2].Logins.Lines ) {
			Logindate = Lefttok(Database.Planet[Planet2].Logins.Line[d],5," ");
			long int Diff = ( DatetoSec(Fleetdate) - DatetoSec(Logindate) );
			if (( Diff > 0 ) && ( Diff < MyDiff )) {
				MyDiff = Diff;
				MyLogin = Database.Planet[Planet2].Logins.Line[d];
				MyIP = Gettok(MyLogin,6," ");

			}
			d++;
		}
		// the closest matching login for the fleet launch is now in MyLogin
		int e = 0;
		while ( e < Ldata.Items ) {
			if ( ( Ldata.count[e] <= 30 ) && ( Ldata.Subnet[e] == Gettok(MyIP,1,".") + "." + Gettok(MyIP,2,".") ) ) {
				Log("Planet - " + Database.Planet[Planet2].Coords + "\nMovement : " + Database.Planet[Planet2].Launches.Line[c] + "\nClosest Login On : " + MyLogin + "\nFrom IP subnet : " + Ldata.Subnet[e] + ".x.x , Seen " + IntToString(Ldata.count[e]) + " Times \n\n");
				Movements++;
			}
			e++;
		}
		d =0;
		c++;
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";
	Log(IntToString(Movements) + " Suspicious Fleet Movements Detected on " + Database.Planet[Planet2].Coords + "\n");
	if ( Movements > 0 ) {
		Summary = Summary + "\n" + IntToString(Movements) + " Suspicious Fleet Movements Detected on " + Database.Planet[Planet2].Coords;
	}
    // ---------------------------------------------------------------------------------
	// Common Targets for Both planets
	ColQuery();

	cout << "Common Targets Check... ";
	Log("\nCommon Targets Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	TARGETS Targ1;
	TARGETS Targ2;

	c = 0;
	while ( c < Database.Planet[Planet1].Launches.Lines ) {
		Targ1.Add(Database.Planet[Planet1].Launches.Line[c]);
		c++;
	}
	c = 0;
	while ( c < Database.Planet[Planet2].Launches.Lines ) {
		Targ2.Add(Database.Planet[Planet2].Launches.Line[c]);
		c++;
	}
	
	c = 0;
	d = 0;
	int Commtarg = 0;
	while ( c < Targ1.Targets ) {
		cout << Progress(c,Targ1.Targets);
		while ( d < Targ2.Targets ) {
			if ( Targ1.Target[c] == Targ2.Target[d] ) {
				Log("Common Target : " + Targ1.Target[c] + "\n");
				Log("Launched at " + IntToString(Targ1.Count[c]) + " times by " + Database.Planet[Planet1].Coords + "\n");
				Log("Launched at " + IntToString(Targ2.Count[d]) + " times by " + Database.Planet[Planet2].Coords + "\n\n");
				Commtarg++;
			}
			d++;
		}
		d=0;
		c++;
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";
	Log(IntToString(Commtarg) + " Common Targets for " + Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords + "\n\n");
	if ( Commtarg > 0 ) {
		Summary = Summary + "\n" + IntToString(Commtarg) + " Common Targets for " + Database.Planet[Planet1].Coords + " and " + Database.Planet[Planet2].Coords;
	}
	//
    // ---------------------------------------------------------------------------------
	// Changed Password Check
	ColQuery();
	cout << "Password Change Check... ";
	Log("\nPassword Change Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	
	c = 0;
	PASSWORD PwDb;
	while ( c <= Database.Planet[Planet1].Upgrades.Lines ) {
		if ( Gettok(Database.Planet[Planet1].Upgrades.Line[c],8," ") == "Password" ) {
			PwDb.Pass[PwDb.Items] = Gettok(Database.Planet[Planet1].Upgrades.Line[c],11," ");
			PwDb.Items++;
		}
		c++;
	}
	// all pass changes stored in db now.
	// check for matching ones
	c = 0;
	while ( c <= PwDb.Items ) {
		Progress(c,PwDb.Items);
		d = c+1;
		while ( d <= PwDb.Items ) {
			if ( PwDb.Pass[c] == PwDb.Pass[d]) {
				// We have a winner
				Log("Password change and back again on " + Database.Planet[Planet1].Coords + " - " + PwDb.Pass[c] + "\n");
				Summary = Summary + "\nPassword change and back again on " + Database.Planet[Planet1].Coords + " - " + PwDb.Pass[c];
			}
			d++;
		}
		c++;
	}
	// reset
	PwDb.Items = 0;
	// Next Planet
	while ( c <= Database.Planet[Planet2].Upgrades.Lines ) {
		if ( Gettok(Database.Planet[Planet2].Upgrades.Line[c],8," ") == "Password" ) {
			PwDb.Pass[PwDb.Items] = Gettok(Database.Planet[Planet2].Upgrades.Line[c],11," ");
			PwDb.Items++;
		}
		c++;
	}
	// all pass changes stored in db now.
	// check for matching ones
	c = 0;
	while ( c < PwDb.Items ) {
		Progress(c,PwDb.Items);
		d = c+1;
		while ( d < PwDb.Items ) {
			if ( PwDb.Pass[c] == PwDb.Pass[d]) {
				// We have a winner
				Log("Password change and back again on " + Database.Planet[Planet2].Coords + " - " + PwDb.Pass[c] + "\n");
				Summary = Summary + "\nPassword change and back again on " + Database.Planet[Planet2].Coords + " - " + PwDb.Pass[c];
			}
			d++;
		}
		c++;
	}
	PwDb.Items = 0;

	cout << Progress(0,0); // Bugfix
	cout << "\n";
	//
	// ---------------------------------------------------------------------------------
	// Potential Farmers Check
	ColQuery();
	cout << "Farming Check ... ";
	Log("\nFarming Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	//
	TARGETS Farm1;
	TARGETS Farm2;
	// do the counting of attacks to each target
	c = 0;
	while ( c < Database.Planet[Planet1].Launches.Lines ) {
		string Order = Gettok(Database.Planet[Planet1].Launches.Line[c],4," ");
		if ( Order == "Attack" ) {
			string Target = Database.Planet[Planet1].Launches.Line[c];
			Farm1.Add(Target);
		}
		c++;
	}

	c = 0;
	while ( c < Database.Planet[Planet2].Launches.Lines ) {
		string Order = Gettok(Database.Planet[Planet2].Launches.Line[c],4," ");
		if ( Order == "Attack" ) {
			string Target = Database.Planet[Planet2].Launches.Line[c];
			Farm2.Add(Target);
		}
		c++;
	}
	// ok All of them are counted now. 
	// now we want to return those where they`re over 20% of the planets attacks
	c = 0;
	int susfarm1 = 0;
	int susfarm2 = 0;
	int inter1 = 0;
	int inter2 = 0;
	int totfarm1 = 0;
	int totfarm2 = 0;
	while ( c < Farm1.Targets ) {
		cout << Progress(c,Farm1.Targets);


		if ( abs((Farm1.Count[c] * 100 ) / Farm1.Targets) > 20 ) {
			Log("Possible farming of " + Farm1.Target[c] + " by " + Database.Planet[Planet1].Coords + " , Attacked " + IntToString(abs(Farm1.Count[c])) + " Times\n");
			susfarm1++;
			totfarm1 += Farm1.Count[c];

		}
		// Check to see if its the other planet.
		if ( Farm1.Target[c] == Database.Planet[Planet2].Coords ) {
			Log("Account Interaction - " + Database.Planet[Planet1].Coords + " Attacked " + Database.Planet[Planet2].Coords + "\n");
			inter1++;
		}
		c++;
	}
	cout << Progress(0,0);
	c = 0;
	cout << " , ";
	cout << "[----------] 000%";
	while ( c < Farm2.Targets ) {
		cout << Progress(c,Farm2.Targets);
		if ( abs((Farm2.Count[c] * 100 ) / Farm2.Targets) > 20 ) {
			Log("Possible farming of " + Farm2.Target[c] + " by " + Database.Planet[Planet2].Coords + " , Attacked " + IntToString(abs(Farm2.Count[c])) + " Times\n");
			susfarm2++;
			totfarm2 += Farm2.Count[c];

		}
		if ( Farm2.Target[c] == Database.Planet[Planet1].Coords ) {
			Log("Account Interaction - " + Database.Planet[Planet1].Coords + " Attacked " + Database.Planet[Planet2].Coords + "\n");
			inter2++;
		}
		c++;
	}
	Log(Database.Planet[Planet1].Coords + " initiated roids while under attack " + IntToString(Database.Planet[Planet1].Roid_Init.lines) + " times\n");
	Log(Database.Planet[Planet2].Coords + " initiated roids while under attack " + IntToString(Database.Planet[Planet2].Roid_Init.lines) + " times\n");
	Log("Possible Farms Attacked by " + Database.Planet[Planet1].Coords + " = " + IntToString(susfarm1) + ", Total Farmings = " + IntToString(totfarm1) + "\n");
	Log("Possible Farms Attacked by " + Database.Planet[Planet2].Coords + " = " + IntToString(susfarm2) + ", Total Farmings = " + IntToString(totfarm2) + "\n");
	Log("Interactions by " + Database.Planet[Planet1].Coords + " = " + IntToString(inter1) + "\n");
	Log("Interactions by " + Database.Planet[Planet2].Coords + " = " + IntToString(inter2) + "\n");
	if ( susfarm1 > 0 ) {
		Summary = Summary + "\nPossible Farms Attacked by " + Database.Planet[Planet1].Coords + " = " + IntToString(susfarm1) + ", Total Farmings = " + IntToString(totfarm1);
	}
	if ( susfarm2 > 0 ) {
		Summary = Summary + "\nPossible Farms Attacked by " + Database.Planet[Planet2].Coords + " = " + IntToString(susfarm2) + ", Total Farmings = " + IntToString(totfarm2);
	}
	if ( inter1 > 0 ) {
		Summary = Summary + "\nInteractions by " + Database.Planet[Planet1].Coords + " = " + IntToString(inter1);
	}

	if ( inter2 > 0 ) {
		Summary = Summary + "\nInteractions by " + Database.Planet[Planet2].Coords + " = " + IntToString(inter2);
	}

	if ( Database.Planet[Planet1].Roid_Init.lines > 0 ) {
		Summary = Summary + "\n" + Database.Planet[Planet1].Coords + " initiated roids while under attack " + IntToString(Database.Planet[Planet1].Roid_Init.lines) + " times";
	}

	if ( Database.Planet[Planet2].Roid_Init.lines > 0 ) {
		Summary = Summary + "\n" + Database.Planet[Planet2].Coords + " initiated roids while under attack " + IntToString(Database.Planet[Planet2].Roid_Init.lines) + " times";
	} 
	c out << Progress(0,0); // Bugfix
	c out << "\n";
 
     // ---------------------------------------------------------------------------------
 	// Scan Planet Check
 	ColQuery();
	cout << "Scan Planet Check... ";
	Log("\nScan Planet Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	// scan planets have lots of launches and recalls. say 60% be the threshold
	c = 0;
	int Recalls = 0;
	if ( Database.Planet[Planet1].Launches.Lines > 0 ) {
		while ( c < Database.Planet[Planet1].Launches.Lines ) {
			cout << Progress(c,Database.Planet[Planet1].Launches.Lines);
			if ( Gettok(Database.Planet[Planet1].Launches.Line[c],4," ") == "Recall") {
				Recalls++;
			}
			c++;
		}
		if (abs((Recalls * 100) / Database.Planet[Planet1].Launches.Lines) >= 60 ) {
			Log(Database.Planet[Planet1].Coords + " May be a Scan Planet, " + IntToString(Recalls) + " Launch/Recall combos detected (" + IntToString(abs((Recalls * 100) / Database.Planet[Planet1].Launches.Lines)) + "%)\n");
			Summary = Summary + "\n" + Database.Planet[Planet1].Coords + " May be a Scan Planet, " + IntToString(Recalls) + " Launch/Recall combos detected (" + IntToString(abs((Recalls * 100) / Database.Planet[Planet1].Launches.Lines)) + "%)";
		}
		c = 0;
	}
	Log(IntToString(Recalls) + " Launch/Recall Combos Detected from " + Database.Planet[Planet1].Coords + "\n");
	if ( Recalls > 0 ) {
		Summary = Summary + "\n" + IntToString(Recalls) + " Launch/Recall Combos detected from " + Database.Planet[Planet1].Coords;
	
	}
	Recalls = 0;
	if ( Database.Planet[Planet2].Launches.Lines > 0 ) {
		while ( c < Database.Planet[Planet2].Launches.Lines ) {
			cout << Progress(c,Database.Planet[Planet2].Launches.Lines);
			if ( Gettok(Database.Planet[Planet2].Launches.Line[c],4," ") == "Recall") {
				Recalls++;
			}
			c++;
		}
		if (abs((Recalls * 100) / Database.Planet[Planet2].Launches.Lines) >= 60 ) {
			Log(Database.Planet[Planet2].Coords + " May be a Scan Planet, " + IntToString(Recalls) + " Launch/Recall combos detected (" + IntToString(abs((Recalls * 100) / Database.Planet[Planet2].Launches.Lines)) + "%)\n");
			Summary = Summary + "\n" + Database.Planet[Planet2].Coords + " May be a Scan Planet, " + IntToString(Recalls) + " Launch/Recall combos detected (" + IntToString(abs((Recalls * 100) / Database.Planet[Planet2].Launches.Lines)) + "%)";
 		}
 	}
	Log(IntToString(Recalls) + " Launch/Recall Combos Detected from " + Database.Planet[Planet2].Coords + "\n");
	if ( Recalls > 0 ) {
		Summary = Summary + "\n" + IntToString(Recalls) + " Launch/Recall Combos detected from " + Database.Planet[Planet2].Coords;
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";

    // ---------------------------------------------------------------------------------
	// Signups Check
	ColQuery();
	cout << "Signups Check... ";
	Log("\nSignups Check\n");
	Log("============================================\n");
	ColText();
	cout << "[----------] 000%";
	//
	if ( abs(Database.Planet[Planet1].UserID - Database.Planet[Planet2].UserID) <= 30 ) {
		Log("Planets may have signed up together, " + IntToString(abs(Database.Planet[Planet1].UserID - Database.Planet[Planet2].UserID)) + " Difference in the UserIDs\n");
		Summary = Summary + "\nPlanets may have signed up together, " + IntToString(abs(Database.Planet[Planet1].UserID - Database.Planet[Planet2].UserID)) + " Difference in the UserIDs";
	}
	else {
		Log("Nothing Significant in the User ID Difference\n");
	}
	cout << Progress(0,0); // Bugfix
	cout << "\n";

	// ----------------------------------------------------------------------------------
	// Ips Data Addition
	ColQuery();
	cout << "IP Data Addition... ";
	ColText();
	cout << "[----------] 000%";
	c = 0;
	while ( c < Database.Planet[Planet1].Logins.Lines ) {
		string Ip = Database.Planet[Planet1].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Database.Planet[Planet1].Ips.Add(Ip2,Ip);
		cout << Progress(c,Database.Planet[Planet1].Logins.Lines);
		c++;
	}
	cout << Progress(0,0); // Bugfix
	cout << " , ";
	cout << "[----------] 000%";
	c = 0;
	while ( c < Database.Planet[Planet2].Logins.Lines ) {
		string Ip = Database.Planet[Planet2].Logins.Line[c];
		string Ip2 = Gettok(Gettok(Ip,6," "),1,".") + "." + Gettok(Gettok(Ip,6," "),2,".");
		Database.Planet[Planet2].Ips.Add(Ip2,Ip);
		cout << Progress(c,Database.Planet[Planet2].Logins.Lines);
		c++;
	}
	cout << Progress(0,0); // Bugfix

	//

	Log("============================================\n");
	Log("\n\nSummary:\n" + Summary + "\n");
	Log("===================================================================================\n\n");
	GlobalSummary = GlobalSummary + Summary + "\n\n";

}

void DB::DelPlanet(int Number) {
	// Deletes a planet record and bumps the others down to it

	while ( Number <= Database.Planets ) {
		Database.Planet[Number] = Database.Planet[(Number + 1)]; // Hurrah! a quick way to do it 
		Number++;
	}
	Database.Planets--;
}

void Log(string Line) {
	Database.Report.Add(Line);	
}

void REPORT::Add(string InLine) {
	Line[Lines] = InLine;
	Lines++;
}
void REPORT::Dump(char* Filename) {
	ofstream fout(Filename);
	if (!fout) {
		ColError();
		cout << "CRITICAL ERROR OPENING OUTPUT FILE\n";
		cout << "Check the Drive is not Read Only, and is not Full\n";
		ResetColour();
		exit(1);
	}
	int c = 0;
	fout.clear();
	while ( c <= Database.Report.Lines ) {
		fout << Database.Report.Line[c];
		c++;
	}
	fout.close();
}
void REPORT::Clear(char* Filename) {
	ofstream fout(Filename);
	fout.clear(0);
	fout.close();
	Lines = 0;
}

void INVLOGINS::Add(string IP,string Raw) {
	int c = 0;
	bool found = false;
	bool ipfound = false;
	while ( c < Items ) {
		if ( IP == Subnet[c] ) {
			// if one exists - increment the relevent counter on it
			count[c]++;
			found = true;
		}
		c++;		
	}

	c = 0;
	while ( c < ipitems ) {
		if ( Gettok(Raw,6," ") == UniqueIP[c] ) {
			ipcount[c]++;
			ipfound = true;
		}
		c++;
	}

	if (( found == false ) || ( Items == 0 )) {
		// Otherwise make one
		Subnet[Items] = IP;
		count[Items] = 1;
		Items++;

	}

	if (( ipfound == false ) || ( ipitems == 0 )) {
		UniqueIP[ipitems] = Gettok(Raw,6," ");
		ipcount[ipitems] = 1;
		ipitems++;
	}
	
}		

void INVLOGINS::Reset() {
	int c = 0;
	while ( c <= Items ) {
		Subnet[Items] = "";
		count[Items] = 0;
		c++;
	}
	Items = 0;
}


string StripNum(string Line) {
return Remove(Remove(Remove(Remove(Remove(Remove(Remove(Remove(Remove(Remove(Line,"1"),"2"),"3"),"4"),"5"),"6"),"7"),"8"),"9"),"0");
}

void ParseFile(string filename) {
	ColQuery();
	cout << "Selecting file " + filename + "..." << endl;
	ColText();
	bool ishtml = false;
	string htmlfn = "";
	if (Right(filename,5) == ".html") {
		htmltotxt(filename);
		ishtml = true;
		htmlfn = filename;
		filename = "html.txt";
	}
	else if (Right(filename,4) == ".htm") {
		htmltotxt(filename);
		ishtml = true;
		htmlfn = filename;
		filename = "html.txt";
	}

	

	cout << "Opening file " + filename + "..." << endl;
	
	ifstream filein(filename.c_str());

	if (!filein) {
		ColError();
		cout << "Error opening File!" << endl;
	}
	if (filein) {
		ColText();
		string Browser = "";
		cout << "Validating..." << endl;
		// Ok , here we do the nitty gritty parsing stuff
		// This will go through each line one at a time and parse it accordingly
		char buffer[99999]; // string buffer
		int linenum = 0; // the line number counter.
		string Linetype = "Unknown";
		string line;
		bool Valid = false;
		if ( ishtml == true ) {
			Database.Planet[Database.Planets].Filename = htmlfn; // Filename
		}
		else {
			Database.Planet[Database.Planets].Filename = filename; // Filename
		}
		filein.getline(buffer,99999);
		line = Trim(buffer," ");

		if ( (Gettok(line,1," ") == "<-Game" ) && ( Gettok(line,2," ") == "MOTD")) {
			// VALID file. Continue to parse
			Valid = true;
			Browser = "IE";
			cout << "Parsing... ( Internet Explorer Detected )\n";
			Linetype = "Unknown";
		}

		if ( (Gettok(Remove(line," "),1,"\t") == "<-Game" ) && ( Gettok(Remove(line," "),2,"\t") == "MOTD") ) {
			// VALID file. Continue to parse
			Valid = true;
			Browser = "Firefox";
			cout << "Parsing ... ( Firefox/Opera Detected )\n";
			Linetype = "Unknown";
		}
		if ( Gettok(line,1," ") == "Planetarion