1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00
Added K65 LUX RGB support
Added K65 RGB RAPIDFIRE support
Replaced ETS2 telemetry reader with a better one
Fixed ETS2 plugin placement
Cleaned up plugin-placing code on several modules
This commit is contained in:
SpoinkyNL 2016-08-27 13:00:57 +02:00
parent 3256666f79
commit 3873c68518
22 changed files with 1609 additions and 84 deletions

View File

@ -171,10 +171,6 @@
<HintPath>..\packages\DynamicExpresso.Core.1.3.1.0\lib\net40\DynamicExpresso.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Ets2SdkClient, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>lib\Ets2SdkClient.dll</HintPath>
</Reference>
<Reference Include="GongSolutions.Wpf.DragDrop, Version=0.1.4.3, Culture=neutral, PublicKeyToken=d19974ea350ccea1, processorArchitecture=MSIL">
<HintPath>..\packages\gong-wpf-dragdrop.0.1.4.3\lib\net40\GongSolutions.Wpf.DragDrop.dll</HintPath>
<Private>True</Private>
@ -370,6 +366,11 @@
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualization.cs" />
<Compile Include="Modules\Effects\Bubbles\Bubbles.cs" />
<Compile Include="Modules\Effects\WindowsProfile\PerformanceInfo.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryDataReader.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\IEts2TelemetryData.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Reader\Ets2TelemetryStructure.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Reader\SharedProcessMemory.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\EurotruckSimulator2DataModel.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\EurotruckSimulator2Model.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\EurotruckSimulator2Settings.cs" />
@ -838,6 +839,8 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="Modules\Games\UnrealTournament\Resources\redeemer.gif" />
<None Include="Modules\Games\EurotruckSimulator2\Resources\Win32\ets2-telemetry-server.dll" />
<None Include="Modules\Games\EurotruckSimulator2\Resources\Win64\ets2-telemetry-server.dll" />
<Content Include="Resources\CounterStrike\csgoGamestateConfiguration.txt" />
</ItemGroup>
<ItemGroup>

View File

@ -65,6 +65,8 @@ namespace Artemis.DeviceProviders.Corsair
break;
case "K65 RGB":
case "CGK65 RGB":
case "K65 LUX RGB":
case "K65 RGB RAPIDFIRE":
Height = 7;
Width = 18;
Slug = "corsair-k65-rgb";

View File

@ -0,0 +1,367 @@
using System;
using System.Text;
using Artemis.Modules.Games.EurotruckSimulator2.Data.Reader;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data
{
internal class Ets2TelemetryData : IEts2TelemetryData
{
private Box<Ets2TelemetryStructure> _rawData;
public IEts2Game Game => new Ets2Game(_rawData);
public IEts2Truck Truck => new Ets2Truck(_rawData);
public IEts2Trailer Trailer => new Ets2Trailer(_rawData);
public IEts2Job Job => new Ets2Job(_rawData);
public IEts2Navigation Navigation => new Ets2Navigation(_rawData);
public void Update(Ets2TelemetryStructure rawData)
{
_rawData = new Box<Ets2TelemetryStructure>(rawData);
}
internal static DateTime SecondsToDate(int seconds)
{
if (seconds < 0) seconds = 0;
return new DateTime((long) seconds*10000000, DateTimeKind.Utc);
}
internal static DateTime MinutesToDate(int minutes)
{
return SecondsToDate(minutes*60);
}
internal static string BytesToString(byte[] bytes)
{
if (bytes == null)
return string.Empty;
return Encoding.UTF8.GetString(bytes, 0, Array.FindIndex(bytes, b => b == 0));
}
}
internal class Ets2Game : IEts2Game
{
private readonly Box<Ets2TelemetryStructure> _rawData;
public Ets2Game(Box<Ets2TelemetryStructure> rawData)
{
_rawData = rawData;
}
public bool Paused => _rawData.Struct.paused != 0;
public DateTime Time => Ets2TelemetryData.MinutesToDate(_rawData.Struct.timeAbsolute);
public float TimeScale => _rawData.Struct.localScale;
public DateTime NextRestStopTime => Ets2TelemetryData.MinutesToDate(_rawData.Struct.nextRestStop);
public string Version => $"{_rawData.Struct.ets2_version_major}.{_rawData.Struct.ets2_version_minor}";
public string TelemetryPluginVersion => _rawData.Struct.ets2_telemetry_plugin_revision.ToString();
}
internal class Ets2Vector : IEts2Vector
{
public Ets2Vector(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public float X { get; }
public float Y { get; }
public float Z { get; }
}
internal class Ets2Placement : IEts2Placement
{
public Ets2Placement(float x, float y, float z,
float heading, float pitch, float roll)
{
X = x;
Y = y;
Z = z;
Heading = heading;
Pitch = pitch;
Roll = roll;
}
public float X { get; }
public float Y { get; }
public float Z { get; }
public float Heading { get; }
public float Pitch { get; }
public float Roll { get; }
}
internal class Ets2Truck : IEts2Truck
{
private readonly Box<Ets2TelemetryStructure> _rawData;
public Ets2Truck(Box<Ets2TelemetryStructure> rawData)
{
_rawData = rawData;
}
public string Id => Ets2TelemetryData.BytesToString(_rawData.Struct.truckMakeId);
public string Make => Ets2TelemetryData.BytesToString(_rawData.Struct.truckMake);
public string Model => Ets2TelemetryData.BytesToString(_rawData.Struct.truckModel);
/// <summary>
/// Truck speed in km/h.
/// </summary>
public float Speed => _rawData.Struct.speed*3.6f;
/// <summary>
/// Cruise control speed in km/h.
/// </summary>
public float CruiseControlSpeed => _rawData.Struct.cruiseControlSpeed*3.6f;
public bool CruiseControlOn => _rawData.Struct.cruiseControl != 0;
public float Odometer => _rawData.Struct.truckOdometer;
public int Gear => _rawData.Struct.gear;
public int DisplayedGear => _rawData.Struct.displayedGear;
public int ForwardGears => _rawData.Struct.gearsForward;
public int ReverseGears => _rawData.Struct.gearsReverse;
public string ShifterType => Ets2TelemetryData.BytesToString(_rawData.Struct.shifterType);
public float EngineRpm => _rawData.Struct.engineRpm;
public float EngineRpmMax => _rawData.Struct.engineRpmMax;
public float Fuel => _rawData.Struct.fuel;
public float FuelCapacity => _rawData.Struct.fuelCapacity;
public float FuelAverageConsumption => _rawData.Struct.fuelAvgConsumption;
public float FuelWarningFactor => _rawData.Struct.fuelWarningFactor;
public bool FuelWarningOn => _rawData.Struct.fuelWarning != 0;
public float WearEngine => _rawData.Struct.wearEngine;
public float WearTransmission => _rawData.Struct.wearTransmission;
public float WearCabin => _rawData.Struct.wearCabin;
public float WearChassis => _rawData.Struct.wearChassis;
public float WearWheels => _rawData.Struct.wearWheels;
public float UserSteer => _rawData.Struct.userSteer;
public float UserThrottle => _rawData.Struct.userThrottle;
public float UserBrake => _rawData.Struct.userBrake;
public float UserClutch => _rawData.Struct.userClutch;
public float GameSteer => _rawData.Struct.gameSteer;
public float GameThrottle => _rawData.Struct.gameThrottle;
public float GameBrake => _rawData.Struct.gameBrake;
public float GameClutch => _rawData.Struct.gameClutch;
public int ShifterSlot => _rawData.Struct.shifterSlot;
//public int ShifterToggle
//{
// get { return _rawData.Struct.shifterToggle; }
//}
public bool EngineOn => _rawData.Struct.engineEnabled != 0;
public bool ElectricOn => _rawData.Struct.electricEnabled != 0;
public bool WipersOn => _rawData.Struct.wipers != 0;
public int RetarderBrake => _rawData.Struct.retarderBrake;
public int RetarderStepCount => (int) _rawData.Struct.retarderStepCount;
public bool ParkBrakeOn => _rawData.Struct.parkBrake != 0;
public bool MotorBrakeOn => _rawData.Struct.motorBrake != 0;
public float BrakeTemperature => _rawData.Struct.brakeTemperature;
public float Adblue => _rawData.Struct.adblue;
public float AdblueCapacity => _rawData.Struct.adblueCapacity;
public float AdblueAverageConsumption => _rawData.Struct.adblueConsumption;
public bool AdblueWarningOn => _rawData.Struct.adblueWarning != 0;
public float AirPressure => _rawData.Struct.airPressure;
public bool AirPressureWarningOn => _rawData.Struct.airPressureWarning != 0;
public float AirPressureWarningValue => _rawData.Struct.airPressureWarningValue;
public bool AirPressureEmergencyOn => _rawData.Struct.airPressureEmergency != 0;
public float AirPressureEmergencyValue => _rawData.Struct.airPressureEmergencyValue;
public float OilTemperature => _rawData.Struct.oilTemperature;
public float OilPressure => _rawData.Struct.oilPressure;
public bool OilPressureWarningOn => _rawData.Struct.oilPressureWarning != 0;
public float OilPressureWarningValue => _rawData.Struct.oilPressureWarningValue;
public float WaterTemperature => _rawData.Struct.waterTemperature;
public bool WaterTemperatureWarningOn => _rawData.Struct.waterTemperatureWarning != 0;
public float WaterTemperatureWarningValue => _rawData.Struct.waterTemperatureWarningValue;
public float BatteryVoltage => _rawData.Struct.batteryVoltage;
public bool BatteryVoltageWarningOn => _rawData.Struct.batteryVoltageWarning != 0;
public float BatteryVoltageWarningValue => _rawData.Struct.batteryVoltageWarningValue;
public float LightsDashboardValue => _rawData.Struct.lightsDashboard;
public bool LightsDashboardOn => _rawData.Struct.lightsDashboard > 0;
public bool BlinkerLeftActive => _rawData.Struct.blinkerLeftActive != 0;
public bool BlinkerRightActive => _rawData.Struct.blinkerRightActive != 0;
public bool BlinkerLeftOn => _rawData.Struct.blinkerLeftOn != 0;
public bool BlinkerRightOn => _rawData.Struct.blinkerRightOn != 0;
public bool LightsParkingOn => _rawData.Struct.lightsParking != 0;
public bool LightsBeamLowOn => _rawData.Struct.lightsBeamLow != 0;
public bool LightsBeamHighOn => _rawData.Struct.lightsBeamHigh != 0;
public bool LightsAuxFrontOn => _rawData.Struct.lightsAuxFront != 0;
public bool LightsAuxRoofOn => _rawData.Struct.lightsAuxRoof != 0;
public bool LightsBeaconOn => _rawData.Struct.lightsBeacon != 0;
public bool LightsBrakeOn => _rawData.Struct.lightsBrake != 0;
public bool LightsReverseOn => _rawData.Struct.lightsReverse != 0;
public IEts2Placement Placement => new Ets2Placement(
_rawData.Struct.coordinateX,
_rawData.Struct.coordinateY,
_rawData.Struct.coordinateZ,
_rawData.Struct.rotationX,
_rawData.Struct.rotationY,
_rawData.Struct.rotationZ);
public IEts2Vector Acceleration => new Ets2Vector(
_rawData.Struct.accelerationX,
_rawData.Struct.accelerationY,
_rawData.Struct.accelerationZ);
public IEts2Vector Head => new Ets2Vector(
_rawData.Struct.headPositionX,
_rawData.Struct.headPositionY,
_rawData.Struct.headPositionZ);
public IEts2Vector Cabin => new Ets2Vector(
_rawData.Struct.cabinPositionX,
_rawData.Struct.cabinPositionY,
_rawData.Struct.cabinPositionZ);
public IEts2Vector Hook => new Ets2Vector(
_rawData.Struct.hookPositionX,
_rawData.Struct.hookPositionY,
_rawData.Struct.hookPositionZ);
/*
public IEts2GearSlot[] GearSlots
{
get
{
var array = new IEts2GearSlot[_rawData.Struct.selectorCount];
for (int i = 0; i < array.Length; i++)
array[i] = new Ets2GearSlot(_rawData, i);
return array;
}
}
public IEts2Wheel[] Wheels
{
get
{
var array = new IEts2Wheel[_rawData.Struct.wheelCount];
for (int i = 0; i < array.Length; i++)
array[i] = new Ets2Wheel(_rawData, i);
return array;
}
}
*/
}
internal class Ets2Trailer : IEts2Trailer
{
private readonly Box<Ets2TelemetryStructure> _rawData;
public Ets2Trailer(Box<Ets2TelemetryStructure> rawData)
{
_rawData = rawData;
}
public bool Attached => _rawData.Struct.trailer_attached != 0;
public string Id => Ets2TelemetryData.BytesToString(_rawData.Struct.trailerId);
public string Name => Ets2TelemetryData.BytesToString(_rawData.Struct.trailerName);
/// <summary>
/// Trailer mass in kilograms.
/// </summary>
public float Mass => _rawData.Struct.trailerMass;
public float Wear => _rawData.Struct.wearTrailer;
public IEts2Placement Placement => new Ets2Placement(
_rawData.Struct.trailerCoordinateX,
_rawData.Struct.trailerCoordinateY,
_rawData.Struct.trailerCoordinateZ,
_rawData.Struct.trailerRotationX,
_rawData.Struct.trailerRotationY,
_rawData.Struct.trailerRotationZ);
}
internal class Ets2Navigation : IEts2Navigation
{
private readonly Box<Ets2TelemetryStructure> _rawData;
public Ets2Navigation(Box<Ets2TelemetryStructure> rawData)
{
_rawData = rawData;
}
public DateTime EstimatedTime => Ets2TelemetryData.SecondsToDate((int) _rawData.Struct.navigationTime);
public int EstimatedDistance => (int) _rawData.Struct.navigationDistance;
public int SpeedLimit
=>
_rawData.Struct.navigationSpeedLimit > 0 ? (int) Math.Round(_rawData.Struct.navigationSpeedLimit*3.6f) : 0;
}
internal class Ets2Job : IEts2Job
{
private readonly Box<Ets2TelemetryStructure> _rawData;
public Ets2Job(Box<Ets2TelemetryStructure> rawData)
{
_rawData = rawData;
}
public int Income => _rawData.Struct.jobIncome;
public DateTime DeadlineTime => Ets2TelemetryData.MinutesToDate(_rawData.Struct.jobDeadline);
public DateTime RemainingTime
{
get
{
if (_rawData.Struct.jobDeadline > 0)
return Ets2TelemetryData.MinutesToDate(_rawData.Struct.jobDeadline - _rawData.Struct.timeAbsolute);
return Ets2TelemetryData.MinutesToDate(0);
}
}
public string SourceCity => Ets2TelemetryData.BytesToString(_rawData.Struct.jobCitySource);
public string SourceCompany => Ets2TelemetryData.BytesToString(_rawData.Struct.jobCompanySource);
public string DestinationCity => Ets2TelemetryData.BytesToString(_rawData.Struct.jobCityDestination);
public string DestinationCompany => Ets2TelemetryData.BytesToString(_rawData.Struct.jobCompanyDestination);
}
/*
class Ets2Wheel : IEts2Wheel
{
public Ets2Wheel(Box<Ets2TelemetryStructure> rawData, int wheelIndex)
{
Simulated = rawData.Struct.wheelSimulated[wheelIndex] != 0;
Steerable = rawData.Struct.wheelSteerable[wheelIndex] != 0;
Radius = rawData.Struct.wheelRadius[wheelIndex];
Position = new Ets2Vector(
rawData.Struct.wheelPositionX[wheelIndex],
rawData.Struct.wheelPositionY[wheelIndex],
rawData.Struct.wheelPositionZ[wheelIndex]);
Powered = rawData.Struct.wheelPowered[wheelIndex] != 0;
Liftable = rawData.Struct.wheelLiftable[wheelIndex] != 0;
}
public bool Simulated { get; private set; }
public bool Steerable { get; private set; }
public bool Powered { get; private set; }
public bool Liftable { get; private set; }
public float Radius { get; private set; }
public IEts2Vector Position { get; private set; }
}
class Ets2GearSlot : IEts2GearSlot
{
public Ets2GearSlot(Box<Ets2TelemetryStructure> rawData, int slotIndex)
{
Gear = rawData.Struct.slotGear[slotIndex];
HandlePosition = (int)rawData.Struct.slotHandlePosition[slotIndex];
SlotSelectors = (int)rawData.Struct.slotSelectors[slotIndex];
}
public int Gear { get; private set; }
public int HandlePosition { get; private set; }
public int SlotSelectors { get; private set; }
}
*/
internal class Box<T> where T : struct
{
public Box(T @struct)
{
Struct = @struct;
}
public T Struct { get; set; }
}
}

View File

@ -0,0 +1,44 @@
using System;
using Artemis.Modules.Games.EurotruckSimulator2.Data.Reader;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data
{
public class Ets2TelemetryDataReader : IDisposable
{
/// <summary>
/// ETS2 telemetry plugin maps the data to this mapped file name.
/// </summary>
private const string Ets2TelemetryMappedFileName = "Local\\Ets2TelemetryServer";
// ReSharper disable once InconsistentNaming
private static readonly Lazy<Ets2TelemetryDataReader> instance = new Lazy<Ets2TelemetryDataReader>(
() => new Ets2TelemetryDataReader());
private readonly Ets2TelemetryData _data = new Ets2TelemetryData();
private readonly object _lock = new object();
private readonly SharedProcessMemory<Ets2TelemetryStructure> _sharedMemory =
new SharedProcessMemory<Ets2TelemetryStructure>(Ets2TelemetryMappedFileName);
public static Ets2TelemetryDataReader Instance => instance.Value;
public bool IsConnected => _sharedMemory.IsConnected;
public void Dispose()
{
_sharedMemory?.Dispose();
}
public IEts2TelemetryData Read()
{
lock (_lock)
{
_sharedMemory.Data = default(Ets2TelemetryStructure);
_sharedMemory.Read();
_data.Update(_sharedMemory.Data);
return _data;
}
}
}
}

View File

@ -0,0 +1,763 @@
using System;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data
{
public interface IEts2TelemetryData
{
/// <summary>
/// Game information.
/// </summary>
IEts2Game Game { get; }
/// <summary>
/// Truck information.
/// </summary>
IEts2Truck Truck { get; }
/// <summary>
/// Trailer information.
/// </summary>
IEts2Trailer Trailer { get; }
/// <summary>
/// Job information.
/// </summary>
IEts2Job Job { get; }
/// <summary>
/// Navigation information.
/// </summary>
IEts2Navigation Navigation { get; }
}
public interface IEts2Game
{
/// <summary>
/// Current game time.
/// Serializes to ISO 8601 string in JSON.
/// Example: "0001-01-05T05:11:00Z"
/// </summary>
DateTime Time { get; }
/// <summary>
/// True if game is currently paused, false otherwise.
/// </summary>
bool Paused { get; }
/// <summary>
/// Current version of the telemetry plugin DLL file.
/// Example: "4"
/// </summary>
string TelemetryPluginVersion { get; }
/// <summary>
/// Current version of the game.
/// Example: "1.10"
/// </summary>
string Version { get; }
/// <summary>
/// When the fatigue simulation is disabled, the behavior of this channel
/// is implementation dependent. The game might provide the value which would
/// apply if it was enabled or provide no value at all.
/// Example: "0001-01-01T10:52:00Z"
/// </summary>
DateTime NextRestStopTime { get; }
/// <summary>
/// Scale applied to distance and time to compensate
/// for the scale of the map (e.g. 1s of real time corresponds
/// to local_scale seconds of simulated game time).
/// Example: 3
/// </summary>
float TimeScale { get; }
}
public interface IEts2Vector
{
float X { get; }
float Y { get; }
float Z { get; }
}
public interface IEts2Placement
{
/// <summary>
/// X coordinate of the placement.
/// Example: 13723.7881
/// </summary>
float X { get; }
/// <summary>
/// Y coordinate of the placement.
/// Example: 65.22377
/// </summary>
float Y { get; }
/// <summary>
/// Z coordinate of the placement.
/// Example: 13738.8018
/// </summary>
float Z { get; }
/// <summary>
/// The angle is measured counterclockwise in horizontal plane when looking
/// from top where 0 corresponds to forward (north), 0.25 to left (west),
/// 0.5 to backward (south) and 0.75 to right (east).
/// Stored in unit range where (0,1) corresponds to (0,360).
/// Example: 0.13688866
/// </summary>
float Heading { get; }
/// <summary>
/// The pitch angle is zero when in horizontal direction,
/// with positive values pointing up (0.25 directly to zenith),
/// and negative values pointing down (-0.25 directly to nadir).
/// Stored in unit range where (-0.25,0.25) corresponds to (-90,90).
/// Example: 0.00005
/// </summary>
float Pitch { get; }
/// <summary>
/// The angle is measured in counterclockwise when looking in direction of the roll axis.
/// Stored in unit range where (-0.5,0.5) corresponds to (-180,180).
/// Example: -0.00009
/// </summary>
float Roll { get; }
}
public interface IEts2Truck
{
/// <summary>
/// Current truck speed in km/h.
/// Example: 50.411231
/// </summary>
float Speed { get; }
/// <summary>
/// Represents vehicle space linear acceleration of
/// the truck measured in meters per second^2.
/// Example: { "x": 0.046569, "y": -0.00116, "z": -1.03676 }
/// </summary>
IEts2Vector Acceleration { get; }
/// <summary>
/// Current truck placement in the game world.
/// </summary>
IEts2Placement Placement { get; }
/// <summary>
/// The value of the odometer in km.
/// Example: 105809.25
/// </summary>
float Odometer { get; }
/// <summary>
/// Speed selected for the cruise control in km/h.
/// Example: 75
/// </summary>
float CruiseControlSpeed { get; }
/// <summary>
/// Brand Id of the current truck.
/// Example: "man".
/// </summary>
string Id { get; }
/// <summary>
/// Localized brand name of the current truck for display purposes.
/// Example: "MAN".
/// </summary>
string Make { get; }
/// <summary>
/// Localized model name of the current truck.
/// Example: "TGX".
/// </summary>
string Model { get; }
/// <summary>
/// Gear that is currently selected in the engine.
/// Positive values reflect forward gears, negative - reverse.
/// Example: 9
/// </summary>
int Gear { get; }
/// <summary>
/// Gear that is currently displayed on the main dashboard.
/// Positive values reflect forward gears, negative - reverse.
/// Example: 4
/// </summary>
int DisplayedGear { get; }
/// <summary>
/// Number of forward gears on undamaged truck.
/// Example: 12
/// </summary>
int ForwardGears { get; }
/// <summary>
/// Number of reverse gears on undamaged truck.
/// Example: 2
/// </summary>
int ReverseGears { get; }
/// <summary>
/// Current RPM value of the truck's engine (rotates per minute).
/// Example: 1372.3175
/// </summary>
float EngineRpm { get; }
/// <summary>
/// Maximal RPM value of the truck's engine.
/// Example: 2500
/// </summary>
float EngineRpmMax { get; }
/// <summary>
/// Current amount of fuel in liters.
/// Example: 696.7544
/// </summary>
float Fuel { get; }
/// <summary>
/// Fuel tank capacity in litres.
/// Example: 700
/// </summary>
float FuelCapacity { get; }
/// <summary>
/// Average consumption of the fuel in liters/km.
/// Example: 0.4923077
/// </summary>
float FuelAverageConsumption { get; }
/// <summary>
/// Steering received from input (-1;1).
/// Note that it is interpreted counterclockwise.
/// If the user presses the steer right button on digital input
/// (e.g. keyboard) this value goes immediatelly to -1.0
/// Example: -1.0
/// </summary>
float UserSteer { get; }
/// <summary>
/// Throttle received from input (-1;1).
/// If the user presses the forward button on digital input
/// (e.g. keyboard) this value goes immediatelly to 1.0
/// Example: 0
/// </summary>
float UserThrottle { get; }
/// <summary>
/// Brake received from input (-1;1)
/// If the user presses the brake button on digital input
/// (e.g. keyboard) this value goes immediatelly to 1.0
/// Example: 0
/// </summary>
float UserBrake { get; }
/// <summary>
/// Clutch received from input (-1;1)
/// If the user presses the clutch button on digital input
/// (e.g. keyboard) this value goes immediatelly to 1.0
/// Example: 0
/// </summary>
float UserClutch { get; }
/// <summary>
/// Steering as used by the simulation (-1;1)
/// Note that it is interpreted counterclockwise.
/// Accounts for interpolation speeds and simulated
/// counterfoces for digital inputs.
/// Example: -0.423521
/// </summary>
float GameSteer { get; }
/// <summary>
/// Throttle pedal input as used by the simulation (0;1)
/// Accounts for the press attack curve for digital inputs
/// or cruise-control input.
/// Example: 0.17161
/// </summary>
float GameThrottle { get; }
/// <summary>
/// Brake pedal input as used by the simulation (0;1)
/// Accounts for the press attack curve for digital inputs.
/// Does not contain retarder, parking or motor brake.
/// Example: 0
/// </summary>
float GameBrake { get; }
/// <summary>
/// Clutch pedal input as used by the simulation (0;1)
/// Accounts for the automatic shifting or interpolation of
/// player input.
/// Example: 0
/// </summary>
float GameClutch { get; }
/// <summary>
/// Current level of the retarder brake.
/// Ranges from 0 to RetarderStepCount.
/// Example: 0
/// </summary>
int RetarderBrake { get; }
/// <summary>
/// Number of steps in the retarder.
/// Set to zero if retarder is not mounted to the truck.
/// Example: 3
/// </summary>
int RetarderStepCount { get; }
/// <summary>
/// Gearbox slot the h-shifter handle is currently in.
/// 0 means that no slot is selected.
/// Example: 0
/// </summary>
int ShifterSlot { get; }
/// <summary>
/// TODO: need to fix.
/// </summary>
/// <summary>
/// Pressure in the brake air tank in psi.
/// Example: 133.043961
/// </summary>
float AirPressure { get; }
/// <summary>
/// Temperature of the brakes in degrees celsius.
/// Example: 15.9377184
/// </summary>
float BrakeTemperature { get; }
/// <summary>
/// Amount of AdBlue in liters.
/// Example: 0
/// </summary>
float Adblue { get; }
/// <summary>
/// Average consumption of the adblue in liters/km.
/// Example: 0
/// </summary>
float AdblueAverageConsumption { get; }
/// <summary>
/// Pressure of the oil in psi.
/// Example: 36.4550362
/// </summary>
float OilPressure { get; }
/// <summary>
/// Temperature of the oil in degrees celsius.
/// Example: 16.2580566
/// </summary>
float OilTemperature { get; }
/// <summary>
/// Temperature of the water in degrees celsius.
/// Example: 16.1623955
/// </summary>
float WaterTemperature { get; }
/// <summary>
/// Voltage of the battery in volts.
/// Example: 23.4985161
/// </summary>
float BatteryVoltage { get; }
/// <summary>
/// AdBlue tank capacity in litres.
/// Example: 0
/// </summary>
float AdblueCapacity { get; }
/// <summary>
/// Current level of truck's engine wear/damage between 0 (min) and 1 (max).
/// Example: 0.00675457
/// </summary>
float WearEngine { get; }
/// <summary>
/// Current level of truck's transmission wear/damage between 0 (min) and 1 (max).
/// </summary>
float WearTransmission { get; }
/// <summary>
/// Current level of truck's cabin wear/damage between 0 (min) and 1 (max).
/// </summary>
float WearCabin { get; }
/// <summary>
/// Current level of truck's chassis wear/damage between 0 (min) and 1 (max).
/// </summary>
float WearChassis { get; }
/// <summary>
/// Current level of truck's wheel wear/damage between 0 (min) and 1 (max).
/// </summary>
float WearWheels { get; }
/// <summary>
/// Default position of the head in the cabin space.
/// Example: { "x": -0.795116067, "y": 1.43522251, "z": -0.08483863 }
/// </summary>
IEts2Vector Head { get; }
/// <summary>
/// Position of the cabin in the vehicle space.
/// This is position of the joint around which the cabin rotates.
/// This attribute might be not present if the vehicle does not have a separate cabin.
/// Example: { "x": 0, "y": 1.36506855, "z": -1.70362806 }
/// </summary>
IEts2Vector Cabin { get; }
/// <summary>
/// Position of the trailer connection hook in vehicle space.
/// Example: { "x": 0, "y": 0.939669, "z": -6.17736959 }
/// </summary>
IEts2Vector Hook { get; }
/// <summary>
/// All available selectors (e.g. range/splitter toggles). TODO: need to fix.
/// </summary>
/// <summary>
/// Type of the shifter.
/// One of the following values: "arcade", "automatic", "manual", "hshifter".
/// </summary>
string ShifterType { get; }
/// <summary>
/// Indicates whether cruise control is turned on or off.
/// </summary>
bool CruiseControlOn { get; }
/// <summary>
/// Indicates whether wipers are currently turned on or off.
/// </summary>
bool WipersOn { get; }
/// <summary>
/// Is the parking brake enabled or not.
/// </summary>
bool ParkBrakeOn { get; }
/// <summary>
/// Is the motor brake enabled or not.
/// </summary>
bool MotorBrakeOn { get; }
/// <summary>
/// Is the engine enabled or not.
/// </summary>
bool EngineOn { get; }
/// <summary>
/// Is the electric enabled or not.
/// </summary>
bool ElectricOn { get; }
/// <summary>
/// Is left blinker currently emits light or not.
/// </summary>
bool BlinkerLeftActive { get; }
/// <summary>
/// Is right blinker currently emits light or not.
/// </summary>
bool BlinkerRightActive { get; }
/// <summary>
/// Is left blinker currently turned on or off.
/// </summary>
bool BlinkerLeftOn { get; }
/// <summary>
/// Is right blinker currently turned on or off.
/// </summary>
bool BlinkerRightOn { get; }
/// <summary>
/// Are the parking lights enabled or not.
/// </summary>
bool LightsParkingOn { get; }
/// <summary>
/// Are the low beam lights enabled or not.
/// </summary>
bool LightsBeamLowOn { get; }
/// <summary>
/// Are the high beam lights enabled or not.
/// </summary>
bool LightsBeamHighOn { get; }
/// <summary>
/// Are the auxiliary front lights active or not.
/// </summary>
bool LightsAuxFrontOn { get; }
/// <summary>
/// Are the auxiliary roof lights active or not.
/// </summary>
bool LightsAuxRoofOn { get; }
/// <summary>
/// Are the beacon lights enabled or not.
/// </summary>
bool LightsBeaconOn { get; }
/// <summary>
/// Is the brake light active or not.
/// </summary>
bool LightsBrakeOn { get; }
/// <summary>
/// Is the reverse light active or not.
/// </summary>
bool LightsReverseOn { get; }
/// <summary>
/// Is the battery voltage/not charging warning active or not.
/// </summary>
bool BatteryVoltageWarningOn { get; }
/// <summary>
/// Is the air pressure warning active or not.
/// </summary>
bool AirPressureWarningOn { get; }
/// <summary>
/// Are the emergency brakes active as result of low air pressure or not.
/// </summary>
bool AirPressureEmergencyOn { get; }
/// <summary>
/// Is the low adblue warning active or not.
/// </summary>
bool AdblueWarningOn { get; }
/// <summary>
/// Is the oil pressure warning active or not.
/// </summary>
bool OilPressureWarningOn { get; }
/// <summary>
/// Is the water temperature warning active or not.
/// </summary>
bool WaterTemperatureWarningOn { get; }
/// <summary>
/// Intensity of the dashboard backlight between 0 (off) and 1 (max).
/// </summary>
float LightsDashboardValue { get; }
/// <summary>
/// Is the dashboard backlight currently turned on or off.
/// </summary>
bool LightsDashboardOn { get; }
/// <summary>
/// Is the low fuel warning active or not.
/// </summary>
bool FuelWarningOn { get; }
/// <summary>
/// Fraction of the fuel capacity bellow which is activated the fuel warning.
/// Example: 0.15
/// </summary>
float FuelWarningFactor { get; }
/// <summary>
/// Pressure of the air in the tank bellow which the warning activates.
/// Example: 65
/// </summary>
float AirPressureWarningValue { get; }
/// <summary>
/// Pressure of the air in the tank bellow which the emergency brakes activate.
/// Example: 30
/// </summary>
float AirPressureEmergencyValue { get; }
/// <summary>
/// Pressure of the oil bellow which the warning activates.
/// Example: 10
/// </summary>
float OilPressureWarningValue { get; }
/// <summary>
/// Temperature of the water above which the warning activates.
/// Example: 105
/// </summary>
float WaterTemperatureWarningValue { get; }
/// <summary>
/// Voltage of the battery bellow which the warning activates.
/// Example: 22
/// </summary>
float BatteryVoltageWarningValue { get; }
}
public interface IEts2Navigation
{
/// <summary>
/// Relative estimated time of arrival.
/// Example: "0001-01-01T02:05:00Z"
/// </summary>
DateTime EstimatedTime { get; }
/// <summary>
/// Estimated distance to the destination in meters.
/// Example: 1224
/// </summary>
int EstimatedDistance { get; }
/// <summary>
/// Current value of the "Route Advisor speed limit" in km/h.
/// Example: 50
/// </summary>
int SpeedLimit { get; }
}
public interface IEts2Job
{
/// <summary>
/// Reward in internal game-specific currency.
/// Example: 2316
/// </summary>
int Income { get; }
/// <summary>
/// Absolute in-game time of end of job delivery window.
/// Delivering the job after this time will cause it be late.
/// Example: "0001-01-09T03:34:00Z"
/// </summary>
DateTime DeadlineTime { get; }
/// <summary>
/// Relative remaining in-game time left before deadline.
/// Example: "0001-01-01T07:06:00Z"
/// </summary>
DateTime RemainingTime { get; }
/// <summary>
/// Localized name of the source city for display purposes.
/// Example: "Linz"
/// </summary>
string SourceCity { get; }
/// <summary>
/// Localized name of the destination city for display purposes.
/// Example: "Salzburg"
/// </summary>
string DestinationCity { get; }
/// <summary>
/// Localized name of the source company for display purposes.
/// Example: "DHL"
/// </summary>
string SourceCompany { get; }
/// <summary>
/// Localized name of the destination company for display purposes.
/// Example: "JCB"
/// </summary>
string DestinationCompany { get; }
}
public interface IEts2Trailer
{
/// <summary>
/// Id of the cargo for internal use by code.
/// Example: "derrick"
/// </summary>
string Id { get; }
/// <summary>
/// Localized name of the current trailer for display purposes.
/// Example: "Derrick"
/// </summary>
string Name { get; }
/// <summary>
/// Is the trailer attached to the truck or not.
/// </summary>
bool Attached { get; }
/// <summary>
/// Mass of the cargo in kilograms.
/// Example: 22000
/// </summary>
float Mass { get; }
/// <summary>
/// Current trailer placement in the game world.
/// </summary>
IEts2Placement Placement { get; }
/// <summary>
/// Current level of trailer wear/damage between 0 (min) and 1 (max).
/// Example: 0.0314717
/// </summary>
float Wear { get; }
}
/*
public interface IEts2Wheel
{
/// <summary>
/// Is the wheel physically simulated or not.
/// </summary>
bool Simulated { get; }
/// <summary>
/// Is the wheel steerable or not.
/// </summary>
bool Steerable { get; }
/// <summary>
/// Radius of the wheel.
/// Example: 0.5120504
/// </summary>
float Radius { get; }
/// <summary>
/// Position of respective wheels in the vehicle space.
/// Example: { "x": -0.9, "y": 0.506898463, "z": 6.25029 }
/// </summary>
IEts2Vector Position { get; }
/// <summary>
/// Is the wheel powered or not.
/// </summary>
bool Powered { get; }
/// <summary>
/// Is the wheel liftable or not.
/// </summary>
bool Liftable { get; }
}
public interface IEts2GearSlot
{
/// <summary>
/// Gear selected when requirements for this h-shifter slot are meet.
/// Example: 0
/// </summary>
int Gear { get; }
/// <summary>
/// Position of h-shifter handle.
/// Zero corresponds to neutral position.
/// Mapping to physical position of the handle depends on input setup.
/// Example: 0
/// </summary>
int HandlePosition { get; }
/// <summary>
/// Bitmask of required on/off state of selectors.
/// Only first N number of bits are relevant (where N is the number of IEts2GearSlot objects).
/// Example: 0
/// </summary>
int SlotSelectors { get; }
}
*/
}

View File

@ -0,0 +1,214 @@
using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal struct Ets2TelemetryStructure
{
private const int GeneralStringSize = 64;
public uint time;
public uint paused;
public uint ets2_telemetry_plugin_revision;
public uint ets2_version_major;
public uint ets2_version_minor;
// ***** REVISION 1 ****** //
private readonly byte padding1;
public byte trailer_attached;
public byte padding2;
public byte padding3;
public float speed;
public float accelerationX;
public float accelerationY;
public float accelerationZ;
public float coordinateX;
public float coordinateY;
public float coordinateZ;
public float rotationX;
public float rotationY;
public float rotationZ;
public int gear;
public int gearsForward;
public int gearRanges;
public int gearRangeActive;
public float engineRpm;
public float engineRpmMax;
public float fuel;
public float fuelCapacity;
public float fuelRate;
public float fuelAvgConsumption;
public float userSteer;
public float userThrottle;
public float userBrake;
public float userClutch;
public float gameSteer;
public float gameThrottle;
public float gameBrake;
public float gameClutch;
public float truckWeight;
public float trailerWeight;
public int modelOffset;
public int modelLength;
public int trailerOffset;
public int trailerLength;
public int timeAbsolute;
public int gearsReverse;
public float trailerMass;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] trailerId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] trailerName;
public int jobIncome;
public int jobDeadline;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] jobCitySource;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] jobCityDestination;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] jobCompanySource;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] jobCompanyDestination;
// ***** REVISION 3 ****** //
public int retarderBrake;
public int shifterSlot;
public int shifterToggle;
public int padding4;
public byte cruiseControl;
public byte wipers;
public byte parkBrake;
public byte motorBrake;
public byte electricEnabled;
public byte engineEnabled;
public byte blinkerLeftActive;
public byte blinkerRightActive;
public byte blinkerLeftOn;
public byte blinkerRightOn;
public byte lightsParking;
public byte lightsBeamLow;
public byte lightsBeamHigh;
public uint lightsAuxFront;
public uint lightsAuxRoof;
public byte lightsBeacon;
public byte lightsBrake;
public byte lightsReverse;
public byte batteryVoltageWarning;
public byte airPressureWarning;
public byte airPressureEmergency;
public byte adblueWarning;
public byte oilPressureWarning;
public byte waterTemperatureWarning;
public float airPressure;
public float brakeTemperature;
public int fuelWarning;
public float adblue;
public float adblueConsumption;
public float oilPressure;
public float oilTemperature;
public float waterTemperature;
public float batteryVoltage;
public float lightsDashboard;
public float wearEngine;
public float wearTransmission;
public float wearCabin;
public float wearChassis;
public float wearWheels;
public float wearTrailer;
public float truckOdometer;
public float cruiseControlSpeed;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] truckMake;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] truckMakeId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GeneralStringSize)] public byte[] truckModel;
// ***** REVISION 4 ****** //
public float fuelWarningFactor;
public float adblueCapacity;
public float airPressureWarningValue;
public float airPressureEmergencyValue;
public float oilPressureWarningValue;
public float waterTemperatureWarningValue;
public float batteryVoltageWarningValue;
public uint retarderStepCount;
public float cabinPositionX;
public float cabinPositionY;
public float cabinPositionZ;
public float headPositionX;
public float headPositionY;
public float headPositionZ;
public float hookPositionX;
public float hookPositionY;
public float hookPositionZ;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] shifterType;
public float localScale;
public int nextRestStop;
public float trailerCoordinateX;
public float trailerCoordinateY;
public float trailerCoordinateZ;
public float trailerRotationX;
public float trailerRotationY;
public float trailerRotationZ;
public int displayedGear;
public float navigationDistance;
public float navigationTime;
public float navigationSpeedLimit;
/*
const int MaxSlotCount = 32; // TODO: need to fix.
const int MaxWheelCount = 20;
public uint wheelCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public float[] wheelPositionX;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public float[] wheelPositionY;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public float[] wheelPositionZ;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public byte[] wheelSteerable;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public byte[] wheelSimulated;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public float[] wheelRadius;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public byte[] wheelPowered;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxWheelCount)]
public byte[] wheelLiftable;
public uint selectorCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxSlotCount)]
public int[] slotGear;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxSlotCount)]
public uint[] slotHandlePosition;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MaxSlotCount)]
public uint[] slotSelectors;
*/
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
namespace Artemis.Modules.Games.EurotruckSimulator2.Data.Reader
{
internal class SharedProcessMemory<T> : IDisposable
{
private readonly string _mapName;
private MemoryMappedViewAccessor _memoryMappedAccessor;
private MemoryMappedFile _memoryMappedFile;
public SharedProcessMemory(string mapName)
{
_mapName = mapName;
Data = default(T);
}
public T Data { get; set; }
public bool IsConnected
{
get
{
InitializeViewAccessor();
return _memoryMappedAccessor != null;
}
}
public void Dispose()
{
if (_memoryMappedAccessor != null)
{
_memoryMappedAccessor.Dispose();
_memoryMappedFile.Dispose();
}
}
private void InitializeViewAccessor()
{
if (_memoryMappedAccessor == null)
try
{
_memoryMappedFile = MemoryMappedFile.OpenExisting(_mapName, MemoryMappedFileRights.ReadWrite);
_memoryMappedAccessor = _memoryMappedFile.CreateViewAccessor(0, Marshal.SizeOf(typeof(T)),
MemoryMappedFileAccess.Read);
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{
}
}
public void Read()
{
InitializeViewAccessor();
if (_memoryMappedAccessor == null)
return;
var rawData = new byte[Marshal.SizeOf(typeof(T))];
_memoryMappedAccessor.ReadArray(0, rawData, 0, rawData.Length);
T createdObject;
var reservedMemPtr = IntPtr.Zero;
try
{
reservedMemPtr = Marshal.AllocHGlobal(rawData.Length);
Marshal.Copy(rawData, 0, reservedMemPtr, rawData.Length);
createdObject = (T) Marshal.PtrToStructure(reservedMemPtr, typeof(T));
}
finally
{
if (reservedMemPtr != IntPtr.Zero)
Marshal.FreeHGlobal(reservedMemPtr);
}
Data = createdObject;
}
}
}

View File

@ -1,18 +1,14 @@
using Artemis.Models.Interfaces;
using Ets2SdkClient;
using Artemis.Modules.Games.EurotruckSimulator2.Data;
namespace Artemis.Modules.Games.EurotruckSimulator2
{
public class EurotruckSimulator2DataModel : IDataModel
{
public Ets2Telemetry._Axilliary Axilliary { get; set; }
public Ets2Telemetry._Controls Controls { get; set; }
public Ets2Telemetry._Damage Damage { get; set; }
public Ets2Telemetry._Drivetrain Drivetrain { get; set; }
public Ets2Telemetry._Job Job { get; set; }
public Ets2Telemetry._Lights Lights { get; set; }
public string Manufacturer { get; set; }
public string ManufacturerId { get; set; }
public Ets2Telemetry._Physics Physics { get; set; }
public IEts2Game Game { get; set; }
public IEts2Job Job { get; set; }
public IEts2Navigation Navigation { get; set; }
public IEts2Trailer Trailer { get; set; }
public IEts2Truck Truck { get; set; }
}
}

View File

@ -2,8 +2,8 @@
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Modules.Games.EurotruckSimulator2.Data;
using Artemis.Profiles.Layers.Models;
using Ets2SdkClient;
using Ninject.Extensions.Logging;
namespace Artemis.Modules.Games.EurotruckSimulator2
@ -24,42 +24,26 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
public ILogger Logger { get; set; }
public int Scale { get; set; }
public Ets2SdkTelemetry Telemetry { get; set; }
public override void Dispose()
{
Initialized = false;
Telemetry.Data -= TelemetryOnData;
Telemetry = null;
}
public override void Enable()
{
Telemetry = new Ets2SdkTelemetry();
Telemetry.Data += TelemetryOnData;
if (Telemetry.Error != null)
MainManager.Logger.Error(Telemetry.Error, "Exception in the Eurotruck SDK");
Initialized = true;
}
private void TelemetryOnData(Ets2Telemetry data, bool newTimestamp)
{
((EurotruckSimulator2DataModel) DataModel).Axilliary = data.Axilliary;
((EurotruckSimulator2DataModel) DataModel).Controls = data.Controls;
((EurotruckSimulator2DataModel) DataModel).Damage = data.Damage;
((EurotruckSimulator2DataModel) DataModel).Drivetrain = data.Drivetrain;
((EurotruckSimulator2DataModel) DataModel).Job = data.Job;
((EurotruckSimulator2DataModel) DataModel).Lights = data.Lights;
((EurotruckSimulator2DataModel) DataModel).Manufacturer = data.Manufacturer;
((EurotruckSimulator2DataModel) DataModel).ManufacturerId = data.ManufacturerId;
((EurotruckSimulator2DataModel) DataModel).Physics = data.Physics;
}
public override void Update()
{
// Updating is handled in the TelemetryOnData event
var dataModel = (EurotruckSimulator2DataModel) DataModel;
var telemetryData = Ets2TelemetryDataReader.Instance.Read();
dataModel.Game = telemetryData.Game;
dataModel.Job = telemetryData.Job;
dataModel.Navigation = telemetryData.Navigation;
dataModel.Trailer = telemetryData.Trailer;
dataModel.Truck = telemetryData.Truck;
}
public override List<LayerModel> GetRenderLayers(bool keyboardOnly)

View File

@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="476.986" d:DesignWidth="538.772">
d:DesignHeight="559.725" d:DesignWidth="882.696">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid Margin="15,5,5,5">
<Grid.ColumnDefinitions>
@ -20,31 +20,50 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
<Label FontSize="20" HorizontalAlignment="Left">
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="By default shows indicator lights, speed and engine RPM on the keyboard" />
</Label.Content>
</Label>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
TextAlignment="Justify" Margin="5,0,0,10">
The Euro Truck Simulator 2 module uses code from the
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate"
NavigateUri="https://github.com/Funbit/ets2-telemetry-server">
ETS2 Telemetry Web Server
</Hyperlink>
project by Funbit
</TextBlock>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
IsChecked="{Binding Path=GameSettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
</Grid>
<StackPanel Grid.Row="1"
<StackPanel Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2" Margin="0,0,1,0">
<Label FontSize="20" HorizontalAlignment="Left" Content="Eurotruck Simulator 2 directory" />
<Label FontSize="20" HorizontalAlignment="Left" Content="Euro Truck Simulator 2 directory" />
<Grid>
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
cal:Message.Attach="[Event LostFocus] = [Action PlaceConfigFile]" />
cal:Message.Attach="[Event LostFocus] = [Action PlacePlugin]" />
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
HorizontalAlignment="Right" Width="25"
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />

View File

@ -1,4 +1,5 @@
using System.Windows.Controls;
using System.Windows.Navigation;
namespace Artemis.Modules.Games.EurotruckSimulator2
{
@ -11,5 +12,10 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
{
InitializeComponent();
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.ToString());
}
}
}

View File

@ -1,7 +1,9 @@
using System.IO;
using System;
using System.IO;
using System.Windows.Forms;
using Artemis.InjectionFactories;
using Artemis.Managers;
using Artemis.Properties;
using Artemis.Utilities;
using Artemis.ViewModels.Abstract;
@ -15,23 +17,24 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
DisplayName = "ETS 2";
FindGameDir();
PlacePlugin();
}
public void FindGameDir()
{
var gameSettings = (EurotruckSimulator2Settings) GameSettings;
// If already propertly set up, don't do anything
//if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "csgo.exe") &&
// File.Exists(gameSettings.GameDirectory + "/csgo/cfg/gamestate_integration_artemis.cfg"))
// return;
// Demo is also supported but resides in a different directory
var dir = GeneralHelpers.FindSteamGame(@"\Euro Truck Simulator 2\bin\win_x86\eurotrucks2.exe") ??
// Demo is also supported but resides in a different directory, the full game can also be 64-bits
var dir = GeneralHelpers.FindSteamGame(@"\Euro Truck Simulator 2\bin\win_x64\eurotrucks2.exe") ??
GeneralHelpers.FindSteamGame(@"\Euro Truck Simulator 2\bin\win_x86\eurotrucks2.exe") ??
GeneralHelpers.FindSteamGame(@"\Euro Truck Simulator 2 Demo\bin\win_x86\eurotrucks2.exe");
gameSettings.GameDirectory = dir ?? string.Empty;
if (string.IsNullOrEmpty(dir))
return;
gameSettings.GameDirectory = dir;
gameSettings.Save();
if (!File.Exists(dir + "/plugins/ets2-telemetry-server.dll"))
PlacePlugin();
}
public void BrowseDirectory()
@ -57,21 +60,40 @@ namespace Artemis.Modules.Games.EurotruckSimulator2
return;
var path = ((EurotruckSimulator2Settings) GameSettings).GameDirectory;
//if (Directory.Exists(path + "/csgo/cfg"))
//{
// var cfgFile = Resources.csgoGamestateConfiguration.Replace("{{port}}",
// MainManager.GameStateWebServer.Port.ToString());
// File.WriteAllText(path + "/csgo/cfg/gamestate_integration_artemis.cfg", cfgFile);
// return;
//}
// Ensure the selected directory exists
if (!Directory.Exists(path))
{
DialogService.ShowErrorMessageBox($"Directory '{path}' not found.");
return;
}
// Ensure it's the ETS2 directory by looking for the executable
if (!File.Exists(path + "/eurotrucks2.exe"))
{
DialogService.ShowErrorMessageBox("Please select a valid Eurotruck Simulator 2 directory\n\n" +
@"By default ETS2 is in \SteamApps\common\Euro Truck Simulator 2\bin\win_x64");
return;
}
//DialogService.ShowErrorMessageBox("Please select a valid CS:GO directory\n\n" +
// @"By default CS:GO is in \SteamApps\common\Counter-Strike Global Offensive");
// Create the plugins folder if it's not already there
Directory.CreateDirectory(path + "/plugins");
//((EurotruckSimulator2Settings) GameSettings).GameDirectory = string.Empty;
//NotifyOfPropertyChange(() => GameSettings);
//GameSettings.Save();
// Place either the 64-bits or 32-bits DLL
try
{
if (path.Contains("win_x64"))
File.WriteAllBytes(path + "/plugins/ets2-telemetry-server.dll", Resources.ets2_telemetry_server_x64);
else
File.WriteAllBytes(path + "/plugins/ets2-telemetry-server.dll", Resources.ets2_telemetry_server_x86);
MainManager.Logger.Debug("Installed ETS2 plugin in {0}", path);
}
catch (Exception e)
{
MainManager.Logger.Error(e, "Failed to install ETS2 plugin in {0}", path);
throw;
}
}
}
}

View File

@ -96,11 +96,7 @@ namespace Artemis.Modules.Games.UnrealTournament
}
// Load the ZIP from resources
var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("Artemis.Modules.Games.UnrealTournament.Resources.ut-plugin.zip");
if (stream == null)
throw new FileNotFoundException("Couldn't load the UT plugin files from resources.");
var stream = new MemoryStream(Resources.ut_plugin);
var archive = new ZipArchive(stream);
try
{

View File

@ -7,6 +7,7 @@ using System.Reflection;
using System.Windows.Forms;
using Artemis.InjectionFactories;
using Artemis.Managers;
using Artemis.Properties;
using Artemis.Utilities;
using Artemis.ViewModels.Abstract;
@ -47,10 +48,7 @@ namespace Artemis.Modules.Games.Witcher3
}
// Load the ZIP from resources
var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("Artemis.Modules.Games.Witcher3.Resources.witcher3-mod.zip");
if (stream == null)
throw new FileNotFoundException("Couldn't load the Witcher 3 mod files from resources.");
var stream = new MemoryStream(Resources.witcher3_mod);
var archive = new ZipArchive(stream);
// Look for any conflicting mods

View File

@ -52,5 +52,5 @@ using System.Windows;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyVersion("1.3.1.0")]
[assembly: AssemblyFileVersion("1.3.1.0")]

View File

@ -148,6 +148,26 @@ namespace Artemis.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] ets2_telemetry_server_x64 {
get {
object obj = ResourceManager.GetObject("ets2_telemetry_server_x64", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] ets2_telemetry_server_x86 {
get {
object obj = ResourceManager.GetObject("ets2_telemetry_server_x86", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@ -193,4 +193,10 @@
<data name="redeemer" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Modules\Games\UnrealTournament\Resources\redeemer.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ets2_telemetry_server_x64" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Modules\Games\EurotruckSimulator2\Resources\Win64\ets2-telemetry-server.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="ets2_telemetry_server_x86" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Modules\Games\EurotruckSimulator2\Resources\Win32\ets2-telemetry-server.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>

View File

@ -76,7 +76,7 @@ namespace Artemis.Utilities
if (friendlyName != Empty)
list.Add(parent);
if (propertyInfo.PropertyType.Name != "String")
if (propertyInfo.PropertyType.Name != "String" && propertyInfo.PropertyType.Name != "DateTime")
list.AddRange(GenerateTypeMap(propertyInfo.PropertyType.GetProperties(),
path + $"{propertyInfo.Name}."));
}

View File

@ -40,11 +40,13 @@ namespace Artemis.Utilities
{
await mgr.Result.UpdateApp();
Logger.Info("Update check complete");
mgr.Result.Dispose();
mgr.Result.Dispose(); // This seems odd but if it's not disposed and exception is thrown
}
catch (Exception e)
{
// These exceptions should only really occur when running from VS
Logger.Error(e, "Update check failed");
mgr.Result.Dispose();
}
}
}

View File

@ -15,8 +15,7 @@ namespace Artemis.Views
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(
"https://github.com/SpoinkyNL/Artemis/wiki/Frequently-Asked-Questions-(FAQ)");
System.Diagnostics.Process.Start(e.Uri.ToString());
}
}
}