diff --git a/Contract/Tesla.Contract.csproj b/Contract/Tesla.Contract.csproj index d6fe5b4..c3a8c24 100644 --- a/Contract/Tesla.Contract.csproj +++ b/Contract/Tesla.Contract.csproj @@ -1,8 +1,9 @@ - - net48;net8.0-windows + + net48 - + + + diff --git a/Launcher/TeslaLauncherService.cs b/Launcher/TeslaLauncherService.cs index 2a6dba7..ff7cfc6 100644 --- a/Launcher/TeslaLauncherService.cs +++ b/Launcher/TeslaLauncherService.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.IO; using System.IO.Compression; using System.IO.Pipes; @@ -151,31 +152,39 @@ namespace Tesla.Launcher.Service _listener.Start(); _logger.LogInformation("Listening. Waiting for Console connections..."); + // net48's TcpListener has no CancellationToken overload for accept; + // stop the listener on cancellation so the pending accept unblocks. + using var stopReg = stoppingToken.Register(() => { try { _listener.Stop(); } catch { } }); + while (!stoppingToken.IsCancellationRequested) { + TcpClient client; try { - var client = await _listener.AcceptTcpClientAsync(stoppingToken); - _logger.LogInformation( - "Console connected from {EP}", client.Client.RemoteEndPoint); - - // Handle each Console connection on its own thread. - // Frame reads are synchronous, so we offload to a - // thread-pool thread via Task.Run. - var task = Task.Run( - () => HandleConsoleClient(client, stoppingToken), - stoppingToken); - - lock (_taskLock) - { - _clientTasks.Add(task); - _clientTasks.RemoveAll(t => t.IsCompleted); - } + client = await _listener.AcceptTcpClientAsync(); } catch (OperationCanceledException) { break; } + catch (Exception) when (stoppingToken.IsCancellationRequested) { break; } catch (Exception ex) { _logger.LogError(ex, "Error accepting Console connection"); + continue; + } + + _logger.LogInformation( + "Console connected from {EP}", client.Client.RemoteEndPoint); + + // Handle each Console connection on its own thread. + // Frame reads are synchronous, so we offload to a + // thread-pool thread via Task.Run. + var task = Task.Run( + () => HandleConsoleClient(client, stoppingToken), + stoppingToken); + + lock (_taskLock) + { + _clientTasks.Add(task); + _clientTasks.RemoveAll(t => t.IsCompleted); } } } @@ -209,7 +218,7 @@ namespace Tesla.Launcher.Service // Generate and send our IV var podIv = new byte[16]; - RandomNumberGenerator.Fill(podIv); + using (var rng = RandomNumberGenerator.Create()) rng.GetBytes(podIv); netStream.Write(podIv, 0, 16); netStream.Flush(); @@ -230,7 +239,7 @@ namespace Tesla.Launcher.Service _logger.LogWarning("CONF read failed: {Msg}", ex.Message); return; } - if (!confReply.AsSpan().SequenceEqual(confMsg)) + if (!confReply.SequenceEqual(confMsg)) { _logger.LogWarning("CONF mismatch — session key mismatch, dropping connection."); return; @@ -879,8 +888,8 @@ namespace Tesla.Launcher.Service // Send IpcMessage var reqBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(msg)); - await pipe.WriteAsync(BitConverter.GetBytes(reqBytes.Length), ct); - await pipe.WriteAsync(reqBytes, ct); + await pipe.WriteAsync(BitConverter.GetBytes(reqBytes.Length), 0, 4, ct); + await pipe.WriteAsync(reqBytes, 0, reqBytes.Length, ct); await pipe.FlushAsync(ct); // Read IpcResponse diff --git a/Launcher/TeslaLauncherService.csproj b/Launcher/TeslaLauncherService.csproj index b6d15a4..406795f 100644 --- a/Launcher/TeslaLauncherService.csproj +++ b/Launcher/TeslaLauncherService.csproj @@ -1,20 +1,17 @@ - + - net8.0-windows + net48 + Exe disable disable + latest true 4.11.4.1 app.ico TeslaLauncherService Tesla.Launcher.Service - x64 - win-x64 - true - true - true @@ -23,22 +20,26 @@ + + + + + + + + + - + + - - + - diff --git a/Launcher/build.bat b/Launcher/build.bat index eacebba..6c12ab1 100644 --- a/Launcher/build.bat +++ b/Launcher/build.bat @@ -3,11 +3,12 @@ :: TeslaLauncher — Unified Build / Package Script :: ============================================================================= :: Publishes TeslaLauncherService.exe and TeslaLauncherAgent.exe as -:: self-contained single-file win-x64 executables (net8) and assembles the -:: installable TeslaLauncher\ package next to install.bat. +:: framework-dependent net48 builds and assembles the installable TeslaLauncher\ +:: package next to install.bat. The target pod needs .NET Framework 4.8 (built +:: into Windows 10/11) — there is no bundled runtime, so the package is small. :: :: Requirements: -:: .NET 8 SDK https://dotnet.microsoft.com/download/dotnet/8.0 +:: .NET SDK (6.0+) to drive the build https://dotnet.microsoft.com/download :: Internet access for NuGet restore (first build only) :: :: Usage: @@ -31,7 +32,6 @@ setlocal enabledelayedexpansion set ROOT=%~dp0 set BUILD_DIR=%ROOT%TeslaLauncher -set RID=win-x64 :: -- Parse arguments ---------------------------------------------------------- set BUILD_SERVICE=1 @@ -46,7 +46,7 @@ for %%a in (%*) do ( echo. echo ============================================================ -echo Tesla Launcher v0.1 - Build ^& Package (net8, %RID%) +echo Tesla Launcher v0.1 - Build ^& Package (net48, framework-dependent) echo Output : %BUILD_DIR% echo ============================================================ echo. @@ -75,9 +75,6 @@ echo [1/2] Publishing TeslaLauncherService (Session 0 Windows Service)... echo. dotnet publish "%ROOT%TeslaLauncherService.csproj" ^ -c Release ^ - -r %RID% ^ - --self-contained true ^ - -p:PublishSingleFile=true ^ -o "%BUILD_DIR%\Service" if errorlevel 1 ( echo. @@ -98,9 +95,6 @@ if %BUILD_SERVICE%==1 (echo [2/2] Publishing TeslaLauncherAgent...) else (echo [ echo. dotnet publish "%ROOT%TeslaLauncherAgent.csproj" ^ -c Release ^ - -r %RID% ^ - --self-contained true ^ - -p:PublishSingleFile=true ^ "-p:DefineConstants=WINFORMS" ^ -o "%BUILD_DIR%\Agent" if errorlevel 1 ( diff --git a/Launcher/install.bat b/Launcher/install.bat index f3ccfc3..fb488ed 100644 --- a/Launcher/install.bat +++ b/Launcher/install.bat @@ -120,9 +120,11 @@ echo C:\Games (Users: modify access) :: ── STEP 2: Copy files ──────────────────────────────────────────────────────── echo [2/8] Copying files... -copy /Y "%SERVICE_SRC%\TeslaLauncherService.exe" "%INSTALL_DIR%\" >nul -copy /Y "%AGENT_SRC%\TeslaLauncherAgent.exe" "%INSTALL_DIR%\" >nul -copy /Y "%AGENT_SRC%\*.dll" "%INSTALL_DIR%\" >nul 2>&1 +:: net48 framework-dependent build: each folder holds the exe + its dependency +:: DLLs + .config. Copy both folders into the install dir (shared DLLs overwrite +:: identically; the two .exe.config files coexist). +copy /Y "%SERVICE_SRC%\*.*" "%INSTALL_DIR%\" >nul +copy /Y "%AGENT_SRC%\*.*" "%INSTALL_DIR%\" >nul :: Install DirectX June 2010 runtime (required by games) if exist "%ROOT%\dx9201006\DXSETUP.exe" ( diff --git a/TeslaSuite.sln b/TeslaSuite.sln index 43359de..7de397a 100644 --- a/TeslaSuite.sln +++ b/TeslaSuite.sln @@ -36,14 +36,14 @@ Global {467AA87A-FBD4-45D7-B8F8-9336C95884D2}.Debug|Any CPU.Build.0 = Debug|Any CPU {467AA87A-FBD4-45D7-B8F8-9336C95884D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {467AA87A-FBD4-45D7-B8F8-9336C95884D2}.Release|Any CPU.Build.0 = Release|Any CPU - {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Debug|Any CPU.ActiveCfg = Debug|x64 - {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Debug|Any CPU.Build.0 = Debug|x64 - {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Release|Any CPU.ActiveCfg = Release|x64 - {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Release|Any CPU.Build.0 = Release|x64 - {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Debug|Any CPU.ActiveCfg = Debug|x64 - {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Debug|Any CPU.Build.0 = Debug|x64 - {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Release|Any CPU.ActiveCfg = Release|x64 - {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Release|Any CPU.Build.0 = Release|x64 + {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {910D4404-B3A2-4217-B61C-D43E7F22CDAA}.Release|Any CPU.Build.0 = Release|Any CPU + {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {916DCDA5-3379-4383-96F0-AC7B26FAF64E}.Release|Any CPU.Build.0 = Release|Any CPU {0B2E3F1F-56C4-4B1A-AC26-4BF34AA10F1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0B2E3F1F-56C4-4B1A-AC26-4BF34AA10F1B}.Debug|Any CPU.Build.0 = Debug|Any CPU {0B2E3F1F-56C4-4B1A-AC26-4BF34AA10F1B}.Release|Any CPU.ActiveCfg = Release|Any CPU