Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions RaceOverlay/API/Overlays/FlagPanel/FlagPanel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flag Panel</title>
<style>
body {
margin: 0;
padding: 0;
background-color: transparent;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

.overlay-container {
background-color: #1E1E1E;
border-radius: 10px;
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
}

.flag-canvas {
border-radius: 5px;
display: block;
}
</style>
</head>
<body>
<div class="overlay-container">
<canvas id="canvas" class="flag-canvas" width="80" height="80"></canvas>
</div>
<script>
let dsqFlag = new Image();
let checkeredFlag = new Image();
let debrisFlag = new Image();
let meetball_flag = new Image();

async function getImages() {
try {
const responseDsq = await fetch('/overlay/flag_panel/dsq_flag');
const dataDsq = await responseDsq.json();
dsqFlag.src = dataDsq.image;
} catch (error) {
console.error('Failed to get image:', error);
}

try {
const responseCheck = await fetch('/overlay/flag_panel/checkered_flag');
const dataCheck = await responseCheck.json();
checkeredFlag.src = dataCheck.image;
} catch (error) {
console.error('Failed to get image:', error);
}

try {
const responseDeb = await fetch('/overlay/flag_panel/debris_flag');
const dataDeb = await responseDeb.json();
debrisFlag.src = dataDeb.image;
} catch (error) {
console.error('Failed to get image:', error);
}

try {
const responseMeet = await fetch('/overlay/flag_panel/meetball_flag');
const dataMeet = await responseMeet.json();
meetball_flag.src = dataMeet.image;
} catch (error) {
console.error('Failed to get image:', error);
}
}

async function updateFlagPanel() {
try {
const response = await fetch('/overlay/flag_panel/data');
const data = await response.json();

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

switch (data.flag) {
case "dsq": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(dsqFlag, 0, 0, canvas.width, canvas.height);
break;
}
case "checkered": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(checkeredFlag, 0, 0, canvas.width, canvas.height);
break;
}
case "debris": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(debrisFlag, 0, 0, canvas.width, canvas.height);
break;
}
case "repair": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(meetball_flag, 0, 0, canvas.width, canvas.height);
break;
}
case "green": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#00FF00"; // Green background
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}
case "yellow": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#FFFF00"; // Yellow background
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}
case "red": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#FF0000"; // Red background
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}
case "blue": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#0000FF"; // Blue background
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}
case "white": {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#FFFFFF"; // White background
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}

default: {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#393939"; // Default background color
ctx.fillRect(0, 0, canvas.width, canvas.height);
break;
}
}
} catch (error) {
console.error('Failed to update FlagPanel:', error);
}
}

getImages();
// Update every 16ms (approximately 60fps)
setInterval(updateFlagPanel, 16);
</script>
</body>
</html>
49 changes: 49 additions & 0 deletions RaceOverlay/API/Overlays/FlagPanel/FlagPanelModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using RaceOverlay.Data;

namespace RaceOverlay.API.Overlays.FlagPanel;

public class FlagPanelModel
{
public string flag { get; set; }

public FlagPanelModel()
{
IrsdkFlags flagState = MainWindow.IRacingData.LocalDriver.CurrentIrsdkFlags;
switch (flagState)
{
case IrsdkFlags.Disqualify:
flag = "dsq";
break;
case IrsdkFlags.Checkered:
flag = "checkered";
break;
case IrsdkFlags.Black | IrsdkFlags.Furled:
flag = "black";
break;
case IrsdkFlags.Debris:
flag = "debris";
break;
case IrsdkFlags.Repair:
flag = "repair";
break;
case IrsdkFlags.Red:
flag = "red";
break;
case IrsdkFlags.Blue:
flag = "blue";
break;
case IrsdkFlags.Caution | IrsdkFlags.Yellow | IrsdkFlags.CautionWaving | IrsdkFlags.YellowWaving:
flag = "yellow";
break;
case IrsdkFlags.White:
flag = "white";
break;
case IrsdkFlags.Green:
flag = "green";
break;
default:
flag = "none";
break;
}
}
}
143 changes: 143 additions & 0 deletions RaceOverlay/API/StartAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
using Microsoft.Extensions.Hosting;
using RaceOverlay.API.Overlays.Electronics;
using RaceOverlay.API.Overlays.EnergyInfo;
using RaceOverlay.API.Overlays.FlagPanel;
using RaceOverlay.API.Overlays.LaptimeDelta;
using RaceOverlay.API.Overlays.SetupHider;
using RaceOverlay.API.Overlays.WeatherInfo;
using RaceOverlay.Internals;

namespace RaceOverlay.API;

Expand Down Expand Up @@ -262,6 +264,147 @@ public static IHost StartApiServer()
LaptimeDeltaModel data = new LaptimeDeltaModel(MainWindow.IRacingData.LocalDriver.LastLapDelta);
return Results.Ok(data);
});


//
// Flag Panel
//
endpoints.MapGet("/overlay/flag_panel", () =>
{
var assembly = typeof(StartAPI).Assembly;
var resourceName = "RaceOverlay.API.Overlays.FlagPanel.FlagPanel.html";

using var stream = assembly.GetManifestResourceStream(resourceName);
if (stream == null)
{
return Results.NotFound("Overlay file not found");
}

using var reader = new StreamReader(stream);
var htmlContent = reader.ReadToEnd();
return Results.Content(htmlContent, "text/html");
})
.WithName("GetFlagPanelOverlay");

endpoints.MapGet("/overlay/flag_panel/data", () =>
{
Debug.WriteLine("GetSetupHiderOverlayData");
FlagPanelModel data = new FlagPanelModel();
return Results.Ok(data);
})
.WithName("GetFlagPanelData");

endpoints.MapGet("/overlay/flag_panel/dsq_flag", () =>
{
Debug.WriteLine("GetMeetballFlagImage");

var assembly = typeof(StartAPI).Assembly;
var resourceName = "RaceOverlay.Overlays.FlagPanel.dsq_flag.png";

using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
Debug.WriteLine($"Resource nicht gefunden: {resourceName}");
return Results.NotFound("Flag-Bild nicht gefunden");
}

using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byte[] imageBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string mimeType = "image/png"; // Anpassen je nach Bildformat

ImageClass data = new ImageClass($"data:{mimeType};base64,{base64String}");
return Results.Ok(data);
}
}
}).WithName("GetFlagPanelDSQImage");

endpoints.MapGet("/overlay/flag_panel/checkered_flag", () =>
{
Debug.WriteLine("GetMeetballFlagImage");

var assembly = typeof(StartAPI).Assembly;
var resourceName = "RaceOverlay.Overlays.FlagPanel.checkered_flag.png";

using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
Debug.WriteLine($"Resource nicht gefunden: {resourceName}");
return Results.NotFound("Flag-Bild nicht gefunden");
}

using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byte[] imageBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string mimeType = "image/png"; // Anpassen je nach Bildformat

ImageClass data = new ImageClass($"data:{mimeType};base64,{base64String}");
return Results.Ok(data);
}
}
}).WithName("GetFlagPanelCheckeredImage");

endpoints.MapGet("/overlay/flag_panel/debris_flag", () =>
{
Debug.WriteLine("GetMeetballFlagImage");

var assembly = typeof(StartAPI).Assembly;
var resourceName = "RaceOverlay.Overlays.FlagPanel.debris_flag.png";

using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
Debug.WriteLine($"Resource nicht gefunden: {resourceName}");
return Results.NotFound("Flag-Bild nicht gefunden");
}

using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byte[] imageBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string mimeType = "image/png"; // Anpassen je nach Bildformat

ImageClass data = new ImageClass($"data:{mimeType};base64,{base64String}");
return Results.Ok(data);
}
}
}).WithName("GetFlagPanelDebrisImage");

endpoints.MapGet("/overlay/flag_panel/meetball_flag", () =>
{
Debug.WriteLine("GetMeetballFlagImage");

var assembly = typeof(StartAPI).Assembly;
var resourceName = "RaceOverlay.Overlays.FlagPanel.meetball_flag.png";

using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
Debug.WriteLine($"Resource nicht gefunden: {resourceName}");
return Results.NotFound("Flag-Bild nicht gefunden");
}

using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byte[] imageBytes = memoryStream.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
string mimeType = "image/png"; // Anpassen je nach Bildformat

ImageClass data = new ImageClass($"data:{mimeType};base64,{base64String}");
return Results.Ok(data);
}
}
}).WithName("GetMeetballFlagImage");
});

})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RaceOverlay.API.Overlays.SetupHider;
namespace RaceOverlay.Internals;

public class ImageClass
{
Expand Down
1 change: 1 addition & 0 deletions RaceOverlay/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private void _initOverlays()
StreamOverlays.Add(new BestLaptimeDelta());
StreamOverlays.Add(new StreamOverlay.Electronics.Electronics());
StreamOverlays.Add(new StreamOverlay.EnergyInfo.EnergyInfo());
StreamOverlays.Add(new StreamOverlay.FlagPanel.FlagPanel());
StreamOverlays.Add(new StreamOverlay.Inputs.Inputs());
StreamOverlays.Add(new LastLaptimeDelta());
StreamOverlays.Add(new SetupHider());
Expand Down
2 changes: 1 addition & 1 deletion RaceOverlay/Overlays/FlagPanel/FlagPanel.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public FlagPanel(): base("Flag Panel", "This Overlay shows the current flag stat
LoadEmbeddedImage(CheckeredFlag, "RaceOverlay.Overlays.FlagPanel.checkered_flag.png");
LoadEmbeddedImage(DsqFlag, "RaceOverlay.Overlays.FlagPanel.dsq_flag.png");
LoadEmbeddedImage(RepairFlag, "RaceOverlay.Overlays.FlagPanel.meetball_flag.png");
LoadEmbeddedImage(DebrisFlag, "RaceOverlay.Overlays.FlagPanel.debris_flag.png");
LoadEmbeddedImage(DebrisFlag, "RaceOverlay.Overlays.FlagPanel.debris_flag.png");
SetGreen();

Thread updateThread = new Thread(UpdateThreadMethod);
Expand Down
2 changes: 2 additions & 0 deletions RaceOverlay/RaceOverlay.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
<EmbeddedResource Include="Overlays\FlagPanel\meetball_flag.png" />
<None Remove="Overlays\FlagPanel\debries_flag.png" />
<EmbeddedResource Include="Overlays\FlagPanel\debris_flag.png" />
<None Remove="API\Overlays\FlagPanel\FlagPanel.html" />
<EmbeddedResource Include="API\Overlays\FlagPanel\FlagPanel.html" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading