MMOARPG-代码解读(二)-中心服务器如何初始化DS服务器角色数据

哈喽,大家好,我叫人宅,本次我们将为大家一起分析机器人协议结束后接下来又做了哪些操作。
如果说机器人协议是通知中心服务器用来注册用户登录信息,那么接下来我们来看看当我们角色登录到DS服务器,它是如何进行初始化,如何应用捏脸数据,如何应用角色属性和技能属性等。

我们就从这个代码开始:

添加图片注释,不超过 140 字(可选)
接下来代理(StartDelegate)将会执行以下代码:
void AMMOARPGPlayerCharacter::UpdateKneadingRequest()
{
	if (UMMOARPGGameInstance* InGameInstance = GetWorld()->GetGameInstance<UMMOARPGGameInstance>())
	{
#if UE_MMOARPG_DEBUG_DS

		FMMOARPGUserData TmpUserData;
		TmpUserData.ID = 1;
		TmpUserData.EMail = TEXT("846359787@qq.com");
		TmpUserData.Account = TEXT("renzhai");
		TmpUserData.Name = TEXT("人宅");

		if (GameCount == 1)
		{
			CallServerUpdateKneading(TmpUserData,InGameInstance->GetCharacterSlot());
			//GameCount++;
		}
		else if (GameCount == 2)
		{
			CallServerUpdateKneading(TmpUserData, InGameInstance->GetCharacterSlot());
			GameCount++;
		}
		else if (GameCount == 3)
		{
			TmpUserData.ID = 2;
			TmpUserData.EMail = TEXT("111111@qq.com");
			TmpUserData.Account = TEXT("111111");
			TmpUserData.Name = TEXT("你好");

			CallServerUpdateKneading(TmpUserData, InGameInstance->GetCharacterSlot());
			GameCount = 0;
		}
#else
		//RPC
		CallServerUpdateKneading(
			InGameInstance->GetUserData(),
			InGameInstance->GetCharacterSlot());
#endif		
	}
}
 
如果在编辑器的情况下会走如下代码 这里面是两个模拟注册,模拟两个玩家登录到DS服务器。

添加图片注释,不超过 140 字(可选)
其中最重要的是会走如下函数

添加图片注释,不超过 140 字(可选)
这个函数是一个DS服务器的RPC函数

添加图片注释,不超过 140 字(可选)
也就是客户端接受到了信息后,客户端通知DS服务器开始更新捏脸数据.此时会传递给DS服务器UserData和CharacterSlot的数据。
UserData:主要是模拟用户注册数据
CharacterSlot:玩家的存档位置

添加图片注释,不超过 140 字(可选)
接着会执行 LoginCharacterUpdateKneadingRequest 因为我们现在已经处于DS服务器上面,所以直接请求中心服务器,角色捏脸数据。因为DS服务器和中心服务器处于一个局域网内,所以速度是非常快的。

添加图片注释,不超过 140 字(可选)
 
现在我们来看看中心服务器接受到本次协议后,具体在干嘛?
		case SP_UpdateLoginCharacterInfoRequests:
		{
			int32 UserID = INDEX_NONE;
			SIMPLE_PROTOCOLS_RECEIVE(SP_UpdateLoginCharacterInfoRequests, UserID);

			if (UserID != INDEX_NONE)
			{
				if(FMMOARPGPlayerRegistInfo* InPlayerRegistInfo = CenterUserInfo.FindPlayerData(UserID))
				{
					FString CAJsonString;
					NetDataAnalysis::CharacterAppearancesToString(InPlayerRegistInfo->CAInfo, CAJsonString);
					
					FString ArraySlotStringEquipment;
					FString ArraySlotStringItem;
					FString ArraySlotStringSkill;
					FString ArraySlotStringSkin;

					NetDataAnalysis::MMOARPGProductToString(InPlayerRegistInfo->SkillMap, ArraySlotStringSkill);
					NetDataAnalysis::MMOARPGProductToString(InPlayerRegistInfo->SkinMap, ArraySlotStringSkin);
					NetDataAnalysis::MMOARPGProductToString(InPlayerRegistInfo->WeaponMap, ArraySlotStringEquipment);
					NetDataAnalysis::MMOARPGProductToString(InPlayerRegistInfo->ItemsMap, ArraySlotStringItem);

					if (ArraySlotStringEquipment.IsEmpty()){ArraySlotStringEquipment = TEXT("[]");}
					if (ArraySlotStringItem.IsEmpty()) { ArraySlotStringItem = TEXT("[]"); }
					if (ArraySlotStringSkill.IsEmpty()) { ArraySlotStringSkill = TEXT("[]"); }
					if (ArraySlotStringSkin.IsEmpty()) { ArraySlotStringSkin = TEXT("[]"); }

					SIMPLE_PROTOCOLS_SEND(SP_UpdateLoginCharacterInfoResponses,
						UserID,
						CAJsonString,
						ArraySlotStringEquipment,
						ArraySlotStringItem,
						ArraySlotStringSkill,
						ArraySlotStringSkin,
						InPlayerRegistInfo->DressUPInfo);
				}
			}

			break;
		}

ArraySlotStringEquipment, ArraySlotStringItem, ArraySlotStringSkill, ArraySlotStringSkin, InPlayerRegistInfo->DressUPInfo); } } break; }

因为我们已经在前面通过机器人协议注册了相关的角色信息,这些信息分别是捏脸数据,角色数据,物品数据,技能数据等。这些缓存实际上已经缓存在中心服务器上,下载的时候只需要更新到对应的DS服务器上即可。
先通过用户提供的UserID来找到玩家的 FMMOARPGPlayerRegistInfo 注册信息。

添加图片注释,不超过 140 字(可选)
然后拿到捏脸数据:

添加图片注释,不超过 140 字(可选)
然后还拿到了 技能数据 皮肤数据 武器数据 道具数据 等

添加图片注释,不超过 140 字(可选)
还有DressUPInfo装备信息 通过 SP_UpdateLoginCharacterInfoResponses 协议 ,最后一口气发送到DS服务器上。

添加图片注释,不超过 140 字(可选)
我们现在总结一下,这个协议都干了啥。
SP_UpdateLoginCharacterInfoRequests
由DS服务器向中心服务器请求,主要请求的是捏脸数据,技能数据,装备数据,物品数据,武器数据等

我们现在看看DS服务器在接受到这些数据后,它要做什么?
这块代码在MMOARPGGameMode.cpp
case SP_UpdateLoginCharacterInfoResponses:
		{
			int32 UserID = INDEX_NONE;
			FString CAJsonString;
			FString ArraySlotStringEquipment;
			FString ArraySlotStringItem;
			FString ArraySlotStringSkill;
			FString ArraySlotStringSkin;
			FString DressUPInfoString;
			
			SIMPLE_PROTOCOLS_RECEIVE(
				SP_UpdateLoginCharacterInfoResponses,
				UserID,
				CAJsonString,
				ArraySlotStringEquipment,
				ArraySlotStringItem,
				ArraySlotStringSkill,
				ArraySlotStringSkin, 
				DressUPInfoString);

			if (UserID != INDEX_NONE && !CAJsonString.IsEmpty())
			{
				//装备信息
				FMMOARPGDressUPInfo DressUPInfo;
				NetDataAnalysis::StringToMMOARPGDressUPInfo(DressUPInfoString, DressUPInfo);

				//寻找特定玩家
				MethodUnit::ServerCallAllPlayerController<AMMOARPGPlayerController>(GetWorld(), [&](AMMOARPGPlayerController *InController)->MethodUnit::EServerCallType
				{
					if (AMMOARPGPlayerCharacter *InPlayerCharacter = InController->GetPawn<AMMOARPGPlayerCharacter>())
					{
						if (InPlayerCharacter->GetUserID() == UserID)
						{
							if (AMMOARPGPlayerState* InPlayerState = InController->GetPlayerState<AMMOARPGPlayerState>())		
							{
								NetDataAnalysis::StringToCharacterAppearances(CAJsonString,InPlayerState->GetCA());

								InPlayerCharacter->UpdateKneadingBoby(InPlayerState->GetCA());
								
								//接受装备请求相关的内容
								CommonProtocolFunction::RecvAcquireAllEquipmentResponses(
									GetWorld(),
									UserID,
									DressUPInfo.SlotPosition,
									ArraySlotStringEquipment,
									ArraySlotStringItem,
									ArraySlotStringSkill,
									ArraySlotStringSkin,
									DressUPInfo);

								auto ToGamePlayTags = [&](TArray<FName>& InNames)
								{
									TArray<FName> OutNames;
									AnalysisArrayNameToGamePlayTags(InNames, OutNames);
									InNames = OutNames;
								};

								//地面攻击
								if(1)
								{
									//技能信息的原位转换
									ToGamePlayTags(DressUPInfo.Ground.ComboAttack.Slots);
									ToGamePlayTags(DressUPInfo.Ground.Skill.Slots);
									ToGamePlayTags(DressUPInfo.Ground.Limbs.Slots);

									//更新能力GA
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Ground.ComboAttack.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_COMBOATTACK);
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Ground.Skill.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_SKILLATTACK);
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Ground.Limbs.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_LIMBS);

									//注册Combo连击
									InPlayerCharacter->RegisterComboAttack(DressUPInfo.Ground.ComboAttack.Slots);
								}

								//飞行攻击
								if(0)
								{
									//技能信息的原位转换
									ToGamePlayTags(DressUPInfo.Fly.ComboAttack.Slots);
									ToGamePlayTags(DressUPInfo.Fly.Skill.Slots);
									ToGamePlayTags(DressUPInfo.Fly.Limbs.Slots);

									//更新能力GA
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Fly.ComboAttack.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_COMBOATTACK);
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Fly.Skill.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_SKILLATTACK);
									InPlayerCharacter->RegisterGameplayAbility(DressUPInfo.Fly.Limbs.Slots, EMMOARPGGameplayAbilityType::GAMEPLAYABILITY_LIMBS);

									//注册Combo连击
									InPlayerCharacter->RegisterComboAttack(DressUPInfo.Fly.ComboAttack.Slots);
								}

								//技能装配
								InPlayerCharacter->DeserializationSkillAssemblys(
									DressUPInfo.Fly.SkillAssemblyString,
									DressUPInfo.Ground.SkillAssemblyString);

								//更新技能
								//更新技能表
								//更新技能Slot
								InPlayerCharacter->InitSkill();
							}

							return MethodUnit::EServerCallType::PROGRESS_COMPLETE;
						}
					}

					return MethodUnit::EServerCallType::INPROGRESS;					
				});
			}

			break;
		}
首先我们接受到如下数据

添加图片注释,不超过 140 字(可选)
然后将数据转为实际的装备信息

添加图片注释,不超过 140 字(可选)
通过UserID可以找到具体的玩家

添加图片注释,不超过 140 字(可选)
开始更DS服务器角色的新捏脸数据

添加图片注释,不超过 140 字(可选)
接着将服务器发送过来的数据进行解析,解析的内容有 物品,装备,武器,技能,皮肤等。

添加图片注释,不超过 140 字(可选)
解析出来的DressUPInfo用来产生新的GAS技能数据
这个是初始化地面战斗信息

添加图片注释,不超过 140 字(可选)
天空战斗信息

添加图片注释,不超过 140 字(可选)
更新技能表信息

添加图片注释,不超过 140 字(可选)
最后初始化技能信息

添加图片注释,不超过 140 字(可选)
以上就是我们本次分享的技能装备更新等内容。

发表回复