C++实现的分布式游戏服务端引擎KBEngine详解

KBEngine 是一款开源的游戏服务端引擎,使用简单的约定协议就能够使客户端与服务端进行交互,
使用KBEngine插件能够快速与(Unity3D, OGRE, Cocos2d, HTML5, 等等)技术结合形成一个完整的客户端。

服务端底层框架使用c++编写,游戏逻辑层使用Python(支持热更新),开发者无需重复的实现一些游戏服务端通用的底层技术,
将精力真正集中到游戏开发层面上来,快速的打造各种网络游戏。

(经常被问到承载上限,kbengine底层架构被设计为多进程分布式动态负载均衡方案,
理论上只需要不断扩展硬件就能够不断增加承载上限,单台机器的承载上限取决于游戏逻辑本身的复杂度。)

cstdkbe.hpp

/*
This source file is part of KBEngine
For the latest info, see http://www.kbengine.org/

Copyright (c) 2008-2012 KBEngine.

KBEngine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KBEngine 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with KBEngine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KBE_CSTDKBE_HPP
#define KBE_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"

namespace KBEngine{
/** 安全的释放一个指针内存 */
#define SAFE_RELEASE(i)                   \
  if (i)                         \
    {                          \
      delete i;                    \
      i = NULL;                    \
    }

/** 安全的释放一个指针数组内存 */
#define SAFE_RELEASE_ARRAY(i)                \
  if (i)                         \
    {                          \
      delete[] i;                   \
      i = NULL;                    \
    }

#ifdef CODE_INLINE
  #define INLINE  inline
#else
  #define INLINE
#endif

/** kbe时间 */
extern GAME_TIME g_kbetime;

/** 账号的类别 */
enum ACCOUNT_TYPE
{
  ACCOUNT_TYPE_NORMAL = 1,  // 普通账号
  ACCOUNT_TYPE_MAIL = 2,   // email账号(需激活)
  ACCOUNT_TYPE_SMART = 3   // 智能识别
};

enum ACCOUNT_FLAGS
{
  ACCOUNT_FLAG_NORMAL = 0x00000000,
  ACCOUNT_FLAG_LOCK = 0x000000001,
  ACCOUNT_FLAG_NOT_ACTIVATED = 0x000000002
};

/** entity的mailbox类别 */
enum ENTITY_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索引匹配 */
const char ENTITY_MAILBOX_TYPE_TO_NAME_TABLE[][8] =
{
  "cell",
  "base",
  "client",
  "cell",
  "base",
  "client",
  "client",
};

/** 定义服务器各组件类别 */
enum COMPONENT_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 */
extern COMPONENT_TYPE g_componentType;
extern COMPONENT_ID g_componentID;

/** 定义服务器各组件名称 */
const char COMPONENT_NAME[][255] = {
  "unknown",
  "dbmgr",
  "loginapp",
  "baseappmgr",
  "cellappmgr",
  "cellapp",
  "baseapp",
  "client",
  "kbmachine",
  "console",
  "messagelog",
  "bots",
  "watcher",
  "billing",
};

const char COMPONENT_NAME_1[][255] = {
  "unknown  ",
  "dbmgr   ",
  "loginapp  ",
  "baseappmgr ",
  "cellappmgr ",
  "cellapp  ",
  "baseapp  ",
  "client   ",
  "kbmachine ",
  "console  ",
  "messagelog ",
  "bots",
  "watcher",
  "billing",
};

inline const char* COMPONENT_NAME_EX(COMPONENT_TYPE CTYPE)
{
  if(CTYPE < 0 || CTYPE >= COMPONENT_END_TYPE)
  {
    return COMPONENT_NAME[UNKNOWN_COMPONENT_TYPE];
  }

  return COMPONENT_NAME[CTYPE];
}

inline const char* COMPONENT_NAME_EX_1(COMPONENT_TYPE CTYPE)
{
  if(CTYPE < 0 || CTYPE >= COMPONENT_END_TYPE)
  {
    return COMPONENT_NAME_1[UNKNOWN_COMPONENT_TYPE];
  }

  return COMPONENT_NAME_1[CTYPE];
}

inline COMPONENT_TYPE ComponentName2ComponentType(const char* name)
{
  for(int i=0; i<(int)COMPONENT_END_TYPE; i++)
  {
    if(kbe_stricmp(COMPONENT_NAME[i], name) == 0)
      return (COMPONENT_TYPE)i;
  }

  return UNKNOWN_COMPONENT_TYPE;
}

// 所有的组件列表
const COMPONENT_TYPE ALL_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};

// 所有的后端组件列表
const COMPONENT_TYPE ALL_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};

// 所有的后端组件列表
const COMPONENT_TYPE ALL_GAME_SERVER_COMPONENT_TYPES[] = {BASEAPPMGR_TYPE, CELLAPPMGR_TYPE, DBMGR_TYPE, CELLAPP_TYPE,
            BASEAPP_TYPE, LOGINAPP_TYPE, BILLING_TYPE, UNKNOWN_COMPONENT_TYPE};

// 所有的辅助性组件
const COMPONENT_TYPE ALL_HELPER_COMPONENT_TYPE[] = {MESSAGELOG_TYPE, UNKNOWN_COMPONENT_TYPE};

// 返回是否是一个有效的组件
#define VALID_COMPONENT(C_TYPE) ((C_TYPE) > 0 && (C_TYPE) < COMPONENT_END_TYPE)

// 前端应用的类别, All client type
enum COMPONENT_CLIENT_TYPE
{
  UNKNOWN_CLIENT_COMPONENT_TYPE  = 0,

  // 移动类,手机,平板电脑
  // Mobile, Phone, Pad(Allowing does not contain Python-scripts and entitydefs analysis, can be imported protocol from network)
  CLIENT_TYPE_MOBILE       = 1,

  // 独立的Windows/Linux/Mac应用程序(包含python脚本,entitydefs解析与检查entitydefs的MD5,原生的)
  // Windows/Linux/Mac Application program (Contains the Python-scripts, entitydefs parsing and check entitydefs-MD5, Native)
  CLIENT_TYPE_PC         = 2,  

  // 不包含Python脚本,entitydefs协议可使用网络导入
  // Web, HTML5, Flash
  CLIENT_TYPE_BROWSER       = 3,  

  // 包含Python脚本,entitydefs解析与检查entitydefs的MD5,原生的
  // bots (Contains the Python-scripts, entitydefs parsing and check entitydefs-MD5, Native)
  CLIENT_TYPE_BOTS        = 4,  

  // 轻端类, 可不包含python脚本,entitydefs协议可使用网络导入
  // Mini-Client(Allowing does not contain Python-scripts and entitydefs analysis, can be imported protocol from network)
  CLIENT_TYPE_MINI        = 5,  

  // End
  CLIENT_TYPE_END         = 6
};

/** 定义前端应用的类别名称 */
const char COMPONENT_CLIENT_NAME[][255] = {
  "UNKNOWN_CLIENT_COMPONENT_TYPE",
  "CLIENT_TYPE_MOBILE",
  "CLIENT_TYPE_PC",
  "CLIENT_TYPE_BROWSER",
  "CLIENT_TYPE_BOTS",
  "CLIENT_TYPE_MINI",
};

// 所有前端应用的类别
const COMPONENT_CLIENT_TYPE ALL_CLIENT_TYPES[] = {CLIENT_TYPE_MOBILE, CLIENT_TYPE_PC, CLIENT_TYPE_BROWSER,
                        CLIENT_TYPE_BOTS, CLIENT_TYPE_MINI, UNKNOWN_CLIENT_COMPONENT_TYPE};

typedef int8 CLIENT_CTYPE;

// 前端是否支持浮点数
// #define CLIENT_NO_FLOAT

// 一个cell的默认的边界或者最小大小
#define CELL_DEF_MIN_AREA_SIZE       500.0f

/** 一个空间的一个chunk大小 */
#define SPACE_CHUNK_SIZE          100

/** 检查用户名合法性 */
inline bool validName(const char* name, int size)
{
  if(size >= 256)
    return false;

  for(int i=0; i<size; i++)
  {
    char ch = name[i];
    if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_'))
      continue;

    return false;
  }

  return true;
}

inline bool validName(const std::string& name)
{
  return validName(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])?
*/
#ifdef USE_REGEX
#include <regex>
#endif

inline bool email_isvalid(const char *address)
{
#ifdef USE_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])?)");
  return std::tr1::regex_match(accountName, _mail_pattern);
#endif
  int len = strlen(address);
  if(len <= 3)
    return false;

  char ch = address[len - 1];
  if(!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')))
    return false;

  int    count = 0;
  const char *c, *domain;
  static const char *rfc822_specials = "()<>@,;:\\\"[]";

  /* first we validate the name portion (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) return false;
   }
   if (!*c++) return false;
   if (*c == '@') break;
   if (*c != '.') return false;
   continue;
  }
  if (*c == '@') break;
  if (*c <= ' ' || *c >= 127) return false;
  if (strchr(rfc822_specials, *c)) return false;
  }
  if (c == address || *(c - 1) == '.') return false;

  /* next we validate the domain portion (name@domain) */
  if (!*(domain = ++c)) return false;
  do {
  if (*c == '.') {
   if (c == domain || *(c - 1) == '.') return false;
   count++;
  }
  if (*c <= ' ' || *c >= 127) return false;
  if (strchr(rfc822_specials, *c)) return false;
  } while (*++c);

  return (count >= 1);
}

}
#endif // KBE_CSTDKBE_HPP

以上所述就是本文的全部内容了,有需要的小伙伴可以参考下。

(0)

相关推荐

  • C++基于控制台实现的贪吃蛇小游戏

    本文实例讲述了C++基于控制台实现的贪吃蛇小游戏.分享给大家供大家参考.具体实现方法如下: #include <windows.h> #include <time.h> #include <stdio.h> #define MAX 100 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define MOVING 5 #define STOP 0 HANDLE hMain_Out = NULL; H

  • 用VC++6.0实现石头剪刀布游戏的程序

    源程序是从网上看到的, geek_monkey于2015年3月3日修改了bug(输入字符非石头剪刀布都算是玩家赢) 编译环境为VC++6.0 增加"上帝模式"和数据统计,纯属娱乐. 我是C语言初学者,轻喷 复制代码 代码如下: #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> int exist_in(char *arr1[][2],

  • javascript贪吃蛇完整版(源码)

    javascript贪吃蛇完整版 注释完整,面向对象 复制代码 代码如下: <html><head>    <title>贪吃蛇 Snake v2.4</title><style>    body{        font-size:9pt;    }    table{        border-collapse: collapse;        border:solid #333 1px;    }    td{        heigh

  • 基于C语言实现的贪吃蛇游戏完整实例代码

    本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助. 贪吃蛇完整实现代码如下: #include <graphics.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #define NULL 0 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #defi

  • C++编写简单的打靶游戏

    首次自己写程序,很不完善,还有许多问题需要解决...见谅见谅 #define GDIPVER 0x0110 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <ObjIdl.h> #include <GdiPlus.h> #include <windowsx.h> #include <tchar.h> #include <mmsystem.h> #include <

  • 贪吃蛇游戏C++命令行版实例代码

    本文实例讲述了贪吃蛇游戏C++命令行版的实现代码,是非常经典的游戏.分享给大家供大家参考.具体实现方法如下: 众所周知,贪吃蛇游戏是经典的计算机游戏. 游戏描述如下: 1. 贪吃蛇可以自动直线前进,或者玩家可以通过方向键操纵贪吃蛇上下左右前进,每次前进一格. 2. 贪吃蛇在规定的区域内活动,当: ①贪吃蛇触碰到墙壁时: ②贪吃蛇的蛇头触碰到蛇身或者蛇尾时: ③玩家的键盘输入不是方向键时: 命令行显示"Game Over!"并且退出游戏. 3. 贪吃蛇活动的区域内每次随机产生一颗&quo

  • C++面向对象实现五子棋小游戏

    尽量将面向对象的思想融入进程序中 ChessBoard.h //ChessBoard.h #pragma once #define ROW 15 #define COL 15 #include<iostream> using namespace std; class ChessBoard//棋盘类 { public: char m_cSquare[ROW][COL]; public: ChessBoard(); void show(); }; ChessBoard.cpp //ChessBoa

  • 用VC++6.0的控制台实现2048小游戏的程序

    首先感谢这位大侠的无私分享,仔细学习这个程序以后收获很多,试着添加一些注释 源程序是从开源中国看到的,原作者是 刘地(sir?) 地址为http://www.oschina.net/code/snippet_593413_46040 geek_monkey于2015年3月5日为拜读该程序,受益匪浅 为了方便自己,以及更多初学者阅读,我试着写了写了注释供参考 我是C语言初学者,如有错误希望指正.轻喷 复制代码 代码如下: #include <stdlib.h> #include <stdi

  • C++实现的分布式游戏服务端引擎KBEngine详解

    KBEngine 是一款开源的游戏服务端引擎,使用简单的约定协议就能够使客户端与服务端进行交互, 使用KBEngine插件能够快速与(Unity3D, OGRE, Cocos2d, HTML5, 等等)技术结合形成一个完整的客户端. 服务端底层框架使用c++编写,游戏逻辑层使用Python(支持热更新),开发者无需重复的实现一些游戏服务端通用的底层技术, 将精力真正集中到游戏开发层面上来,快速的打造各种网络游戏. (经常被问到承载上限,kbengine底层架构被设计为多进程分布式动态负载均衡方案

  • Servlet服务端实现原理详解

    servlet(serverapplet)(服务端程序) 作用:作用在于交互式的浏览和修改数据,生成动态数据 狭义的servlet就是java提供的一个接口,广义的servlet是任何实现servlet接口的实现类,一般情况下,servlet为后者. servlet接口: init()当servlet第一次被请求时,初始化Servlet对象, service()每次请求时,service方法调用 destroy()当销毁Servlet对象,destroy方法调用 getServletlnfo (

  • 基于vue-ssr服务端渲染入门详解

    第一部分 基本介绍 1.前言 服务端渲染实现原理机制:在服务端拿数据进行解析渲染,直接生成html片段返回给前端.然后前端可以通过解析后端返回的html片段到前端页面,大致有以下两种形式: 1.服务器通过模版引擎直接渲染整个页面,例如java后端的vm模版引擎,php后端的smarty模版引擎. 2.服务渲染生成html代码块, 前端通过AJAX获取然后使用js动态添加. 2.服务端渲染的优劣 服务端渲染能够解决两大问题: 1.seo问题,有利于搜索引擎蜘蛛抓取网站内容,利于网站的收录和排名.

  • PHP:微信小程序 微信支付服务端集成实例详解及源码下载

    微信小程序 微信支付服务端集 理论上集成微信支付的全部工作可以在小程序端完成,因为小程序js有访问网络的能力,但是为了安全,不暴露敏感key,而且可以使用官方提供的现成php demo更省力,于是在服务端完成签名与发起请求,小程序端只做一个wx.requestPayment(OBJECT)接口的对接. 整体集成过程与JSAPI.APP类似,先统一下单,然后拿返回的结果来请求支付. 一共三步: 1.小程序端通过wx.login的返回的code换取openid 2.服务端向微信统一下单 3.小程序端

  • subversion服务端配置步骤详解

    配置过程:1.安装subversion 服务端软件 复制代码 代码如下: yum install subersion -ymkdir -p /data/svn_svncd  /data/svn_svn 2. 创建代码仓库 复制代码 代码如下: svnadmin create  svn_version 配置权限 复制代码 代码如下: vim conf/svnserve.confpassword-db = passwd  #取消注释anon-access = noneauth-access = wr

  • vue的ssr服务端渲染示例详解

    为什么使用服务器端渲染 (SSR) 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面. 请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引.在这里,同步是关键.如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容.也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题. 更快的内容到达时间 (ti

  • Java微服务开发之Swagger详解

    目录 一.Swagger的作用和概念 1.Swagger 的优势 2.SwaggerUI 特点 2.SpringBoot集成Swagger 3.配置Swagger 4.实体配置 5.其他皮肤 一.Swagger的作用和概念 ​ 官方地址:https://swagger.io/ ​ Swagger 是一个规范且完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务以及 集成Swagger自动生成API文档. ​ Swagger 的目标是对 REST API 定义一个标准且和

  • vue移动端屏幕适配详解

    flexible vue移动端屏幕适配,查看项目地址 效果预览 # 项目clone git clone git@github.com:NicolasGui/flexible.git # 进入项目目录 cd flexible # 安装依赖 npm install # 启动服务 localhost:8080 npm run dev 原理概述 插件安装 # 插件一:amfe-flexible npm install amfe-flexible --save #  插件二: node-sass npm

  • springcloud微服务之Eureka配置详解

    Eureka注册中心/服务发现框架 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能. Eureka包含两个组件:Eureka Server和Eureka Client. Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Serve

  • python分布式爬虫中消息队列知识点详解

    当排队等待人数过多的时候,我们需要设置一个等待区防止秩序混乱,同时再有新来的想要排队也可以呆在这个地方.那么在python分布式爬虫中,消息队列就相当于这样的一个区域,爬虫要进入这个区域找寻自己想要的资源,当然这个是一定的次序的,不然数据获取就会出现重复.就下来我们就python分布式爬虫中的消息队列进行详细解释,小伙伴们可以进一步了解一下. 实现分布式爬取的关键是消息队列,这个问题以消费端为视角更容易理解.你的爬虫程序部署到很多台机器上,那么他们怎么知道自己要爬什么呢?总要有一个地方存储了他们

随机推荐