void ANetworkController::ReceivedRemoveAllVehicles() {
	for (TActorIterator<AWheeledVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AWheeledVehicle* Vehicle = *ObjIt;
		Vehicle->Destroy();
	}

	for (TActorIterator<AMockingVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AMockingVehicle* Vehicle = *ObjIt;
		Vehicle->Destroy();
	}

	for (TActorIterator<AActor> ObjIt(GetWorld(), AArrow); ObjIt; ++ObjIt) {
		(*ObjIt)->Destroy();
	}
}
void ANetworkController::ReceivedCameraLookAtVehicle(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		uint32 VehicleId = Unpack<uint64>(Data);
		(*ObjIt)->SetCameraLookAtVehicle(VehicleId);
		break;
	}
}
Esempio n. 3
0
void FLiveEditorManager::FPieObjectCache::EvaluatePendingCreations()
{
	if ( !CacheStarted() || ObjectLookupCache.Num() <= 0 || GEngine == NULL )
		return;

	for ( TArray< const UObjectBase* >::TIterator PendingObjIt(PendingObjectCreations); PendingObjIt; ++PendingObjIt )
	{
		const UObjectBase *ObjectBase = (*PendingObjIt);
		if ( ObjectBase != NULL )
		{
			if ( !ObjectBaseIsA(ObjectBase, UObject::StaticClass()) || (ObjectBase->GetFlags() & RF_ClassDefaultObject) != 0 )
				continue;
			UObject *AsObject = const_cast<UObject*>( static_cast<const UObject*>(ObjectBase) );
	
			//UWorld *World = GEngine->GetWorldFromContextObject( AsObject, false );
			//if ( World == NULL || World->WorldType != EWorldType::PIE )
			//	continue;

			for ( TMultiMap< const UObject*, TWeakObjectPtr<UObject> >::TConstIterator ObjIt(ObjectLookupCache); ObjIt; ++ObjIt )
			{
				const UObject *Key = (*ObjIt).Key;
				if ( !nPieObjectCache::IsPiePartner(*Key, *AsObject) )
					continue;

				ObjectLookupCache.AddUnique( Key, AsObject );
				TrackedObjects.Add( AsObject );
			}
		}
	}
	PendingObjectCreations.Empty();
}
void ANetworkController::ReceivedStartPlayback(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		FString Filename = Unpack<FString>(Data);
		(*ObjIt)->StartPlayback(Filename);
		break;
	}
}
void ANetworkController::ReceivedSetReplaySpeed(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		float Speed = Unpack<double>(Data);
		(*ObjIt)->SetSpeed(Speed);
		break;
	}
}
void ANetworkController::ReceivedSetReplayPaused(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		bool Paused = Unpack<bool>(Data);
		(*ObjIt)->SetPaused(Paused);
		break;
	}
}
void ANetworkController::ReceivedSeekAndPauseReplay(msgpack_object* Data) {
	AReplayPlayer* Player = NULL;
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		Player = *ObjIt;
		break;
	}
	check(Player != NULL);

	float Seconds = Unpack<double>(Data);
	Player->SeekAndPause(Seconds);

	msgpack_sbuffer sbuf;
	msgpack_sbuffer_init(&sbuf);

	msgpack_packer pk;
	msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);

	msgpack_pack_array(&pk, 2);
	msgpack_pack_uint16(&pk, EPacketType::PT_SeekAndPauseReplay);

	msgpack_pack_float(&pk, Player->GetTime());

	int32 BytesSent;
	TcpSocket->Send((uint8*)sbuf.data, sbuf.size, BytesSent);

	msgpack_sbuffer_destroy(&sbuf);
}
void ANetworkController::ReceivedSelectCamera(msgpack_object* Data) {
	FString name = Unpack<FString>(Data);
	APlayerController* PlayerController = NULL;
	for (auto Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) {
		PlayerController = *Iterator;
		break;
	}
	if (!PlayerController) {
		return;
	}

	//PlayerController->PlayerCameraManager->PlayCameraAnim()

	for (TActorIterator<ACameraActor> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ACameraActor* Camera = *ObjIt;
		//GEngine->AddOnScreenDebugMessage(-1, 60.f, FColor::Yellow, Camera->GetName());
		if (Camera->GetName() == name) {
			PlayerController->SetViewTarget(Camera);

			AFollowRoadCamera* FollowRoadCamera = Cast<AFollowRoadCamera>(Camera);

			if (FollowRoadCamera) {
				FollowRoadCamera->Start(false, 0);
			}

			return;
		}
	}
}
void AFollowRoadCamera::BeginPlay() {
    for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
        ReplayPlayer = *ObjIt;
        break;
    }

    for (TActorIterator<ARoadmap> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
        Roadmap = *ObjIt;
        break;
    }

    if (!Roadmap) {
        return;
    }

    /*float Min = 9999.0f;
    float Max = 0.0f;

    for (auto Iter = SplineInfo->Points.CreateConstIterator(); Iter; ++Iter) {
    auto Point = &*Iter;
    float Val = Point->InVal;
    Min = FMath::Min(Min, Val);
    Max = FMath::Max(Max, Val);
    }

    float TVal = 0.0f;
    float TotalDist = 0.0f;
    FVector PrevPoint = SplineInfo->Eval(0.0f, FVector(0, 0, 0));
    while (TVal < Max) {
    FVector Point = SplineInfo->Eval(TVal, PrevPoint);
    float Dist = (Point - PrevPoint).Size2D();
    PrevPoint = Point;
    TotalDist += Dist;
    SplineInfoDistance.AddPoint(TotalDist, TVal);

    TVal += 0.5;
    }


    for (auto Iter = SplineInfoDistance.Points.CreateIterator(); Iter; ++Iter) {
    	auto Point = &*Iter;
    	Point->InterpMode = CIM_CurveAuto;
    }

    SplineInfoDistance.AutoSetTangents();
    */
}
void AReplayPlayer::SetShowArrows(bool AShowArrows) {
	ShowArrows = AShowArrows;

	for (TActorIterator<AMockingVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AMockingVehicle* Vehicle = *ObjIt;

		Vehicle->SetFlockingState(Vehicle->GetFlockingState(), ShowArrows);
	}
}
void ANetworkController::ReceivedSelectVehicleCamera(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		TMap<FName, msgpack_object*> Received = Unpack<TMap<FName, msgpack_object*>>(Data);
		FString CameraName = Unpack<FString>(Received[CAMERA_NAME]);
		uint32 VehicleId = Unpack<uint64>(Received[VEHICLE_ID]);
		(*ObjIt)->SetUseVehicleCamera(VehicleId, CameraName);
		break;
	}
}
void ANetworkController::ReceivedSetArrowsVisible(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		TMap<FName, msgpack_object*> Received = Unpack<TMap<FName, msgpack_object*>>(Data);
		bool Visible = Unpack<bool>(Received[VISIBLE]);
		auto Behaviors = Unpack<TArray<FString>>(Received[BEHAVIORS]);

		(*ObjIt)->SetShowArrows(Visible);
		(*ObjIt)->SetShowArrowsBehaviors(Behaviors);
		break;
	}
}
void ANetworkController::ReceivedStartMatinee(msgpack_object* Data) {
	FString name = Unpack<FString>(Data);

	for (TActorIterator<AMatineeActor> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AMatineeActor* Matinee = *ObjIt;
		if (Matinee->GetName() == name) {
			Matinee->Play();
			break;
		}
	}
}
void AReplayPlayer::SetShowArrowsBehaviors(TArray<FString> BehaviorNames) {
	ShowArrowBehaviors.Empty(BehaviorNames.Num());

	for (TActorIterator<ABehaviours> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ABehaviours* Behaviors = *ObjIt;
		for (auto Iter = Behaviors->Behaviours.CreateConstIterator(); Iter; ++Iter) {
			const UBehaviour* Behavior = *Iter;
			FString Name = Behavior->GetClass()->GetName();
			if (BehaviorNames.Contains(Behavior->GetClass()->GetName())) {
				ShowArrowBehaviors.Add(Behavior);
			}
		}
	}

	for (TActorIterator<AMockingVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AMockingVehicle* Vehicle = *ObjIt;

		Vehicle->SetFlockingState(Vehicle->GetFlockingState(), ShowArrows);
	}
}
void AReplayPlayer::StartPlayback(FString Filename) {
	for (TActorIterator<AWheeledVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		(*ObjIt)->Destroy();
	}

	//GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::Printf(TEXT("Playing from '%s'"), *Filename));

	file = CreateFile(*Filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (file == INVALID_HANDLE_VALUE) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Could not open: %s"), *Filename));
		return;
	};

	size = GetFileSize(file, 0);

	mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0);

	if (mapping == 0) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Could not map: %s"), *Filename));
		CloseHandle(file);
		return;
	}

	data = (const char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);

	if (!data) {
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Could not create a view of %s"), *Filename));
		CloseHandle(mapping);
		CloseHandle(file);
		return;
	}

	// If we sometime in the future wants to support Posix (Linux or Mac), something like this might do it
	/*int fd = open(TCHAR_TO_ANSI(*Filename), O_RDONLY);
	fstat(fd, &sb);
	struct stat sb;
	size = sb.st_size;
	file = mmap(NULL, size, PROT_READ, MAP_SHARED, fs, 0);*/

	ResetPlayback();

	IsPlaybacking = true;

	//msgpack_unpacker_init(&unpacker, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);


	// Jump time to the time of the first packet. No reason to look at an empty screen

}
void ANetworkController::ReceivedConfigureSpawner(TMap<FName, msgpack_object*> data) {

	const EDirection Direction = (EDirection)data[DIRECTION]->via.i64;
	const TArray<int64> Lanes = Unpack<TArray<int64>>(data[LANES]);
	const float MinWait = data[MIN_WAIT]->via.f64;
	const float MaxWait = data[MAX_WAIT]->via.f64;
	const TMap<FName, int64> VehicleTypes = Unpack<TMap<FName, int64>>(data[VEHICLE_TYPES]);

	for (TActorIterator<ACVehicleSpawner> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ACVehicleSpawner* Spawner = *ObjIt;
		if (!Lanes.Contains(Spawner->Lane)) {
			continue;
		}
		if (!(Spawner->Direction == Direction)) {
			continue;
		}

		Spawner->Active = true;
		Spawner->MaxTimeWait = MaxWait;
		Spawner->MinTimeWait = MinWait;
		Spawner->VehicleTypes.Empty();
		for (auto Iter = VehicleTypes.CreateConstIterator(); Iter; ++Iter) {
			EVehicleType VehicleType = EVehicleType::VT_Car;
			if (Iter.Key() == CAR) {
				VehicleType = EVehicleType::VT_Car;
			}
			else if (Iter.Key() == SEDAN) {
				VehicleType = EVehicleType::VT_Sedan;
			}
			else if (Iter.Key() == BUS) {
				VehicleType = EVehicleType::VT_Bus;
			}
			else if (Iter.Key() == EMERGENCY) {
				VehicleType = EVehicleType::VT_Emergency;
			}
			else {
				check(false);
			}

			Spawner->VehicleTypes.Add(FVehicleTypeStruct(VehicleType, Iter.Value()));
		}

		Spawner->TurnBucket();
	}
}
void AReplayPlayer::ResetPlayback() {
	Speed = 1.0;
	Direction = EPlaybackDirection::PD_Forward;
	Time = 0.0f;
	offset = 0;
	Paused = false;
	Vehicles.Empty();
	for (TActorIterator<AMockingVehicle> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		(*ObjIt)->Destroy();
	}

	msgpack_object* obj = NextPacket();

	// Version 1 of the replay type started with an array. Version two and further starts
	// with the version number.
	if (obj->type != MSGPACK_OBJECT_ARRAY) {
		check(obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER);
		ReplayVersion = obj->via.u64;
	}
	else {
		offset = 0;
		ReplayVersion = 1;
	}

	// Resetting offset history
	while (OffsetHistory != NULL) {
		EOffsetHistory* LastOffset = OffsetHistory;
		OffsetHistory = LastOffset->Previous;
		free(LastOffset);
	}

	msgpack_object* p = PeekNextPacket()->via.array.ptr;
	float PacketTime = p[0].via.f64;

	StartTime = PacketTime;
	Time = PacketTime;
}
void FLatentActionManager::ProcessLatentActions(UObject* InObject, float DeltaTime)
{
    for (FActionsForObject::TIterator It(ActionsToRemoveMap); It; ++It)
    {
        auto ActionList = GetActionListForObject(It.Key());
        auto ActionToRemoveListPtr = It.Value();
        if (ActionToRemoveListPtr.IsValid() && ActionList)
        {
            for (auto PendingActionToKill : *ActionToRemoveListPtr)
            {
                const int32 RemovedNum = ActionList->RemoveSingle(PendingActionToKill.Key, PendingActionToKill.Value);
                auto Action = PendingActionToKill.Value;
                if (RemovedNum && Action)
                {
                    Action->NotifyActionAborted();
                    delete Action;
                }
            }
        }
    }
    ActionsToRemoveMap.Empty();

    //@TODO: K2: Very inefficient code right now
    if (InObject != NULL)
    {
        if (!ProcessedThisFrame.Contains(InObject))
        {
            if (FActionList* ObjectActionList = GetActionListForObject(InObject))
            {
                TickLatentActionForObject(DeltaTime, *ObjectActionList, InObject);
                ProcessedThisFrame.Add(InObject);
            }
        }
    }
    else
    {
        for (FObjectToActionListMap::TIterator ObjIt(ObjectToActionListMap); ObjIt; ++ObjIt)
        {
            TWeakObjectPtr<UObject> WeakPtr = ObjIt.Key();
            UObject* Object = WeakPtr.Get();
            auto ObjectActionListPtr = ObjIt.Value().Get();
            check(ObjectActionListPtr);
            FActionList& ObjectActionList = *ObjectActionListPtr;

            if (Object != NULL)
            {
                // Tick all outstanding actions for this object
                if (ObjectActionList.Num() > 0)
                {
                    if (!ProcessedThisFrame.Contains(Object))
                    {
                        TickLatentActionForObject(DeltaTime, ObjectActionList, Object);
                        ensure(ObjectActionListPtr == ObjIt.Value().Get());
                        ProcessedThisFrame.Add(Object);
                    }
                }
            }
            else
            {
                // Terminate all outstanding actions for this object, which has been GCed
                for (TMultiMap<int32, FPendingLatentAction*>::TConstIterator It(ObjectActionList); It; ++It)
                {
                    FPendingLatentAction* Action = It.Value();
                    Action->NotifyObjectDestroyed();
                    delete Action;
                }
                ObjectActionList.Empty();
            }

            // Remove the entry if there are no pending actions remaining for this object (or if the object was NULLed and cleaned up)
            if (ObjectActionList.Num() == 0)
            {
                ObjIt.RemoveCurrent();
            }
        }
    }
}
void AReplayPlayer::BeginPlay() {
	for (TActorIterator<AVehiclestats> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		Stats = *ObjIt;
	}
}
void ANetworkController::ReceivedStopPlayback(msgpack_object* Data) {
	for (TActorIterator<AReplayPlayer> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		(*ObjIt)->StopPlayback();
		break;
	}
}
void ANetworkController::ReceivedSetPaused(bool Paused) {
	for (TActorIterator<ACVehicleSpawner> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ACVehicleSpawner* Spawner = *ObjIt;
		Spawner->Paused = Paused;
	}
}
void ANetworkController::ReceivedGetBehaviors() {
	msgpack_sbuffer sbuf;
	msgpack_sbuffer_init(&sbuf);

	/* serialize values into the buffer using msgpack_sbuffer_write callback function. */
	msgpack_packer pk;
	msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);

	msgpack_pack_array(&pk, 2);
	msgpack_pack_uint16(&pk, EPacketType::PT_GetBehaviors);

	TArray<ABehaviours*> BehaviorsList;
	for (TActorIterator<ABehaviours> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ABehaviours* Behaviors = *ObjIt;
		BehaviorsList.Add(Behaviors);
	}

	int32 BehaviorsListNum = BehaviorsList.Num();
	msgpack_pack_array(&pk, BehaviorsListNum);
	for (int i = 0; i < BehaviorsListNum; i++) {
		ABehaviours* Behaviors = BehaviorsList[i];
		msgpack_pack_map(&pk, 4);
		msgpack_pack_str(&pk, 13);
		msgpack_pack_str_body(&pk, "FlockingState", 13);
		msgpack_pack_uint8(&pk, (uint8)Behaviors->FlockingState);
		msgpack_pack_str(&pk, 13);
		msgpack_pack_str_body(&pk, "ThrottleGains", 13);
		Pack(&pk, Behaviors->ThrottleGains);
		msgpack_pack_str(&pk, 13);
		msgpack_pack_str_body(&pk, "SteeringGains", 13);
		Pack(&pk, Behaviors->SteeringGains);

		int32 BehaviorsNum = Behaviors->Behaviours.Num();
		msgpack_pack_str(&pk, 9);
		msgpack_pack_str_body(&pk, "Behaviors", 9);
		msgpack_pack_array(&pk, BehaviorsNum);
		for (int j = 0; j < BehaviorsNum; j++) {
			UBehaviour* Behavior = Behaviors->Behaviours[j];

			TArray<UProperty*> Properties;
			for (TFieldIterator<UProperty> PropIt(Behavior->GetClass()); PropIt; ++PropIt) {
				UProperty* Property = *PropIt;
				if (Cast<UNumericProperty>(Property) || Cast<UBoolProperty>(Property)) {
					Properties.Add(Property);
				}
			}

			msgpack_pack_map(&pk, Properties.Num() + 1);
			msgpack_pack_str(&pk, 4);
			msgpack_pack_str_body(&pk, "Name", 4);
			FString Name = Behavior->GetClass()->GetName();
			msgpack_pack_str(&pk, Name.Len());
			msgpack_pack_str_body(&pk, TCHAR_TO_UTF8(*Name), Name.Len());
			for (auto PropIt(Properties.CreateIterator()); PropIt; ++PropIt) {
				UProperty* Property = *PropIt;
				const void* Value = Property->ContainerPtrToValuePtr<uint8>(Behavior);
				FString Name = Property->GetName();
				msgpack_pack_str(&pk, Name.Len());
				msgpack_pack_str_body(&pk, TCHAR_TO_UTF8(*Name), Name.Len());
				if (UNumericProperty *NumericProperty = Cast<UNumericProperty>(Property)) {
					if (NumericProperty->IsFloatingPoint()) {
						msgpack_pack_double(&pk, NumericProperty->GetFloatingPointPropertyValue(Value));
					}
					else if (NumericProperty->IsInteger()) {
						msgpack_pack_int(&pk, NumericProperty->GetSignedIntPropertyValue(Value));
					}
				}
				else if (UBoolProperty *BoolProperty = Cast<UBoolProperty>(Property)) {
					if (BoolProperty->GetPropertyValue(Value)) {
						msgpack_pack_true(&pk);
					}
					else {
						msgpack_pack_false(&pk);
					}
				}
			}
		}
	}

	int32 BytesSent;
	TcpSocket->Send((uint8*)sbuf.data, sbuf.size, BytesSent);

	msgpack_sbuffer_destroy(&sbuf);
}
void ANetworkController::ReceivedDisableAllSpawners() {
	for (TActorIterator<ACVehicleSpawner> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		ACVehicleSpawner* Spawner = *ObjIt;
		Spawner->Active = false;
	}
}
void ANetworkController::SendData() {
	if (!TcpSocket) {
		return;
	}

	// Clear the data if there is anything on the stream
	TryReceiveData();

	AVehiclestats* Stats = NULL;
	for (TActorIterator<AVehiclestats> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		Stats = *ObjIt;
		break;
	}
	if (Stats == NULL) {
		return;
	}

	// Send crashlog

	msgpack_sbuffer sbuf;
	msgpack_sbuffer_init(&sbuf);

	msgpack_packer pk;
	msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);


	for (auto Iter = Stats->IncidentLog.CreateConstIterator(); Iter; ++Iter) {
		msgpack_pack_array(&pk, 2);
		msgpack_pack_uint16(&pk, EPacketType::PT_IncidentLog);
		Pack(&pk, *Iter);
	}

	Stats->IncidentLog.Empty();


	// Send the statestics

	msgpack_pack_array(&pk, 2);
	msgpack_pack_uint16(&pk, EPacketType::PT_GetStats);

	msgpack_pack_map(&pk, 6);

	msgpack_pack_str(&pk, 7);
	msgpack_pack_str_body(&pk, "spawned", 7);
	msgpack_pack_uint32(&pk, Stats->GetNumVehiclesSpawned());

	msgpack_pack_str(&pk, 6);
	msgpack_pack_str_body(&pk, "onroad", 6);
	msgpack_pack_uint32(&pk, Stats->GetNumVehiclesOnTheRoad());

	msgpack_pack_str(&pk, 7);
	msgpack_pack_str_body(&pk, "crashed", 7);
	msgpack_pack_uint32(&pk, Stats->GetNumVehiclesCrashed());

	msgpack_pack_str(&pk, 9);
	msgpack_pack_str_body(&pk, "incidents", 9);
	msgpack_pack_uint32(&pk, Stats->GetNumVehiclesIncidents());

	TArray<float> Throughputs;

	for (TActorIterator<AMeasurementGate> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		AMeasurementGate* Gate = *ObjIt;
		Throughputs.Add(Gate->GetThroughput(0));
		Throughputs.Add(Gate->GetThroughput(1));
	}

	msgpack_pack_str(&pk, 11);
	msgpack_pack_str_body(&pk, "throughputs", 11);
	msgpack_pack_array(&pk, Throughputs.Num());
	for (auto Iter = Throughputs.CreateConstIterator(); Iter; ++Iter) {
		msgpack_pack_float(&pk, *Iter);
	}

	msgpack_pack_str(&pk, 4);
	msgpack_pack_str_body(&pk, "time", 4);
	msgpack_pack_float(&pk, Stats->GetTime());

	int32 BytesLeft = sbuf.size;
	while (BytesLeft > 0) {
		int32 Index = sbuf.size - BytesLeft;
		int32 BytesSent;
		TcpSocket->Send((uint8*)sbuf.data + Index, BytesLeft, BytesSent);
		BytesLeft = BytesLeft - BytesSent;
		if (BytesSent == -1) {
			break;
		}
	}

	msgpack_sbuffer_destroy(&sbuf);
}
void ANetworkController::ReceivedResetStats() {
	for (TActorIterator<AVehiclestats> ObjIt(GetWorld()); ObjIt; ++ObjIt) {
		auto Stats = *ObjIt;
		Stats->ResetStats();
	}
}