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
以上所述就是本文的全部内容了,有需要的小伙伴可以参考下。