【HLSDK系列】服务端实体 edict_t 和 控制类
我们来了解一下引擎是怎么管理实体的吧!我们这里就说说服务端的实体(edict_t)
服务端用 edict_t 这个结构体来保存一个实体,可以说一个 edict_t 就是一个 服务端实体,下文简称实体。
我们在 mp.dll 的源码里经常看到的那些 CBaseXXX 又和 edict_t 有什么关系呢?
引擎只管理小部分实体的功能,更多功能需要我们自己写代码去实现,这里就引入了 实体控制类 这个东西(就是那些 CBaseXXX),类就是C++的那个类。下文简称控制类。
接下来我们就分析 edict_t 到底是怎么跟 控制类 挂上勾的。
我们通常用 CREATE_NAMED_ENTITY( MAKE_STRING("weapon_mp5") ); 来创建一个 weapon_mp5 的武器实体,那我们就来分析这个函数到底做了什么吧!
1. 用户调用 CREATE_NAMED_ENTITY。
2. 引擎在 mp.dll (的导出函数)里查找名为“weapon_mp5”的函数。(你可能会有疑问:我从来没写过这个函数啊?别急,下文分析)
3. 引擎调用“weapon_mp5”函数来创建出一个CMP5类实例。“weapon_mp5”还调用了 CREATE_ENTITY 来创建出一个 edict_t。(用数学老师的话说:CMP5就是实体weapon_mp5的控制类)
4. 引擎把类实例的指针赋值到 edict_t 的 pvPrivateData 成员变量里。
5. 引擎返回 edict_t 给用户。
看了上面的步骤,你一定注意到非常关键的一步,“weapon_mp5”函数到底是怎么一回事。
打开 mp5.cpp 你会发现有一行
LINK_ENTITY_TO_CLASS( weapon_mp5, CMP5 );
这行就是关键,它会生成一个函数,这个函数起了类似如下代码的作用:
注:实际上不是这么简单的,只是为了更容易理解。
CMP5 *weapon_mp5() {return new CMP5(); }
再往回看上面的步骤3和4,能理解了吧。
引擎先创建一个 edict_t 然后又 new CMP5 把指针存到 pvPreivateData 这个变量里,到此一个实体就创建出来了。
然后我们还要了解控制类是怎么工作的。首先请你打开 cbase.cpp 你会看到一堆 Dispatch 开头的函数,下文简称派遣函数。
派遣函数用来干嘛呢?当一个实体要 Think 的时候,引擎就会调用 mp.dll 里的 DispatchThink 这个函数,它有一个参数 edict_t *pent 就是要 Think 的实体!
接着才是关键!
我们来看 DispatchThink 的源码:
void DispatchThink( edict_t *pent ) {CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent);if (pEntity){// ...pEntity->Think();} }
顺便还有 GET_PRIVATE 的源码:
inline void *GET_PRIVATE( edict_t *pent ) {if ( pent )return pent->pvPrivateData;return NULL; }
我们可以看到它获取了 edict_t 里面的 pvPrivateData 变量,你一定还记得这个变量是怎么来的吧!不记得请马上往回看!
没错,之前引擎创建实体的时候,把 控制类 的 指针 存这变量里了,我们这里就把这个 控制类 拿出来而已!
接着它检查了一下 控制类 是不是 NULL,然后它在 if 里面调用了 控制类 的 Think 函数!
整个过程就是这样的:引擎 -> 派遣函数 -> 控制类 也就是说,引擎是不管 控制类 的,为让 控制类 工作,我们还需要在派遣函数里写东西(虽然HLSDK已经写好了,但是你一定要去看看他是怎么写的)。
如果你写过 AMXX 你肯定会认识 FM_Think FM_Spawn 这些东西,它们就是HOOK了这些派遣函数!
本来还想仔细讲解 LINK_ENTITY_TO_CLASS 的,留到下一篇文章吧!
转载于:https://www.cnblogs.com/crsky/p/6881146.html
【HLSDK系列】服务端实体 edict_t 和 控制类相关推荐
- Netty 源码解析系列-服务端启动流程解析
netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...
- 搭建简易的物联网服务端和客户端-Maibu控制(二十一)
创建麦布应用程序,麦步按键控制.原理和网页控制差不多,就是麦步访问之前创建的两个buttonclick接口.感谢qs100371大神. 代码地址:https://github.com/ZZES-ZVD ...
- BS1022-基于React native+springboot开发服务端后台实现体育资讯类APP
基于React native的体育资讯类APP的开发目的是方便互联网用户线上接收日常生活中的体育赛事新闻,体育活动新闻,体育赛事直播等,方便人们在体育行业的社交,极大的缩减人们在体育运动方面的距离,也 ...
- TCP连接建立系列 — 服务端接收ACK段(二)
本文主要分析:三次握手中最后一个ACK段到达时,服务器端的处理路径. 内核版本:3.6 Author:zhangskd @ csdn blog 创建新sock 协议族相关的操作函数,我们要看的是TCP ...
- 【HLSDK系列】服务端 AddToFullPack 函数
服务端会给客户端发送一些数据,其中两大种类数据是 clientdata_t 和 entity_state_t 这里我们说说 entity_state_t 这个结构体. 你在丢在地上的枪.C4等等是服务 ...
- 【Netty系列_3】Netty源码分析之服务端channel
highlight: androidstudio 前言 学习源码要有十足的耐性!越是封装完美的框架,内部就越复杂,源码很深很长!不过要抓住要点分析,实在不行多看几遍,配合debug,去一窥优秀框架的精 ...
- 限制会话id服务端不共享_【干货分享】Web安全漏洞深入分析及其安全编码
阅读: 13,003 超全Web漏洞详解及其对应的安全编码规则,包括:SQL注入.XSS.CSRF.文件上传.路径遍历.越权.XML以及业务安全等,实例告诉你各个漏洞对应的编码规则.给你的代码加把安全 ...
- tortoisesvn创建部署项目_TortoiseSVN服务端的配置与使用
客户端访问方式 说明 svn:// 通过TCP/IP自定义协议访问svnserve服务器. http:// 通过WebDAV协议访问支持Subversion的Apache服务器 https:// 与h ...
- 用Swift写服务端 — Perfect框架学习(一)
用Swift写服务端 - Perfect框架学习(一) 一.Perfect简介 Perfect是一组完整.强大的工具箱.软件框架体系和Web应用服务器,可以在Linux.iOS和macOS (OS X ...
最新文章
- python接口自动化测试书籍_skPython接口自动化测试 自动化测试教程书籍 用Python实现UI自动化测试 轻松入门Python语法 MySQL数据库 Python基础教程书籍...
- [NOIP 2011普及组 No.4] 表达式的值
- 计算机组成原理试卷五套,计算机组成原理(五套试题)
- Response文件下载
- oracle的to_char中的fm
- 母版页(Master Pages)--轉載
- 服务器系统崩溃文件系统损坏,explorer启动崩溃,提示文件系统错误-2147219200
- php删除英文链接词,英语写作词汇大全:转折连接词
- 在中国程序员工作是青春饭吗?
- 08 SCLSDA,类IIC协议(附源码)
- 机器人系统仿真(七)——xacro语法详解
- 上市公司产权和股权性质-区分非国企、国企和央企(2003-2020)
- matplotlib模块总结一【基本绘图操作】
- 整除7,9,11的数的性质
- android ops,安卓OPS电脑解决方案,促进城市智能化
- 日记侠:如何在微信赚钱?你要学会细分思维!
- DV-Hop 定位算法
- 宝信软件企业信息化解决方案
- 博客九周年:稳中求胜 持续发展
- 基于simulink的三相PWM电压型逆变器系统建模与仿真
热门文章
- 基于Spring等框架的会议管理系统
- 【微信小程序】基于Java+uniapp框架开发的全开源微信小程序商城系统
- 鸿蒙版瑞幸咖啡开发日记(一)首页布局设计
- 7-42 圆形体体积计算器 (20分)
- 【GEOS】GEOS库学习之几何关系判断
- 个人备注:经济学的自学顺序
- 高等数学:第四章 不定积分(1)不定积分的概念与性质
- EXSI自定义第三方驱动生成镜像——筑梦之路
- avada 修改head.php,php - 使用WordPress Avada子主题将主徽标链接到自定义URL而不是首页? - 堆栈内存溢出...
- 计算机硬片,PVC 硬片拉伸强度试验机