//===========================================================================// // File: NetClientServerController.hpp // Contents : All movement messages and rewind capabilites //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 01/18/1999 JSE Inital coding //---------------------------------------------------------------------------// // Copyright (C) 1998, Microsoft Corp. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4Headers.hpp" #include "NetClientServerController.hpp" #include "MWEntityManager.hpp" #include "MWApplication.hpp" #include "Mech.hpp" #include "Torso.hpp" #include "VehicleInterface.hpp" #include "MWPlayer.hpp" #include "Weapon.hpp" #include "MissileWeapon.hpp" #include "SubsystemClassData.hpp" #include #include #include #include // for OutputDebugString^^ #include #undef min #undef max // for OutputDebugString^^ #define DIRECTINPUT_VERSION 0x700 #include #include #include #include #include #include #pragma warning( disable: 4201 ) // nameless struct/union (again - something reenables this!) #include #include #include #include #include #ifndef __IDDrawExclModeVideo_FWD_DEFINED__ #error DirectX Media 6.0 SDK is required #endif #include "gameos\Net_header.hpp" #include "gameos\mreplay.h" #include "mreplay2.h" extern bool g_bCOOP; DWORD g_clientControlPackets; DWORD g_clientPacketsWaitingConfirmation; DWORD g_clientForgotenPackets; DWORD g_clientSkippedPackets; DWORD g_clientTimedOutPackets; DWORD g_clientLatePackets; DWORD g_clientFullConfirms; DWORD g_clientSmallConfirms; DWORD g_serverControlsApplied; DWORD g_serverFullRetransmits; DWORD g_serverSmallRetransmits; DWORD g_serverPacketsOutOfRange; DWORD g_serverFullConfirms; DWORD g_serverSmallConfirms; DWORD g_serverTimeOuts; SecurityQueryInfo::SecurityQueryInfo() { lastSecurityKey = 0; memset(&lastSecurityAnswer,0,sizeof(lastSecurityAnswer)); securityKey = 0; memset(&securityAnswer,0,sizeof(securityAnswer)); securityTimer = 0; otherSidesKey = 0; needInit = true; } void SecurityQueryInfo::Reset(void) { lastSecurityKey = 0; memset(&lastSecurityAnswer,0,sizeof(lastSecurityAnswer)); securityKey = 0; memset(&securityAnswer,0,sizeof(securityAnswer)); securityTimer = 0; otherSidesKey = 0; needInit = true; } Point3D ClampPoint(Point3D origin, Point3D target, Point3D min_box, Point3D max_box) { Verify(origin.x > min_box.x); Verify(origin.z > min_box.z); Verify(origin.x < max_box.x); Verify(origin.z < max_box.z); Verify(origin != target); if (origin == target) return target; Scalar original_y = target.y; origin.y = 0.0f; target.y = 0.0f; min_box.y = 0.0f; max_box.y = 0.0f; Vector3D vec; vec.Subtract(target,origin); UnitVector3D u_vec; u_vec = vec; Line3D line(origin, u_vec, vec.GetLength()); Scalar max_distance = line.m_length; Scalar distance; if (target.x > max_box.x) { distance = Abs((max_box.x - origin.x) / line.m_direction.x); if (distance < max_distance) { max_distance = distance; } } else if (target.x < min_box.x) { distance = Abs((min_box.x - origin.x) / line.m_direction.x); if (distance < max_distance) { max_distance = distance; } } if (target.z > max_box.z) { distance = Abs((max_box.z - origin.z) / line.m_direction.z); if (distance < max_distance) { max_distance = distance; } } else if (target.z < min_box.z) { distance = Abs((min_box.x - origin.z) / line.m_direction.z); if (distance < max_distance) { max_distance = distance; } } line.m_length = max_distance * 0.9f; Point3D end_point; line.FindEnd(&end_point); Verify(end_point.x <= max_box.x); Verify(end_point.x >= min_box.x); Verify(end_point.z <= max_box.z); Verify(end_point.z >= min_box.z); end_point.y = original_y; return end_point; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ServerController::ServerController() { m_EntityManager = Cast_Object(MWEntityManager*, EntityManager::GetInstance()); for (int i = 0; i < Maximum_Players; ++i) { lastControlPacketID[i] = 0; lastPingDelta[i] = 0.0f; lastControlPacket[i] = 0.0f; lastControlPacketLocal[i] = (float)gos_GetElapsedTime(1); lastTimeFailure[i] = (float)gos_GetElapsedTime(1); lastReportedPosition[i] = Point3D::HellPoint; positionErrors[i] = 0; waitingForRespawn[i] = true; clockDifference[i] = 0.0f; lowestLatency[i] = 1000000.0f; latencyDelay[i] = 0; securityQuery[i].Reset(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ServerController::~ServerController() { } void ServerController::Reset() { for (int i = 0; i < Maximum_Players; ++i) { lastControlPacketID[i] = 0; lastPingDelta[i] = 0.0f; lastControlPacket[i] = 0.0f; lastControlPacketLocal[i] = (float)gos_GetElapsedTime(1); lastTimeFailure[i] = (float)gos_GetElapsedTime(1); lastReportedPosition[i] = Point3D::HellPoint; positionErrors[i] = 0; waitingForRespawn[i] = true; clockDifference[i] = 0.0f; lowestLatency[i] = 1000000.0f; latencyDelay[i] = 0; securityQuery[i].Reset(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::ResetClient(int connection_id) { lastControlPacketID[connection_id] = 0; lastPingDelta[connection_id] = 0.0f; lastControlPacket[connection_id] = 0.0f; lastControlPacketLocal[connection_id] = (float)gos_GetElapsedTime(1); lastTimeFailure[connection_id] = (float)gos_GetElapsedTime(1); lastReportedPosition[connection_id] = Point3D::HellPoint; positionErrors[connection_id] = 0; waitingForRespawn[connection_id] = true; clockDifference[connection_id] = 0.0f; lowestLatency[connection_id] = 1000000.0f; latencyDelay[connection_id] = 0; securityQuery[connection_id].Reset(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::ReceivePlayerControl(int connection, Stuff::MemoryStream *message) { MWEntityManager *manager = Cast_Object (MWEntityManager*, MWEntityManager::GetInstance()); ThrottleTest(connection); Mech *vehicle = (Mech *) manager->playerVehicle[connection]; int bandwidth = 0; if (vehicle != NULL) { Scalar old_speed = vehicle->currentSpeedMPS; Scalar packet_time = 0; double latency = 0; double better_latency = 0; DictionaryManager *dictionary_manager = manager->GetDictionaryManager(connection); if(dictionary_manager != NULL) { int version = 0; message->ReadBits(&version,8); BYTE packet_number; message->ReadBits(&packet_number,8); if (MWEntityManager::IsNumberBehind(packet_number, lastControlPacketID[connection], 40, 255)) { //SPEWALWAYS(("jerryeds", "LATE CONTROL PACKET THROWN OUT")); return; } // calculate ping... //t1-t2 Scalar t2_minus_t1; message->ReadBits(&t2_minus_t1, 32); Scalar t3; Scalar t4 = (float)(gos_GetElapsedTime(1) * 1000.0); message->ReadBits(&t3, 32); lastPingDelta[connection] = t4 - t3; //SPEWALWAYS(("jerryeds", "S-REC - %d : t2-t1 : %f, t4-t3 %f : t3 : %f t4 : %f", packet_number, t2_minus_t1, t4 - t3, t3, t4)); MWApplication::GetInstance()->servedConnectionData[connection].effectivePing = t2_minus_t1 + (t4 - t3); MWApplication::GetInstance()->servedConnectionData[connection].averagePing.Add(MWApplication::GetInstance()->servedConnectionData[connection].effectivePing); latency = MWApplication::GetInstance()->servedConnectionData[connection].effectivePing * 0.5f; bool do_clock_sync = true; if (latency < 0.0f) do_clock_sync = false; Min_Clamp(latency, 0.01f); latency *= 0.001f; packet_time = t3 * 0.001f; double current_time = gos_GetElapsedTime(1); if (do_clock_sync && latencyDelay[connection] > 5 ) { if (latency < lowestLatency[connection]) { lowestLatency[connection] = latency; clockDifference[connection] = current_time - (packet_time + latency); //SPEWALWAYS(("jerryeds", "new clock diff %f", clockDifference[connection])); } } else if (do_clock_sync) { clockDifference[connection] = current_time - (packet_time + latency); //SPEWALWAYS(("jerryeds", "DELAY - new clock diff %f", clockDifference[connection])); ++latencyDelay[connection]; } //latency now equals current_time - packet_time+clock_difference better_latency = current_time - (packet_time + clockDifference[connection]); //SPEWALWAYS(("jerryeds", "better latency %f : orig: %f diff: %f\n", better_latency, latency, better_latency - latency)); //latency = better_latency; Min_Clamp(latency, 0.00001f); Min_Clamp(better_latency, 0.00001f); // clockDifference[connection] - (current_time - (packet_time + latency)) // //SPEWALWAYS(("jerryeds", "local:%f client:%f clock_adj:%f", current_time, packet_time, clockDifference[connection] )); //MWApplication::GetInstance()->servedConnectionData[connection].effectivePing = (float)(latency * 2.0 * 1000.0); //doesn't get executed due to the above clamp and never has. I can remove this, but am not for compile consistancy. if (do_clock_sync && latency < 0.0f) { clockDifference[connection] += latency; //SPEWALWAYS(("jerryeds", "clock adj : %f", clockDifference[connection])); } lastControlPacketID[connection] = packet_number; // used to be GetVersion, but that will cause packets to not be read for no reason. Dictionary *dictionary = dictionary_manager->GetCurrentDictionary(); if (dictionary != NULL) { bandwidth = dictionary->dictionaryBandwidth; // if this is ahead and not more than 30 messages ahead... int rate_type = manager->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate; Scalar rate = DictionaryPage::CalculateSeconds(rate_type); SecurityQuery::Decode(vehicle, message, 0.0, (float)latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); MechPositionUpdate::Decode(vehicle, message, 0.0, (float)latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); SecurityResponse::Decode(vehicle, message, 0.0, (float)latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); ExternalJumpJetUpdate::Decode(vehicle, message, 0.0, (float)latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); //MechMovemntUpdate::Decode(vehicle, message, 0.0, latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); //MechAnimationUpdate::Decode(vehicle, message, 0.0, latency, connection, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); int command_count=0; message->ReadBits(&command_count, 8); while (command_count) { int command=0; message->ReadBits(&command, 5); vehicle->ProcessCommand(command); command_count--; } } } YawPitchRoll ypr; vehicle->GetDeadReckonedNetworkPosition(MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition, ypr); MWApplication::GetInstance()->servedConnectionData[connection].vehicleRotation.yaw = ypr.yaw; Point3D current_position; current_position = vehicle->GetLocalToWorld(); Point3D distance_traveled; //SPEWALWAYS(("jerryeds", "MOVE COMMAND : %d", connection)); //SPEWALWAYS(("jerryeds", "CUR POS %f %f %f", current_position.x, current_position.y, current_position.z)); //SPEWALWAYS(("jerryeds", "NET POS %f %f %f", MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.x, MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.y, MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.z)); if (!waitingForRespawn[connection]) { //SPEWALWAYS((0,"CLIENT : %d", connection)); positionErrors[connection] = 0; Point3D real_last_position = lastReportedPosition[connection]; lastReportedPosition[connection] = MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition; //SPEWALWAYS(("jerryeds", "REAL LAST %f %f %f", real_last_position.x, real_last_position.y, real_last_position.z)); //SPEWALWAYS(("jerryeds", "LAST REPORTED %f %f %f", lastReportedPosition[connection].x, lastReportedPosition[connection].y, lastReportedPosition[connection].z)); distance_traveled.Subtract(lastReportedPosition[connection], real_last_position); // if the mech was breaking the rules.... Scalar local_time = (Scalar)gos_GetElapsedTime(1) - (Scalar)better_latency; Scalar local_dif = local_time-lastControlPacketLocal[connection]; Scalar remote_dif = packet_time-lastControlPacket[connection]; //SPEW(("jerryeds","TIME DIFFERENCE %f", local_dif-remote_dif)); Scalar time_dif = remote_dif - local_dif; // jcem - Verify(fabs(time_dif) > 0.0f); //SPEWALWAYS((0,"local_time : %f remote_time : %f", gos_GetElapsedTime(), packet_time)); //SPEWALWAYS((0,"TIME SINCE FAILURE : %f", gos_GetElapsedTime() - lastTimeFailure[connection])); bool loose_time = true; if (gos_GetElapsedTime(1) - lastTimeFailure[connection] < 3.0f) { loose_time = false; } //double time_since_failure = (float)gos_GetElapsedTime(1) - lastTimeFailure[connection]; if (time_dif > 0.04f) { lastTimeFailure[connection] = (float)gos_GetElapsedTime(1); //SPEWALWAYS((0, "ALLOWED TIME RULE BREAKER")); } //SPEWALWAYS((0,"SERVER : %f - CLIENT : %f - DIF %f - latency %f\n", local_dif, remote_dif, time_dif, latency)); //SPEWALWAYS((0, "TIME DIFF %f : %f : %f", local_dif, remote_dif, fabs(time_dif))); if (Close_Enough(real_last_position, Point3D::HellPoint, 100.0f)) { // the real position is in hell on the server but the client got to move // go ahead and let this one by } else if (loose_time && time_dif > 0.25f) { //Connection *conn = Network::GetInstance()->GetConnection(connection); //DWORD que = reinterpret_cast(gos_NetInformation(gos_GetOutboundWindowSizeDpid, conn->GetNetworkAddress())); lowestLatency[connection] = 0.5f; clockDifference[connection] = gos_GetElapsedTime(1) - packet_time + 0.5f; //SPEWALWAYS((0, "LOOSE TIME - RULE BREAK")); //SPEWALWAYS((0,"CLIENT : %d : %s", connection, (char *)Network::GetInstance()->GetConnection(connection)->GetConnectionName())); //SPEWALWAYS((0,"connection speed : %d", bandwidth)); //SPEWALWAYS((0,"QUE : %d", que)); //SPEWALWAYS((0, "clock_adj:%f", clockDifference[connection] )); //SPEWALWAYS((0,"local_time : %f remote_time : %f : diff : %f", gos_GetElapsedTime(1), packet_time, gos_GetElapsedTime(1) - packet_time)); //SPEWALWAYS((0,"TIME SINCE FAILURE : %f", time_since_failure)); //SPEWALWAYS((0,"SERVER : %f - CLIENT : %f - DIF %f - latency %f", local_dif, remote_dif, time_dif, latency)); //SPEWALWAYS((0, "TIME DIFF %f : %f : %f", local_dif, remote_dif, fabs(time_dif))); //SPEWALWAYS((0,"-----------------------------\n", connection)); //PAUSE(("RULE BREAKER")); vehicle->ClearNetworkPosition(); vehicle->speedDemand = 0.0f; vehicle->yawDemand = 0.0f; vehicle->currentSpeedMPS = old_speed; SendFullConfirmation(connection); lastReportedPosition[connection] = vehicle->GetLocalToWorld(); } else if (!loose_time && time_dif > 0.04f) { //Connection *conn = Network::GetInstance()->GetConnection(connection); //DWORD que = reinterpret_cast(gos_NetInformation(gos_GetOutboundWindowSizeDpid, conn->GetNetworkAddress())); lowestLatency[connection] = 0.5f; clockDifference[connection] = gos_GetElapsedTime(1) - packet_time + 0.5f; //SPEWALWAYS((0,"NO LOOSE TIME - RULE BREAKER")); //SPEWALWAYS((0,"CLIENT : %d : %s", connection, (char *)Network::GetInstance()->GetConnection(connection)->GetConnectionName())); //SPEWALWAYS((0,"connection speed : %d", bandwidth)); //SPEWALWAYS((0,"QUE : %d", que)); //SPEWALWAYS((0, "clock_adj:%f", clockDifference[connection] )); //SPEWALWAYS((0,"local_time : %f remote_time : %f : diff : %f", gos_GetElapsedTime(1), packet_time, gos_GetElapsedTime(1) - packet_time)); //SPEWALWAYS((0,"TIME SINCE FAILURE : %f", time_since_failure)); //SPEWALWAYS((0,"SERVER : %f - CLIENT : %f - DIF %f - latency %f", local_dif, remote_dif, time_dif, latency)); //SPEWALWAYS((0, "TIME DIFF %f : %f : %f", local_dif, remote_dif, fabs(time_dif))); //SPEWALWAYS((0,"-----------------------------\n", connection)); //PAUSE(("RULE BREAKER")); vehicle->ClearNetworkPosition(); vehicle->speedDemand = 0.0f; vehicle->yawDemand = 0.0f; vehicle->currentSpeedMPS = old_speed; SendFullConfirmation(connection); lastReportedPosition[connection] = vehicle->GetLocalToWorld(); } else if (vehicle->executionState->GetState() == Mech::ExecutionStateEngine::FlyingMotionState) { Scalar time = packet_time-lastControlPacket[connection]; Scalar max_speed_squared = vehicle->GetMaxSpeed()*2.0f*time; max_speed_squared *= max_speed_squared; distance_traveled.y = 0.0f; if (!Small_Enough(time)) { if (distance_traveled.GetLengthSquared() > max_speed_squared) { //rule breaker... //PAUSE(("RULE BREAKER")); //SPEWALWAYS(("jerryeds", "RULE BREAKER %f : %f : %f > %f ", MWApplication::GetInstance()->servedConnectionData[connection].effectivePing, time, distance_traveled.GetLength(), sqrt(max_speed_squared))); vehicle->ClearNetworkPosition(); vehicle->speedDemand = 0.0f; vehicle->yawDemand = 0.0f; vehicle->currentSpeedMPS = old_speed; SendFullConfirmation(connection); lastReportedPosition[connection] = current_position; } } } else { Scalar time = packet_time-lastControlPacket[connection]; Scalar max_speed_squared = vehicle->GetMaxSpeed()*1.5f*time; max_speed_squared *= max_speed_squared; distance_traveled.y = 0.0f; if (!Small_Enough(time)) { if (distance_traveled.GetLengthSquared() > max_speed_squared) { //rule breaker... //PAUSE(("RULE BREAKER")); //SPEWALWAYS(("jerryeds", "RULE BREAKER %f : %f : %f > %f ", MWApplication::GetInstance()->servedConnectionData[connection].effectivePing, time, distance_traveled.GetLength(), sqrt(max_speed_squared))); vehicle->ClearNetworkPosition(); vehicle->speedDemand = 0.0f; vehicle->yawDemand = 0.0f; vehicle->currentSpeedMPS = old_speed; SendFullConfirmation(connection); lastReportedPosition[connection] = current_position; } } } lastControlPacketLocal[connection] = local_time; lastControlPacket[connection] = packet_time; //SPEWALWAYS((0,"-----------------------------\n", connection)); } else { // if this is the actual respawn... //SPEWALWAYS(("jerryeds", "WAITING FOR RESPAWN <%f:%f:%f> -> <%f:%f:%f>", // MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.x, // MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.y, // MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition.z, // lastReportedPosition[connection].x, lastReportedPosition[connection].y, lastReportedPosition[connection].z)); if (lastReportedPosition[connection] == Point3D::HellPoint && MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition != Point3D::HellPoint) { //STOP (("NEVER SHOULD THIS HAPPEN")); waitingForRespawn[connection] = false; Point3D trans; YawPitchRoll rot; vehicle->GetDeadReckonedNetworkPosition(trans, rot); vehicle->ClearNetworkPosition(); LinearMatrix4D drop_position; drop_position.BuildTranslation(trans); drop_position.BuildRotation(rot); vehicle->SetNewLocalToParent(drop_position); vehicle->SyncMatrices(true); Map::GetInstance()->UpdateZone(vehicle); } else { Point3D distance; distance.Subtract(lastReportedPosition[connection],MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition); distance.y = 0.0f; if (Small_Enough(distance.GetLengthSquared(),100.0f)) { waitingForRespawn[connection] = false; Point3D trans; YawPitchRoll rot; vehicle->GetDeadReckonedNetworkPosition(trans, rot); vehicle->ClearNetworkPosition(); LinearMatrix4D drop_position; drop_position.BuildTranslation(trans); drop_position.BuildRotation(rot); vehicle->SetNewLocalToParent(drop_position); vehicle->SyncMatrices(true); Map::GetInstance()->UpdateZone(vehicle); } else { vehicle->speedDemand = 0.0f; vehicle->yawDemand = 0.0f; vehicle->currentSpeedMPS = old_speed; vehicle->ClearNetworkPosition(); ++positionErrors[connection]; if (positionErrors[connection] > 10) { //SPEWALWAYS(("jerryeds", "NO RESPAWN %f %f %f", current_position.x, current_position.y, current_position.z)); Point3D trans; YawPitchRoll rot; LinearMatrix4D drop_position = LinearMatrix4D::Identity; drop_position.BuildTranslation(lastReportedPosition[connection]); vehicle->SetNewLocalToParent(drop_position); vehicle->SyncMatrices(true); Map::GetInstance()->UpdateZone(vehicle); SendFullConfirmation(connection); vehicle->ClearNetworkPosition(); //lastReportedPosition[connection] = current_position; waitingForRespawn[connection] = false; } } } } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::SendFullConfirmation(int connection) { MWEntityManager *manager = Cast_Object (MWEntityManager*, MWEntityManager::GetInstance()); DictionaryManager *dictionary_manager = manager->GetDictionaryManager(connection); if(dictionary_manager != NULL) { Dictionary *dictionary = dictionary_manager->GetCurrentDictionary(); //int rate_type = manager->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate; //Scalar rate = DictionaryPage::CalculateSeconds(rate_type); DynamicMemoryStream movement_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); Player *player = MWApplication::GetInstance()->servedConnectionData[connection].clientPlayer; movement_packet.WriteBits(&dictionary->versionNumber,8); MechPositionUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); ExternalJumpJetUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); MechInternalDamageUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); movement_packet.WriteByteAlign(); movement_packet.Rewind(); Network::GetInstance()->SendNetMessage(connection, MWEntityManager::FirstPersonFullConfirmationMessageID, &movement_packet, false); } /* if (!((g_nMR == 1) && (connection != 1))) return; dictionary_manager = manager->GetDictionaryManager(1); if(dictionary_manager != NULL) { Dictionary *dictionary = dictionary_manager->GetCurrentDictionary(); //int rate_type = manager->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate; //Scalar rate = DictionaryPage::CalculateSeconds(rate_type); DynamicMemoryStream movement_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); movement_packet.WriteBits(&dictionary->versionNumber,8); Player *player = MWApplication::GetInstance()->servedConnectionData[connection].clientPlayer; Vehicle* vehicle = Cast_Object(Vehicle*, player->vehicle); ReplicatorID id = vehicle->GetReplicatorID(); movement_packet.WriteBits(&id.connectionID, 8); movement_packet.WriteBits(&id.localID, 16); MechPositionUpdate::Encode(vehicle, &movement_packet, id.connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); ExternalJumpJetUpdate::Encode(vehicle, &movement_packet, id.connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); movement_packet.WriteByteAlign(); movement_packet.Rewind(); g_MRF.SendMessage(1, &movement_packet, MRP_FULLCONFIRM); }*/ } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::ReceivePlayerObserverControl(int connection, Stuff::MemoryStream *message) { ThrottleTest(connection); YawPitchRange viewing_rotation = YawPitchRange::Identity; Point3D viewing_position = Point3D::Identity; Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); message->ReadBitsToScaledFloat(viewing_position.x, min_x, max_x, 24); message->ReadBitsToScaledFloat(viewing_position.y, -2005.0f, 1005.0f, 24); message->ReadBitsToScaledFloat(viewing_position.z, min_z, max_z, 24); message->ReadBitsToScaledFloat(viewing_rotation.yaw.angle, -Stuff::Pi, Stuff::Pi, 24); Scalar t2_minus_t1; message->ReadBits(&t2_minus_t1, 32); Scalar t3; Scalar t4 = (float)(gos_GetElapsedTime(1) * 1000.0); message->ReadBits(&t3, 32); lastPingDelta[connection] = t4 - t3; //SPEWALWAYS(("jerryeds", "S-REC - %d : t2-t1 : %f, t4-t3 %f : t3 : %f t4 : %f", packet_number, t2_minus_t1, t4 - t3, t3, t4)); MWApplication::GetInstance()->servedConnectionData[connection].effectivePing = t2_minus_t1 + (t4 - t3); MWApplication::GetInstance()->servedConnectionData[connection].averagePing.Add(MWApplication::GetInstance()->servedConnectionData[connection].effectivePing); SecurityQuery::Decode(NULL, message, 0.0f, 0.0f, connection, 0, 0); SecurityResponse::Decode(NULL, message, 0.0f, 0.0f, connection, 0, 0); MWApplication::GetInstance()->servedConnectionData[connection].vehiclePosition = viewing_position; MWApplication::GetInstance()->servedConnectionData[connection].vehicleRotation = viewing_rotation; Network::GetInstance()->netStatCollector[Network::IncomingMechMovementBitSizeStat].AddToStatistic(connection,72); //SPEWALWAYS(("jerryeds","REC CAM - %f %f %f : %f", viewing_position.x, viewing_position.y, viewing_position.z, viewing_rotation.yaw.angle)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::ReceiveWeaponCommand(int connection, int message_type, Stuff::MemoryStream *message) { Verify(message_type >= MWEntityManager::StartFirstPersonWeaponMessageID && message_type <= MWEntityManager::EndFirstPersonWeaponMessageID); Verify(Network::GetInstance()->AmIServer()); #if defined(_DEBUG) && 0 // jcem - for MR test { char Buffer[128]; sprintf(Buffer, "Server::ReceiveWeaponCommand\n"); OutputDebugString(Buffer); } #endif // _DEBUG && ... WeaponUpdate *data = new WeaponUpdate; WeaponCommand::SpecialDecode(connection, message_type, *data, message); // send the weapon data to the other clients. if (data->obsolete) return; if (data->originator.GetCurrent() == NULL) return; #if 0 //SPEW(("jerryeds", "SERVER RECIEVED WEAPON COMMAND FROM : %d", data.originator->GetReplicatorID().connectionID)); int message_offset = message_type - MWEntityManager::StartFirstPersonWeaponMessageID; DynamicMemoryStream weapon_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); WeaponCommand::SpecialEncode((BYTE)connection, MWEntityManager::StartThirdPersonWeaponMessageID+message_offset, *data, &weapon_packet); weapon_packet.WriteByteAlign(); weapon_packet.Rewind(); for (int i = 0; i < Maximum_Players; ++i) { if(MWApplication::GetInstance()->servedConnectionData[i].clientReady && i != connection && i != Connection::Server->GetID()) { Network::GetInstance()->netStatCollector[Network::OutgoingWeaponMessageBitSizeStat].AddToStatistic(i,message->GetBufferBytesUsed()*8); Network::GetInstance()->SendNetMessage(i, MWEntityManager::StartThirdPersonWeaponMessageID+message_offset, &weapon_packet, false); } } #endif m_EntityManager->PlayerWeaponUpdate(data); // create the collision packet and fire the weapon //m_EntityManager->CreateWeaponEffect(data); m_EntityManager->QueWeapon(data); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool ServerController::SendWeaponCommands() { Stuff::ChainIteratorOf iterator(&m_EntityManager->weaponUpdates); WeaponUpdate *update; DynamicMemoryStream weapon_bundle_packet(DefaultPacketBufferSize); while ((update = iterator.GetCurrent()) != NULL) { if (update->originator.GetCurrent()) { DynamicMemoryStream weapon_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); int message_type = 0; bool fire_weapon = false; if (update->originator.GetCurrent()->IsPlayerVehicle()) message_type = MWEntityManager::StartThirdPersonWeaponMessageID; else message_type = MWEntityManager::StartAIWeaponMessageID; if (update->target.GetCurrent() == NULL) { // SPEWALWAYS(("jackyc", "Server Sends - Third Person Weapon To No Target")); message_type += MWEntityManager::ToNoTargetOffset; Point3D min(Point3D::Identity); Point3D max(Point3D::Identity); Map::GetInstance()->GetMapExtents(&min.z, &max.z, &min.x, &max.x); Point3D origin; origin = update->originator.GetCurrent()->GetLocalToWorld(); update->targetOffset = ClampPoint(origin, update->targetOffset, min, max); Clamp(update->targetOffset.y, -1000.0f, 1000.0f); fire_weapon = true; } else if (update->target.GetCurrent() == Map::GetInstance()) { message_type += MWEntityManager::ToGroundOffset; fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID == Connection::Hermit->GetID()) { // SPEWALWAYS(("jackyc", "Server Sends - Third Person Weapon To Ground")); message_type += MWEntityManager::ToGroundOffset; Point3D new_point; new_point.Multiply(update->targetOffset, update->target.GetCurrent()->GetLocalToWorld()); update->targetOffset = new_point; update->target.Remove(); update->target.Add( Map::GetInstance() ); fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID != Connection::Server->GetID()) { // SPEWALWAYS(("jackyc", "Server Sends - Third Person Weapon To Mech")); message_type += MWEntityManager::ToMechOffset; fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID == Connection::Server->GetID()) { // SPEWALWAYS(("jackyc", "Server Sends - Third Person Weapon To Server")); // we hit a server object message_type += MWEntityManager::ToServerOffset; fire_weapon = true; } if (fire_weapon) { WeaponCommand::SpecialEncode((BYTE)Connection::Server->GetID(), message_type, *update, &weapon_packet); //weapon_packet.WriteByteAlign(); //weapon_packet.Rewind(); weapon_packet.WriteByteAlign(); weapon_packet.Rewind(); int size = weapon_packet.GetBufferBytesUsed(); weapon_bundle_packet.WriteBytes(&size, 1); weapon_bundle_packet.WriteBytes(&message_type, 1); weapon_bundle_packet.WriteBytes(weapon_packet.GetPointer(), size); // SPEW(("jackyc", "SIZE - %d", size)); // SPEW(("jackyc", "TYPE - %d", message_type)); } iterator.Remove(); delete update; if (weapon_bundle_packet.GetBufferBytesUsed() + 45 >= Network::DefaultPacketSize) break; } else { iterator.Remove(); delete update; } } if (weapon_bundle_packet.GetBufferBytesUsed() > 0) { for (int i = 0; i < Maximum_Players; ++i) { if(MWApplication::GetInstance()->servedConnectionData[i].clientReady) { if (i == Connection::Server->GetID()) { if ((g_nMR != 1) || (g_MRF.m_nCount < 0)) continue; } Network::GetInstance()->SendNetMessage(i, MWEntityManager::WeaponBundleMessageID, &weapon_bundle_packet, false); Network::GetInstance()->netStatCollector[Network::OutgoingWeaponMessageBitSizeStat].AddToStatistic(i,weapon_bundle_packet.GetBufferBytesUsed()*8); } } } if (iterator.GetCurrent()) return true; return false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::SendAIWeaponCommands() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::RespawnClient(int connection_id, Point3D translation) { waitingForRespawn[connection_id] = true; lastReportedPosition[connection_id] = translation; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ServerController::ThrottleTest(int connection_id) { MWApplication *app = MWApplication::GetInstance(); Network *net = Network::GetInstance(); if (app->servedConnectionData[connection_id].bandwidthThrottle) return; Scalar cur_time = (Scalar)gos_GetElapsedTime(); if (app->servedConnectionData[connection_id].timeSinceLastThrottleTest == -1.0f) { app->servedConnectionData[connection_id].timeSinceLastThrottleTest = cur_time; net->packetsSent[connection_id] = 0; net->packetsDropped[connection_id] = 0; } else if (cur_time - app->servedConnectionData[connection_id].timeSinceLastThrottleTest > 30.0f) { Scalar percent = 0.0f; app->servedConnectionData[connection_id].timeSinceLastThrottleTest = cur_time; if (net->packetsSent[connection_id]) { percent = (Scalar)net->packetsDropped[connection_id] / (Scalar)net->packetsSent[connection_id]; } if (percent > 0.1) { //PAUSE(("THROTTLE TEST")); app->servedConnectionData[connection_id].bandwidthThrottle = 1; MWEntityManager::GetInstance()->UpdateDictionaries(connection_id); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ClientController::ClientController() { m_EntityManager = Cast_Object(MWEntityManager*, EntityManager::GetInstance()); controlUpdateTimer = 0.0f; lastControlPacketID = 0; lastPingDelta = 0.0f; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ClientController::~ClientController() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::Reset() { controlUpdateTimer = 0.0f; securityQuery.Reset(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::SendControlPacketToServer(Scalar time_slice) { controlUpdateTimer += time_slice; MWPlayer *player = Cast_Object(MWPlayer *, MWPlayer::GetInstance()); VehicleInterface *veh_interface = Cast_Object(VehicleInterface *, player->playerInterface); if (!veh_interface->observerMode) { if (MWEntityManager::GetInstance() == NULL) return; MWEntityManager *manager = Cast_Object (MWEntityManager*, MWEntityManager::GetInstance()); if (manager->GetDictionaryManager(Connection::Local->GetID()) == NULL) return; Dictionary *dictionary = manager->GetDictionaryManager(Connection::Local->GetID())->GetCurrentDictionary(); if (dictionary == NULL) return; int rate_type = manager->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate; Scalar rate = DictionaryPage::CalculateSeconds(rate_type); if (controlUpdateTimer < rate) { return; } controlUpdateTimer = 0.0f; DynamicMemoryStream movement_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); movement_packet.WriteBits(&dictionary->versionNumber,8); ++lastControlPacketID; if (lastControlPacketID == 255) lastControlPacketID = 0; movement_packet.WriteBits(&lastControlPacketID,8); movement_packet.WriteBits(&lastPingDelta, 32); Scalar current_time = (float)(gos_GetElapsedTime(1) * 1000.0); movement_packet.WriteBits(¤t_time, 32); //SPEWALWAYS(("jerryeds", "C-SEND - %d : t2-t1 : %f, t3 : %f", lastControlPacketID, lastPingDelta, current_time)); SecurityQuery::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); MechPositionUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); SecurityResponse::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); ExternalJumpJetUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); //MechMovemntUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); //MechAnimationUpdate::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth); movement_packet.WriteBits(&m_EntityManager->commandCount, 8); Verify(m_EntityManager->commandCount < 256); ChainIteratorOf command_iterator(&m_EntityManager->quedCommands); VehicleCommand *command; while ((command = command_iterator.GetCurrent()) != NULL) { movement_packet.WriteBits(&command->m_Command, 5); m_EntityManager->commandCount--; command_iterator.Remove(); delete command; } Verify(m_EntityManager->commandCount == 0); movement_packet.WriteByteAlign(); movement_packet.Rewind(); Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWEntityManager::FirstPersonControlMessageID, &movement_packet, false); } else { if (controlUpdateTimer < 1.0f) { return; } controlUpdateTimer = 0.0f; Point3D viewing_position; YawPitchRoll viewing_rotation; //if(veh_interface->observingEntity.GetCurrent() != NULL) //{ // viewing_position = veh_interface->observingEntity.GetCurrent()->GetLocalToWorld(); // viewing_rotation = veh_interface->observingEntity.GetCurrent()->GetLocalToWorld(); //} //else //{ // viewing_position = veh_interface->vehicle->GetLocalToWorld(); // viewing_rotation = veh_interface->vehicle->GetLocalToWorld(); //} viewing_position = Player::GetInstance()->GetEyePoint(); viewing_rotation = Player::GetInstance()->GetEyePoint(); DynamicMemoryStream movement_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); movement_packet.WriteScaledFloatToBits(viewing_position.x, min_x, max_x, 24); movement_packet.WriteScaledFloatToBits(viewing_position.y, -2005.0f, 1005.0f, 24); movement_packet.WriteScaledFloatToBits(viewing_position.z, min_z, max_z, 24); movement_packet.WriteScaledFloatToBits(viewing_rotation.yaw.angle, -Stuff::Pi, Stuff::Pi, 24); movement_packet.WriteBits(&lastPingDelta, 32); Scalar current_time = (float)(gos_GetElapsedTime(1) * 1000.0); movement_packet.WriteBits(¤t_time, 32); SecurityQuery::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, 0, 0); SecurityResponse::Encode(player->vehicle, &movement_packet, player->vehicle->GetReplicatorID().connectionID, 0, 0); movement_packet.Rewind(); //SPEWALWAYS(("jerryeds","SEND CAM - %f %f %f : %f", viewing_position.x, viewing_position.y, viewing_position.z, viewing_rotation.yaw.angle)); Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWEntityManager::FirstPersonObserverControlMessageID, &movement_packet, false); Network::GetInstance()->netStatCollector[Network::OutgoingMechMovementBitSizeStat].AddToStatistic(Connection::Server->GetID(),72); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::SendWeaponCommands(void) { Stuff::ChainIteratorOf iterator(&m_EntityManager->weaponUpdates); WeaponUpdate *update; while ((update = iterator.GetCurrent()) != NULL) { int message_type = 0; bool fire_weapon = false; if (update->target.GetCurrent() == NULL) { // SPEWALWAYS(("jackyc", "Client Sends - First Person Weapon To No Target")); message_type = MWEntityManager::FirstPersonWeaponNoTargetCommandMessageID; Point3D min(Point3D::Identity); Point3D max(Point3D::Identity); Map::GetInstance()->GetMapExtents(&min.z, &max.z, &min.x, &max.x); Point3D origin; origin = update->originator.GetCurrent()->GetLocalToWorld(); update->targetOffset = ClampPoint(origin, update->targetOffset, min, max); Clamp(update->targetOffset.y, -1000.0f, 1000.0f); fire_weapon = true; } else if (update->target.GetCurrent() == Map::GetInstance()) { // SPEWALWAYS(("jackyc", "Client Sends - First Person Weapon To Ground")); message_type = MWEntityManager::FirstPersonWeaponToGroundCommandMessageID; fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID == Connection::Hermit->GetID()) { // SPEWALWAYS(("jackyc", "Client Sends - First Person Weapon To Ground")); message_type = MWEntityManager::FirstPersonWeaponToGroundCommandMessageID; Point3D new_point; new_point.Multiply(update->targetOffset, update->target.GetCurrent()->GetLocalToWorld()); update->targetOffset = new_point; update->target.Add( Map::GetInstance() ); fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID != Connection::Server->GetID()) { // SPEWALWAYS(("jackyc", "Client Sends - First Person Weapon To Mech")); message_type = MWEntityManager::FirstPersonWeaponToMechCommandMessageID; fire_weapon = true; } else if (update->target.GetCurrent()->GetReplicatorID().connectionID == Connection::Server->GetID()) { // SPEWALWAYS(("jackyc", "Client Sends - First Person Weapon To Server Object")); // we hit a server object message_type = MWEntityManager::FirstPersonWeaponToServerObjectCommandMessageID; fire_weapon = true; } if (fire_weapon) { DynamicMemoryStream weapon_packet(MWEntityManager::Packet_Buffer, DefaultPacketBufferSize); WeaponCommand::SpecialEncode((BYTE)Connection::Server->GetID(), message_type, *update, &weapon_packet); weapon_packet.WriteByteAlign(); weapon_packet.Rewind(); Network::GetInstance()->netStatCollector[Network::OutgoingWeaponMessageBitSizeStat].AddToStatistic(Connection::Server->GetID(),weapon_packet.GetBufferBytesUsed()*8); Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), message_type, &weapon_packet, false); } iterator.Remove(); delete update; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::ReceiveWeaponCommand(int connection, int message_type, Stuff::MemoryStream *message) { Verify(message_type >= MWEntityManager::StartThirdPersonWeaponMessageID && message_type <= MWEntityManager::EndAIWeaponMessageID); Verify(!Network::GetInstance()->AmIServer()); #if defined(_DEBUG) && 0 // jcem - for MR test { char Buffer[128]; sprintf(Buffer, "Client::ReceiveWeaponCommand\n"); OutputDebugString(Buffer); } #endif // _DEBUG && ... WeaponUpdate *data = new WeaponUpdate; WeaponCommand::SpecialDecode(connection, message_type, *data, message); //SPEW(("jerryeds", "CLEINT RECEIVED WEAPON COMMAND FROM : %d ", data.originator->GetReplicatorID().connectionID)); // create the collision packet and fire the weapon //m_EntityManager->CreateWeaponEffect(data); m_EntityManager->QueWeapon(data); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::ReceiveWeaponBundle(int connection, int message_type, Stuff::MemoryStream *message) { Verify(message_type == MWEntityManager::WeaponBundleMessageID); if (g_nMR != 2) Verify(!Network::GetInstance()->AmIServer()); while (message->GetBytesRemaining()) { int size = 0; int real_type = 0; message->ReadBytes(&size,1); message->ReadBytes(&real_type,1); // SPEW(("jackyc", "SIZE - %d", size)); // SPEW(("jackyc", "TYPE - %d", real_type)); MemoryStream sub_message(message->GetPointer(), size); message->AdvancePointer(size); WeaponUpdate *data = new WeaponUpdate; WeaponCommand::SpecialDecode(connection, real_type, *data, &sub_message); //SPEW(("jerryeds", "CLEINT RECEIVED WEAPON COMMAND FROM : %d ", data.originator->GetReplicatorID().connectionID)); // create the collision packet and fire the weapon //m_EntityManager->CreateWeaponEffect(data); m_EntityManager->QueWeapon(data); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::RespawnClient(int connection_id) { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ClientController::ReceiveFullConfirmation(Stuff::MemoryStream *message) { MWEntityManager *manager = Cast_Object (MWEntityManager*, MWEntityManager::GetInstance()); DictionaryManager *dictionary_manager = manager->GetDictionaryManager(Connection::Local->GetID()); if(dictionary_manager != NULL) { int version = 0; message->ReadBits(&version,8); Dictionary *dictionary = dictionary_manager->GetDictionary(version); if (dictionary != NULL) { Player *player = MWApplication::GetInstance()->servedConnectionData[Connection::Local->GetID()].clientPlayer; int rate_type = manager->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate; Scalar rate = DictionaryPage::CalculateSeconds(rate_type); MechPositionUpdate::Decode(player->vehicle, message, 0.0, 0.0f, Connection::Local->GetID(), dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); ExternalJumpJetUpdate::Decode(player->vehicle, message, 0.0, 0.0f, Connection::Local->GetID(), dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); MechInternalDamageUpdate::Decode(player->vehicle, message, 0.0, 0.0f, Connection::Local->GetID(), dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate); #if 0 YawPitchRoll ypr; Point3D position; Vehicle *vehicle = Cast_Object(Vehicle *, player->vehicle); vehicle->GetDeadReckonedNetworkPosition(position, ypr); #endif //SPEW(("jerryeds","MOVEMENT CONF : %f %f %f", position.x, position.y, position.z)); } } }