www.pudn.com > loseserver.rar > ObjectsMultimap.h


/* 
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 "Types.h" 
#include "Logging.h" 
 
using namespace std; 
 
// pointer to send packet from main file 
void sendpacket(char * data, int size, DWORD ptr); 
 
struct KnownObjects 
{ 
	unsigned int yoursocket; 
	unsigned int objectsocket; 
	unsigned long yourobj; 
	unsigned long knownobject; 
	DWORD yourptr; 
	DWORD knownptr; 
}; 
 
class objects 
{ 
private: 
	multimap ko; 
	struct KnownObjects known; 
	int sendmovepacket(DWORD ptr, unsigned long objid, unsigned int cp); 
	int senduserobjnewpack(DWORD ptr, unsigned long objid, unsigned int cp); 
	void sendnewheading(DWORD ptr, unsigned int cp, unsigned long objid); 
	void deleteuserpack(unsigned int cp, DWORD ptr, unsigned long ObjectId); 
 
public: 
	//************************ 
	// std::map remove all maps belong to id 
	//************************ 
	void removeMap(unsigned int keyid) 
	{ 
		ko.erase(keyid); 
	} 
	//************************ 
	// std::map setters / getters 
	//************************ 
	//** Your Socket ** 
    void setYourSocket(unsigned int key, unsigned int socket) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.yoursocket = socket; 
		else 
		{			  
			known.yoursocket = socket; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Your Socket ** 
	unsigned int getYourSocket(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        unsigned int socket = (*it).second.yoursocket; 
        return socket; 
    } 
	//** Other Persons Socket ** 
    void setObjectSocket(unsigned int key, unsigned int socket) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.objectsocket = socket; 
		else 
		{			  
			known.objectsocket = socket; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Other Persons Socket ** 
	unsigned int getObjectSocket(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        unsigned int socket = (*it).second.objectsocket; 
        return socket; 
    } 
	//** Your Object ** 
    void setYourObject(unsigned int key, unsigned long obj) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.yourobj = obj; 
		else 
		{			  
			known.yourobj = obj; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Your Object ** 
	unsigned long getYourObject(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        unsigned int obj = (*it).second.yourobj; 
        return obj; 
    } 
	//** Other Object ** 
    void setOtherObject(unsigned int key, unsigned long obj) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.knownobject = obj; 
		else 
		{			  
			known.knownobject = obj; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Other Object ** 
	unsigned long getOtherObject(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        unsigned int obj = (*it).second.knownobject; 
        return obj; 
    } 
	//** Your Pointer (ptr) ** 
    void setYourptr(unsigned int key, DWORD ptr) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.yourptr = ptr; 
		else 
		{			  
			known.yourptr = ptr; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Your Pointer (ptr) ** 
	DWORD getYourptr(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        DWORD ptr = (*it).second.yourptr; 
        return ptr; 
    } 
	//** Others Pointer (ptr) ** 
    void setOtherptr(unsigned int key, DWORD ptr) 
    { 
		multimap::iterator it = ko.find(key); 
		if(it != ko.end()) 
			(*it).second.knownptr = ptr; 
		else 
		{			  
			known.knownptr = ptr; 
			ko.insert(make_pair(key, known)); 
		} 
    } 
	//** Others Pointer (ptr) ** 
	DWORD getOtherptr(unsigned int key) 
    { 
		multimap::iterator it = ko.find(key); 
        DWORD ptr = (*it).second.knownptr; 
        return ptr; 
    } 
	//**************************// 
	//* Utilities for multimap *// 
	//**************************// 
 
	// check if known (used by Charmap.cpp) 
	void checkknownobject(DWORD myptr, DWORD ptr, unsigned int key, unsigned int cp, unsigned long otherobj, unsigned long myobj) 
	{	 
		bool found; 
 
		if (ko.empty() == true) 
		{ 
			// have to put something in at first time run, since its empty. no need to do any checking 
				// object is not known, we add it to ourself. 
				setYourSocket(key, key); 
				setYourptr(key, myptr); 
				setYourObject(key, myobj); 
				setObjectSocket(key, cp); 
				setOtherObject(key, otherobj); 
				setOtherptr(key, ptr); 
				// then we add it to the other user 
				setYourSocket(cp, cp); 
				setYourptr(cp, ptr); 
				setYourObject(cp, otherobj); 
				setObjectSocket(cp, key); 
				setOtherObject(cp, myobj); 
				setOtherptr(cp, myptr); 
 
				// send to self and other person 
				senduserobjnewpack(myptr, otherobj, cp); 
				 
				// dont send objects higher then 200.000 those are npc, mobs, ect (dont need to send us to them) 
				senduserobjnewpack(ptr, myobj, key); 
		} 
		else 
		{ 
			multimap::iterator it; 
			for (it = ko.begin(); it != ko.end(); ++it) 
			{ 
				unsigned int id = (*it).first; 
				unsigned long thisobjid = (*it).second.knownobject; 
 
				if (key == id && otherobj == thisobjid) 
				{ 
					// found a object, so no need to add one. 
					found = true; 
					break; 
				} 
				else 
				{	 
					// didnt find a object so we add it 
					found = false; 
				} 
			} 
			if(found == true) 
			{ 
				// object is already known, only need to send move packet. 
				sendmovepacket(ptr, myobj, key); 
			} 
			if(found == false) 
			{ 
				// object is not known, we add it to ourself. 
				setYourSocket(key, key); 
				setYourptr(key, myptr); 
				setYourObject(key, myobj); 
				setObjectSocket(key, cp); 
				setOtherObject(key, otherobj); 
				setOtherptr(key, ptr); 
				// then we add it to the other user 
				setYourSocket(cp, cp); 
				setYourptr(cp, ptr); 
				setYourObject(cp, otherobj); 
				setObjectSocket(cp, key); 
				setOtherObject(cp, myobj); 
				setOtherptr(cp, myptr); 
 
				// send to self and other person 
				senduserobjnewpack(myptr, otherobj, cp); 
				// dont send objects higher then 200.000 those are npc, mobs, ect (dont need to send us to them) 
				//senduserobjnewpack(ptr, myobj, key); 
			} 
		} 
		return; 
	} 
 
	// remove known object 
	void removeknownobject(unsigned int cp, unsigned long objid) 
	{ 
		if (ko.empty() == true) 
		{ 
			// map is empty no need to remove anything 
		} 
		else 
		{ 
			for (multimap::iterator it = ko.begin(); it != ko.end(); ++it) 
			{ 
				unsigned int id = (*it).first; 
				unsigned long thisobjid = (*it).second.knownobject; 
 
				if (cp == id && objid == thisobjid) 
				{ 
					ko.erase( id ); 
					break; 
				} 
			} 
		} 
	} 
 
	// logout user, remove object 
	void removeknownobjectlogout(unsigned int cp, unsigned long objid) 
	{ 
		if (ko.empty() == true) 
		{ 
			// map is empty no need to remove anything 
		} 
		else 
		{ 
			for (multimap::iterator it = ko.begin(); it != ko.end(); ++it) 
			{ 
				unsigned int id = (*it).first; 
				unsigned long thisobjid = (*it).second.knownobject; 
				unsigned long myobjid = (*it).second.yourobj; 
				DWORD otherptr = (*it).second.yourptr; 
 
				if (objid == thisobjid || objid == myobjid) 
				{ 
					if(cp < id || cp > id) 
					{ 
						deleteuserpack(cp, otherptr, objid); 
					} 
				} 
			} 
		} 
	} 
 
	// object new heading 
	void newheadingpacket(DWORD ptr, unsigned int cp, unsigned long myobj) 
	{ 
		if (ko.empty() == true) 
		{ 
			// map is empty no need to remove anything 
		} 
		else 
		{ 
			for (multimap::iterator it = ko.begin(); it != ko.end(); ++it) 
			{ 
				unsigned int id = (*it).first; 
				DWORD yourptr = (*it).second.yourptr; 
				DWORD otherptr = (*it).second.knownptr; 
				unsigned long thisobjid = (*it).second.knownobject; 
				unsigned long myobjid = (*it).second.yourobj; 
				 
				if(id < cp || id > cp) 
				{ 
					if(myobj == thisobjid) 
					{ 
						sendnewheading(yourptr, cp, myobj); 
					} 
				} 
			} 
		} 
	} 
};