From d66306cf7105e28882feba304fdf96cc0b32eddb Mon Sep 17 00:00:00 2001 From: hodasemi Date: Mon, 16 Jan 2023 22:28:54 +0100 Subject: [PATCH] Update cs reference --- rfactor_plugin/RF2Data.cs | 881 ++++++++++++++++++++++++-------------- src/lib.rs | 2 +- 2 files changed, 554 insertions(+), 329 deletions(-) diff --git a/rfactor_plugin/RF2Data.cs b/rfactor_plugin/RF2Data.cs index e60574b..7687f03 100644 --- a/rfactor_plugin/RF2Data.cs +++ b/rfactor_plugin/RF2Data.cs @@ -7,13 +7,14 @@ See: MainForm.MainUpdate for sample on how to marshall from native in memory str Author: The Iron Wolf (vleonavicius@hotmail.com) Website: thecrewchief.org */ +using Newtonsoft.Json; using System; using System.Runtime.InteropServices; using System.Xml.Serialization; -// CC specific: Mark more common unused members with XmlIgnore for reduced trace sizes. +// CC specific: Mark more common unused members with JsonIgnore for reduced trace sizes. -namespace CrewChiefV4.rFactor2 +namespace rF2SharedMemory { // Marshalled types: // C++ C# @@ -22,17 +23,32 @@ namespace CrewChiefV4.rFactor2 // signed char -> sbyte // bool -> byte // long -> int - // ULONGLONG -> Int64 // unsigned long -> uint + // short -> short + // unsigned short -> ushort + // ULONGLONG -> Int64 public class rFactor2Constants { public const string MM_TELEMETRY_FILE_NAME = "$rFactor2SMMP_Telemetry$"; public const string MM_SCORING_FILE_NAME = "$rFactor2SMMP_Scoring$"; public const string MM_RULES_FILE_NAME = "$rFactor2SMMP_Rules$"; + public const string MM_FORCE_FEEDBACK_FILE_NAME = "$rFactor2SMMP_ForceFeedback$"; + public const string MM_GRAPHICS_FILE_NAME = "$rFactor2SMMP_Graphics$"; + public const string MM_PITINFO_FILE_NAME = "$rFactor2SMMP_PitInfo$"; + public const string MM_WEATHER_FILE_NAME = "$rFactor2SMMP_Weather$"; public const string MM_EXTENDED_FILE_NAME = "$rFactor2SMMP_Extended$"; + public const string MM_HWCONTROL_FILE_NAME = "$rFactor2SMMP_HWControl$"; + public const int MM_HWCONTROL_LAYOUT_VERSION = 1; + + public const string MM_WEATHER_CONTROL_FILE_NAME = "$rFactor2SMMP_WeatherControl$"; + public const int MM_WEATHER_CONTROL_LAYOUT_VERSION = 1; + public const int MAX_MAPPED_VEHICLES = 128; public const int MAX_MAPPED_IDS = 512; + public const int MAX_STATUS_MSG_LEN = 128; + public const int MAX_RULES_INSTRUCTION_MSG_LEN = 96; + public const int MAX_HWCONTROL_NAME_LEN = 96; public const string RFACTOR2_PROCESS_NAME = "rFactor2"; public const byte RowX = 0; @@ -48,6 +64,7 @@ namespace CrewChiefV4.rFactor2 // 6 Full course yellow / safety car // 7 Session stopped // 8 Session over + // 9 Paused (tag.2015.09.14 - this is new, and indicates that this is a heartbeat call to the plugin) public enum rF2GamePhase { Garage = 0, @@ -59,7 +76,7 @@ namespace CrewChiefV4.rFactor2 FullCourseYellow = 6, SessionStopped = 7, SessionOver = 8, - Undocumented_PreRace = 9 // I suspect 9 means we're in a garage/monitor, waiting for race to start. + PausedOrHeartbeat = 9 } // Yellow flag states (applies to full-course only) @@ -163,7 +180,7 @@ namespace CrewChiefV4.rFactor2 { Disallowed = 0, DetectedButNotAllowedYet = 1, - Alllowed = 2 + Allowed = 2 } // 0=off 1=ignition 2=ignition+starter @@ -173,6 +190,14 @@ namespace CrewChiefV4.rFactor2 Ignition = 1, IgnitionAndStarter = 2 } + + // 0=no change, 1=go active, 2=head for pits + public enum rF2SafetyCarInstruction + { + NoChange = 0, + GoActive = 1, + HeadForPits = 2 + } } namespace rFactor2Data @@ -187,45 +212,44 @@ namespace CrewChiefV4.rFactor2 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2Wheel { - [XmlIgnore] public double mSuspensionDeflection; // meters - [XmlIgnore] public double mRideHeight; // meters - [XmlIgnore] public double mSuspForce; // pushrod load in Newtons - public double mBrakeTemp; // Celsius - [XmlIgnore] public double mBrakePressure; // currently 0.0-1.0, depending on driver input and brake balance; will convert to true brake pressure (kPa) in future - public double mRotation; // radians/sec - [XmlIgnore] public double mLateralPatchVel; // lateral velocity at contact patch - [XmlIgnore] public double mLongitudinalPatchVel; // longitudinal velocity at contact patch - [XmlIgnore] public double mLateralGroundVel; // lateral velocity at contact patch - [XmlIgnore] public double mLongitudinalGroundVel; // longitudinal velocity at contact patch - [XmlIgnore] public double mCamber; // radians (positive is left for left-side wheels, right for right-side wheels) - [XmlIgnore] public double mLateralForce; // Newtons - [XmlIgnore] public double mLongitudinalForce; // Newtons - [XmlIgnore] public double mTireLoad; // Newtons + [JsonIgnore] public double mSuspensionDeflection; // meters + [JsonIgnore] public double mRideHeight; // meters + [JsonIgnore] public double mSuspForce; // pushrod load in Newtons + public double mBrakeTemp; // Celsius + [JsonIgnore] public double mBrakePressure; // currently 0.0-1.0, depending on driver input and brake balance; will convert to true brake pressure (kPa) in future - [XmlIgnore] public double mGripFract; // an approximation of what fraction of the contact patch is sliding - public double mPressure; // kPa (tire pressure) + public double mRotation; // radians/sec + [JsonIgnore] public double mLateralPatchVel; // lateral velocity at contact patch + [JsonIgnore] public double mLongitudinalPatchVel; // longitudinal velocity at contact patch + [JsonIgnore] public double mLateralGroundVel; // lateral velocity at contact patch + [JsonIgnore] public double mLongitudinalGroundVel; // longitudinal velocity at contact patch + [JsonIgnore] public double mCamber; // radians (positive is left for left-side wheels, right for right-side wheels) + [JsonIgnore] public double mLateralForce; // Newtons + [JsonIgnore] public double mLongitudinalForce; // Newtons + [JsonIgnore] public double mTireLoad; // Newtons + [JsonIgnore] public double mGripFract; // an approximation of what fraction of the contact patch is sliding + public double mPressure; // kPa (tire pressure) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - public double[] mTemperature; // Kelvin (subtract 273.15 to get Celsius), left/center/right (not to be confused with inside/center/outside!) - public double mWear; // wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss - + public double[] mTemperature; // Kelvin (subtract 273.15 to get Celsius), left/center/right (not to be confused with inside/center/outside!) + public double mWear; // wear (0.0-1.0, fraction of maximum) ... this is not necessarily proportional with grip loss [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 16)] - [XmlIgnore] public byte[] mTerrainName; // the material prefixes from the TDF file - public byte mSurfaceType; // 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip, 6=special - public byte mFlat; // whether tire is flat - public byte mDetached; // whether wheel is detached + [JsonIgnore] public byte[] mTerrainName; // the material prefixes from the TDF file + public byte mSurfaceType; // 0=dry, 1=wet, 2=grass, 3=dirt, 4=gravel, 5=rumblestrip, 6=special + public byte mFlat; // whether tire is flat + public byte mDetached; // whether wheel is detached + public byte mStaticUndeflectedRadius; // tire radius in centimeters - [XmlIgnore] public double mVerticalTireDeflection;// how much is tire deflected from its (speed-sensitive) radius - [XmlIgnore] public double mWheelYLocation; // wheel's y location relative to vehicle y location - [XmlIgnore] public double mToe; // current toe angle w.r.t. the vehicle - - [XmlIgnore] public double mTireCarcassTemperature; // rough average of temperature samples from carcass (Kelvin) + [JsonIgnore] public double mVerticalTireDeflection; // how much is tire deflected from its (speed-sensitive) radius + [JsonIgnore] public double mWheelYLocation; // wheel's y location relative to vehicle y location + [JsonIgnore] public double mToe; // current toe angle w.r.t. the vehicle + [JsonIgnore] public double mTireCarcassTemperature; // rough average of temperature samples from carcass (Kelvin) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - [XmlIgnore] public double[] mTireInnerLayerTemperature; // rough average of temperature samples from innermost layer of rubber (before carcass) (Kelvin) + [JsonIgnore] public double[] mTireInnerLayerTemperature; // rough average of temperature samples from innermost layer of rubber (before carcass) (Kelvin) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 24)] - [XmlIgnore] byte[] mExpansion; // for future use + [JsonIgnore] byte[] mExpansion; // for future use } @@ -233,121 +257,110 @@ namespace CrewChiefV4.rFactor2 public struct rF2VehicleTelemetry { // Time - public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) - [XmlIgnore] public double mDeltaTime; // time since last update (seconds) - public double mElapsedTime; // game session time - [XmlIgnore] public int mLapNumber; // current lap number - [XmlIgnore] public double mLapStartET; // time this lap was started - + public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) + [JsonIgnore] public double mDeltaTime; // time since last update (seconds) + public double mElapsedTime; // game session time + [JsonIgnore] public int mLapNumber; // current lap number + [JsonIgnore] public double mLapStartET; // time this lap was started [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64)] - [XmlIgnore] public byte[] mVehicleName; // current vehicle name - + [JsonIgnore] public byte[] mVehicleName; // current vehicle name [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64)] - [XmlIgnore] public byte[] mTrackName; // current track name + [JsonIgnore] public byte[] mTrackName; // current track name // Position and derivatives - public rF2Vec3 mPos; // world position in meters - public rF2Vec3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates - [XmlIgnore] public rF2Vec3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates + public rF2Vec3 mPos; // world position in meters + public rF2Vec3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates + [JsonIgnore] public rF2Vec3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates // Orientation and derivatives [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - public rF2Vec3[] mOri; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local - // vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively - - [XmlIgnore] public rF2Vec3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates - - [XmlIgnore] public rF2Vec3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates + public rF2Vec3[] mOri; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local + // vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively + [JsonIgnore] public rF2Vec3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates + [JsonIgnore] public rF2Vec3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates // Vehicle status - public int mGear; // -1=reverse, 0=neutral, 1+=forward gears - public double mEngineRPM; // engine RPM - public double mEngineWaterTemp; // Celsius - public double mEngineOilTemp; // Celsius - [XmlIgnore] public double mClutchRPM; // clutch RPM + public int mGear; // -1=reverse, 0=neutral, 1+=forward gears + public double mEngineRPM; // engine RPM + public double mEngineWaterTemp; // Celsius + public double mEngineOilTemp; // Celsius + [JsonIgnore] public double mClutchRPM; // clutch RPM // Driver input - public double mUnfilteredThrottle; // ranges 0.0-1.0 - public double mUnfilteredBrake; // ranges 0.0-1.0 - [XmlIgnore] public double mUnfilteredSteering; // ranges -1.0-1.0 (left to right) - public double mUnfilteredClutch; // ranges 0.0-1.0 + public double mUnfilteredThrottle; // ranges 0.0-1.0 + public double mUnfilteredBrake; // ranges 0.0-1.0 + [JsonIgnore] public double mUnfilteredSteering; // ranges -1.0-1.0 (left to right) + public double mUnfilteredClutch; // ranges 0.0-1.0 // Filtered input (various adjustments for rev or speed limiting, TC, ABS?, speed sensitive steering, clutch work for semi-automatic shifting, etc.) - [XmlIgnore] public double mFilteredThrottle; // ranges 0.0-1.0 - [XmlIgnore] public double mFilteredBrake; // ranges 0.0-1.0 - [XmlIgnore] public double mFilteredSteering; // ranges -1.0-1.0 (left to right) - [XmlIgnore] public double mFilteredClutch; // ranges 0.0-1.0 + [JsonIgnore] public double mFilteredThrottle; // ranges 0.0-1.0 + [JsonIgnore] public double mFilteredBrake; // ranges 0.0-1.0 + [JsonIgnore] public double mFilteredSteering; // ranges -1.0-1.0 (left to right) + [JsonIgnore] public double mFilteredClutch; // ranges 0.0-1.0 // Misc - [XmlIgnore] public double mSteeringShaftTorque; // torque around steering shaft (used to be mSteeringArmForce, but that is not necessarily accurate for feedback purposes) - [XmlIgnore] public double mFront3rdDeflection; // deflection at front 3rd spring - [XmlIgnore] public double mRear3rdDeflection; // deflection at rear 3rd spring + [JsonIgnore] public double mSteeringShaftTorque; // torque around steering shaft (used to be mSteeringArmForce, but that is not necessarily accurate for feedback purposes) + [JsonIgnore] public double mFront3rdDeflection; // deflection at front 3rd spring + [JsonIgnore] public double mRear3rdDeflection; // deflection at rear 3rd spring // Aerodynamics - [XmlIgnore] public double mFrontWingHeight; // front wing height - [XmlIgnore] public double mFrontRideHeight; // front ride height - [XmlIgnore] public double mRearRideHeight; // rear ride height - [XmlIgnore] public double mDrag; // drag - [XmlIgnore] public double mFrontDownforce; // front downforce - [XmlIgnore] public double mRearDownforce; // rear downforce + [JsonIgnore] public double mFrontWingHeight; // front wing height + [JsonIgnore] public double mFrontRideHeight; // front ride height + [JsonIgnore] public double mRearRideHeight; // rear ride height + [JsonIgnore] public double mDrag; // drag + [JsonIgnore] public double mFrontDownforce; // front downforce + [JsonIgnore] public double mRearDownforce; // rear downforce // State/damage info - public double mFuel; // amount of fuel (liters) - public double mEngineMaxRPM; // rev limit - public byte mScheduledStops; // number of scheduled pitstops - public byte mOverheating; // whether overheating icon is shown - public byte mDetached; // whether any parts (besides wheels) have been detached - [XmlIgnore] public byte mHeadlights; // whether headlights are on - - // mDentSeverity is always zero as of 7/3/2017. + public double mFuel; // amount of fuel (liters) + public double mEngineMaxRPM; // rev limit + public byte mScheduledStops; // number of scheduled pitstops + public byte mOverheating; // whether overheating icon is shown + public byte mDetached; // whether any parts (besides wheels) have been detached + [JsonIgnore] public byte mHeadlights; // whether headlights are on [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - [XmlIgnore] public byte[] mDentSeverity;// dent severity at 8 locations around the car (0=none, 1=some, 2=more) - public double mLastImpactET; // time of last impact - [XmlIgnore] public double mLastImpactMagnitude; // magnitude of last impact - [XmlIgnore] public rF2Vec3 mLastImpactPos; // location of last impact + [JsonIgnore] public byte[] mDentSeverity; // dent severity at 8 locations around the car (0=none, 1=some, 2=more) + public double mLastImpactET; // time of last impact + [JsonIgnore] public double mLastImpactMagnitude; // magnitude of last impact + [JsonIgnore] public rF2Vec3 mLastImpactPos; // location of last impact // Expanded - [XmlIgnore] public double mEngineTorque; // current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it) - [XmlIgnore] public int mCurrentSector; // the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002) - public byte mSpeedLimiter; // whether speed limiter is on - [XmlIgnore] public byte mMaxGears; // maximum forward gears - public byte mFrontTireCompoundIndex; // index within brand - [XmlIgnore] public byte mRearTireCompoundIndex; // index within brand - [XmlIgnore] public double mFuelCapacity; // capacity in liters - [XmlIgnore] public byte mFrontFlapActivated; // whether front flap is activated - public byte mRearFlapActivated; // whether rear flap is activated - public byte mRearFlapLegalStatus; // 0=disallowed, 1=criteria detected but not allowed quite yet, 2=allowed - [XmlIgnore] public byte mIgnitionStarter; // 0=off 1=ignition 2=ignition+starter + [JsonIgnore] public double mEngineTorque; // current engine torque (including additive torque) (used to be mEngineTq, but there's little reason to abbreviate it) + [JsonIgnore] public int mCurrentSector; // the current sector (zero-based) with the pitlane stored in the sign bit (example: entering pits from third sector gives 0x80000002) + public byte mSpeedLimiter; // whether speed limiter is on + [JsonIgnore] public byte mMaxGears; // maximum forward gears + public byte mFrontTireCompoundIndex; // index within brand + [JsonIgnore] public byte mRearTireCompoundIndex; // index within brand + [JsonIgnore] public double mFuelCapacity; // capacity in liters + [JsonIgnore] public byte mFrontFlapActivated; // whether front flap is activated + public byte mRearFlapActivated; // whether rear flap is activated + public byte mRearFlapLegalStatus; // 0=disallowed, 1=criteria detected but not allowed quite yet, 2=allowed + [JsonIgnore] public byte mIgnitionStarter; // 0=off 1=ignition 2=ignition+starter [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 18)] - public byte[] mFrontTireCompoundName; // name of front tire compound - + public byte[] mFrontTireCompoundName; // name of front tire compound [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 18)] - [XmlIgnore] public byte[] mRearTireCompoundName; // name of rear tire compound - - public byte mSpeedLimiterAvailable; // whether speed limiter is available - [XmlIgnore] public byte mAntiStallActivated; // whether (hard) anti-stall is activated + [JsonIgnore] public byte[] mRearTireCompoundName; // name of rear tire compound + public byte mSpeedLimiterAvailable; // whether speed limiter is available + [JsonIgnore] public byte mAntiStallActivated; // whether (hard) anti-stall is activated [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)] - [XmlIgnore] public byte[] mUnused; // - - [XmlIgnore] public float mVisualSteeringWheelRange; // the *visual* steering wheel range - - [XmlIgnore] public double mRearBrakeBias; // fraction of brakes on rear - [XmlIgnore] public double mTurboBoostPressure; // current turbo boost pressure if available + [JsonIgnore] public byte[] mUnused; // + [JsonIgnore] public float mVisualSteeringWheelRange; // the *visual* steering wheel range + [JsonIgnore] public double mRearBrakeBias; // fraction of brakes on rear + [JsonIgnore] public double mTurboBoostPressure; // current turbo boost pressure if available [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - [XmlIgnore] public float[] mPhysicsToGraphicsOffset; // offset from static CG to graphical center - - [XmlIgnore] public float mPhysicalSteeringWheelRange; // the *physical* steering wheel range + [JsonIgnore] public float[] mPhysicsToGraphicsOffset; // offset from static CG to graphical center + [JsonIgnore] public float mPhysicalSteeringWheelRange; // the *physical* steering wheel range // Future use [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 152)] - [XmlIgnore] public byte[] mExpansion; // for future use (note that the slot ID has been moved to mID above) + [JsonIgnore] public byte[] mExpansion; // for future use (note that the slot ID has been moved to mID above) // keeping this at the end of the structure to make it easier to replace in future versions [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)] - public rF2Wheel[] mWheels; // wheel info (front left, front right, rear left, rear right) + public rF2Wheel[] mWheels; // wheel info (front left, front right, rear left, rear right) } @@ -355,19 +368,19 @@ namespace CrewChiefV4.rFactor2 public struct rF2ScoringInfo { [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64)] - public byte[] mTrackName; // current track name - public int mSession; // current session (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race) - public double mCurrentET; // current time - public double mEndET; // ending time - public int mMaxLaps; // maximum laps - public double mLapDist; // distance around track - // MM_NOT_USED - //char *mResultsStream; // results stream additions since last update (newline-delimited and NULL-terminated) - // MM_NEW + public byte[] mTrackName; // current track name + public int mSession; // current session (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race) + public double mCurrentET; // current time + public double mEndET; // ending time + public int mMaxLaps; // maximum laps + public double mLapDist; // distance around track + // MM_NOT_USED + //char *mResultsStream; // results stream additions since last update (newline-delimited and NULL-terminated) + // MM_NEW [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - [XmlIgnore] public byte[] pointer1; + [JsonIgnore] public byte[] pointer1; - public int mNumVehicles; // current number of vehicles + public int mNumVehicles; // current number of vehicles // Game phases: // 0 Before session has begun @@ -379,6 +392,7 @@ namespace CrewChiefV4.rFactor2 // 6 Full course yellow / safety car // 7 Session stopped // 8 Session over + // 9 Paused (tag.2015.09.14 - this is new, and indicates that this is a heartbeat call to the plugin) public byte mGamePhase; // Yellow flag states (applies to full-course only) @@ -394,162 +408,171 @@ namespace CrewChiefV4.rFactor2 public sbyte mYellowFlagState; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - public sbyte[] mSectorFlag; // whether there are any local yellows at the moment in each sector (not sure if sector 0 is first or last, so test) - [XmlIgnore] public byte mStartLight; // start light frame (number depends on track) - [XmlIgnore] public byte mNumRedLights; // number of red lights in start sequence - public byte mInRealtime; // in realtime as opposed to at the monitor - + public sbyte[] mSectorFlag; // whether there are any local yellows at the moment in each sector (not sure if sector 0 is first or last, so test) + [JsonIgnore] public byte mStartLight; // start light frame (number depends on track) + [JsonIgnore] public byte mNumRedLights; // number of red lights in start sequence + public byte mInRealtime; // in realtime as opposed to at the monitor [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] - [XmlIgnore] public byte[] mPlayerName; // player name (including possible multiplayer override) - + [JsonIgnore] public byte[] mPlayerName; // player name (including possible multiplayer override) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64)] - [XmlIgnore] public byte[] mPlrFileName; // may be encoded to be a legal filename + [JsonIgnore] public byte[] mPlrFileName; // may be encoded to be a legal filename // weather - [XmlIgnore] public double mDarkCloud; // cloud darkness? 0.0-1.0 - public double mRaining; // raining severity 0.0-1.0 - public double mAmbientTemp; // temperature (Celsius) - public double mTrackTemp; // temperature (Celsius) - public rF2Vec3 mWind; // wind speed - [XmlIgnore] public double mMinPathWetness; // minimum wetness on main path 0.0-1.0 - [XmlIgnore] public double mMaxPathWetness; // maximum wetness on main path 0.0-1.0 + [JsonIgnore] public double mDarkCloud; // cloud darkness? 0.0-1.0 + public double mRaining; // raining severity 0.0-1.0 + public double mAmbientTemp; // temperature (Celsius) + public double mTrackTemp; // temperature (Celsius) + public rF2Vec3 mWind; // wind speed + [JsonIgnore] public double mMinPathWetness; // minimum wetness on main path 0.0-1.0 + [JsonIgnore] public double mMaxPathWetness; // maximum wetness on main path 0.0-1.0 + + // multiplayer + public byte mGameMode; // 1 = server, 2 = client, 3 = server and client + [JsonIgnore] public byte mIsPasswordProtected; // is the server password protected + [JsonIgnore] public ushort mServerPort; // the port of the server (if on a server) + [JsonIgnore] public uint mServerPublicIP; // the public IP address of the server (if on a server) + [JsonIgnore] public int mMaxPlayers; // maximum number of vehicles that can be in the session + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] + [JsonIgnore] public byte[] mServerName; // name of the server + [JsonIgnore] public float mStartET; // start time (seconds since midnight) of the event + + [JsonIgnore] public double mAvgPathWetness; // average wetness on main path 0.0-1.0 // Future use - [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)] - [XmlIgnore] public byte[] mExpansion; + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 200)] + [JsonIgnore] public byte[] mExpansion; // MM_NOT_USED // keeping this at the end of the structure to make it easier to replace in future versions - // VehicleScoringInfoV01 *mVehicle; // array of vehicle scoring info's + // VehicleScoringInfoV01 *mVehicle; // array of vehicle scoring info's // MM_NEW [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - [XmlIgnore] public byte[] pointer2; + [JsonIgnore] public byte[] pointer2; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2VehicleScoring { - public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) - + public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] mDriverName; // driver name - + public byte[] mDriverName; // driver name [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64)] - [XmlIgnore] public byte[] mVehicleName; // vehicle name + [JsonIgnore] public byte[] mVehicleName; // vehicle name + public short mTotalLaps; // laps completed + public sbyte mSector; // 0=sector3, 1=sector1, 2=sector2 (don't ask why) + public sbyte mFinishStatus; // 0=none, 1=finished, 2=dnf, 3=dq + public double mLapDist; // current distance around track + public double mPathLateral; // lateral position with respect to *very approximate* "center" path + public double mTrackEdge; // track edge (w.r.t. "center" path) on same side of track as vehicle - public short mTotalLaps; // laps completed - public sbyte mSector; // 0=sector3, 1=sector1, 2=sector2 (don't ask why) - public sbyte mFinishStatus; // 0=none, 1=finished, 2=dnf, 3=dq - public double mLapDist; // current distance around track - public double mPathLateral; // lateral position with respect to *very approximate* "center" path - public double mTrackEdge; // track edge (w.r.t. "center" path) on same side of track as vehicle + public double mBestSector1; // best sector 1 + public double mBestSector2; // best sector 2 (plus sector 1) + public double mBestLapTime; // best lap time + public double mLastSector1; // last sector 1 + public double mLastSector2; // last sector 2 (plus sector 1) + public double mLastLapTime; // last lap time + public double mCurSector1; // current sector 1 if valid + public double mCurSector2; // current sector 2 (plus sector 1) if valid + // no current laptime because it instantly becomes "last" - public double mBestSector1; // best sector 1 - public double mBestSector2; // best sector 2 (plus sector 1) - public double mBestLapTime; // best lap time - public double mLastSector1; // last sector 1 - public double mLastSector2; // last sector 2 (plus sector 1) - public double mLastLapTime; // last lap time - public double mCurSector1; // current sector 1 if valid - public double mCurSector2; // current sector 2 (plus sector 1) if valid - // no current laptime because it instantly becomes "last" + public short mNumPitstops; // number of pitstops made + public short mNumPenalties; // number of outstanding penalties + public byte mIsPlayer; // is this the player's vehicle - public short mNumPitstops; // number of pitstops made - public short mNumPenalties; // number of outstanding penalties - public byte mIsPlayer; // is this the player's vehicle - - public sbyte mControl; // who's in control: -1=nobody (shouldn't get this), 0=local player, 1=local AI, 2=remote, 3=replay (shouldn't get this) - public byte mInPits; // between pit entrance and pit exit (not always accurate for remote vehicles) - public byte mPlace; // 1-based position + public sbyte mControl; // who's in control: -1=nobody (shouldn't get this), 0=local player, 1=local AI, 2=remote, 3=replay (shouldn't get this) + public byte mInPits; // between pit entrance and pit exit (not always accurate for remote vehicles) + public byte mPlace; // 1-based position [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] mVehicleClass; // vehicle class + public byte[] mVehicleClass; // vehicle class // Dash Indicators - public double mTimeBehindNext; // time behind vehicle in next higher place - [XmlIgnore] public int mLapsBehindNext; // laps behind vehicle in next higher place - [XmlIgnore] public double mTimeBehindLeader; // time behind leader - [XmlIgnore] public int mLapsBehindLeader; // laps behind leader - public double mLapStartET; // time this lap was started + public double mTimeBehindNext; // time behind vehicle in next higher place + [JsonIgnore] public int mLapsBehindNext; // laps behind vehicle in next higher place + [JsonIgnore] public double mTimeBehindLeader; // time behind leader + [JsonIgnore] public int mLapsBehindLeader; // laps behind leader + public double mLapStartET; // time this lap was started // Position and derivatives - [XmlIgnore] public rF2Vec3 mPos; // world position in meters - // TODO: remove these serialization, once we use telemetry - public rF2Vec3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates - public rF2Vec3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates + [JsonIgnore] public rF2Vec3 mPos; // world position in meters + public rF2Vec3 mLocalVel; // velocity (meters/sec) in local vehicle coordinates + public rF2Vec3 mLocalAccel; // acceleration (meters/sec^2) in local vehicle coordinates // Orientation and derivatives [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - [XmlIgnore] public rF2Vec3[] mOri; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local - // vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively - - [XmlIgnore] public rF2Vec3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates - - [XmlIgnore] public rF2Vec3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates + [JsonIgnore] public rF2Vec3[] mOri; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local + // vehicle vectors into world X, Y, or Z using dot product of rows 0, 1, or 2 respectively + [JsonIgnore] public rF2Vec3 mLocalRot; // rotation (radians/sec) in local vehicle coordinates + [JsonIgnore] public rF2Vec3 mLocalRotAccel; // rotational acceleration (radians/sec^2) in local vehicle coordinates // tag.2012.03.01 - stopped casting some of these so variables now have names and mExpansion has shrunk, overall size and old data locations should be same - [XmlIgnore] public byte mHeadlights; // status of headlights - public byte mPitState; // 0=none, 1=request, 2=entering, 3=stopped, 4=exiting - [XmlIgnore] public byte mServerScored; // whether this vehicle is being scored by server (could be off in qualifying or racing heats) - [XmlIgnore] public byte mIndividualPhase;// game phases (described below) plus 9=after formation, 10=under yellow, 11=under blue (not used) + [JsonIgnore] public byte mHeadlights; // status of headlights + public byte mPitState; // 0=none, 1=request, 2=entering, 3=stopped, 4=exiting + [JsonIgnore] public byte mServerScored; // whether this vehicle is being scored by server (could be off in qualifying or racing heats) + [JsonIgnore] public byte mIndividualPhase; // game phases (described below) plus 9=after formation, 10=under yellow, 11=under blue (not used) - [XmlIgnore] public int mQualification; // 1-based, can be -1 when invalid + [JsonIgnore] public int mQualification; // 1-based, can be -1 when invalid - [XmlIgnore] public double mTimeIntoLap; // estimated time into lap - [XmlIgnore] public double mEstimatedLapTime; // estimated laptime used for 'time behind' and 'time into lap' (note: this may changed based on vehicle and setup!?) + [JsonIgnore] public double mTimeIntoLap; // estimated time into lap + [JsonIgnore] public double mEstimatedLapTime; // estimated laptime used for 'time behind' and 'time into lap' (note: this may changed based on vehicle and setup!?) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 24)] - [XmlIgnore] public byte[] mPitGroup; // pit group (same as team name unless pit is shared) - public byte mFlag; // primary flag being shown to vehicle (currently only 0=green or 6=blue) - [XmlIgnore] public byte mUnderYellow; // whether this car has taken a full-course caution flag at the start/finish line - public byte mCountLapFlag; // 0 = do not count lap or time, 1 = count lap but not time, 2 = count lap and time - public byte mInGarageStall; // appears to be within the correct garage stall + [JsonIgnore] public byte[] mPitGroup; // pit group (same as team name unless pit is shared) + public byte mFlag; // primary flag being shown to vehicle (currently only 0=green or 6=blue) + [JsonIgnore] public byte mUnderYellow; // whether this car has taken a full-course caution flag at the start/finish line + public byte mCountLapFlag; // 0 = do not count lap or time, 1 = count lap but not time, 2 = count lap and time + public byte mInGarageStall; // appears to be within the correct garage stall [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 16)] - [XmlIgnore] public byte[] mUpgradePack; // Coded upgrades + [JsonIgnore] public byte[] mUpgradePack; // Coded upgrades + + public float mPitLapDist; // location of pit in terms of lap distance + + [JsonIgnore] public float mBestLapSector1; // sector 1 time from best lap (not necessarily the best sector 1 time) + [JsonIgnore] public float mBestLapSector2; // sector 2 time from best lap (not necessarily the best sector 2 time) // Future use // tag.2012.04.06 - SEE ABOVE! - [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 60)] - [XmlIgnore] public byte[] mExpansion; // for future use + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 48)] + [JsonIgnore] public byte[] mExpansion; // for future use } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2PhysicsOptions { - [XmlIgnore] public byte mTractionControl; // 0 (off) - 3 (high) - [XmlIgnore] public byte mAntiLockBrakes; // 0 (off) - 2 (high) - [XmlIgnore] public byte mStabilityControl; // 0 (off) - 2 (high) - [XmlIgnore] public byte mAutoShift; // 0 (off), 1 (upshifts), 2 (downshifts), 3 (all) - [XmlIgnore] public byte mAutoClutch; // 0 (off), 1 (on) - public byte mInvulnerable; // 0 (off), 1 (on) - [XmlIgnore] public byte mOppositeLock; // 0 (off), 1 (on) - [XmlIgnore] public byte mSteeringHelp; // 0 (off) - 3 (high) - [XmlIgnore] public byte mBrakingHelp; // 0 (off) - 2 (high) - [XmlIgnore] public byte mSpinRecovery; // 0 (off), 1 (on) - [XmlIgnore] public byte mAutoPit; // 0 (off), 1 (on) - [XmlIgnore] public byte mAutoLift; // 0 (off), 1 (on) - [XmlIgnore] public byte mAutoBlip; // 0 (off), 1 (on) + [JsonIgnore] public byte mTractionControl; // 0 (off) - 3 (high) + [JsonIgnore] public byte mAntiLockBrakes; // 0 (off) - 2 (high) + [JsonIgnore] public byte mStabilityControl; // 0 (off) - 2 (high) + [JsonIgnore] public byte mAutoShift; // 0 (off), 1 (upshifts), 2 (downshifts), 3 (all) + [JsonIgnore] public byte mAutoClutch; // 0 (off), 1 (on) + public byte mInvulnerable; // 0 (off), 1 (on) + [JsonIgnore] public byte mOppositeLock; // 0 (off), 1 (on) + [JsonIgnore] public byte mSteeringHelp; // 0 (off) - 3 (high) + [JsonIgnore] public byte mBrakingHelp; // 0 (off) - 2 (high) + [JsonIgnore] public byte mSpinRecovery; // 0 (off), 1 (on) + [JsonIgnore] public byte mAutoPit; // 0 (off), 1 (on) + [JsonIgnore] public byte mAutoLift; // 0 (off), 1 (on) + [JsonIgnore] public byte mAutoBlip; // 0 (off), 1 (on) - public byte mFuelMult; // fuel multiplier (0x-7x) - [XmlIgnore] public byte mTireMult; // tire wear multiplier (0x-7x) - [XmlIgnore] public byte mMechFail; // mechanical failure setting; 0 (off), 1 (normal), 2 (timescaled) - [XmlIgnore] public byte mAllowPitcrewPush; // 0 (off), 1 (on) - [XmlIgnore] public byte mRepeatShifts; // accidental repeat shift prevention (0-5; see PLR file) - [XmlIgnore] public byte mHoldClutch; // for auto-shifters at start of race: 0 (off), 1 (on) - [XmlIgnore] public byte mAutoReverse; // 0 (off), 1 (on) - [XmlIgnore] public byte mAlternateNeutral; // Whether shifting up and down simultaneously equals neutral + public byte mFuelMult; // fuel multiplier (0x-7x) + [JsonIgnore] public byte mTireMult; // tire wear multiplier (0x-7x) + [JsonIgnore] public byte mMechFail; // mechanical failure setting; 0 (off), 1 (normal), 2 (timescaled) + [JsonIgnore] public byte mAllowPitcrewPush; // 0 (off), 1 (on) + [JsonIgnore] public byte mRepeatShifts; // accidental repeat shift prevention (0-5; see PLR file) + [JsonIgnore] public byte mHoldClutch; // for auto-shifters at start of race: 0 (off), 1 (on) + [JsonIgnore] public byte mAutoReverse; // 0 (off), 1 (on) + [JsonIgnore] public byte mAlternateNeutral; // Whether shifting up and down simultaneously equals neutral // tag.2014.06.09 - yes these are new, but no they don't change the size of the structure nor the address of the other variables in it (because we're just using the existing padding) - [XmlIgnore] public byte mAIControl; // Whether player vehicle is currently under AI control - [XmlIgnore] public byte mUnused1; // - [XmlIgnore] public byte mUnused2; // + [JsonIgnore] public byte mAIControl; // Whether player vehicle is currently under AI control + [JsonIgnore] public byte mUnused1; // + [JsonIgnore] public byte mUnused2; // - [XmlIgnore] public float mManualShiftOverrideTime; // time before auto-shifting can resume after recent manual shift - [XmlIgnore] public float mAutoShiftOverrideTime; // time before manual shifting can resume after recent auto shift - [XmlIgnore] public float mSpeedSensitiveSteering; // 0.0 (off) - 1.0 - [XmlIgnore] public float mSteerRatioSpeed; // speed (m/s) under which lock gets expanded to full + [JsonIgnore] public float mManualShiftOverrideTime; // time before auto-shifting can resume after recent manual shift + [JsonIgnore] public float mAutoShiftOverrideTime; // time before manual shifting can resume after recent auto shift + [JsonIgnore] public float mSpeedSensitiveSteering; // 0.0 (off) - 1.0 + [JsonIgnore] public float mSteerRatioSpeed; // speed (m/s) under which lock gets expanded to full } @@ -579,9 +602,9 @@ namespace CrewChiefV4.rFactor2 public struct rF2TrackRulesAction { // input only - [XmlIgnore] public rF2TrackRulesCommand mCommand; // recommended action - [XmlIgnore] public int mID; // slot ID if applicable - [XmlIgnore] public double mET; // elapsed time that event occurred, if applicable + [JsonIgnore] public rF2TrackRulesCommand mCommand; // recommended action + [JsonIgnore] public int mID; // slot ID if applicable + [JsonIgnore] public double mET; // elapsed time that event occurred, if applicable } @@ -613,29 +636,30 @@ namespace CrewChiefV4.rFactor2 public struct rF2TrackRulesParticipant { // input only - public int mID; // slot ID - [XmlIgnore] public short mFrozenOrder; // 0-based place when caution came out (not valid for formation laps) - public short mPlace; // 1-based place (typically used for the initialization of the formation lap track order) - [XmlIgnore] public float mYellowSeverity; // a rating of how much this vehicle is contributing to a yellow flag (the sum of all vehicles is compared to TrackRulesV01::mSafetyCarThreshold) - [XmlIgnore] public double mCurrentRelativeDistance; // equal to ( ( ScoringInfoV01::mLapDist * this->mRelativeLaps ) + VehicleScoringInfoV01::mLapDist ) + public int mID; // slot ID + [JsonIgnore] public short mFrozenOrder; // 0-based place when caution came out (not valid for formation laps) + public short mPlace; // 1-based place (typically used for the initialization of the formation lap track order) + [JsonIgnore] public float mYellowSeverity; // a rating of how much this vehicle is contributing to a yellow flag (the sum of all vehicles is compared to TrackRulesV01::mSafetyCarThreshold) + [JsonIgnore] public double mCurrentRelativeDistance; // equal to ( ( ScoringInfoV01::mLapDist * this->mRelativeLaps ) + VehicleScoringInfoV01::mLapDist ) // input/output - public int mRelativeLaps; // current formation/caution laps relative to safety car (should generally be zero except when safety car crosses s/f line); this can be decremented to implement 'wave around' or 'beneficiary rule' (a.k.a. 'lucky dog' or 'free pass') - public rF2TrackRulesColumn mColumnAssignment;// which column (line/lane) that participant is supposed to be in - public int mPositionAssignment; // 0-based position within column (line/lane) that participant is supposed to be located at (-1 is invalid) - public byte mAllowedToPit; // whether the rules allow this particular vehicle to enter pits right now + public int mRelativeLaps; // current formation/caution laps relative to safety car (should generally be zero except when safety car crosses s/f line); this can be decremented to implement 'wave around' or 'beneficiary rule' (a.k.a. 'lucky dog' or 'free pass') + public rF2TrackRulesColumn mColumnAssignment; // which column (line/lane) that participant is supposed to be in + public int mPositionAssignment; // 0-based position within column (line/lane) that participant is supposed to be located at (-1 is invalid) + public byte mPitsOpen; // whether the rules allow this particular vehicle to enter pits right now (input is 2=false or 3=true; if you want to edit it, set to 0=false or 1=true) + [JsonIgnore] public byte mUpToSpeed; // while in the frozen order, this flag indicates whether the vehicle can be followed (this should be false for somebody who has temporarily spun and hasn't gotten back up to speed yet) - [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] - [XmlIgnore] public byte[] mUnused; // + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)] + [JsonIgnore] public byte[] mUnused; // - [XmlIgnore] public double mGoalRelativeDistance; // calculated based on where the leader is, and adjusted by the desired column spacing and the column/position assignments + [JsonIgnore] public double mGoalRelativeDistance; // calculated based on where the leader is, and adjusted by the desired column spacing and the column/position assignments [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 96)] - public byte[] mMessage; // a message for this participant to explain what is going on (untranslated; it will get run through translator on client machines) + public byte[] mMessage; // a message for this participant to explain what is going on (untranslated; it will get run through translator on client machines) // future expansion [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 192)] - [XmlIgnore] public byte[] mExpansion; + [JsonIgnore] public byte[] mExpansion; } @@ -661,97 +685,154 @@ namespace CrewChiefV4.rFactor2 public struct rF2TrackRules { // input only - [XmlIgnore] public double mCurrentET; // current time - public rF2TrackRulesStage mStage; // current stage - public rF2TrackRulesColumn mPoleColumn; // column assignment where pole position seems to be located - [XmlIgnore] public int mNumActions; // number of recent actions + [JsonIgnore] public double mCurrentET; // current time + public rF2TrackRulesStage mStage; // current stage + public rF2TrackRulesColumn mPoleColumn; // column assignment where pole position seems to be located + [JsonIgnore] public int mNumActions; // number of recent actions // MM_NOT_USED - // TrackRulesActionV01 *mAction; // array of recent actions + // TrackRulesActionV01 *mAction; // array of recent actions // MM_NEW - [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - [XmlIgnore] public byte[] pointer1; + [JsonIgnore] public byte[] pointer1; - public int mNumParticipants; // number of participants (vehicles) + public int mNumParticipants; // number of participants (vehicles) - [XmlIgnore] public byte mYellowFlagDetected; // whether yellow flag was requested or sum of participant mYellowSeverity's exceeds mSafetyCarThreshold - [XmlIgnore] public byte mYellowFlagLapsWasOverridden; // whether mYellowFlagLaps (below) is an admin request - [XmlIgnore] public byte mSafetyCarExists; // whether safety car even exists - public byte mSafetyCarActive; // whether safety car is active + [JsonIgnore] public byte mYellowFlagDetected; // whether yellow flag was requested or sum of participant mYellowSeverity's exceeds mSafetyCarThreshold + [JsonIgnore] public byte mYellowFlagLapsWasOverridden; // whether mYellowFlagLaps (below) is an admin request (0=no 1=yes 2=clear yellow) - public int mSafetyCarLaps; // number of laps - [XmlIgnore] public float mSafetyCarThreshold; // the threshold at which a safety car is called out (compared to the sum of TrackRulesParticipantV01::mYellowSeverity for each vehicle) - public double mSafetyCarLapDist; // safety car lap distance + [JsonIgnore] public byte mSafetyCarExists; // whether safety car even exists + public byte mSafetyCarActive; // whether safety car is active + public int mSafetyCarLaps; // number of laps + [JsonIgnore] public float mSafetyCarThreshold; // the threshold at which a safety car is called out (compared to the sum of TrackRulesParticipantV01::mYellowSeverity for each vehicle) + public double mSafetyCarLapDist; // safety car lap distance - [XmlIgnore] public float mSafetyCarLapDistAtStart; // where the safety car starts from - public float mPitLaneStartDist; // where the waypoint branch to the pits breaks off (this may not be perfectly accurate) - [XmlIgnore] public float mTeleportLapDist; // the front of the teleport locations (a useful first guess as to where to throw the green flag) + [JsonIgnore] public float mSafetyCarLapDistAtStart; // where the safety car starts from + public float mPitLaneStartDist; // where the waypoint branch to the pits breaks off (this may not be perfectly accurate) + [JsonIgnore] public float mTeleportLapDist; // the front of the teleport locations (a useful first guess as to where to throw the green flag) // future input expansion [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)] - [XmlIgnore] public byte[] mInputExpansion; + [JsonIgnore] public byte[] mInputExpansion; // input/output - [XmlIgnore] public sbyte mYellowFlagState; // see ScoringInfoV01 for values - [XmlIgnore] public short mYellowFlagLaps; // suggested number of laps to run under yellow (may be passed in with admin command) - [XmlIgnore] public int mSafetyCarInstruction; // 0=no change, 1=go active, 2=head for pits - public float mSafetyCarSpeed; // maximum speed at which to drive + [JsonIgnore] public sbyte mYellowFlagState; // see ScoringInfoV01 for values + [JsonIgnore] public short mYellowFlagLaps; // suggested number of laps to run under yellow (may be passed in with admin command) - [XmlIgnore] public float mSafetyCarMinimumSpacing; // minimum spacing behind safety car (-1 to indicate no limit) - [XmlIgnore] public float mSafetyCarMaximumSpacing; // maximum spacing behind safety car (-1 to indicate no limit) - [XmlIgnore] public float mMinimumColumnSpacing; // minimum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced) - [XmlIgnore] public float mMaximumColumnSpacing; // maximum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced) + [JsonIgnore] public int mSafetyCarInstruction; // 0=no change, 1=go active, 2=head for pits + public float mSafetyCarSpeed; // maximum speed at which to drive + [JsonIgnore] public float mSafetyCarMinimumSpacing; // minimum spacing behind safety car (-1 to indicate no limit) + [JsonIgnore] public float mSafetyCarMaximumSpacing; // maximum spacing behind safety car (-1 to indicate no limit) - [XmlIgnore] public float mMinimumSpeed; // minimum speed that anybody should be driving (-1 to indicate no limit) - [XmlIgnore] public float mMaximumSpeed; // maximum speed that anybody should be driving (-1 to indicate no limit) + [JsonIgnore] public float mMinimumColumnSpacing; // minimum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced) + [JsonIgnore] public float mMaximumColumnSpacing; // maximum desired spacing between vehicles in a column (-1 to indicate indeterminate/unenforced) + + [JsonIgnore] public float mMinimumSpeed; // minimum speed that anybody should be driving (-1 to indicate no limit) + [JsonIgnore] public float mMaximumSpeed; // maximum speed that anybody should be driving (-1 to indicate no limit) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 96)] - public byte[] mMessage; // a message for everybody to explain what is going on (which will get run through translator on client machines) + public byte[] mMessage; // a message for everybody to explain what is going on (which will get run through translator on client machines) // MM_NOT_USED - // TrackRulesParticipantV01 *mParticipant; // array of partipants (vehicles) + // TrackRulesParticipantV01 *mParticipant; // array of partipants (vehicles) // MM_NEW [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - [XmlIgnore] public byte[] pointer2; + [JsonIgnore] public byte[] pointer2; // future input/output expansion [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)] - [XmlIgnore] public byte[] mInputOutputExpansion; - }; + [JsonIgnore] public byte[] mInputOutputExpansion; + } + ////////////////////////////////////////////////////////////////////////////////////////// + // Identical to PitMenuV01, except where noted by MM_NEW/MM_NOT_USED comments. + ////////////////////////////////////////////////////////////////////////////////////////// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2PitMenu + { + public int mCategoryIndex; // index of the current category + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] mCategoryName; // name of the current category (untranslated) + public int mChoiceIndex; // index of the current choice (within the current category) + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] mChoiceString; // name of the current choice (may have some translated words) + public int mNumChoices; // total number of choices (0 <= mChoiceIndex < mNumChoices) + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256)] + public byte[] mExpansion; // for future use + } + + + ////////////////////////////////////////////////////////////////////////////////////////// + // Identical to WeatherControlInfoV01, except where noted by MM_NEW/MM_NOT_USED comments. + ////////////////////////////////////////////////////////////////////////////////////////// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2WeatherControlInfo + { + // The current conditions are passed in with the API call. The following ET (Elapsed Time) value should typically be far + // enough in the future that it can be interpolated smoothly, and allow clouds time to roll in before rain starts. In + // other words you probably shouldn't have mCloudiness and mRaining suddenly change from 0.0 to 1.0 and expect that + // to happen in a few seconds without looking crazy. + public double mET; // when you want this weather to take effect + + // mRaining[1][1] is at the origin (2013.12.19 - and currently the only implemented node), while the others + // are spaced at meters where is the maximum absolute value of a track vertex + // coordinate (and is passed into the API call). + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 9)] + public double[] mRaining; // rain (0.0-1.0) at different nodes + + public double mCloudiness; // general cloudiness (0.0=clear to 1.0=dark), will be automatically overridden to help ensure clouds exist over rainy areas + public double mAmbientTempK; // ambient temperature (Kelvin) + public double mWindMaxSpeed; // maximum speed of wind (ground speed, but it affects how fast the clouds move, too) + + public bool mApplyCloudinessInstantly; // preferably we roll the new clouds in, but you can instantly change them now + public bool mUnused1; // + public bool mUnused2; // + public bool mUnused3; // + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 508)] + public byte[] mExpansion; // future use (humidity, pressure, air density, etc.) + } + + + /////////////////////////////////////////// + // Mapped wrapper structures + /////////////////////////////////////////// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2MappedBufferVersionBlock { // If both version variables are equal, buffer is not being written to, or we're extremely unlucky and second check is necessary. // If versions don't match, buffer is being written to, or is incomplete (game crash, or missed transition). - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2MappedBufferVersionBlockWithSize { - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. - [XmlIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. - // 0 means unknown (whole buffer should be considered as updated). + [JsonIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + // 0 means unknown (whole buffer should be considered as updated). } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2Telemetry { - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. - [XmlIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. - // 0 means unknown (whole buffer should be considered as updated). + [JsonIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + // 0 means unknown (whole buffer should be considered as updated). - public int mNumVehicles; // current number of vehicles + public int mNumVehicles; // current number of vehicles [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_MAPPED_VEHICLES)] public rF2VehicleTelemetry[] mVehicles; } @@ -760,10 +841,11 @@ namespace CrewChiefV4.rFactor2 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2Scoring { - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. - [XmlIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + [JsonIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + // 0 means unknown (whole buffer should be considered as updated). public rF2ScoringInfo mScoringInfo; @@ -775,26 +857,103 @@ namespace CrewChiefV4.rFactor2 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2Rules { - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. - [XmlIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + [JsonIgnore] public int mBytesUpdatedHint; // How many bytes of the structure were written during the last update. + // 0 means unknown (whole buffer should be considered as updated). public rF2TrackRules mTrackRules; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_MAPPED_VEHICLES)] - [XmlIgnore] public rF2TrackRulesAction[] mActions; + [JsonIgnore] public rF2TrackRulesAction[] mActions; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_MAPPED_VEHICLES)] public rF2TrackRulesParticipant[] mParticipants; } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2ForceFeedback + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public double mForceValue; // Current FFB value reported via InternalsPlugin::ForceFeedback. + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2GraphicsInfo + { + public rF2Vec3 mCamPos; // camera position + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] + public rF2Vec3[] mCamOri; // rows of orientation matrix (use TelemQuat conversions if desired), also converts local + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] mHWND; // app handle + + public double mAmbientRed; + public double mAmbientGreen; + public double mAmbientBlue; + + public int mID; // slot ID being viewed (-1 if invalid) + + // Camera types (some of these may only be used for *setting* the camera type in WantsToViewVehicle()) + // 0 = TV cockpit + // 1 = cockpit + // 2 = nosecam + // 3 = swingman + // 4 = trackside (nearest) + // 5 = onboard000 + // : + // : + // 1004 = onboard999 + // 1005+ = (currently unsupported, in the future may be able to set/get specific trackside camera) + public int mCameraType; // see above comments for possible values + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 128)] + public byte[] mExpansion; // for future use (possibly camera name) + }; + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2Graphics + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public rF2GraphicsInfo mGraphicsInfo; + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2PitInfo + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public rF2PitMenu mPitMneu; + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + struct rF2Weather + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public double mTrackNodeSize; + public rF2WeatherControlInfo mWeatherInfo; + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct rF2TrackedDamage { - public double mMaxImpactMagnitude; // Max impact magnitude. Tracked on every telemetry update, and reset on visit to pits or Session restart. - public double mAccumulatedImpactMagnitude; // Accumulated impact magnitude. Tracked on every telemetry update, and reset on visit to pits or Session restart. + public double mMaxImpactMagnitude; // Max impact magnitude. Tracked on every telemetry update, and reset on visit to pits or Session restart. + public double mAccumulatedImpactMagnitude; // Accumulated impact magnitude. Tracked on every telemetry update, and reset on visit to pits or Session restart. }; @@ -802,10 +961,10 @@ namespace CrewChiefV4.rFactor2 public struct rF2VehScoringCapture { // VehicleScoringInfoV01 members: - public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) + public int mID; // slot ID (note that it can be re-used in multiplayer after someone leaves) public byte mPlace; public byte mIsPlayer; - [XmlIgnore] public sbyte mFinishStatus; // 0=none, 1=finished, 2=dnf, 3=dq + [JsonIgnore] public sbyte mFinishStatus; // 0=none, 1=finished, 2=dnf, 3=dq }; @@ -813,8 +972,8 @@ namespace CrewChiefV4.rFactor2 public struct rF2SessionTransitionCapture { // ScoringInfoV01 members: - [XmlIgnore] public byte mGamePhase; - [XmlIgnore] public int mSession; + [JsonIgnore] public byte mGamePhase; + [JsonIgnore] public int mSession; // VehicleScoringInfoV01 members: public int mNumScoringVehicles; @@ -823,23 +982,15 @@ namespace CrewChiefV4.rFactor2 }; - [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct rF2HostedPluginVars - { - public byte StockCarRules_IsHosted; // Is StockCarRules.dll successfully loaded into SM plugin? - public int StockCarRules_DoubleFileType; // DoubleFileType plugin variable value. - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct rF2Extended { - [XmlIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. - [XmlIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. + [JsonIgnore] public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + [JsonIgnore] public uint mVersionUpdateEnd; // Incremented after buffer write is done. - [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] - public byte[] mVersion; // API version - public byte is64bit; // Is 64bit plugin? + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 12)] + public byte[] mVersion; // API version + public byte is64bit; // Is 64bit plugin? // Physics options (updated on session start): public rF2PhysicsOptions mPhysics; @@ -849,20 +1000,94 @@ namespace CrewChiefV4.rFactor2 public rF2TrackedDamage[] mTrackedDamages; // Function call based flags: - public byte mInRealtimeFC; // in realtime as opposed to at the monitor (reported via last EnterRealtime/ExitRealtime calls). - [XmlIgnore] public byte mMultimediaThreadStarted; // multimedia thread started (reported via ThreadStarted/ThreadStopped calls). - [XmlIgnore] public byte mSimulationThreadStarted; // simulation thread started (reported via ThreadStarted/ThreadStopped calls). + public byte mInRealtimeFC; // in realtime as opposed to at the monitor (reported via last EnterRealtime/ExitRealtime calls). + [JsonIgnore] public byte mMultimediaThreadStarted; // multimedia thread started (reported via ThreadStarted/ThreadStopped calls). + [JsonIgnore] public byte mSimulationThreadStarted; // simulation thread started (reported via ThreadStarted/ThreadStopped calls). - public byte mSessionStarted; // Set to true on Session Started, set to false on Session Ended. - [XmlIgnore] public Int64 mTicksSessionStarted; // Ticks when session started. - public Int64 mTicksSessionEnded; // Ticks when session ended. - public rF2SessionTransitionCapture mSessionTransitionCapture; // Contains partial internals capture at session transition time. + public byte mSessionStarted; // Set to true on Session Started, set to false on Session Ended. + [JsonIgnore] public Int64 mTicksSessionStarted; // Ticks when session started. + public Int64 mTicksSessionEnded; // Ticks when session ended. + public rF2SessionTransitionCapture mSessionTransitionCapture;// Contains partial internals capture at session transition time. // Captured non-empty MessageInfoV01::mText message. [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] mDisplayedMessageUpdateCapture; - public rF2HostedPluginVars mHostedPluginVars; + // Direct Memory access stuff + public byte mDirectMemoryAccessEnabled; + + public Int64 mTicksStatusMessageUpdated; // Ticks when status message was updated; + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_STATUS_MSG_LEN)] + public byte[] mStatusMessage; + + public Int64 mTicksLastHistoryMessageUpdated; // Ticks when last message history message was updated; + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_STATUS_MSG_LEN)] + public byte[] mLastHistoryMessage; + + public float mCurrentPitSpeedLimit; // speed limit m/s. + + public byte mSCRPluginEnabled; // Is Stock Car Rules plugin enabled? + public int mSCRPluginDoubleFileType; // Stock Car Rules plugin DoubleFileType value, only meaningful if mSCRPluginEnabled is true. + + public Int64 mTicksLSIPhaseMessageUpdated; // Ticks when last LSI phase message was updated. + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_RULES_INSTRUCTION_MSG_LEN)] + public byte[] mLSIPhaseMessage; + + public Int64 mTicksLSIPitStateMessageUpdated; // Ticks when last LSI pit state message was updated. + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_RULES_INSTRUCTION_MSG_LEN)] + public byte[] mLSIPitStateMessage; + + public Int64 mTicksLSIOrderInstructionMessageUpdated; // Ticks when last LSI order instruction message was updated. + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_RULES_INSTRUCTION_MSG_LEN)] + public byte[] mLSIOrderInstructionMessage; + + public Int64 mTicksLSIRulesInstructionMessageUpdated; // Ticks when last FCY rules message was updated. Currently, only SCR plugin sets that. + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_RULES_INSTRUCTION_MSG_LEN)] + public byte[] mLSIRulesInstructionMessage; + + [JsonIgnore] public int mUnsubscribedBuffersMask; // Currently active UnsbscribedBuffersMask value. This will be allowed for clients to write to in the future, but not yet. + + public byte mHWControlInputEnabled; // HWControl input buffer is enabled. + public byte mWeatherControlInputEnabled; // WeatherControl input buffer is enabled. + public byte mRulesControlInputEnabled; // RulesControl input buffer is enabled. } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + public struct rF2HWControl + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public int mLayoutVersion; + + [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = rFactor2Constants.MAX_HWCONTROL_NAME_LEN)] + public byte[] mControlName; + public double mfRetVal; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] + struct rF2WeatherControl + { + public uint mVersionUpdateBegin; // Incremented right before buffer is written to. + public uint mVersionUpdateEnd; // Incremented after buffer write is done. + + public int mLayoutVersion; + + public rF2WeatherControlInfo mWeatherInfo; + } + + enum SubscribedBuffer + { + Telemetry = 1, + Scoring = 2, + Rules = 4, + MultiRules = 8, + ForceFeedback = 16, + Graphics = 32, + PitInfo = 64, + Weather = 128, + All = 255 + }; } -} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 0af81bb..58d48a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,7 +210,7 @@ mod tests { telemetry_reader.query_telemetry(start.elapsed().as_secs_f32()) { for telemetry in telemetries { - println!("ID: {}", telemetry.id); + println!("ID: {}, Pos: {:?}", telemetry.id, telemetry.position); } } }