博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UE3客户端加入DS过程
阅读量:4672 次
发布时间:2019-06-09

本文共 2328 字,大约阅读时间需要 7 分钟。

拉起DS进程

客户端将比赛地图及相关参数发送给ZoneSvr请求开赛,收到消息后,ZoneSvr会分配一个ip和端口号,并与客户端发过来的地图及其他参数,来构建一个命令行来拉起一个DS进程,

DS启动时在UGameEngine::Init ==> UGameEngine::Browse中调用UGameEngine::LoadMap来序列化地图数据到UWorld* GWorld,

并调用UWorld::SetGameInfo来创建AGameInfo对象(在SetGameInfo函数中,会调用SetGameType静态函数来根据地图名前缀查找对应模式类型),

然后调用UWorld::Listen来创建UNetDriver* NetDriver,并调用UTcpNetDriver::InitListen来创建socket,

在LoadMap结尾发送一个信号量通知ZoneSvr,要ZoneSvr将ip和端口号发送给客户端,告诉客户端自己已经准备好了。

最后,DS在UWorld::Tick中每帧调用NetDriver的UTcpNetDriver::TickDispatch函数中检查是否有客户端连接过来

客户端加入DS

客户端得到DS的ip和端口后,执行命令:open 10.123.102.132:7500?Uin=5897623?Name=Tom?Team=0?ClanName=?SpectatorOnly=0?bVIP=0?bIsRoomOwner=0

open命令会调用UGameEngine::SetClientTravel函数将open命令参数内容设置给UGameEngine的TravelURL变量

客户端在游戏主循环UGameEngine::Tick中会每帧检查UGameEngine的TravelURL变量是否为空

当不为空时,会调用UGameEngine::Browse来创建UNetPendingLevel类型的全局指针变量GPendingLevel

GPendingLevel在其构造函数中创建UTcpNetDriver对象,然后调用该对象的InitConnect函数来创建UDP的Socket、UTcpipConnection对象及Control Channel

然后客户端就正式开启了加入DS的过程,详细如下图所示

 

Step2补充说明

Ds在UWorld::Tick中每帧调用NetDriver的UTcpNetDriver::TickDispatch函数会先在ClientConnections数组中查找是否已经创建了这个客户端的连接,

发现没有会调用UTcpipConnection::InitConnection来创建一个新的NetConnection,然后加入到ClientConnections数组中,

然后使用这个新的NetConnection调用ReceivedRawPacket来处理网络包数据,由于NMT_Hello包使用的是ControlChanel发送的,

而当前NetConnection的Channels数组中没有该Chanel,于是会调用UNetConnection::CreateChannel创建ControlChanel,

然后使用新的ControlChanel调用UChannel::ReceivedRawBunch ==> UChannel::ReceivedSequencedBunch ==> UControlChannel::ReceivedBunch ==> UWorld::NotifyControlMessage来做出应答

Step5补充说明

bSuccessfullyConnected为true,并有了URL.Map及游戏模式,使得UGameEngine::Tick中检查通过开始LoadMap加载客户端地图:

① 加载失败,则调用传入?failed参数调用UGameEngine::Browse来关闭UNetPendingLevel连接并将GPendingLevel置NULL(在UGameEngine::CancelPending函数中实现),然后加载缺省地图(如大厅地图)

② 加载成功,在LoadMap函数中会将GPendingLevel的NetDriver、NetConnection、ControlChannel转交给新地图的GWorld,地图加载完成后会发送NMT_JOIN消息,并将GPendingLevel置NULL

Step6补充说明

在SpawnPlayActor函数中:服务器端通过调用GameInfo.Login来创建PlayerController对象,然后设置PlayerController的NetPlayerIndex、Role、RemoteRole并关联Player

 

其他说明

a. UE3通过FSocketSubsystem类型封装了windows(FSocketSubsystemWindows)和unix(FSocketSubsystemBSD)上的Socket,向上对引擎提供了一致的编程接口

    引擎通过提供全局变量FSocketSubsystem* GSocketSubsystem单例的方式来使用Socket相关功能

b. 服务器的收包逻辑在UWorld::NotifyControlMessage函数的else分支中,客户端的收包逻辑在UNetPendingLevel::NotifyControlMessage函数中

 

转载于:https://www.cnblogs.com/kekec/p/9515798.html

你可能感兴趣的文章
mysql忘记密码
查看>>
小股神助A股股民畅享经济发展红利
查看>>
Python灰帽子pdf
查看>>
Node.js区块链开发pdf
查看>>
轻松学SQL Server数据库pdf
查看>>
Oracle 日期查询
查看>>
说说今年的计划
查看>>
把discuzX 的用户登录信息添加到纯静态页面
查看>>
文件大小计算
查看>>
iOS:给图片置灰色
查看>>
Java 8 (5) Stream 流 - 收集数据
查看>>
ubuntu下安装JDK
查看>>
【C#】使用DWM实现无边框窗体阴影或全透窗体
查看>>
【MySql】脚本备份数据库
查看>>
keil5 配置 stm32f103rc 软件仿真
查看>>
RESTful到底是什么玩意??
查看>>
Oracle创建视图的一个问题
查看>>
(一)线性表
查看>>
hdu 1003 Max Sum (DP)
查看>>
mysql增备
查看>>