MMOARPG-代码解读(一) 编辑器的机器人协议流程详细分析

哈喽,大家好,我叫人宅,这里详细讲解一下关于本次代码的一个解读,毕竟代码量好几万了,代码融合了很多的技术,如果真的要看懂,阅读者需要一定的代码火候,所以这次我们来解读一下本次代码,希望对大家有所帮助。

这次主要介绍的是机器人协议,什么意思呢?

拿到源码后,进入TestGameMap,点击开始游戏,内部会接通一个协议,这个协议就是机器人协议。

为什么要有机器人协议呢?

这套工程是基于分布式+DS服务器架构模式来架构的,没办法通过登录到大厅再到游戏场景里面。

内部原理是登录->捏脸->大厅 这些是在分布式SNC进行的,但是游戏场景是DS服务器,并不是单一的服务器来接管,是多服务器合作运行。

如果游戏打包后,那这种问题就不存在。关键现在是编辑器中,我们不能写一行代码都要打包游戏才可以看到结果,那效率太低了,所以才有了机器人协议。

什么是机器人协议呢?

就是可以完成从登录到大厅再到游戏场景中的过程,也就是把所有主要协议都走一边,然后再进入到游戏场景。

这就是机器人的第一句协议,获取捏脸数据,这个捏脸数据是直接通过网关获取,模拟角色在大厅的效果。

我们不用关心服务器到底返回什么,以后会详细分析大厅协议的执行内容。

现在我们详细分析协议的登录流程

当我们接受到捏脸协议后 我们直接运行RunLoginToDSServerRequests 函数内容

这个函数可以直接连接到DS服务器,也就是登录DS服务器,依然是通过网关发送,我们重点来看看这个协议都干了什么.

首先可以看到 它发送了一个ID和SlotID,这两个主要是用户的ID和它存档的位置。因为本次的角色是具有可以创建存档位置的,所以这么操作是非常有必要,只有这些数据正确才可以保证后续的玩家登录到DS服务器。

我们刚刚考伦的内容都发生在MMOARPG的项目里面,这里我们省区了网关的代码转发,直接看中心服务器那边都做了什么?

这个是目前的中心服务器:

中心服务器实际上需要存储用户登录到DS服务器的用户信息,这些信息在本地是没有的,所以这里也是一个转发,但是这种转发是通过dbClient进行,通过数据库客户端来实现转发,将客户端传递的UserID和SlotID发送过来,同样需要传递两个地址,一个是链接客户端的地址和中心服务器的地址到db数据库中。

这里的协议是 SP_PlayerRegistInfoRequests

现在我们看看db服务器那边是如何获取用户数据

case SP_PlayerRegistInfoRequests: { int32 UserID = INDEX_NONE; int32 SlotID = INDEX_NONE; FSimpleAddrInfo GateAddrInfo; FSimpleAddrInfo CenterAddrInfo; //拿到客户端发送的账号 SIMPLE_PROTOCOLS_RECEIVE( SP_PlayerRegistInfoRequests, UserID, SlotID, GateAddrInfo, CenterAddrInfo); if (UserID != INDEX_NONE && SlotID != INDEX_NONE) { FMMOARPGUserState UserState; FString UserInfoJson; FString SlotInfoJson; FString DressUPInfoString; FString JsonString = TEXT(“[]”); if (GetUserInfo(UserID, UserInfoJson) && GetSlotCAInfo(UserID,SlotID,SlotInfoJson) && GetCharacterSave(UserID, SlotID, UserState)) { FString ArraySlotStringEquipment; FString ArraySlotStringItem; FString ArraySlotStringSkill; FString ArraySlotStringSkin; GetAllKnapsack( UserID, SlotID, ArraySlotStringEquipment, ArraySlotStringSkill, ArraySlotStringItem, ArraySlotStringSkin, DressUPInfoString); SIMPLE_PROTOCOLS_SEND(SP_PlayerRegistInfoResponses, UserInfoJson, SlotInfoJson, UserState, ArraySlotStringEquipment, ArraySlotStringSkill, ArraySlotStringItem, ArraySlotStringSkin, DressUPInfoString, GateAddrInfo, CenterAddrInfo); } else { SIMPLE_PROTOCOLS_SEND(SP_PlayerRegistInfoResponses, JsonString, JsonString, UserState, JsonString, JsonString, JsonString, JsonString, DressUPInfoString, GateAddrInfo, CenterAddrInfo); } } break;

首先通过 SP_PlayerRegistInfoRequests 已经接受到了用户数据。

然后通过 以下的三个API获取对应的 玩家数据 捏脸数据 角色的存档数据

对应数据库是以下的数据:

这三个数据属于主要数据,如果这三个都拿不到后面就不用拿了。

接下来再拿到如下的数据 物品栏和装备栏数据

这里对应数据库如下的内容:

分别是装备栏,道具栏,皮肤栏,技能栏,对应内容如下。

物品位置

接着还有一个非常重要的内容,就是这个数据

它记录玩家的装备信息,主要体现如下:

武器皮肤和技能装备

数据库代码如下:

拿到这些数据后 正式将其返回到中心服务器,中心服务器会将这些数据缓存起来:

此时我们来到中心服务器

//出 case SP_PlayerRegistInfoResponses: { FString ArraySlotStringEquipment; FString ArraySlotStringItem; FString ArraySlotStringSkill; FString ArraySlotStringSkin; FString DressUPInfoString; FSimpleAddrInfo GateAddrInfo; FSimpleAddrInfo CenterAddrInfo; FMMOARPGPlayerRegistInfo RI; FString UserJson; FString SlotJson; SIMPLE_PROTOCOLS_RECEIVE( SP_PlayerRegistInfoResponses, UserJson, SlotJson, RI.UserState, ArraySlotStringEquipment, ArraySlotStringSkill, ArraySlotStringItem, ArraySlotStringSkin, DressUPInfoString, GateAddrInfo, CenterAddrInfo); if (UserJson != TEXT(“[]”) && SlotJson != TEXT(“[]”)) { FMMOARPGDressUPInfo DressUPInfo; NetDataAnalysis::StringToMMOARPGDressUPInfo(DressUPInfoString, DressUPInfo); NetDataAnalysis::StringToCharacterAppearances(SlotJson, RI.CAInfo); NetDataAnalysis::StringToUserData(UserJson, RI.UserInfo); RI.DressUPInfo = DressUPInfo; NetDataAnalysis::StringToMMOARPGProduct(ArraySlotStringEquipment,RI.WeaponMap); NetDataAnalysis::StringToMMOARPGProduct(ArraySlotStringSkill, RI.SkillMap); NetDataAnalysis::StringToMMOARPGProduct(ArraySlotStringItem, RI.ItemsMap); NetDataAnalysis::StringToMMOARPGProduct(ArraySlotStringSkin, RI.SkinMap); RI.bInitializeRegistInfo = true; CenterUserInfo.AddRegistInfo(RI); //准备ds服务器 if (FSimpleAddr* DsAddr = CenterUserInfo.FindDicatedServerAddrAndCreate(RI.UserState.DSID)) { SIMPLE_SERVER_SEND(CenterServer, SP_LoginToDSServerResponses, CenterAddrInfo, GateAddrInfo,*DsAddr); UE_LOG(LogMMOARPGCenterServer, Display, TEXT(“A new DS server address was found.Ip=%i,Port=%i.”), DsAddr->IP, DsAddr->Port); } else { FString NewPublicIP = FSimpleNetGlobalInfo::Get()->GetInfo().PublicIP; FSimpleAddr LocalDSAddr = FSimpleNetManage::GetSimpleAddr(*NewPublicIP, 7777); SIMPLE_SERVER_SEND(CenterServer, SP_LoginToDSServerResponses, CenterAddrInfo, GateAddrInfo, LocalDSAddr); UE_LOG(LogMMOARPGCenterServer, Error, TEXT(“ERROR: The address cannot be found. The default address is used here.Ip=%i,Port=%i.”), LocalDSAddr.IP, LocalDSAddr.Port); } } break; }

中心服务器拿到数据后,将字符串解析为中心服务器的结构数据,最终存储再CenterUserInfo里面。

因为MMOARPG是多地图组成的,根据玩家的存储信息,判定它到底是在哪个DS服务器,并且取得它的地址,这个地址就是玩家日后要链接的DS服务器地址。

最后 中心服务器会将 DS服务器的地址,发送到MMOARPG的客户端,客户端就可以通过这个地址链接到DS服务器。

以下是客户端接受本次信息,因为在客户端是在编辑器内部执行,也就是本次是DS和客户端一起启动,客户端已经链接到DS服务器,所以没有必要再连一次,除非是打包后的游戏。

课程地址:

作者其他文章

游戏实例

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片