服务器——UID

一、介绍

在rpg这类游戏中,有大量的实体存在,实体包括玩家、NPC、怪物、坐骑、宠物等等,每天实体有一个id,这个id是在实体创建的时候生成的,我们称之为uid,通过uid我们可以获取到实体对象。(对于玩家实体它们还有一个id,是在玩家注册账号的时候db生成的id,我们称之为dbid,用于数据库中记录玩家唯一标记。)

二、uid设计

uid是实体的唯一标记,通过uid我们需要查询到实体对象。uid设计重要考虑的是怎样通过uid查询到实体对象。这里有几种设计方案:

方案一:map存储

map的key值为uid,value为实体对象指针。查询时间复杂度lg(n),map底层是红黑数当实体创建或删除的时候红黑树需要进行调整,当实体删除或创建频繁的时候性能消耗也会增大。

方案二:数组索引

uid是服务器自己生成的,那我们可以让uid从1连续递增生成,通过索引搜索效率可以为常数级。当有实体创建的时候可以一次创建一批,供后续实体创建使用,实体删除可以将uid回收用于后续新创建的实体使用。

实现过程,定义一个数组,用于记录当前服务器中创建的实体,通过uid可以直接搜索到实体对象指针,再定义一个列表用于记录空闲的实体,当我们需要一个uid对象的时候,我们去列表中获取一个,如果列表为空,我们将数组进行扩容,并将新创建的空闲实体添加到列表中。

总结,通过方案一和方案二对比,方案二效果跟好。

三、类结构演示

3.1 结构定义

下图为一个实现例子。

  • CGlobalServer: 服务器全局对象,服务器的主对象。
  • CEntityWorld:实体世界,管理整个服务器的实体。
  • IEntity:实体接口。
  • ConcreteEntity:一个具体的实体,可能是NPC、怪物、坐骑、宠物等等。
  • SEntity:一个实体序列号和实体指针组合,我们可以将其转为一个64位整数,也就是定义的uid。

一个uid定义如下,UID 和 SEntity结构是等价的可以相互转换。

typedef LONGLONG UID;
struct ___UID
{
	DWORD dwSerialNo;	// 序列号,不可逆,单通过此ID也可以标识对像
	DWORD dwHandle;		// 对像句柄,可重复的(此成员需放后面,uid小点)
};

// 分解出序列号
#define ANALYZEUID_SERIALNO(uid)	(((___UID *)&uid)->dwSerialNo)

// 分解出实体句柄
#define ANALYZEUID_HANDLE(uid)	(((___UID *)&uid)->dwHandle)

 

3.2 uid构建和或取对象

uid构建

一个具体的实体ConcreteEntity,创建完成会把自己添加到实体世界中,也就是调用函数CEntityWorld::Add(),CEntityWorld::Add()会调用BuildUID(),为实体构建一个uid。构建uid过程,先判断m_listUsableEntity中是否还有对象,如果有弹出一个用于当前新创建的实体,如果没有先对数组m_pEntityArray进行扩容(可以一次加1W个),将之前数据添加到新的数组中,并将新创建的对象添加到m_listUsableEntity中,用于新创建的对象。当一个对象使用完毕,将对象uid添加到m_listUsableEntity中用于后续创建的实体对象。

通过uid获取实体对象,直接看代码,直观清晰。

IEntity * CEntityWorld::Get(LONGLONG uid)
{
	if(uid == INVALID_UID)
	{
        return NULL;
	}

	// 解析
	DWORD dwSerialNo = ANALYZEUID_SERIALNO(uid);
	DWORD dwHandle = ANALYZEUID_HANDLE(uid);

	// 句柄越过了,非法
	if(dwHandle >= m_dwHandleMaxCount)
	{
        return NULL;
	}

	IEntity * pEntity = m_pEntityArray[dwHandle].pEntity;
	if(pEntity == NULL)
	{
        return NULL;
	}

	// 要判断序列号
	if(m_pEntityArray[dwHandle].dwSerialNo != dwSerialNo)
	{
        return NULL;
	}

	return pEntity;
}

猜你喜欢

转载自blog.csdn.net/nie2314550441/article/details/106866375