mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-11-13 09:40:10 +01:00
Compare commits
11 Commits
feature/bl
...
v1.5.234
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
744720d922 | ||
|
|
b5ba67430f | ||
|
|
c261d4b0ab | ||
|
|
3aa6a256a5 | ||
|
|
95c510b3ac | ||
|
|
5af567be7f | ||
|
|
b201b6f7ab | ||
|
|
3a19fd5da2 | ||
|
|
36df14abee | ||
|
|
da5a1efea1 | ||
|
|
e5330d91a6 |
13
.config/dotnet-tools.json
Normal file
13
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-sonarscanner": {
|
||||
"version": "12.1.0",
|
||||
"commands": [
|
||||
"dotnet-sonarscanner"
|
||||
],
|
||||
"rollForward": true
|
||||
}
|
||||
}
|
||||
}
|
||||
114
.github/workflows/sonar.yml
vendored
Normal file
114
.github/workflows/sonar.yml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# .github/workflows/sonar.yml
|
||||
# Has SONAR_TOKEN, so it only ever builds code that is already trusted: pushes to
|
||||
# main and pull requests opened from a branch of this repository.
|
||||
#
|
||||
# Unlike the C++ analysis of maszyna, this one cannot be split into an untrusted
|
||||
# build and a trusted scan. The C# analyzers run inside the compiler, and the
|
||||
# scanner's begin step, which needs the token, has to run before the build on the
|
||||
# same machine. A fork's build could leave a process behind to read the token from
|
||||
# the end step, so fork pull requests are not analysed here. GitHub withholds the
|
||||
# secret from them (and from Dependabot) anyway.
|
||||
#
|
||||
# The scanner is pinned in .config/dotnet-tools.json, where Dependabot updates it.
|
||||
# SonarScanner for .NET takes its settings on the command line only; it refuses
|
||||
# to run next to a sonar-project.properties, so there is none.
|
||||
|
||||
name: SonarQube Cloud
|
||||
|
||||
on:
|
||||
# Main branch only: analysing other branches is a paid feature, pull requests
|
||||
# are not.
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- staging
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: sonar-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
DOTNET_NOLOGO: true
|
||||
SOLUTION_PATH: StarterNG.sln
|
||||
TEST_PROJECT_PATH: StarterNG.Tests/StarterNG.Tests.csproj
|
||||
|
||||
jobs:
|
||||
sonar:
|
||||
name: Analyze
|
||||
if: >
|
||||
github.event_name != 'pull_request' ||
|
||||
(github.event.pull_request.head.repo.full_name == github.repository &&
|
||||
github.actor != 'dependabot[bot]')
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
# Full history, so new code and blame are told apart correctly.
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup .NET 9
|
||||
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
|
||||
with:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Restore tools
|
||||
run: dotnet tool restore
|
||||
|
||||
# sonar.qualitygate.wait=true blocks the end step until the server has
|
||||
# processed the report, so the job's result is the quality gate's.
|
||||
- name: Begin analysis
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: >
|
||||
dotnet tool run dotnet-sonarscanner begin
|
||||
/k:"MaSzyna-EU07_StarterNG"
|
||||
/o:"maszyna-eu07"
|
||||
/n:"StarterNG"
|
||||
/d:sonar.host.url="https://sonarcloud.io"
|
||||
/d:sonar.token="$SONAR_TOKEN"
|
||||
/d:sonar.scm.revision="${{ github.event.pull_request.head.sha || github.sha }}"
|
||||
/d:sonar.cs.opencover.reportsPaths="TestResults/**/coverage.opencover.xml"
|
||||
/d:sonar.cs.vstest.reportsPaths="TestResults/*.trx"
|
||||
/d:sonar.qualitygate.wait=true
|
||||
|
||||
# A full, non-incremental build: the analyzers only see what is compiled.
|
||||
- name: Build
|
||||
run: >
|
||||
dotnet build "${{ env.SOLUTION_PATH }}"
|
||||
-c Release
|
||||
--no-incremental
|
||||
|
||||
# Coverlet is already referenced by the test project; OpenCover is the
|
||||
# format the C# analyzer reads.
|
||||
- name: Test with coverage
|
||||
run: >
|
||||
dotnet test "${{ env.TEST_PROJECT_PATH }}"
|
||||
-c Release
|
||||
--no-build
|
||||
--results-directory TestResults
|
||||
--logger trx
|
||||
--collect "XPlat Code Coverage"
|
||||
--
|
||||
DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
|
||||
|
||||
- name: End analysis
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: >
|
||||
dotnet tool run dotnet-sonarscanner end
|
||||
/d:sonar.token="$SONAR_TOKEN"
|
||||
@@ -65,6 +65,19 @@ public class PhysicsAndAssetsTests
|
||||
Assert.Equal(125, physics.VMax);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_dot_in_the_model_name_is_part_of_the_name()
|
||||
{
|
||||
// As in the game: cd/9-107_v1 holds 9-107.13.fiz, 9-107.6.fiz and more.
|
||||
var installation = new TestInstallation(new InMemoryFileSystem()
|
||||
.WithFile(Fiz("cd", "9-107_v1", "9-107.13"), "Load: LoadAccepted=coal MaxLoad=58")
|
||||
.WithFile(Fiz("cd", "9-107_v1", "9-107.6"), "Load: LoadAccepted=coal MaxLoad=55"));
|
||||
|
||||
Assert.Equal(58, installation.Physics.For("cd/9-107_v1/", "9-107.13")!.MaxLoad);
|
||||
Assert.Equal(55, installation.Physics.For("cd/9-107_v1/", "9-107.6")!.MaxLoad);
|
||||
Assert.Equal(58, installation.Physics.For("cd/9-107_v1/", "9-107.13.e3d")!.MaxLoad);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_dumb_variant_stands_in_when_the_model_has_no_fiz_of_its_own()
|
||||
{
|
||||
|
||||
@@ -13,6 +13,6 @@ public static class AppInfo
|
||||
#if DEBUG
|
||||
text += " (DEBUG)";
|
||||
#endif
|
||||
return text + " public beta";
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public sealed class FizPhysicsRepository : IPhysicsRepository
|
||||
if (string.IsNullOrEmpty(model))
|
||||
return null;
|
||||
|
||||
string name = Path.GetFileNameWithoutExtension(model);
|
||||
string name = Path.GetFileName(model);
|
||||
if (name.Length == 0)
|
||||
return null;
|
||||
|
||||
@@ -60,7 +60,10 @@ public sealed class FizPhysicsRepository : IPhysicsRepository
|
||||
if (_cache.TryGetValue(key, out var cached))
|
||||
return cached;
|
||||
|
||||
var physics = Read(folder, name);
|
||||
// The name as written first: in 9-107.13 the dot is part of the name, not an extension.
|
||||
string bare = Path.GetFileNameWithoutExtension(name);
|
||||
var physics = Read(folder, name)
|
||||
?? (bare.Length > 0 && bare != name ? Read(folder, bare) : null);
|
||||
_cache[key] = physics;
|
||||
return physics;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ public partial class MainWindow : Window
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
InitializeComponent();
|
||||
// The top bar lets the version go first when it runs short of room, which at the usual widths it does;
|
||||
// the title has room for it at any width.
|
||||
Title = $"{Title} {AppInfo.Version}";
|
||||
|
||||
ExtendClientAreaToDecorationsHint = true;
|
||||
ExtendClientAreaTitleBarHeightHint = TitleBarHeight;
|
||||
|
||||
@@ -1009,12 +1009,14 @@ public partial class Scenarios : UserControl
|
||||
int thumbH = AppServices.Current.Settings.LargeThumbnails ? 64 : 32;
|
||||
|
||||
var bmp = LoadMini(miniName, thumbH);
|
||||
// Fill, not Uniform: at a scale such as 125 % layout rounds the slot up to whole pixels,
|
||||
// and a mini keeping its own width inside it left a line of the background between two vehicles.
|
||||
Control visual = bmp is not null
|
||||
? MiniTextures.Sharp(new Image
|
||||
{
|
||||
Source = bmp,
|
||||
Height = thumbH,
|
||||
Stretch = Avalonia.Media.Stretch.Uniform,
|
||||
Stretch = Avalonia.Media.Stretch.Fill,
|
||||
Margin = new Thickness(0)
|
||||
})
|
||||
: MiniTextures.MissingVisual(train.SkinFile, thumbH);
|
||||
@@ -1022,6 +1024,22 @@ public partial class Scenarios : UserControl
|
||||
bool selected = !string.IsNullOrEmpty(train.Name) &&
|
||||
string.Equals(train.Name, AppServices.Current.State.StartingVehicleName,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
// The vehicle started in gets a frame over its picture as well as the lines above and below:
|
||||
// two thin lines alone were hard to see. Drawn over the picture, it moves no vehicle aside.
|
||||
if (selected)
|
||||
visual = new Panel
|
||||
{
|
||||
Children =
|
||||
{
|
||||
visual,
|
||||
new Border
|
||||
{
|
||||
BorderThickness = new Thickness(3),
|
||||
BorderBrush = SelectedVehicleBrush,
|
||||
IsHitTestVisible = false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var slot = new Border
|
||||
{
|
||||
@@ -1210,7 +1228,9 @@ public partial class Scenarios : UserControl
|
||||
var source = consistStack.Children[i];
|
||||
// The ghost mirrors what the slot shows, stand-in wagons included, so
|
||||
// dragging a vehicle with no thumbnail still carries something visible.
|
||||
Control copy = source is Border { Child: Image image }
|
||||
// The picked vehicle's picture sits under its frame.
|
||||
var shown = source is Border { Child: Panel { Children: [Image framed, ..] } } ? framed : (source as Border)?.Child;
|
||||
Control copy = shown is Image image
|
||||
? new Image { Source = image.Source, Height = image.Height, Stretch = image.Stretch }
|
||||
: MiniTextures.MissingVisual(null, (int)source.Bounds.Height);
|
||||
panel.Children.Add(copy);
|
||||
|
||||
Reference in New Issue
Block a user