C++实现的分布式游戏服务端引擎KBEngine详解
KBEngine是一款开源的游戏服务端引擎,使用简单的约定协议就能够使客户端与服务端进行交互,
使用KBEngine插件能够快速与(Unity3D,OGRE,Cocos2d,HTML5,等等)技术结合形成一个完整的客户端。
服务端底层框架使用c++编写,游戏逻辑层使用Python(支持热更新),开发者无需重复的实现一些游戏服务端通用的底层技术,
将精力真正集中到游戏开发层面上来,快速的打造各种网络游戏。
(经常被问到承载上限,kbengine底层架构被设计为多进程分布式动态负载均衡方案,
理论上只需要不断扩展硬件就能够不断增加承载上限,单台机器的承载上限取决于游戏逻辑本身的复杂度。)
cstdkbe.hpp
/*
ThissourcefileispartofKBEngine
Forthelatestinfo,seehttp://www.kbengine.org/
Copyright(c)2008-2012KBEngine.
KBEngineisfreesoftware:youcanredistributeitand/ormodify
itunderthetermsoftheGNULesserGeneralPublicLicenseaspublishedby
theFreeSoftwareFoundation,eitherversion3oftheLicense,or
(atyouroption)anylaterversion.
KBEngineisdistributedinthehopethatitwillbeuseful,
butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
GNULesserGeneralPublicLicenseformoredetails.
YoushouldhavereceivedacopyoftheGNULesserGeneralPublicLicense
alongwithKBEngine.Ifnot,see<http://www.gnu.org/licenses/>.
*/
#ifndefKBE_CSTDKBE_HPP
#defineKBE_CSTDKBE_HPP
#include"cstdkbe/platform.hpp"
#include"cstdkbe/singleton.hpp"
#include"cstdkbe/kbeversion.hpp"
#include"cstdkbe/kbemalloc.hpp"
#include"cstdkbe/stringconv.hpp"
#include"cstdkbe/format.hpp"
namespaceKBEngine{
/**安全的释放一个指针内存*/
#defineSAFE_RELEASE(i)\
if(i)\
{\
deletei;\
i=NULL;\
}
/**安全的释放一个指针数组内存*/
#defineSAFE_RELEASE_ARRAY(i)\
if(i)\
{\
delete[]i;\
i=NULL;\
}
#ifdefCODE_INLINE
#defineINLINEinline
#else
#defineINLINE
#endif
/**kbe时间*/
externGAME_TIMEg_kbetime;
/**账号的类别*/
enumACCOUNT_TYPE
{
ACCOUNT_TYPE_NORMAL=1,//普通账号
ACCOUNT_TYPE_MAIL=2,//email账号(需激活)
ACCOUNT_TYPE_SMART=3//智能识别
};
enumACCOUNT_FLAGS
{
ACCOUNT_FLAG_NORMAL=0x00000000,
ACCOUNT_FLAG_LOCK=0x000000001,
ACCOUNT_FLAG_NOT_ACTIVATED=0x000000002
};
/**entity的mailbox类别*/
enumENTITY_MAILBOX_TYPE
{
MAILBOX_TYPE_CELL=0,
MAILBOX_TYPE_BASE=1,
MAILBOX_TYPE_CLIENT=2,
MAILBOX_TYPE_CELL_VIA_BASE=3,
MAILBOX_TYPE_BASE_VIA_CELL=4,
MAILBOX_TYPE_CLIENT_VIA_CELL=5,
MAILBOX_TYPE_CLIENT_VIA_BASE=6,
};
/**mailbox的类别对换为字符串名称严格和ENTITY_MAILBOX_TYPE索引匹配*/
constcharENTITY_MAILBOX_TYPE_TO_NAME_TABLE[][8]=
{
"cell",
"base",
"client",
"cell",
"base",
"client",
"client",
};
/**定义服务器各组件类别*/
enumCOMPONENT_TYPE
{
UNKNOWN_COMPONENT_TYPE=0,
DBMGR_TYPE=1,
LOGINAPP_TYPE=2,
BASEAPPMGR_TYPE=3,
CELLAPPMGR_TYPE=4,
CELLAPP_TYPE=5,
BASEAPP_TYPE=6,
CLIENT_TYPE=7,
MACHINE_TYPE=8,
CONSOLE_TYPE=9,
MESSAGELOG_TYPE=10,
BOTS_TYPE=11,
WATCHER_TYPE=12,
BILLING_TYPE=13,
COMPONENT_END_TYPE=14,
};
/**当前服务器组件类别和ID*/
externCOMPONENT_TYPEg_componentType;
externCOMPONENT_IDg_componentID;
/**定义服务器各组件名称*/
constcharCOMPONENT_NAME[][255]={
"unknown",
"dbmgr",
"loginapp",
"baseappmgr",
"cellappmgr",
"cellapp",
"baseapp",
"client",
"kbmachine",
"console",
"messagelog",
"bots",
"watcher",
"billing",
};
constcharCOMPONENT_NAME_1[][255]={
"unknown",
"dbmgr",
"loginapp",
"baseappmgr",
"cellappmgr",
"cellapp",
"baseapp",
"client",
"kbmachine",
"console",
"messagelog",
"bots",
"watcher",
"billing",
};
inlineconstchar*COMPONENT_NAME_EX(COMPONENT_TYPECTYPE)
{
if(CTYPE<0||CTYPE>=COMPONENT_END_TYPE)
{
returnCOMPONENT_NAME[UNKNOWN_COMPONENT_TYPE];
}
returnCOMPONENT_NAME[CTYPE];
}
inlineconstchar*COMPONENT_NAME_EX_1(COMPONENT_TYPECTYPE)
{
if(CTYPE<0||CTYPE>=COMPONENT_END_TYPE)
{
returnCOMPONENT_NAME_1[UNKNOWN_COMPONENT_TYPE];
}
returnCOMPONENT_NAME_1[CTYPE];
}
inlineCOMPONENT_TYPEComponentName2ComponentType(constchar*name)
{
for(inti=0;i<(int)COMPONENT_END_TYPE;i++)
{
if(kbe_stricmp(COMPONENT_NAME[i],name)==0)
return(COMPONENT_TYPE)i;
}
returnUNKNOWN_COMPONENT_TYPE;
}
//所有的组件列表
constCOMPONENT_TYPEALL_COMPONENT_TYPES[]={BASEAPPMGR_TYPE,CELLAPPMGR_TYPE,DBMGR_TYPE,CELLAPP_TYPE,
BASEAPP_TYPE,LOGINAPP_TYPE,MACHINE_TYPE,CONSOLE_TYPE,MESSAGELOG_TYPE,
WATCHER_TYPE,BILLING_TYPE,BOTS_TYPE,UNKNOWN_COMPONENT_TYPE};
//所有的后端组件列表
constCOMPONENT_TYPEALL_SERVER_COMPONENT_TYPES[]={BASEAPPMGR_TYPE,CELLAPPMGR_TYPE,DBMGR_TYPE,CELLAPP_TYPE,
BASEAPP_TYPE,LOGINAPP_TYPE,MACHINE_TYPE,MESSAGELOG_TYPE,
WATCHER_TYPE,BILLING_TYPE,BOTS_TYPE,UNKNOWN_COMPONENT_TYPE};
//所有的后端组件列表
constCOMPONENT_TYPEALL_GAME_SERVER_COMPONENT_TYPES[]={BASEAPPMGR_TYPE,CELLAPPMGR_TYPE,DBMGR_TYPE,CELLAPP_TYPE,
BASEAPP_TYPE,LOGINAPP_TYPE,BILLING_TYPE,UNKNOWN_COMPONENT_TYPE};
//所有的辅助性组件
constCOMPONENT_TYPEALL_HELPER_COMPONENT_TYPE[]={MESSAGELOG_TYPE,UNKNOWN_COMPONENT_TYPE};
//返回是否是一个有效的组件
#defineVALID_COMPONENT(C_TYPE)((C_TYPE)>0&&(C_TYPE)<COMPONENT_END_TYPE)
//前端应用的类别,Allclienttype
enumCOMPONENT_CLIENT_TYPE
{
UNKNOWN_CLIENT_COMPONENT_TYPE=0,
//移动类,手机,平板电脑
//Mobile,Phone,Pad(AllowingdoesnotcontainPython-scriptsandentitydefsanalysis,canbeimportedprotocolfromnetwork)
CLIENT_TYPE_MOBILE=1,
//独立的Windows/Linux/Mac应用程序(包含python脚本,entitydefs解析与检查entitydefs的MD5,原生的)
//Windows/Linux/MacApplicationprogram(ContainsthePython-scripts,entitydefsparsingandcheckentitydefs-MD5,Native)
CLIENT_TYPE_PC=2,
//不包含Python脚本,entitydefs协议可使用网络导入
//Web,HTML5,Flash
CLIENT_TYPE_BROWSER=3,
//包含Python脚本,entitydefs解析与检查entitydefs的MD5,原生的
//bots(ContainsthePython-scripts,entitydefsparsingandcheckentitydefs-MD5,Native)
CLIENT_TYPE_BOTS=4,
//轻端类,可不包含python脚本,entitydefs协议可使用网络导入
//Mini-Client(AllowingdoesnotcontainPython-scriptsandentitydefsanalysis,canbeimportedprotocolfromnetwork)
CLIENT_TYPE_MINI=5,
//End
CLIENT_TYPE_END=6
};
/**定义前端应用的类别名称*/
constcharCOMPONENT_CLIENT_NAME[][255]={
"UNKNOWN_CLIENT_COMPONENT_TYPE",
"CLIENT_TYPE_MOBILE",
"CLIENT_TYPE_PC",
"CLIENT_TYPE_BROWSER",
"CLIENT_TYPE_BOTS",
"CLIENT_TYPE_MINI",
};
//所有前端应用的类别
constCOMPONENT_CLIENT_TYPEALL_CLIENT_TYPES[]={CLIENT_TYPE_MOBILE,CLIENT_TYPE_PC,CLIENT_TYPE_BROWSER,
CLIENT_TYPE_BOTS,CLIENT_TYPE_MINI,UNKNOWN_CLIENT_COMPONENT_TYPE};
typedefint8CLIENT_CTYPE;
//前端是否支持浮点数
//#defineCLIENT_NO_FLOAT
//一个cell的默认的边界或者最小大小
#defineCELL_DEF_MIN_AREA_SIZE500.0f
/**一个空间的一个chunk大小*/
#defineSPACE_CHUNK_SIZE100
/**检查用户名合法性*/
inlineboolvalidName(constchar*name,intsize)
{
if(size>=256)
returnfalse;
for(inti=0;i<size;i++)
{
charch=name[i];
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')||(ch=='_'))
continue;
returnfalse;
}
returntrue;
}
inlineboolvalidName(conststd::string&name)
{
returnvalidName(name.c_str(),name.size());
}
/**检查email地址合法性
严格匹配请用如下表达式
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
*/
#ifdefUSE_REGEX
#include<regex>
#endif
inlineboolemail_isvalid(constchar*address)
{
#ifdefUSE_REGEX
std::tr1::regex_mail_pattern("([a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)");
returnstd::tr1::regex_match(accountName,_mail_pattern);
#endif
intlen=strlen(address);
if(len<=3)
returnfalse;
charch=address[len-1];
if(!((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')))
returnfalse;
intcount=0;
constchar*c,*domain;
staticconstchar*rfc822_specials="()<>@,;:\\\"[]";
/*firstwevalidatethenameportion(name@domain)*/
for(c=address;*c;c++){
if(*c=='\"'&&(c==address||*(c-1)=='.'||*(c-1)==
'\"')){
while(*++c){
if(*c=='\"')break;
if(*c=='\\'&&(*++c==''))continue;
if(*c<=''||*c>=127)returnfalse;
}
if(!*c++)returnfalse;
if(*c=='@')break;
if(*c!='.')returnfalse;
continue;
}
if(*c=='@')break;
if(*c<=''||*c>=127)returnfalse;
if(strchr(rfc822_specials,*c))returnfalse;
}
if(c==address||*(c-1)=='.')returnfalse;
/*nextwevalidatethedomainportion(name@domain)*/
if(!*(domain=++c))returnfalse;
do{
if(*c=='.'){
if(c==domain||*(c-1)=='.')returnfalse;
count++;
}
if(*c<=''||*c>=127)returnfalse;
if(strchr(rfc822_specials,*c))returnfalse;
}while(*++c);
return(count>=1);
}
}
#endif//KBE_CSTDKBE_HPP
以上所述就是本文的全部内容了,有需要的小伙伴可以参考下。