【HLSDK系列】服务端 AddToFullPack 函数
服务端会给客户端发送一些数据,其中两大种类数据是 clientdata_t 和 entity_state_t 这里我们说说 entity_state_t 这个结构体。
你在丢在地上的枪、C4等等是服务端实体(edict_t),并且你能在客户端看到它们(废话),这些实体们是怎样发送到你的客户端的呢?
引擎不可能原原本本地把 edict_t 发送出去的,所以就有了 entity_state_t 这个结构体,它表示了一个可见实体所有必要的数据。
接上面:如果实体不可见,那何必发到客户端呢?:-)
所以 entity_state_t 只保存跟实体显示有关的数据,例如 origin、angles、model 这些,引擎只需要把这些数据发到客户端就行了。
引擎里有一个叫做 FullPack 的包(实际上就是数组),这个包里有全部需要发送给客户端的实体的 entity_state_t。
引擎会逐个检查服务端的所有实体,并且添加到包里,准备发送给客户端。
那引擎是不是默认就把能看见的实体都添加到包里了呢?并不是,因为引擎提供了一个接口让我们自己决定哪些实体可以被添加到包里!
你可以在 mp.dll 的源码里找到 AddToFullPack 这函数,可以看到这样的代码:
int AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
if ((ent->v.effects == EF_NODRAW) && ent != host)
return ; // 有EF_NODRAW这个标记的实体是不可见的,不添加到包里。 if (!ent->v.modelindex || !STRING(ent->v.model))
return ; // 没有模型的实体是不可见的,不添加到包里。 if ((ent->v.flags & FL_SPECTATOR) && ent != host)
return ; // 观察者也是不可见的,不添加到包里。 // ... if (ent != host)
{
// 在可视范围(PVS)外的实体是看不到的,不添加到包里。
if (!CheckEntityRecentlyInPVS(hostindex, e, gpGlobals->time))
{
if (!ENGINE_CHECK_VISIBILITY((const struct edict_s *)ent, pSet))
{
MarkEntityInPVS(hostindex, e, gpGlobals->time, true);
return ;
} MarkEntityInPVS(hostindex, e, gpGlobals->time);
}
} // ...
}
参数 state 是将要添加到包里的 entity_state_t ,参数 ent 是正在处理的实体,参数 host 是包要发送到的那个玩家(的客户端)!
如果这个函数返回 0 (FALSE)引擎就不会把这个实体添加到包里,这个实体自然也就不会被发送到那个客户端(看不到)。
你甚至可以在这个函数里自定义需要发送的实体的数据!我们可以看到这样的代码:
int AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
{
// ... state->number = e;
state->entityType = ENTITY_NORMAL; state->animtime = (int)(1000.0 * ent->v.animtime) / 1000.0; memcpy(state->origin, ent->v.origin, * sizeof(float));
memcpy(state->angles, ent->v.angles, * sizeof(float));
memcpy(state->mins, ent->v.mins, * sizeof(float));
memcpy(state->maxs, ent->v.maxs, * sizeof(float));
memcpy(state->startpos, ent->v.startpos, * sizeof(float));
memcpy(state->endpos, ent->v.endpos, * sizeof(float)); state->impacttime = ent->v.impacttime;
state->starttime = ent->v.starttime;
state->modelindex = ent->v.modelindex;
state->frame = ent->v.frame; // ...
}
你可以看到它从服务端实体(edict_t)抽出必要的数据填充到 entity_state_t 里!
最后返回 1(TRUE)引擎将会把我们填充好的 entity_state_t 添加到包里,发送给客户端。
这个函数真的很有用对吧,我们可以做一些有趣的功能,让一个实体可以被玩家A看到,玩家B却看不到!
我们只需要检查当前正在处理的实体(ent)是那个我们不让玩家B看到的实体,然后判断 host 是不是玩家B,如果是,就返回 0 不让这个实体发送给玩家B!
你甚至可以设置一个玩家(玩家也是实体)不让其它玩家看到!(玩家实体必须被发送,所以如果要隐藏一个玩家,请使用EF_NODRAW这个FLAG)
注意,引擎里的包最多只能容纳 256 个实体!如果超出了这个数量,引擎将会忽略超出部分的实体!
【HLSDK系列】服务端 AddToFullPack 函数的更多相关文章
- 2.live555源码分析----服务端doEventLoop()函数分析
上一篇博客说道,live555服务端main函数做的最后一件事就是调用如下代码陷入死循环: env->taskScheduler().doEventLoop(); // does not ret ...
- 前端学习 node 快速入门 系列 —— 服务端渲染
其他章节请看: 前端学习 node 快速入门 系列 服务端渲染 在简易版 Apache一文中,我们用 node 做了一个简单的服务器,能提供静态资源访问的能力. 对于真正的网站,页面中的数据应该来自服 ...
- Nacos源码系列—服务端那些事儿
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 nacos,即可免费获取源码 前言 在上节课中,我们讲解了客户端注册服 ...
- 【HLSDK系列】服务端 UpdateClientData 函数
首先说明下,这个函数是写在 mp.dll 里的. 服务器会给每个客户端发送一些数据,其中两大数据种类就是 clientdata_t 和 entity_state_t 这里要说的是 clientdata ...
- TCP连接建立系列 — 服务端接收ACK段(一)
http://blog.csdn.net/zhangskd/article/details/17923917 分类: Linux TCP/IP Linux Kernel 2014-01-07 09 ...
- TCP连接建立系列 — 服务端接收SYN段
本文主要分析:服务器端接收到SYN包时的处理路径. 内核版本:3.6 Author:zhangskd @ csdn blog 接收入口 1. 状态为ESTABLISHED时,用tcp_rcv_esta ...
- TCP连接建立系列 — 服务端接收ACK段(二)
本文主要分析:三次握手中最后一个ACK段到达时,服务器端的处理路径. 内核版本:3.6 Author:zhangskd @ csdn blog 创建新sock 协议族相关的操作函数,我们要看的是TCP ...
- TCP连接建立系列 — 服务端发送SYNACK段
本文主要分析:服务器端如何构造和发送SYNACK段. 内核版本:3.6 Author:zhangskd @ csdn blog 发送入口 tcp_v4_send_synack()用于发送SYNACK段 ...
- 解决有关flask-socketio中服务端和客户端回调函数callback参数的问题(全网最全)
由于工作当中需要用的flask_socketio,所以自己学习了一下如何使用,查阅了有关文档,当看到回调函数callback的时候,发现文档里都描述的不太清楚,最后终于琢磨出来了,分享给有需要的朋友 ...
随机推荐
- 【java笔记】Calendar.getInstance()是什么意思
Calendar类是个抽象类,因此本身不能被实例化,然而在却创建了Calendar 的对象,但并不是抽象类可以创建对象这个对象并不是Calendar 自身实例,而是其子类实例,这是在getInstan ...
- 为什么说private方法是有罪的
具体的这句话从什么地方获得,我已经无从考证了,但是想想我们现在使用private的场景,你慢慢的就会发现,private的方法,大多数都是copy代码,当然我只是说大多数,还有就是大多数private ...
- Mac 用Ctr+C复制,Ctr+V 粘贴
用习惯Windows的用户,进入Mac,不习惯快捷方式. 用下面的方法,可以返回windows 习惯. 1.进入系统偏好设置->键盘->修饰键 2.Control 选择 Command,C ...
- sql语句-4-子查询
- 分块算法&BZOJ2002
题目传送门 第一次接触分块...... 分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况. 分块修改理论复杂度为O ...
- [BJOI2017]树的难题 点分治,线段树合并
[BJOI2017]树的难题 LG传送门 点分治+线段树合并. 我不会写单调队列,所以就写了好写的线段树. 考虑对于每一个分治中心,把出边按颜色排序,这样就能把颜色相同的子树放在一起处理.用一棵动态开 ...
- Windows环境下php开启GD库的方法
一.GD库是什么? GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印.在网站上GD库通常用来生成缩略图,或者用来对图片加 ...
- 用php实现简单的自制计算器
存档: <!DOCTYPE html> <html> <head> <title>PHP实现计算器</title> </head> ...
- python接口自动化1-发送get请求 前言
前言 requests模块,也就是老污龟,为啥叫它老污龟呢,因为这个官网上的logo就是这只污龟,接下来就是学习它了. 一.环境安装 1.用pip安装requests模块 >>pip in ...
- Vue 项目在其他电脑 npm run dev 运行报错的解决方法
一个 Vue 项目从一台电脑上传到 github 上之后,再另外一台电脑上 git clone .并使用 npm run dev 或 npm run start 发生以下报错的解决方法. 报错原因 ...