public override Object ReadGameData() { lock (this) { rfShared _rf1apistruct = new rfShared(); if (!initialised) { if (!InitialiseInternal()) { throw new Exception("Failed to initialise shared memory"); } } try { using (var sharedMemoryStreamView = memoryMappedFile.CreateViewStream()) { BinaryReader _SharedMemoryStream = new BinaryReader(sharedMemoryStreamView); sharedMemoryReadBuffer = _SharedMemoryStream.ReadBytes(sharedmemorysize); handle = GCHandle.Alloc(sharedMemoryReadBuffer, GCHandleType.Pinned); _rf1apistruct = (rfShared)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(rfShared)); handle.Free(); } RF1StructWrapper structWrapper = new RF1StructWrapper(); structWrapper.ticksWhenRead = DateTime.Now.Ticks; structWrapper.data = _rf1apistruct; return(structWrapper); } catch (Exception ex) { throw new Exception(ex.Message, ex); } } }
private rfVehicleInfo getVehicleInfo(rfShared shared) { foreach (rfVehicleInfo vehicle in shared.vehicle) { if (vehicle.isPlayer == 1) { return(vehicle); } } throw new Exception("no vehicle for player!"); }
public void trigger(Object lastStateObj, Object currentStateObj, GameStateData currentGameState) { if (paused) { return; } rfShared lastState = ((CrewChiefV4.rFactor1.RF1SharedMemoryReader.RF1StructWrapper)lastStateObj).data; rfShared currentState = ((CrewChiefV4.rFactor1.RF1SharedMemoryReader.RF1StructWrapper)currentStateObj).data; if (!enabled || currentState.currentET < timeAfterRaceStartToActivate || currentState.inRealtime == 0 || (currentState.numVehicles <= 2)) { return; } DateTime now = DateTime.Now; rfVehicleInfo currentPlayerData; rfVehicleInfo previousPlayerData; float timeDiffSeconds; try { currentPlayerData = getVehicleInfo(currentState); previousPlayerData = getVehicleInfo(lastState); timeDiffSeconds = ((float)(now - previousTime).TotalMilliseconds) / 1000f; previousTime = now; if (timeDiffSeconds <= 0) { // WTF? return; } } catch (Exception) { return; } if (currentGameState != null) { var carClass = currentGameState.carClass; if (carClass != null && !String.Equals(currentPlayerCarClassID, carClass.getClassIdentifier())) { // Retrieve and use user overridable spotter car length/width. currentPlayerCarClassID = carClass.getClassIdentifier(); var preferences = carClass.getPreferences(); this.internalSpotter.setCarDimensions(preferences.spotterVehicleLength, preferences.spotterVehicleWidth); } } float[] currentPlayerPosition = new float[] { currentPlayerData.pos.x, currentPlayerData.pos.z }; if (currentPlayerData.inPits == 0 && currentPlayerData.control == (int)rFactor1Constant.rfControl.player && // turn off spotter for formation lap before going green !(currentState.gamePhase == (int)rFactor1Constant.rfGamePhase.formation)) { List <float[]> currentOpponentPositions = new List <float[]>(); float[] playerVelocityData = new float[3]; playerVelocityData[0] = currentState.speed; playerVelocityData[1] = (currentPlayerData.pos.x - previousPlayerData.pos.x) / timeDiffSeconds; playerVelocityData[2] = (currentPlayerData.pos.z - previousPlayerData.pos.z) / timeDiffSeconds; for (int i = 0; i < currentState.numVehicles; i++) { rfVehicleInfo vehicle = currentState.vehicle[i]; if (vehicle.isPlayer == 1 || vehicle.inPits == 1 || vehicle.lapDist < 0) { continue; } currentOpponentPositions.Add(new float[] { vehicle.pos.x, vehicle.pos.z }); } float playerRotation = (float)(Math.Atan2((double)(currentState.oriZ.x), (double)(currentState.oriZ.z))); if (playerRotation < 0) { playerRotation = (float)(2 * Math.PI) + playerRotation; } internalSpotter.triggerInternal(playerRotation, currentPlayerPosition, playerVelocityData, currentOpponentPositions); } }