www.pudn.com > 天堂1服务端模拟程序.rar > Database.cpp


/* 
Copyright (C) 2004  freeplay.dk 
 
This program is free software; you can redistribute it and/or 
modify it under the terms of the GNU General Public License 
as published by the Free Software Foundation; either version 2 
of the License, or (at your option) any later version. 
 
This program is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU General Public License for more details. 
 
You should have received a copy of the GNU General Public License 
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 
You may contact me for further information on admin@freeplay.dk 
*/ 
 
#define WIN32_LEAN_AND_MEAN 
 
// disable map warnings for std::map 
#pragma warning (disable: 4786) 
#pragma warning (disable: 4788) 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include "Database.h" 
#include "Types.h" 
#include "resource.h" 
#include "Logging.h" 
#include "ComWindows.h" 
#include "LoginMap.h" 
#include "CharMap.h" 
#include "CConnection.h" 
#include "GameServer.h" 
#include "ObjectsMultimap.h" 
#include "WorldNPC.h" 
#include "Serversettings.h" 
#include "OpCodes.h" 
 
using namespace std; 
 
#define SIZE 256 
 
//****************************** 
// links to other classes 
//****************************** 
extern charmap chm; 
ComWindows comwin; 
extern LoginMap dblmap; 
extern GameServer gs; 
extern objects obj; 
extern ServerSettings ss; 
extern worldnpc npc; 
 
//****************************** 
// pointers to mysql 
//****************************** 
MYSQL *pConn; 
MYSQL_ROW row;  
MYSQL_RES *result; 
 
//****************************** 
// Checks if Database is running 
//****************************** 
bool database::CheckDatabase(HWND hdwnd) 
{	 
	char * ip = ss.getDBIp("DatabaseIP"); 
	char * user = ss.getDBUser("DBUsername"); 
	char * dbpw = ss.getDBPass("DBPassword"); 
	char * dbname = ss.getDBName("DBName"); 
 
	if(!CheckDB(hdwnd, (char*)ip, (char*)user, (char*)dbpw, (char*)dbname)) 
	{ 
		return false; 
	} 
	else 
	{ 
		return true; 
	} 
	return true; 
} 
 
//****************************** 
// Checks database permission connection 
//****************************** 
bool database::CheckDB(HWND hdwnd, char* ip, char* user, char* dbpw, char* dbname) 
{ 
	bool compression = false; 
	unsigned int num_rows; 
 
	pConn = mysql_init(NULL); 
	if(!pConn) 
	{ 
		comwin.WriteDataStr(hdwnd, "Error : Database connection not initialized"); 
		Log2File(TRUE, "Error : Database connection not initialized\n"); 
		Log2File(TRUE, "MySQL Error : %s\n", mysql_error(pConn)); 
		comwin.WriteDBStatus(hdwnd, "OFFLINE"); 
		return false; 
	} 
	if (!mysql_real_connect(pConn, ip, user, dbpw, dbname, 0, NULL, 0)) 
	{ 
		comwin.WriteDataStr(hdwnd, "Error : Failed to connect to database"); 
		comwin.WriteDBStatus(hdwnd, "OFFLINE"); 
		Log2File(TRUE, "Error : Failed to connect to database\n"); 
		Log2File(TRUE, "MySQL Error : %s\n", mysql_error(pConn)); 
		return false; 
	} 
	else 
	{ 
		comwin.WriteDataStr(hdwnd, "Using Database : %s @ %s", dbname, ip); 
		Log2File(TRUE,"Using database : %s @ %s\n", (char*)dbname, (char*)ip); 
		comwin.WriteDBStatus(hdwnd, "ONLINE"); 
 
		if(mysql_query(pConn, "SELECT * FROM account")) 
		{ 
			comwin.WriteDataStr(hdwnd, "Error : Could not open table account in database %s", dbname); 
			return false; 
		} 
		else 
		{  
			result = mysql_store_result(pConn);  
			num_rows = mysql_num_rows(result); 
			comwin.WriteDataStr(hdwnd, "MySQL : %i account(s) on server", num_rows); 
			mysql_free_result(result); 
				 
			char query[100]; 
			sprintf(query,"UPDATE account SET online='0'"); 
			if(mysql_query(pConn,query)) 
			{ 
				// error doing the query 
				Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
				return false; 
			} 
			else 
			{ 
				result = mysql_store_result(pConn); 
				mysql_free_result(result); 
				return true; 
			} 
		} 
	} 
	return true; 
} 
 
//****************************** 
// Closes MySQL connection 
//****************************** 
void database::mysqlclose() 
{ 
	mysql_close(pConn); 
} 
 
//****************************** 
// Ping's MySQL connection (keep alive) every 1 minute. 
//****************************** 
int database::mysqlping() 
{ 
	mysql_ping(pConn); 
	return 1; 
} 
 
//****************************** 
// Resets stuff that needs to be reset when server closes 
//****************************** 
void database::resetDB() 
{ 
	char query[100]; 
	sprintf(query,"UPDATE serversettings SET idsused='10000', setting='0' WHERE id='1'"); 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		mysql_free_result(result); 
		return; 
	} 
} 
 
//****************************** 
// Creates a character based on create char dialog 
//****************************** 
void database::createaccount(HWND hdwnd, char * username, char * password, char * email, char * isgm) 
{ 
 
	char query[100]; 
	sprintf(query,"SELECT * FROM account WHERE name='%s'", username); 
 
	char insertquery[200]; 
	sprintf(query,"INSERT INTO account (name, password, email, admin) VALUES ('%s', '%s', '%s', '%s')", username, password, email, isgm); 
 
	if(mysql_query(pConn, query)) 
	{ 
		comwin.WriteDataStr(hdwnd, "Error : Username already exsists"); 
	} 
		else 
	{ 
		result = mysql_store_result(pConn); 
		// create account 
		if (mysql_query(pConn, insertquery)) 
		{ 
			comwin.WriteDataStr(hdwnd, "MySQL : Error creating new account"); 
			mysql_free_result(result); 
		} 
		else 
		{ 
			comwin.WriteDataStr(hdwnd, "Created new user account : %s", username); 
			Log2File(TRUE, "Created new user account : %s\n", username); 
			mysql_free_result(result); 
		} 
		mysql_free_result(result); 
	} 
} 
 
//****************************** 
// Gets the next availible unique ID 
//****************************** 
unsigned long database::getnewid() 
{ 
	char query[100]; 
	sprintf(query,"SELECT * FROM serversettings WHERE id='1'"); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result);		 
 
		unsigned long id; 
		id = (unsigned long)atol((char *)row[3]); 
		mysql_free_result(result); 
 
		unsigned long newid = id+1; 
 
		char query[100]; 
		sprintf(query,"UPDATE serversettings SET idsused='%d' WHERE id='1'", newid); 
 
		if(mysql_query(pConn,query)) 
		{ 
			// error doing the query 
			Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
			return 0; 
		} 
		else 
		{ 
			result = mysql_store_result(pConn); 
			mysql_free_result(result); 
			return id; 
		} 
	} 
} 
 
//*********************************************************** 
// gets server time 
//*********************************************************** 
int database::getservertime() 
{ 
	char query[200]; 
	sprintf(query,"SELECT * FROM serversettings WHERE id='1'"); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int servertime = (int)atoi((char *)row[1]); 
 
		mysql_free_result(result); 
		return servertime; 
	} 
} 
 
//*********************************************************** 
// sets server time 
//*********************************************************** 
int database::setservertime(long nowtime) 
{ 
	long testtime; 
	testtime = nowtime; 
 
	char query[100]; 
	sprintf(query,"UPDATE serversettings SET servertime='%d' WHERE id='1'", testtime); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		mysql_free_result(result); 
		return 0; 
	} 
	return 0; 
} 
 
//*********************************************************** 
// gets client time 
//*********************************************************** 
int database::getclienttime() 
{ 
	char query[200]; 
	sprintf(query,"SELECT * FROM serversettings WHERE id='1'"); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int clienttime = (int)atoi((char *)row[2]); 
 
		mysql_free_result(result); 
		return clienttime; 
	} 
} 
 
//*********************************************************** 
// sets client time 
//*********************************************************** 
int database::setclienttime(int extra) 
{ 
	long currentime; 
	long currentservertime; 
	long newtime; 
	currentime = getclienttime(); 
	if(extra > 0) 
	{ 
		newtime = currentime + extra; 
	} 
	else 
	{ 
		newtime = currentime + 6; 
	} 
 
	// set new server time 
	currentservertime = getservertime(); 
	if(currentime == currentservertime) 
	{ 
		long newtime = currentservertime+300; 
		setservertime(newtime); 
		chm.sendTime(); 
	} 
 
	char query[100]; 
	sprintf(query,"UPDATE serversettings SET clienttime='%d' WHERE id='1'", newtime); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		mysql_free_result(result); 
		return 1; 
	} 
	return 0; 
} 
 
//*************************************************** 
//			Login Server Database calls 
// 		Used only by the login server files. 
//*************************************************** 
 
//*********************************************************** 
// check username and password. 
//*********************************************************** 
int database::checklogin(HWND hdwnd, DWORD ptr, char * username, char * password) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	unsigned int num_rows; 
 
	char query[200]; 
	sprintf(query,"SELECT * FROM account WHERE name='%s' && password='%s'", username, password); 
	 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		// fetch all the rows from the query. 
		num_rows = mysql_num_rows(result); 
		row = mysql_fetch_row(result); 
 
		// the username and password match, return accountid 
		if(num_rows >= 1) 
		{ 
			int isonline = (int)atoi((char *)row[5]); 
			int accountid = (int)atoi((char *)row[0]); 
 
			// user is not online, so its cool 
			if(isonline == 0) 
			{ 
				string myname = (string)row[1]; 
				char * accname = strdup(myname.c_str()); 
 
				dblmap.setPtr(cp, ptr); 
				dblmap.setSocket(cp, cp); 
				dblmap.setAccountid(cp, accountid); 
				dblmap.setUsername(cp, myname); 
				setisplaying(accountid, 1); 
 
				mysql_free_result(result); 
				return 1; 
			} 
			// user is already online, so d/c him and inform new user is logging in. 
			else if(isonline == 1) 
			{ 
				setisplaying(accountid, 0); 
				DWORD otherptr = dblmap.findPtr(accountid); 
 
				CConnection* o = reinterpret_cast  (otherptr); 
				char			oip[15]; 
				unsigned int	op = 0; 
				o->PeerInfo (&oip[0], 15, &op); 
				// send this packet to old user that new one is logging in, and disconnect him. 
				unsigned char userlogin[] = { 
				0x1C, 0x16, 0x00, 0x5D, 0x39, 0x00, 0x00, 0x96 
				}; 
				sendpacket((char*)userlogin, 8, otherptr); 
 
				string name = dblmap.getUsername(op); 
				char * username = strdup(name.c_str()); 
				comwin.RemoveUserOnline(hdwnd, username); 
 
				comwin.WriteDataStr(hdwnd , "Connection was closed from %s (reason: new login same acc)", oip); 
				Log2File(TRUE, "Connection was closed from %s on socket %i (reason: another user is logging in same acc.)\n", oip, op); 
 
				saveuserobject(otherptr); 
				obj.removeknownobjectlogout(op, chm.getObjectid(op)); 
 
				dblmap.removeMap(op); 
				obj.removeMap(op); 
				obj.removeknownobject(op, chm.getObjectid(op)); 
				chm.removeMap(op); 
 
				o->Disconnect(); 
				mysql_free_result(result); 
				return 2; 
			} 
		} 
 
		// no such username 
		else if(num_rows == 0) 
		{ 
			mysql_free_result(result); 
			return 0; 
		} 
		mysql_free_result(result); 
	} 
	return 0; 
} 
 
//*********************************************************** 
// set if user is online or not (1, 0) 
//*********************************************************** 
int database::setisplaying(int id, int state) 
{ 
	char query[200]; 
	sprintf(query,"UPDATE account SET online='%i' WHERE id='%i'", state, id); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		mysql_free_result(result); 
		return 0; 
	} 
	return 0; 
} 
 
//*********************************************************** 
// returns value of chars on server 
//*********************************************************** 
int database::loginamountchars(char * username) 
{ 
	unsigned int num_rows; 
	char query[200]; 
	sprintf(query,"SELECT id FROM account WHERE name='%s'", username); 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
		int accid = (int)atoi((char *)row[0]); 
 
		mysql_free_result(result); 
 
		char query2[100]; 
		sprintf(query2,"SELECT * FROM characters WHERE accountid='%i'", accid); 
 
		if(mysql_query(pConn,query2)) 
		{ 
			// error doing the query 
			Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
			return 0; 
		} 
		else 
		{ 
			result = mysql_store_result(pConn); 
			num_rows = mysql_num_rows(result); 
	 
			mysql_free_result(result); 
			return num_rows; 
		} 
		mysql_free_result(result); 
		return 0; 
	} 
	mysql_free_result(result); 
	return 0; 
} 
 
//*********************************************************** 
// returns id's of chars on server 
//*********************************************************** 
int database::getcharids(int amount, char * name, DWORD ptr) 
{ 
	char query1[100]; 
	sprintf(query1,"SELECT id FROM account WHERE name='%s'", name); 
	if(mysql_query(pConn,query1)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
		int accid = (int)atoi((char *)row[0]); 
 
		mysql_free_result(result); 
		 
		static int currentid; 
 
		for(int i = 0; i != amount; i++) 
		{ 
			char query[100]; 
			sprintf(query,"SELECT id FROM characters WHERE accountid='%i' && id > '%i'", accid, currentid); 
 
			if(mysql_query(pConn,query)) 
			{ 
				// error doing the query 
				Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
				return 0; 
			} 
			else 
			{ 
				result = mysql_store_result(pConn); 
				row = mysql_fetch_row(result); 
 
				int id = (int)atoi((char *)row[0]); 
				currentid = id; 
 
				mysql_free_result(result); 
				sendcharid(id, ptr); 
			} 
		} 
		currentid = 0; 
		return 0; 
	} 
	return 0; 
} 
 
//*********************************************************** 
// send one of these for each character the user have. 
//*********************************************************** 
int database::sendcharid(int charid, DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	char query[100]; 
	sprintf(query,"SELECT * FROM characters WHERE id='%i'", charid); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int8 opcode = l_sc_charpacks; 
 
		char buf[50]; 
		char* buf_ptr = buf; // done so we can mover buf_ptr to were we need to memcpy 
		 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		 
		int8 addbyte = 0x00; 
 
		char * name = (char*)row[2]; 
		memcpy(buf_ptr,(char*)name, strlen(name)); 
		buf_ptr+=strlen(name); 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
		char * clanname = (char*)row[3]; 
		memcpy(buf_ptr,(char*)clanname, strlen(clanname)); 
		buf_ptr+=strlen(clanname); 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
		int8 charclass = (int8)atoi((char *)row[4]); 
		memcpy(buf_ptr, (char*)&charclass, 1); 
		buf_ptr+=1; 
		int8 gender = (int8)atoi((char *)row[5]); 
		memcpy(buf_ptr, (char*)&gender, 1); 
		buf_ptr+=1; 
		int16 lawful = (int16)atoi((char *)row[6]); 
		memcpy(buf_ptr, (char*)&lawful, 2); 
		buf_ptr+=2; 
		int16 hp = (int16)atoi((char *)row[7]); 
		memcpy(buf_ptr, (char*)&hp, 2); 
		buf_ptr+=2; 
		int16 mp = (int16)atoi((char *)row[9]); 
		memcpy(buf_ptr, (char*)&mp, 2); 
		buf_ptr+=2; 
		int8 ac = (int8)atoi((char *)row[12]); 
		memcpy(buf_ptr, (char*)&ac, 1); 
		buf_ptr+=1; 
		int8 level = (int8)atoi((char *)row[11]); 
		memcpy(buf_ptr, (char*)&level, 1); 
		buf_ptr+=1; 
		int8 str = (int8)atoi((char *)row[13]); 
		memcpy(buf_ptr, (char*)&str, 1); 
		buf_ptr+=1; 
		int8 dex = (int8)atoi((char *)row[14]); 
		memcpy(buf_ptr, (char*)&dex, 1); 
		buf_ptr+=1; 
		int8 con = (int8)atoi((char *)row[15]); 
		memcpy(buf_ptr, (char*)&con, 1); 
		buf_ptr+=1; 
		int8 cha = (int8)atoi((char *)row[16]); 
		memcpy(buf_ptr, (char*)&cha, 1); 
		buf_ptr+=1; 
		int8 wis = (int8)atoi((char *)row[17]); 
		memcpy(buf_ptr, (char*)&wis, 1); 
		buf_ptr+=1; 
		int8 intel = (int8)atoi((char *)row[18]); 
		memcpy(buf_ptr, (char*)&intel, 1); 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
 
		int size = strlen(name)+strlen(clanname)+20; 
 
		sendpacket(buf, size, ptr); 
		// free mysql result's 
		mysql_free_result(result); 
 
	} 
	return 0; 
} 
 
//*********************************************************** 
// puts a new char into database 
//*********************************************************** 
int database::createnewchar(int accid, const char * name, BYTE charclass, BYTE gender, BYTE str, BYTE dex, BYTE con, BYTE wis, BYTE cha, BYTE intel) 
{ 
	unsigned int num_rows; 
	char query[100]; 
	sprintf(query,"SELECT * FROM characters WHERE name='%s'", name); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		// fetch all the rows from the query. 
		num_rows = mysql_num_rows(result); 
		// character exsist. 
		if(num_rows >= 1) 
		{ 
			mysql_free_result(result); 
			return 0; 
		} 
 
		// no such character name, make one is ok 
		else 
		{ 
			BYTE hp; 
			BYTE maxhp; 
			BYTE mp; 
			BYTE maxmp; 
			int16 charclasslistid; 
			int16 locx; 
			int16 locy; 
			int16 mapid; 
			 
			if(charclass == prince) 
			{ 
				locx = 32780; 
				locy = 32781; 
				mapid = 68; 
				// class prince 
				hp = 14; maxhp = 14; 
				mp = 2;  maxmp = 2; 
				if(gender == male) 
				{ 
					charclasslistid = 0; 
				} 
				else 
				{ 
					charclasslistid = 1; 
				} 
			} 
			if(charclass == knight) 
			{ 
				locx = 32714; 
				locy = 32877; 
				mapid = 69; 
				// class knight 
				hp = 16; maxhp = 16; 
				mp = 1;  maxmp = 1; 
				if(gender == male) 
				{ 
					charclasslistid = 61; 
				} 
				else 
				{ 
					charclasslistid = 48; 
				} 
			} 
			if(charclass == elf) 
			{ 
				locx = 33049; 
				locy = 32353; 
				mapid = 4; 
				// class elf 
				hp = 15; maxhp = 15; 
				mp = 4;  maxmp = 4; 
				if(gender == male) 
				{ 
					charclasslistid = 138; 
				} 
				else 
				{ 
					charclasslistid = 37; 
				} 
 
			} 
			if(charclass == mage) 
			{ 
				locx = 32780; 
				locy = 32781; 
				mapid = 68; 
				// class mage 
				hp = 12; maxhp = 12; 
				mp = 8;  maxmp = 8; 
				if(gender == male) 
				{ 
					charclasslistid = 734; 
				} 
				else 
				{ 
					charclasslistid = 1186; 
				} 
			} 
			if(charclass == darkelf) 
			{ 
				locx = 32937; 
				locy = 32799; 
				mapid = 304; 
				// class darkelf 
				hp = 12; maxhp = 12; 
				mp = 3;  maxmp = 3; 
				if(gender == male) 
				{ 
					charclasslistid = 2786; 
				} 
				else 
				{ 
					charclasslistid = 2796; 
				} 
			} 
 
			char inquery[400]; 
			sprintf(inquery, "INSERT INTO characters (accountid, name, class, gender, lawful, hp, maxhp, mp, maxmp, level, armor, str, dex, con, wis, cha, intel, locx, locy, charclasslistid, mapid, nutrition) VALUES ('%i', '%s', '%i', '%i', '0', '%i', '%i', '%i', '%i', '1', '10', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '5')", accid , name, charclass, gender, hp, maxhp, mp, maxmp, str, dex, con, wis, cha, intel, locx, locy, charclasslistid, mapid); 
 
			if(mysql_query(pConn,inquery)) 
			{ 
				// error doing the query 
				Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
				mysql_free_result(result); 
				return 0; 
			} 
			else 
			{ 
				//result = mysql_store_result(pConn); 
				mysql_free_result(result); 
				return 1; 
			} 
		} 
		mysql_free_result(result); 
	} 
	return 0; 
} 
 
//*********************************************************** 
// retrives and sends the new char to the user if successfully createt a char 
//*********************************************************** 
int database::generatenewcharpack(DWORD ptr, const char * name) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	char query[300]; 
	sprintf(query,"SELECT * FROM characters WHERE name='%s'", name); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int8 opcode = l_sc_createcharpacket; 
 
		char buf[32]; 
		char* buf_ptr= buf; // done so we can mover buf_ptr to were we need to memcpy 
		 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		 
		int8 addbyte = 0x00; 
 
		char * name = (char*)row[2]; 
		memcpy(buf_ptr,(char*)name, strlen(name)); 
		buf_ptr+=strlen(name); 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
		 
		int8 charclass = (int8)atoi((char *)row[4]); 
		memcpy(buf_ptr, (char*)&charclass, 1); 
		buf_ptr+=1; 
		int8 gender = (int8)atoi((char *)row[5]); 
		memcpy(buf_ptr, (char*)&gender, 1); 
		buf_ptr+=1; 
		int16 lawful = (int16)atoi((char *)row[6]); 
		memcpy(buf_ptr, (char*)&lawful, 2); 
		buf_ptr+=2; 
		int16 hp = (int16)atoi((char *)row[7]); 
		memcpy(buf_ptr, (char*)&hp, 2); 
		buf_ptr+=2; 
		int16 mp = (int16)atoi((char *)row[9]); 
		memcpy(buf_ptr, (char*)&mp, 2); 
		buf_ptr+=2; 
		int8 ac = (int8)atoi((char *)row[12]); 
		memcpy(buf_ptr, (char*)&ac, 1); 
		buf_ptr+=1; 
		int8 level = (int8)atoi((char *)row[11]); 
		memcpy(buf_ptr, (char*)&level, 1); 
		buf_ptr+=1; 
		int8 str = (int8)atoi((char *)row[13]); 
		memcpy(buf_ptr, (char*)&str, 1); 
		buf_ptr+=1; 
		int8 dex = (int8)atoi((char *)row[14]); 
		memcpy(buf_ptr, (char*)&dex, 1); 
		buf_ptr+=1; 
		int8 con = (int8)atoi((char *)row[15]); 
		memcpy(buf_ptr, (char*)&con, 1); 
		buf_ptr+=1; 
		int8 cha = (int8)atoi((char *)row[16]); 
		memcpy(buf_ptr, (char*)&cha, 1); 
		buf_ptr+=1; 
		int8 wis = (int8)atoi((char *)row[17]); 
		memcpy(buf_ptr, (char*)&wis, 1); 
		buf_ptr+=1; 
		int8 intel = (int8)atoi((char *)row[18]); 
		memcpy(buf_ptr, (char*)&intel, 1); 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
 
		int size = strlen(name)+20; 
 
		sendpacket(buf, size, ptr); 
		// free mysql result's 
		mysql_free_result(result); 
	} 
	return 0; 
} 
 
//*********************************************************** 
// deletes a character from the account 
//*********************************************************** 
int database::deletechar(char * name, DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	char query[100]; 
	sprintf(query,"DELETE FROM characters WHERE name='%s'", name); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		// this packet has not yet been analyzed, need do that later, for now its working. 
		char buf[8]; 
		char* buf_ptr = buf; 
		 
		int8 opcode = l_sc_deletecharstatus; 
		unsigned char newpack[] = { 0x05, 0x29, 0xC6, 0x01, 0x02, 0x02, 0x6F }; 
 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		memcpy(buf_ptr,(char*)newpack, sizeof(newpack)); 
		 
		sendpacket( buf, 8, ptr); 
		return 0; 
	} 
	return 0; 
} 
 
//*********************************************************** 
// Status packet (contains characters information). 
//*********************************************************** 
int database::statuspacket(char * name, DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	unsigned long charid = chm.getObjectid(cp); 
 
	char query[100]; 
	sprintf(query,"SELECT * FROM characters WHERE name='%s'", name); 
 
	 
	long mytime; 
	mytime = getclienttime(); 
 
	tm * ptm; 
    ptm = gmtime ( &mytime ); 
	 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int8 opcode = l_sc_statuspacket; 
		int8 addbyte = 0x00; 
 
		unsigned char unknown3[] = { 0xB6, 0x00, 0x3D }; 
 
		char buf[40]; 
		char* buf_ptr = buf; // done so we can mover buf_ptr to were we need to memcpy 
 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		memcpy(buf_ptr,(char*)&charid,4); 
		buf_ptr+=4; 
		int8 level = (int8)atoi((char *)row[11]); 
		memcpy(buf_ptr,(char*)&level, 1); 
		buf_ptr+=1; 
		unsigned long exp = (unsigned long)atoi((char *)row[21]); 
		memcpy(buf_ptr, (char*)&exp, 4); // exp points 
		 
		// str dex ect... 
		buf_ptr+=4; 
		int8 str = (int8)atoi((char *)row[13]); 
		memcpy(buf_ptr, (char*)&str, 1); 
		 
		buf_ptr+=1; 
		int8 intel = (int8)atoi((char *)row[18]); 
		memcpy(buf_ptr, (char*)&intel, 1); 
 
		buf_ptr+=1; 
		int8 cha = (int8)atoi((char *)row[16]); 
		memcpy(buf_ptr, (char*)&cha, 1); 
 
		buf_ptr+=1; 
		int8 dex = (int8)atoi((char *)row[14]); 
		memcpy(buf_ptr, (char*)&dex, 1); 
 
		buf_ptr+=1; 
		int8 con = (int8)atoi((char *)row[15]); 
		memcpy(buf_ptr, (char*)&con, 1); 
 
		buf_ptr+=1; 
		int8 wis = (int8)atoi((char *)row[17]); 
		memcpy(buf_ptr, (char*)&wis, 1); 
 
		buf_ptr+=1; 
		// hp, mp 
		int16 hp = (int16)atoi((char *)row[7]); 
		memcpy(buf_ptr, (char*)&hp, 2); 
		 
		buf_ptr+=2; 
		int16 maxhp = (int16)atoi((char *)row[8]); 
		memcpy(buf_ptr, (char*)&maxhp, 2); 
		 
		buf_ptr+=2; 
		int16 mp = (int16)atoi((char *)row[9]); 
		memcpy(buf_ptr, (char*)&mp, 2); 
 
		buf_ptr+=2; 
		int16 maxmp = (int16)atoi((char *)row[10]); 
		memcpy(buf_ptr, (char*)&maxmp, 2); 
		 
		buf_ptr+=2; 
		// ac 
		int8 ac = (int8)atoi((char *)row[12]); 
		memcpy(buf_ptr, (char*)&ac, 1); 
 
		buf_ptr+=1; 
		// current time 
		memcpy(buf_ptr,(char*)&mytime,4); 
		buf_ptr+=4; 
		// new stuff 
		int8 nutricion = (int8)atoi((char *)row[22]); 
		memcpy(buf_ptr, (char*)&nutricion, 1); 
		 
		buf_ptr+=1; 
		int8 weight = (int8)atoi((char *)row[23]); 
		memcpy(buf_ptr, (char*)&weight, 1); 
		 
		buf_ptr+=1; 
		int16 lawful = (int16)atoi((char *)row[6]); 
		memcpy(buf_ptr, (char*)&lawful, 2); 
		 
		buf_ptr+=2; 
		int8 fire = (int8)atoi((char *)row[24]); 
		memcpy(buf_ptr, (char*)&fire, 1); 
		 
		buf_ptr+=1; 
		int8 wind = (int8)atoi((char *)row[25]); 
		memcpy(buf_ptr, (char*)&wind, 1); 
		 
		buf_ptr+=1; 
		int8 air = (int8)atoi((char *)row[26]); 
		memcpy(buf_ptr, (char*)&air, 1); 
		 
		buf_ptr+=1; 
		int8 earth = (int8)atoi((char *)row[27]); 
		memcpy(buf_ptr, (char*)&earth, 1); 
		 
		buf_ptr+=1; 
		memcpy(buf_ptr,(char*)&unknown3, 3); 
 
		// send packet and free resources. 
		mysql_free_result(result); 
		sendpacket(buf, 40, ptr); 
	} 
	return 0; 
} 
 
//*********************************************************** 
// sends the current map id number the user is on. 
//*********************************************************** 
int database::getmapid(char * name, DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	char query[100]; 
	sprintf(query,"SELECT * FROM characters WHERE name='%s'", name); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
		return 0; 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
		 
		int8 opcode = l_sc_currentmapid; 
		unsigned char ignore[] = { 
		// first byte = nornal, underwater ect. 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x25, 0x3B, 0x67 
		}; 
 
		char buf[16]; 
		char* buf_ptr = buf; // done so we can mover buf_ptr to were we need to memcpy 
 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		int16 mapid; 
		mapid = (int16)atoi((char *)row[30]); 
		memcpy(buf_ptr, (char*)&mapid, 2); 
		buf_ptr+=2; 
		memcpy(buf_ptr,(char*)&ignore, 13); 
 
		mysql_free_result(result); 
		sendpacket(buf, 16, ptr); 
	} 
	return 0; 
} 
 
//*********************************************************** 
// sends the users own character details. 
//*********************************************************** 
void database::dbownchar(char * charname, DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
 
	unsigned long charid = chm.getObjectid(cp); 
 
	char query[100]; 
	sprintf(query,"SELECT * FROM characters WHERE name='%s'", charname); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		row = mysql_fetch_row(result); 
 
		int8 opcode = l_sc_owncharstatus; 
		int8 addbyte = 0x00; 
		int8 addbyte1 = 0x01; // speed, 0= normal (?), 1 = fast, 2 = slow, 3 = ? 
		int8 setting = 0x04; // 0x04 = normal, 0x05 = poison. 
		unsigned long iconid = 0x00000000; // no icon 
 
		char buf[90]; 
		char* buf_ptr = buf; // done so we can mover buf_ptr to were we need to memcpy 
 
		unsigned char unknown0[] = { 0x3D, 0x00 }; 
		unsigned char unknown2[] = { 0x00, 0x00 }; 
		unsigned char unknown3[] = { 
		0x00, 0x00, 0xFF, 0x00, 0x00, 0x80, 0x0D 
		}; 
 
		memcpy(buf_ptr,(char*)&opcode,1); 
		buf_ptr+=1; 
		int16 locx = (int16)atoi((char *)row[19]); 
		memcpy(buf_ptr, (char*)&locx, 2);				 
		buf_ptr+=2; 
		int16 locy = (int16)atoi((char *)row[20]);				 
		memcpy(buf_ptr, (char*)&locy, 2); 
		buf_ptr+=2; 
		memcpy(buf_ptr,(char*)&charid, 4);  
		buf_ptr+=4; 
 
		// char class based on list.spr ? 
		int16 chargfxid = (int16)atoi((char *)row[29]); 
		memcpy(buf_ptr, (char*)&chargfxid, 2); 
		buf_ptr+=2; 
 
		// dunno these but all 0x00 
		int8 gender = (int8)atoi((char *)row[5]); 
		//memcpy(buf_ptr, (char*)&gender, 1); 
		//buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte, 1); // makes char invis (0x01), cannot move. 
		buf_ptr+=1; 
 
 
		memcpy(buf_ptr, (char*)&addbyte, 1); // makes char invis (0x01), cannot move. 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte, 1); // status (0x01 = running) 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&addbyte1, 1); // speed 
		buf_ptr+=1; 
 
		unsigned long exp = (unsigned long)atoi((char *)row[21]); 
		memcpy(buf_ptr, (char*)&exp, 4); // exp points 
		buf_ptr+=4; 
 
		int16 lawful = (int16)atoi((char *)row[6]); 
		memcpy(buf_ptr, (char*)&lawful, 2);		 
		buf_ptr+=2; 
		char * name = (char*)row[2]; 
		memcpy(buf_ptr,(char*)name, strlen(name)); 
		buf_ptr+=strlen(name); 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
 
		char * title = (char*)row[32]; 
		memcpy(buf_ptr,(char*)title, strlen(title)); 
		buf_ptr+=strlen(title); 
 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
 
		memcpy(buf_ptr, (char*)&setting, 1); 
		buf_ptr+=1; 
		memcpy(buf_ptr, (char*)&iconid, 4); 
		buf_ptr+=4; 
 
		char * clanname = (char*)row[3]; 
		memcpy(buf_ptr,(char*)clanname, strlen(clanname)); 
		buf_ptr+=strlen(clanname); 
 
		if(strlen(clanname) > 0) 
		{ 
		memcpy(buf_ptr, (char*)&addbyte, 1); 
		buf_ptr+=1; 
		} 
		memcpy(buf_ptr, (char*)&unknown3, 7); 
 
		int size = strlen(charname)+strlen(clanname)+strlen(title)+34+1; 
		 
		//***** get stuff to put in memory ******* 
		int8 heading = (int8)atoi((char *)row[31]); 
		int8 mapid = (int8)atoi((char *)row[30]); 
		int8 ac = (int8)atoi((char *)row[12]); 
		int8 str = (int8)atoi((char *)row[13]); 
		int8 dex = (int8)atoi((char *)row[14]); 
		int8 con = (int8)atoi((char *)row[15]); 
		int8 cha = (int8)atoi((char *)row[16]); 
		int8 wis = (int8)atoi((char *)row[17]);		 
		int8 intel = (int8)atoi((char *)row[18]); 
		int16 hp = (int16)atoi((char *)row[7]); 
		int16 maxhp = (int16)atoi((char *)row[8]); 
		int16 mp = (int16)atoi((char *)row[9]); 
		int16 maxmp = (int16)atoi((char *)row[10]); 
		int8 level = (int8)atoi((char *)row[11]); 
		int8 nutricion = (int8)atoi((char *)row[22]); 
		int8 weight = (int8)atoi((char *)row[23]);		 
		int8 fire = (int8)atoi((char *)row[24]);		 
		int8 water = (int8)atoi((char *)row[25]); 
		int8 air = (int8)atoi((char *)row[26]);		 
		int8 earth = (int8)atoi((char *)row[27]); 
		int isgm = (int)atoi((char *)row[28]); 
 
		// object id's to put in mem map 
		chm.setSocket		( cp, cp ); 
		chm.setPtr			( cp, ptr ); 
		chm.setLocx			( cp, locx ); 
		chm.setLocy			( cp, locy ); 
		chm.setMapid		( cp, mapid ); 
		chm.setHeading		( cp, heading ); 
		chm.setTitle		( cp, (string)title ); 
		chm.setClassid		( cp, chargfxid ); 
		chm.setExp			( cp, exp ); 
		chm.setLawful		( cp, lawful ); 
		chm.setCharname		( cp, (string)name ); 
		chm.setClanname		( cp, (string)clanname );		 
		chm.setAc			( cp, ac ); 
		chm.setStr			( cp, str ); 
		chm.setCon			( cp, con ); 
		chm.setDex			( cp, dex ); 
		chm.setCha			( cp, cha ); 
		chm.setWis			( cp, wis ); 
		chm.setIntel		( cp, intel ); 
		chm.setHp			( cp, hp ); 
		chm.setMaxhp		( cp, maxhp ); 
		chm.setMp			( cp, mp ); 
		chm.setMaxmp		( cp, maxmp ); 
		chm.setLevel		( cp, level ); 
		chm.setNutrition	( cp, nutricion ); 
		chm.setWeight		( cp, weight ); 
		chm.setFireress		( cp, fire ); 
		chm.setWaterress	( cp, water ); 
		chm.setWindress		( cp, air ); 
		chm.setEarthress	( cp, earth ); 
		chm.setIsgm			( cp, isgm ); 
		chm.setGender		( cp, gender ); 
 
		int8 status = 0x00; 
		chm.setStatus		( cp, status ); 
		string classtype = "user"; 
		chm.setClasstype(cp, classtype); 
 
		sendpacket(buf, size, ptr); 
		 
		npc.scanlocation(ptr, cp); 
		chm.checkUserLocataion(cp, ptr); 
 
		mysql_free_result(result); 
	} 
	return; 
} 
 
//*************************************************** 
//			Game Server Database calls 
// 		Used only by the game server files. 
//*************************************************** 
 
//*********************************************************** 
// saves the users details (needs to be completet as we go) 
//*********************************************************** 
int database::saveuserobject(DWORD ptr) 
{ 
	CConnection* c = reinterpret_cast  (ptr); 
	char			cip[15]; 
	unsigned int	cp = 0; 
	c->PeerInfo (&cip[0], 15, &cp); 
	 
	// charname to save. 
	string charus = chm.getCharname(cp); 
	char * charname = strdup(charus.c_str()); 
 
	// get the data to save 
	int16 mapid = chm.getMapid(cp); 
	int16 locx = chm.getLocx(cp); 
	int16 locy = chm.getLocy(cp); 
	int8 heading = chm.getHeading(cp); 
 
	// mysql query 
	char query[500]; 
	sprintf(query,"UPDATE characters SET locx='%i', locy='%i', mapid='%i', heading='%i' WHERE name='%s'", locx, locy, mapid, heading, charname); 
 
	if(mysql_query(pConn,query)) 
	{ 
		// error doing the query 
		Log2File(TRUE, "(MySQL) ERROR : %s\n", mysql_error(pConn)); 
	} 
	else 
	{ 
		result = mysql_store_result(pConn); 
		mysql_free_result(result); 
		return 0; 
	} 
	return 0; 
}