public void SV_ClientThink(ClientNode cl, ref UserCmd cmd){ cmd.CopyTo(cl.lastUserCmd); // CLog.Info("last ucmd time: {0}", cl.lastUserCmd.serverTime); if(cl.state != ClientState.ACTIVE){ return; } CDataModel.GameSimulate.ClientThink(Array.IndexOf(clients, cl)); }
public UserCmd GenerateUserCmd(IUserCmdOwnAdapter player, int intverval) { UpdateLookAt(player, _userCmdProvider.LookAt); if (_userCmdProvider.HasPath) { var vel = player.PlayerTransform.InverseTransformVector(_userCmdProvider.DesirwdVelocity); vel.y = 0; vel = vel.normalized; _userCmd.MoveVertical = vel.z; _userCmd.MoveHorizontal = vel.x; if (_userCmd.DeltaYaw > 1) { _userCmd.IsSlightWalk = true; } else if (_userCmdProvider.DesirwdVelocity.magnitude > 2) { _userCmd.IsRun = true; } else if (_userCmdProvider.DesirwdVelocity.magnitude > 0.5) { } else { _userCmd.IsSlightWalk = true; } } _userCmd.IsCrouch = _userCmdProvider.IsCrouch; _userCmd.IsJump = _userCmdProvider.IsJump; _userCmd.IsProne = _userCmdProvider.IsProne; _userCmd.IsPeekLeft = _userCmdProvider.IsPeekLeft; _userCmd.IsPeekRight = _userCmdProvider.IsPeekRight; _userCmd.IsF = _userCmdProvider.IsF; _userCmd.IsLeftAttack = _userCmdProvider.IsLeftAttack; _userCmd.IsReload = _userCmdProvider.IsReload; //_userCmdProvider.Reset(); // _userCmdProvider.LookAt = Quaternion.Euler(0,0, // 0); _userCmd.FrameInterval = intverval; _userCmd.Seq = _seq++; var rc = UserCmd.Allocate(); _userCmd.CopyTo(rc); _userCmd.Reset(); return(rc); }
public UserCmd GenerateUserCmd(IUserCmdOwnAdapter player, int intverval) { _userCmd.Seq = _seq++; _userCmd.FrameInterval = intverval; _userCmd.ChangedSeat = ChangeSeat(); _userCmd.ChangeChannel = ChangeChannel(); var rc = UserCmd.Allocate(); _userCmd.CopyTo(rc); _userCmd.Reset(); return(rc); }
public UserCmd GenerateUserCmd(IUserCmdOwnAdapter player, int intverval) { logger.DebugFormat("GenerateUserCmd:{0}", MyGameTime.seq); userCmd.Seq = MyGameTime.seq; userCmd.FrameInterval = intverval; userCmd.ChangedSeat = ChangeSeat(); userCmd.ChangeChannel = ChangeChannel(); var rc = UserCmd.Allocate(); userCmd.CopyTo(rc); userCmd.Reset(); return(rc); }
private void ClientEnterWorld(ClientNode cl, UserCmd cmd){ cl.state = ClientState.ACTIVE; int clNum = Array.IndexOf(clients, cl); SharedEntity ent = gEntities[clNum]; ent.s.entityIndex = clNum; cl.gEntity = ent; cl.deltaMessage = -1; cl.lastSnapshotTime = 0; //立即产生一个snapshot if(cmd != null){ cmd.CopyTo(cl.lastUserCmd); }else{ cl.lastUserCmd.Reset(); } CDataModel.GameSimulate.ClientBegin(clNum); }
public void SetLastUserCmd(UserCmd userCmd) { userCmd.CopyTo(_lastUserCmd); }
private void ClientThink_real(GameEntity ent) { GameClient cl = ent.client; if (cl.pers.connected != ClientConnState.CONNECTED) { return; } UserCmd ucmd = ent.client.pers.cmd; if (ucmd.forwardmove != 0 || ucmd.rightmove != 0) { CLog.Info("cmd move {0}, {1}", ucmd.forwardmove, ucmd.rightmove); } if (ucmd.serverTime > time + 200) { ucmd.serverTime = time + 200; } if (ucmd.serverTime < time - 1000) { ucmd.serverTime = time - 1000; } //unlagged - backward reconciliation #4 //frameOffset应该是一帧内收到命令数据包的偏移毫秒数,依赖于服务器运行RunFrame的速度 cl.frameOffset = CDataModel.InputEvent.Milliseconds() - frameStartTime; //unlagged - backward reconciliation #4 //unlagged - lag simulation #3 if (cl.pers.plOut > 0) { float thresh = cl.pers.plOut / 100f; if (CUtils.Random() < thresh) { //这是丢失了的命令,不做任何事情 return; } } //unlagged - lag simulation #3 //unlagged - true ping cl.pers.pingSamples[cl.pers.sampleHead] = prevTime + cl.frameOffset - ucmd.serverTime; cl.pers.sampleHead++; if (cl.pers.sampleHead >= CConstVar.NUM_PING_SAMPLES) { cl.pers.sampleHead -= CConstVar.NUM_PING_SAMPLES; } if (CConstVar.TruePing) { int sum = 0; for (int i = 0; i < CConstVar.NUM_PING_SAMPLES; i++) { sum += cl.pers.pingSamples[i]; } cl.pers.realPing = sum / CConstVar.NUM_PING_SAMPLES; } else { cl.pers.realPing = cl.playerState.ping; } //unlagged - true ping //unlagged - lag simulation #2 // cl.pers.cmdqueue[cl.pers.cmdhead] = cl.pers.cmd; // cl.pers.cmdhead++; // if(cl.pers.cmdhead >= CConstVar.MAX_LATENT_CMDS){ // cl.pers.cmdhead -= CConstVar.MAX_LATENT_CMDS; // } // if(cl.pers.latentCmds > 0){ // int time = ucmd.serverTime; // int cmdindex = cl.pers.cmdhead - cl.pers.latentCmds - 1; // while(cmdindex < 0){ // cmdindex += CConstVar.MAX_LATENT_CMDS; // } // cl.pers.cmd = cl.pers.cmdqueue[cmdindex]; // cl.pers.realPing += time - ucmd.serverTime; // } //unlagged - lag simulation #2 cl.attackTime = ucmd.serverTime; cl.lastUpdateFrame = frameNum; //unlagged - lag simulation #1 // if(cl.pers.latentSnaps > 0){ // cl.pers.realPing += cl.pers.latentSnaps * (1000 / CConstVar.SV_FPS); // cl.attackTime -= cl.pers.latentSnaps * (1000 / CConstVar.SV_FPS); // } //unlagged - lag simulation #1 //unlagged - true ping if (cl.pers.realPing < 0) { cl.pers.realPing = 0; } //unlagged - true ping int msec = ucmd.serverTime - cl.playerState.commandTime; if (msec > 200) { msec = 200; } if (CConstVar.PMoveMsec < 8) { CConstVar.PMoveMsec = 8; } if (CConstVar.PMoveMsec > 33) { CConstVar.PMoveMsec = 33; } if (CConstVar.PMoveFixed > 0 || cl.pers.pmoveFixed) { ucmd.serverTime = ((ucmd.serverTime + CConstVar.PMoveMsec - 1) / CConstVar.PMoveMsec) * CConstVar.PMoveMsec; } if (cl.sess.sessionTeam == TeamType.TEAM_SPECTATOR || cl.isEliminated) { if (cl.sess.spectatorState == SpectatorState.SCOREBOARD) { return; } SpectatorThink(ent, ucmd); return; } if (cl.noclip) { cl.playerState.pmType = PMoveType.NOCLIP; } else if (cl.playerState.states[CConstVar.STAT_HEALTH] <= 0) { cl.playerState.pmType = PMoveType.DEAD; } else { cl.playerState.pmType = PMoveType.NORMAL; } // cl.playerState.gravity = cl.playerState.speed = CConstVar.Speed; int oldEventSeq = cl.playerState.eventSequence; PMove pm = new PMove(); pm.playerState = cl.playerState; pm.agent = cl.agent.Model; ucmd.CopyTo(pm.cmd); if (pm.playerState.pmType == PMoveType.DEAD) { // pm.tracemask } else if ((ent.sEnt.r.svFlags & SVFlags.BOT) != SVFlags.NONE) { // pm. } else { } pm.pmoveFixed = CConstVar.PMoveFixed | (cl.pers.pmoveFixed ? 1 : 0); pm.pmoveMsec = CConstVar.PMoveMsec; pm.pmoveFloat = CConstVar.PMoveFloat; pm.pmvoveFlags = CConstVar.dmFlags; cl.oldOrigin = cl.playerState.origin; pm.Move(); if (ent.client.playerState.eventSequence != oldEventSeq) { ent.eventTime = time; } if (CConstVar.SmoothClients > 1) { CUtils.BG_PlayerStateToEntityStateExtraPolate(ent.client.playerState, ref ent.sEnt.s, ent.client.playerState.commandTime, true); } else { CUtils.PlayerStateToEntityState(ent.client.playerState, ref ent.sEnt.s, true); } SendingPredictableEvents(ent.client.playerState); if ((ent.client.playerState.entityFlags & EntityFlags.FIRING) == 0) { // cl.fireHeld = false; } ent.sEnt.s.pos.GetTrBase(ref ent.sEnt.r.currentOrigin); // ent.sEnt.r.mins = pm.mins; //执行客户端事件 ClientEvents(ent, oldEventSeq); Server.Instance.LinkEntity(ent); if (!ent.client.noclip) { TouchTrigger(ent); } ent.sEnt.r.currentOrigin = ent.client.playerState.origin; ClientImpacts(ent, ref pm); //保存触发器和客户端事件 if (ent.client.playerState.eventSequence != oldEventSeq) { ent.eventTime = time; } cl.oldButtons = cl.buttons; cl.buttons = ucmd.buttons; cl.latched_buttons |= cl.buttons & ~cl.oldButtons; if (cl.playerState.states[CConstVar.STAT_HEALTH] <= 0) { if ((time > cl.respawnTime)) { ClientRespawn(ent); } return; } }