最后一战-游戏场景服务器SS解析

文章目录

    • 游戏场景服务器概况
    • 创建战场
    • 英雄移动
    • 英雄技能
    • 装备买卖
      • 商品配置
    • 整个服务器的心跳

游戏场景服务器概况

最后一战-游戏场景服务器SS解析_第1张图片

指令对应的处理handle的文件:SSBattleMgr.cpp

创建战场

  • 指令: eMsgToSSFromCS_CreateBattle
  • GC服务器发往SS fromCS

收到中心服务器CS创建站场的指令,在函数INT32 CSSBattleMgr::OnMsgFromCS_CreateBattle(const char* pData, int n32DataLength)中创建站场成功后,加入到战场管理器中:

m_cAllBattleMap[pBattle->GetBattleID()] = pBattle;

发送创建结果给CS服务器

CSSWorkThreadMgr::GetInstance().PostMsgToCS(sMsg, sMsg.mgsid());

发送可以进入战场的消息给客户端

CSSWorkThreadMgr::GetInstance().PostMsgToGCLIULU((*iter)->GetUserNetInfo(), sMsgBattle, sMsgBattle.msgid());

英雄移动

  • 指令:eMsgToGSToSSFromGC_AskMoveDir,eMsgToGSToSSFromGC_AskStopMove
  • GSToSS: 客户端发往SS,fromGC

收到客户端发来的移动信息, GCToSS::MoveDir, 转化为服务器能识别的参数 CVector3D, 开始计算客户端移动的位置

CVector3D pcDir(pMoveDir->dir().x(), 0, pMoveDir->dir().z());
m_pMsgBattle->AskMoveDir(m_pMsgUser, pcDir);

开始按照方向移动:

bool CSSMoveMgr::AskStartMoveDir(ISSMoveObject* pMObject, ColVector dir) 
{
...
        //计算下一个100毫秒后的位置
		pMObject->CalculateStepMoveTarget(now + 100);
                //检查是否会直接撞墙
		if(FALSE == TestNextStepMove(pMObject)){
			if(FALSE == TryTurnDir(pMObject)){
				pMObject->Stop(now,FALSE);
				return FALSE;
			}
		}
		pMObject->OnStartMove(pMObject->GetDir());
}

INT32 CSSGameUnit::BeginAction_Move(const CVector3D &crsDir, bool bIfNotifyGC){}

同步移动状态到客户端

pcCurBattle->SyncState(this);
...
SendMsgToAllWatcher(*sMsg, msgid, pcGO); 
...
CSSWorkThreadMgr::GetInstance().PostMsgToGCLIULU(watcherArray[i]->GetUserNetInfo(), sMsg, n32MsgID);
INT32	CSSBattle::SyncState(CSSGameUnit *pcGO, bool spot){}
void CSSBattle::SendMsgToAllWatcher(google::protobuf::Message& sMsg, int n32MsgID, CSSGameUnit* pGU){}

英雄技能

  • 指令:eMsgToGSToSSFromGC_AskBuyGoods
  • GSToSS:客户端发往SS,fromGC

SS服务器接收到请求释放技能的指令eMsgToGSToSSFromGC_AskBuyGoods, 转化数据为GCToSS::UseSkill格式 :

boost::shared_ptr pUseSkill = ParseProtoMsgWithNewMemory(pData, n32DataLength);
INT32 nret = m_pMsgBattle->AskUseSkill(m_pMsgUser, pUseSkill->skillid());

请求释放技能:

INT32 CSSAI_Hero::AskUseSkill(UINT32 un32SkillID) {}
//检查是否是不能操作状态
//检查是否被沉默了
//检查是否在吸附中,如果是,不能使用技能
//获取并检查技能是否存在
//检查技能是否符合可用条件
//检查是否是正在运行的技能

开始使用技能

pSkill->Start();

准备技能的配置

void CSSSkill::MakeSkillEffect(TIME_MILSEC	tUTCMilsec){
...
	pcCurBattle->GetEffectMgr()->AddEffectsFromCfg((SSNextSkillEffectCfg*)cpsCfg->asSkillModelList, pcMasterGU.get(), pcTarGU.get(), cPos, pcMasterGU->GetCurDir(), this, tUTCMilsec);

}

从配置中添加技能

INT32 CSSEffectMgr::AddEffectsFromCfg(SSNextSkillEffectCfg* pEffectCfg, CSSGameUnit* pMaster, CSSGameUnit* pTarget, CVector3D cPos, CVector3D cDir
	,  CSSSkill* pSkill, TIME_MILSEC beginTime, CSSGameUnit* pStartSkillGU){
...
AddEffect(pEffect); 
}

添加效果到管理器中

INT32 CSSEffectMgr::AddEffect(CSSSkillEffect* pEffect) {
...
        //尝试使用效果的启动方法。如果启动成功,将其加入正在运行的技能列表中
		if(eNormal == pEffect->Begin()){
			//if (FALSE == pEffect->m_pCfg->bIsCanMove){
				pEffect->AddSelfToUsingList();
			//}
			m_UpdateEffectMap[pEffect->m_un32UniqueID] = pEffect;
		}
		//如果效果启动失败,检查其是否会开始计算技能CD,然后结束技能。
		else{
			pEffect->CheckCooldown();
			pEffect->End();
			DestroyAFreeSkillEffect(pEffect);
			return eEC_AddEffectFailed;
		}
...
}
//正在运行的效果列表
m_UpdateEffectMap

对应的技能在如下图所示的文件中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uoAAHV02-1609600677855)(https://s3.ax1x.com/2021/01/02/spS5KH.png)]

  • SSSkillEffect_Buf.cpp: 附加的buff技能
  • SSSkillEffect_Fly.cpp: 飞行技能

装备买卖

  • 买装备指令:eMsgToGSToSSFromGC_AskBuyGoods
  • 卖商品指令:eMsgToGSToSSFromGC_AskSellGoods
  • 释放装备技能:eMsgToGSToSSFromGC_AskUseGoods
  • GSToSS: 客户端发往SS,fromGC

商品配置

目录:

  • 商品组合:CSBattleMgr/CombineCfg.xml
  • 商品描述:CSBattleMgr/ItemCfg.xml

商品配置描述:

attributeKeyList / attributeValList 描述
5 / 10 +10 物理攻击
6 / 35 +35点魔法攻击
7 / 20 +20 点物理防御
8 / 25 +25点魔法防御
9 / 60 +60点移动速度
10 / 200 +200生命值
11 / 200 +200生命值
12 / 150 +150魔法值
13 / 2000 +2点/秒生命回复
  • attributeKeyLi: 占位
  • attributeValList: 值
  • n32CPCost: 金币

举例

	
		spe_item_HP
		神果
		3
		6
		65
		0
		0
		0
		0
		0
		1
		0
		Dicon038
		0
		0
		1
		1
		800
		200
		0
		0
		+65点魔法攻击
		0
	

神果+65点魔法攻击, 售价是800金币。

整个服务器的心跳

心跳的作用:

  • 检查掉线时间。如果玩家掉线超过30秒,则将其AI替换为机器人AI
  • 技能心跳
  • 移动心跳
  • NPC和hero的心跳
void	CSSBattle::DoPlayHeartBeat(TIME_MILSEC tUTCMilsec, TIME_TICK tTickSpan){
...
    //移动心跳
    m_pMoveMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
    for (GameObjectMap::iterator iterObj = m_cGameObjectMap.begin(); iterObj != m_cGameObjectMap.end(); ++iterObj){
            //NPC和hero的心跳
    		iterObj->second->OnHeartBeat(tUTCMilsec, tTickSpan);
    }
...
    //技能心跳
    m_pEffectMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
    m_pPassiveSkillMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
    m_pSightMgr->OnHeartBeat(tUTCMilsec, tTickSpan);
...
}

你可能感兴趣的:(最后一战源码解析,游戏服务器,游戏开发,C++,最后一战服务器源码解析,场景服务器)