public void OnMessageReceived(UserToken token, SocketModel sm) { switch (sm.command) { case TimeProtocol.CHECK_CREQ: //客户端发起对时请求 DelayCheckDTO delayCheckDTO = sm.GetMessage <DelayCheckDTO>(); if (delayCheckDTO.timeStamps.Count < delayCheckDTO.checkNum * 2) { delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); Send(token, TimeProtocol.CHECK_SRES, delayCheckDTO); } else { //对时次数够了,计算时差和延迟,这里注意最后一个时间戳是client发来的,因此需要再把现在的时间加上进行计算 delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); DelayAndFloating df = GetDelayAndFloatingEven(delayCheckDTO.timeStamps); userBiz.CacheDelayAndFloating(GetUserId(token), df); } break; case TimeProtocol.CHECK_CRES: //客户端的回应 DelayCheckDTO delayCheck = sm.GetMessage <DelayCheckDTO>(); if (delayCheck.timeStamps.Count <= delayCheck.checkNum * 2) { //对时次数不够,就继续对够 delayCheck.timeStamps.Add(DateTime.Now.Ticks); Send(token, TimeProtocol.CHECK_SREQ, delayCheck); } if (delayCheck.timeStamps.Count == delayCheck.checkNum * 2 + 1) { //对时次数够了,计算时差和延迟 DelayAndFloating df = GetDelayAndFloatingOdd(delayCheck.timeStamps); userBiz.CacheDelayAndFloating(GetUserId(token), df); } break; } }
/// <summary> /// 向服务器发送对时请求 /// </summary> /// <param name="time"></param> private void CheckDelayRequest(int time) { DelayCheckDTO delayCheckDTO = new DelayCheckDTO(time); delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); Send(TimeProtocol.CHECK_CREQ, delayCheckDTO); }
/// <summary> /// 对时消息处理,分为server请求的和client请求的 /// </summary> /// <param name="sm"></param> public override void OnMessageReceived(SocketModel sm) { switch (sm.command) { case TimeProtocol.CHECK_SRES: DelayCheckDTO delayCheckDTO = sm.GetMessage <DelayCheckDTO>(); if (delayCheckDTO.timeStamps.Count <= delayCheckDTO.checkNum * 2) { //对时次数不够,就继续对够 delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); Send(TimeProtocol.CHECK_CREQ, delayCheckDTO); } if (delayCheckDTO.timeStamps.Count == delayCheckDTO.checkNum * 2 + 1) //这里的最后一个timestamp是client的 { //对时次数够了,计算时差和延迟 GameRuntimeData.delayAndFloating = GetDelayAndFloatingOdd(delayCheckDTO.timeStamps); MgrCenter.Instance.SendMsg(Msgs.GetMsgDelayAndFloating((ushort)NetEventTime.DelayGot, GameRuntimeData.delayAndFloating)); } break; case TimeProtocol.CHECK_SREQ: DelayCheckDTO delayCheck = sm.GetMessage <DelayCheckDTO>(); if (delayCheck.timeStamps.Count < delayCheck.checkNum * 2) { delayCheck.timeStamps.Add(DateTime.Now.Ticks); Send(TimeProtocol.CHECK_CRES, delayCheck); } else { //对时次数够了,计算时差和延迟,这里注意最后一个时间戳是server发来的,因此需要再把现在的时间加上再计算 delayCheck.timeStamps.Add(DateTime.Now.Ticks); GameRuntimeData.delayAndFloating = GetDelayAndFloatingEven(delayCheck.timeStamps); MgrCenter.Instance.SendMsg(Msgs.GetMsgDelayAndFloating((ushort)NetEventTime.DelayGot, GameRuntimeData.delayAndFloating)); } break; } }
/// <summary> /// 处理应用内消息 /// </summary> /// <param name="msg"></param> public override void ProcessEvent(MsgBase msg) { switch (msg.MsgId) { case (ushort)NetEventTime.CheckTimeRequest: MsgInt msgInt = msg as MsgInt; DelayCheckDTO delayCheckDTO = new DelayCheckDTO(msgInt.Int); //check多少次 delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); Send(TimeProtocol.CHECK_CREQ, delayCheckDTO); break; } }
/// <summary> /// 根据预测进行移动 /// </summary> /// <param name="token"></param> /// <param name="moveDTO"></param> private void Move(UserToken token, PosSyncDTO moveDTO) { DelayAndFloating delayAndFloating = userBiz.GetDelayAndFloating(token); //time: floating = server - client //server = floating + client long time = delayAndFloating.floating + moveDTO.timeStamp;//将client的发送时间,转换为server时间 float timeBtwClientSendAndNow = (DateTime.Now.Ticks - time) * 0.0000001f; float speed = instances[moveDTO.instanceId].speed; if (timeBtwClientSendAndNow < 0) { Console.WriteLine("time floating is negative : " + timeBtwClientSendAndNow.ToString()); DelayCheckDTO delayCheckDTO = new DelayCheckDTO(5); delayCheckDTO.timeStamps.Add(DateTime.Now.Ticks); Send(token, Protocol.Protocol.TYPE_TIME, area, TimeProtocol.CHECK_SREQ, delayCheckDTO); } else { Console.WriteLine("time floating is : " + timeBtwClientSendAndNow.ToString()); //TODO 如果位置与之前存储的位置相差太大,就发送位置校正消息 Vector3 posNow = GetFuturePos(new Vector3(moveDTO.x, moveDTO.y, moveDTO.z), new Vector3(moveDTO.dirX, moveDTO.dirY, moveDTO.dirZ), timeBtwClientSendAndNow, speed); if (!instancePos.ContainsKey(moveDTO.instanceId)) { instancePos.Add(moveDTO.instanceId, new EntityMoveInfo(posNow, true)); } else { instancePos[moveDTO.instanceId].cVector3.x = posNow.x; instancePos[moveDTO.instanceId].cVector3.y = posNow.y; instancePos[moveDTO.instanceId].cVector3.z = posNow.z; instancePos[moveDTO.instanceId].moveStatus = MoveStatus.Moving; } PosSyncDTO posSyncDTO = new PosSyncDTO(moveDTO.instanceId, posNow.x, posNow.y, posNow.z, moveDTO.dirX, moveDTO.dirY, moveDTO.dirZ, DateTime.Now.Ticks); brocast(FightProtocol.POS_SYNC_BRO, posSyncDTO, token); } }