mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Compare commits
1 Commits
v162.0.0
...
feature/st
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42b414d3b7 |
21
.github/CODEOWNERS
vendored
21
.github/CODEOWNERS
vendored
@@ -1,9 +1,20 @@
|
||||
# Last match in file takes precedence.
|
||||
|
||||
# Ping for all PRs
|
||||
* @PJB3005 @DrSmugleaf
|
||||
* @Acruid @PJB3005 @Silvertorch5
|
||||
|
||||
# commands commands commands commands
|
||||
**/Toolshed/** @moonheart08
|
||||
*Command.cs @moonheart08
|
||||
*Commands.cs @moonheart08
|
||||
/Robust.*/Audio/Midi/ @Zumorica
|
||||
|
||||
/Robust.Client.NameGenerator @PaulRitter
|
||||
/Robust.Client.Injectors @PaulRitter
|
||||
/Robust.Generators @PaulRitter
|
||||
/Robust.Analyzers @PaulRitter
|
||||
/Robust.*/GameStates @PaulRitter
|
||||
/Robust.Shared/Analyzers @PaulRitter
|
||||
/Robust.*/Serialization @PaulRitter @DrSmugleaf
|
||||
/Robust.*/Prototypes @PaulRitter
|
||||
/Robust.Shared/GameObjects/ComponentDependencies @PaulRitter
|
||||
/Robust.*/Containers @PaulRitter
|
||||
|
||||
# Be they Fluent translations or Freemarker templates, I know them both!
|
||||
*.ftl @RemieRichards
|
||||
|
||||
30
.github/workflows/benchmarks.yml
vendored
30
.github/workflows/benchmarks.yml
vendored
@@ -9,6 +9,14 @@ on:
|
||||
|
||||
concurrency: benchmarks
|
||||
|
||||
env:
|
||||
ROBUST_BENCHMARKS_ENABLE_SQL: 1
|
||||
ROBUST_BENCHMARKS_SQL_ADDRESS: ${{ secrets.BENCHMARKS_WRITE_ADDRESS }}
|
||||
ROBUST_BENCHMARKS_SQL_PORT: ${{ secrets.BENCHMARKS_WRITE_PORT }}
|
||||
ROBUST_BENCHMARKS_SQL_USER: ${{ secrets.BENCHMARKS_WRITE_USER }}
|
||||
ROBUST_BENCHMARKS_SQL_PASSWORD: ${{ secrets.BENCHMARKS_WRITE_PASSWORD }}
|
||||
ROBUST_BENCHMARKS_SQL_DATABASE: benchmarks
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
name: Run Benchmarks
|
||||
@@ -20,22 +28,8 @@ jobs:
|
||||
host: centcomm.spacestation14.io
|
||||
username: robust-benchmark-runner
|
||||
key: ${{ secrets.CENTCOMM_ROBUST_BENCHMARK_RUNNER_KEY }}
|
||||
command_timeout: 100000m
|
||||
command_timeout: 100000m
|
||||
script: |
|
||||
mkdir benchmark_run_${{ github.sha }}
|
||||
cd benchmark_run_${{ github.sha }}
|
||||
git clone https://github.com/space-wizards/RobustToolbox.git repo_dir --recursive
|
||||
cd repo_dir
|
||||
git checkout ${{ github.sha }}
|
||||
cd Robust.Benchmarks
|
||||
dotnet restore
|
||||
export ROBUST_BENCHMARKS_ENABLE_SQL=1
|
||||
export ROBUST_BENCHMARKS_SQL_ADDRESS="${{ secrets.BENCHMARKS_WRITE_ADDRESS }}"
|
||||
export ROBUST_BENCHMARKS_SQL_PORT="${{ secrets.BENCHMARKS_WRITE_PORT }}"
|
||||
export ROBUST_BENCHMARKS_SQL_USER="${{ secrets.BENCHMARKS_WRITE_USER }}"
|
||||
export ROBUST_BENCHMARKS_SQL_PASSWORD="${{ secrets.BENCHMARKS_WRITE_PASSWORD }}"
|
||||
export ROBUST_BENCHMARKS_SQL_DATABASE="benchmarks"
|
||||
export GITHUB_SHA="${{ github.sha }}"
|
||||
dotnet run --filter '*' --configuration Release
|
||||
cd ../../..
|
||||
rm -rf benchmark_run_${{ github.sha }}
|
||||
wget https://raw.githubusercontent.com/space-wizards/RobustToolbox/${{ github.sha }}/Tools/run_benchmarks.py
|
||||
python3 run_benchmarks.py "${{ secrets.BENCHMARKS_WRITE_ADDRESS }}" "${{ secrets.BENCHMARKS_WRITE_PORT }}" "${{ secrets.BENCHMARKS_WRITE_USER }}" "${{ secrets.BENCHMARKS_WRITE_PASSWORD }}" "${{ github.sha }}"
|
||||
rm run_benchmarks.py
|
||||
|
||||
20
.github/workflows/build-docfx.yml
vendored
20
.github/workflows/build-docfx.yml
vendored
@@ -6,29 +6,29 @@ on:
|
||||
jobs:
|
||||
docfx:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.6.0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
dotnet-version: 6.0.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
|
||||
|
||||
- name: Build Project
|
||||
run: dotnet build --no-restore /p:WarningsAsErrors=nullable
|
||||
|
||||
- name: Build DocFX
|
||||
uses: nikeee/docfx-action@v1.0.0
|
||||
uses: nikeee/docfx-action@v1.0.0
|
||||
with:
|
||||
args: Robust.Docfx/docfx.json
|
||||
|
||||
|
||||
- name: Publish Docfx Documentation on GitHub Pages
|
||||
uses: maxheld83/ghpages@master
|
||||
env:
|
||||
BUILD_DIR: Robust.Docfx/_robust-site
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
BUILD_DIR: Robust.Docfx/_robust-site
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
|
||||
8
.github/workflows/build-test.yml
vendored
8
.github/workflows/build-test.yml
vendored
@@ -15,19 +15,19 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.6.0
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
dotnet-version: 6.0.x
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build --no-restore /p:WarningsAsErrors=nullable
|
||||
- name: Test Engine
|
||||
run: dotnet test --no-build Robust.UnitTesting/Robust.UnitTesting.csproj -- NUnit.ConsoleOut=0
|
||||
|
||||
|
||||
|
||||
|
||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -35,14 +35,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.6.0
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
dotnet-version: 6.0.100
|
||||
|
||||
- name: Build
|
||||
run: dotnet build
|
||||
|
||||
6
.github/workflows/publish-client.yml
vendored
6
.github/workflows/publish-client.yml
vendored
@@ -16,14 +16,14 @@ jobs:
|
||||
$ver = [regex]::Match($env:GITHUB_REF, "refs/tags/v?(.+)").Groups[1].Value
|
||||
echo ("::set-output name=version::{0}" -f $ver)
|
||||
|
||||
- uses: actions/checkout@v3.6.0
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
dotnet-version: 6.0.100
|
||||
|
||||
- name: Package client
|
||||
run: Tools/package_client_build.py -p windows mac linux
|
||||
|
||||
8
.github/workflows/test-content.yml
vendored
8
.github/workflows/test-content.yml
vendored
@@ -13,15 +13,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out content
|
||||
uses: actions/checkout@v3.6.0
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: space-wizards/space-station-14
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3.2.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 7.0.x
|
||||
dotnet-version: 6.0.100
|
||||
- name: Disable submodule autoupdate
|
||||
run: touch BuildChecker/DISABLE_SUBMODULE_AUTOUPDATE
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
- name: Build
|
||||
run: dotnet build --configuration Tools --no-restore
|
||||
run: dotnet build --configuration Release --no-restore
|
||||
- name: Content.Tests
|
||||
run: dotnet test --no-build Content.Tests/Content.Tests.csproj -v n
|
||||
- name: Content.IntegrationTests
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\MSBuild\Robust.Engine.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Submodule Lidgren.Network/Lidgren.Network updated: f19cea8010...1e7fb3c2b6
@@ -1,23 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>SpaceWizards.Lidgren.Network</AssemblyName>
|
||||
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<DefaultItemExcludes>Lidgren.Network/**/*</DefaultItemExcludes>
|
||||
<DefineConstants>$(DefineConstants);USE_RELEASE_STATISTICS</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
||||
<SkipRobustAnalyzer>true</SkipRobustAnalyzer>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Lidgren.Network\Lidgren.Network\**\*.cs">
|
||||
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
</Compile>
|
||||
<Compile Remove="Lidgren.Network\Lidgren.Network\obj\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="../MSBuild/Robust.Properties.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Robust.Shared.CompNetworkGenerator\Robust.Shared.CompNetworkGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,37 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Build configurations -->
|
||||
<PropertyGroup>
|
||||
<!-- Avoid SDK defining DEBUG/RELEASE/DEBUGOPT/TOOLS itself. -->
|
||||
<DisableImplicitConfigurationDefines>true</DisableImplicitConfigurationDefines>
|
||||
|
||||
<!-- Project configurations -->
|
||||
<Configurations>Debug;Release;Tools;DebugOpt</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
</PropertyGroup>
|
||||
<!-- Debug configuration: asserts, tools, no optimizations -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
|
||||
<Optimize Condition="'$(Optimize)' == ''">false</Optimize>
|
||||
<RobustToolsBuild Condition="'$(RobustToolsBuild)' == ''">true</RobustToolsBuild>
|
||||
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<!-- DebugOpt configuration: asserts, tools, optimizations -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'DebugOpt'">
|
||||
<DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
|
||||
<Optimize Condition="'$(Optimize)' == ''">true</Optimize>
|
||||
<RobustToolsBuild Condition="'$(RobustToolsBuild)' == ''">true</RobustToolsBuild>
|
||||
<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<!-- Tools configuration: no asserts, tools, optimizations -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Tools'">
|
||||
<DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
|
||||
<Optimize Condition="'$(Optimize)' == ''">true</Optimize>
|
||||
<RobustToolsBuild Condition="'$(RobustToolsBuild)' == ''">true</RobustToolsBuild>
|
||||
</PropertyGroup>
|
||||
<!-- Release configuration: no asserts, no tools, optimizations -->
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<Optimize Condition="'$(Optimize)' == ''">true</Optimize>
|
||||
<RobustToolsBuild Condition="'$(RobustToolsBuild)' == ''">false</RobustToolsBuild>
|
||||
<DefineConstants>RELEASE;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -20,19 +20,10 @@
|
||||
<PropertyGroup Condition="'$(FullRelease)' == 'True'">
|
||||
<DefineConstants>$(DefineConstants);FULL_RELEASE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(FullRelease)' != 'True'">
|
||||
<DefineConstants>$(DefineConstants);DEVELOPMENT</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release' Or '$(Configuration)' == 'Tools'">
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DefineConstants>$(DefineConstants);EXCEPTION_TOLERANCE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(EnableClientScripting)' == 'True'">
|
||||
<DefineConstants>$(DefineConstants);CLIENT_SCRIPTING</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(UseSystemSqlite)' == 'True'">
|
||||
<DefineConstants>$(DefineConstants);USE_SYSTEM_SQLITE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(RobustToolsBuild)' == 'true'">
|
||||
<DefineConstants>$(DefineConstants);TOOLS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
|
||||
<Project>
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<PropertyGroup><Version>0.40.3.0</Version></PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<Project>
|
||||
<!-- Engine-specific properties. Content should not use this file. -->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<LangVersion>11</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<WarningsAsErrors>nullable</WarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- MSBuild hurts and I can't find a foolproof way to detect platform. -->
|
||||
<PropertyGroup>
|
||||
<OS Condition="'$(OS)' == ''">Windows_NT</OS>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(OS)' != 'Unix'">
|
||||
<PropertyGroup>
|
||||
<ActualOS>Windows</ActualOS>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<!-- Folders that *probably* only exist on MacOS and not Linux. -->
|
||||
<When Condition="Exists('/Volumes') And Exists('/System') And Exists('/Library')" >
|
||||
<PropertyGroup>
|
||||
<ActualOS>MacOS</ActualOS>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition="$([MSBuild]::IsOSPlatform('FreeBSD'))">
|
||||
<PropertyGroup>
|
||||
<ActualOS>FreeBSD</ActualOS>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<ActualOS>Linux</ActualOS>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<PropertyGroup>
|
||||
<TargetOS Condition="'$(TargetOS)' == ''">$(ActualOS)</TargetOS>
|
||||
<Python>python3</Python>
|
||||
<Python Condition="'$(ActualOS)' == 'Windows'">py -3</Python>
|
||||
<UseSystemSqlite Condition="'$(TargetOS)' == 'FreeBSD'">True</UseSystemSqlite>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,31 +1,34 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Properties for both engine and content. -->
|
||||
<!-- Import this at the end of any project files in Robust and Content. -->
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<Import Project="Robust.Custom.targets" Condition="Exists('Robust.Custom.targets')"/>
|
||||
|
||||
<!-- Configuration logic -->
|
||||
<Import Project="Robust.Configurations.props" />
|
||||
|
||||
<!-- Some platform management logic -->
|
||||
<Import Project="Robust.Platform.props" />
|
||||
|
||||
<!-- MSBuild hurts and I can't find a foolproof way to detect platform. -->
|
||||
<PropertyGroup>
|
||||
<EnableClientScripting>False</EnableClientScripting>
|
||||
<!-- Client scripting is only enabled on tools builds for security and size reasons. -->
|
||||
<EnableClientScripting Condition="'$(RobustToolsBuild)' == 'true'">True</EnableClientScripting>
|
||||
<OS Condition="'$(OS)' == ''">Windows_NT</OS>
|
||||
</PropertyGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(OS)' != 'Unix'">
|
||||
<PropertyGroup>
|
||||
<ActualOS>Windows</ActualOS>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<!-- Folders that *probably* only exist on MacOS and not Linux. -->
|
||||
<When Condition="Exists('/Volumes') And Exists('/System') And Exists('/Library')" >
|
||||
<PropertyGroup>
|
||||
<ActualOS>MacOS</ActualOS>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<PropertyGroup>
|
||||
<ActualOS>Linux</ActualOS>
|
||||
</PropertyGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<PropertyGroup>
|
||||
<TargetOS Condition="'$(TargetOS)' == ''">$(ActualOS)</TargetOS>
|
||||
<Python>python3</Python>
|
||||
<Python Condition="'$(ActualOS)' == 'Windows'">py -3</Python>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<EnableClientScripting>True</EnableClientScripting>
|
||||
<!-- Client scripting is disabled on full release builds for security and size reasons. -->
|
||||
<EnableClientScripting Condition="'$(FullRelease)' == 'True'">False</EnableClientScripting>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- built-in define constants -->
|
||||
<Import Project="Robust.DefineConstants.targets" />
|
||||
|
||||
<!-- analyzer -->
|
||||
<Import Project="Robust.Analyzers.targets" Condition="'$(SkipRobustAnalyzer)' != 'true'" />
|
||||
|
||||
<!-- serialization generator -->
|
||||
<Import Project="Robust.Serialization.Generator.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Robust.Serialization.Generator\Robust.Serialization.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<!-- Avoid MSBuild adding a None entry for XAML files because they'd show up TWICE in the project view. -->
|
||||
<DefaultItemExcludes>**/*.xaml</DefaultItemExcludes>
|
||||
<RobustUseExternalMSBuild>true</RobustUseExternalMSBuild>
|
||||
<RobustUseExternalMSBuild>false</RobustUseExternalMSBuild>
|
||||
<_RobustUseExternalMSBuild>$(RobustUseExternalMSBuild)</_RobustUseExternalMSBuild>
|
||||
<_RobustUseExternalMSBuild Condition="'$(_RobustForceInternalMSBuild)' == 'true'">false</_RobustUseExternalMSBuild>
|
||||
</PropertyGroup>
|
||||
@@ -19,17 +19,10 @@
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Robust.Client.Injectors\Robust.Client.Injectors.csproj" ReferenceOutputAssembly="false"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- XamlIL does not make use of special Robust configurations like DebugOpt. Convert these down. -->
|
||||
<PropertyGroup>
|
||||
<RobustInjectorsConfiguration>$(Configuration)</RobustInjectorsConfiguration>
|
||||
<RobustInjectorsConfiguration Condition="'$(Configuration)' == 'DebugOpt'">Debug</RobustInjectorsConfiguration>
|
||||
<RobustInjectorsConfiguration Condition="'$(Configuration)' == 'Tools'">Release</RobustInjectorsConfiguration>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask
|
||||
Condition="'$(_RobustUseExternalMSBuild)' != 'true' And $(DesignTimeBuild) != true"
|
||||
TaskName="CompileRobustXamlTask"
|
||||
AssemblyFile="$(MSBuildThisFileDirectory)\..\Robust.Client.Injectors\bin\$(RobustInjectorsConfiguration)\netstandard2.0\Robust.Client.Injectors.dll"/>
|
||||
AssemblyFile="$(MSBuildThisFileDirectory)\..\Robust.Client.Injectors\bin\$(Configuration)\netstandard2.0\Robust.Client.Injectors.dll"/>
|
||||
<Target
|
||||
Name="CompileRobustXaml"
|
||||
Condition="Exists('@(IntermediateAssembly)')"
|
||||
|
||||
Submodule NetSerializer updated: 7224829e87...3b28e38d23
@@ -25,7 +25,7 @@ namespace OpenToolkit.GraphicsLibraryFramework
|
||||
}
|
||||
|
||||
string rName = null;
|
||||
if (OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD()) rName = "libglfw.so.3";
|
||||
if (OperatingSystem.IsLinux()) rName = "libglfw.so.3";
|
||||
else if (OperatingSystem.IsMacOS()) rName = "libglfw.3.dylib";
|
||||
|
||||
if ((rName != null) && NativeLibrary.TryLoad(rName, assembly, path, out var handle))
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Work around https://github.com/dotnet/project-system/issues/4314 -->
|
||||
<TargetFramework>$(TargetFramework)</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<SkipRobustAnalyzer>true</SkipRobustAnalyzer>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
<Import Project="..\MSBuild\Robust.DefineConstants.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Condition="'$(TargetFramework)' == 'net472'" Include="System.Memory" Version="4.5.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -18,7 +18,7 @@ We are happy to accept contributions from anybody. Get in Discord or IRC if you
|
||||
|
||||
## Building
|
||||
|
||||
This repository is the **engine** part of SS14. It's the base engine all SS14 servers will be built on. As such, it does not start on its own: it needs the [content repo](https://github.com/space-wizards/space-station-14). Think of Robust Toolbox as BYOND in the context of Space Station 13.
|
||||
This repository is the **engine** part of SS14. It's the base engine all SS14 servers will be built on. As such, it does not start on its own: it needs the [content repo](https://github.com/space-wizards/space-station-14). Think of Robust Toolbox as BYOND in the context of Spacestation 13.
|
||||
|
||||
## Legal Info
|
||||
|
||||
|
||||
3084
RELEASE-NOTES.md
3084
RELEASE-NOTES.md
File diff suppressed because it is too large
Load Diff
@@ -1546,31 +1546,6 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
- name: FastNoise
|
||||
license: |
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2020 Jordan Peck (jordan.me2@gmail.com)
|
||||
Copyright(c) 2020 Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
- name: OpenAL soft
|
||||
license: |
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,34 +0,0 @@
|
||||
- type: entity
|
||||
id: debugRotation
|
||||
abstract: true
|
||||
categories: [ debug ]
|
||||
components:
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
visible: true
|
||||
sprite: debugRotation.rsi
|
||||
state: direction1
|
||||
|
||||
- type: entity
|
||||
id: debugRotation1
|
||||
parent: debugRotation
|
||||
name: dbg_rotation1
|
||||
components:
|
||||
- type: Sprite
|
||||
state: direction1
|
||||
|
||||
- type: entity
|
||||
id: debugRotation4
|
||||
parent: debugRotation
|
||||
name: dbg_rotation4
|
||||
components:
|
||||
- type: Sprite
|
||||
state: direction4
|
||||
|
||||
- type: entity
|
||||
id: debugRotationTex
|
||||
parent: debugRotation
|
||||
name: dbg_rotationTex
|
||||
components:
|
||||
- type: Sprite
|
||||
state: direction1
|
||||
@@ -1,44 +0,0 @@
|
||||
- type: uiTheme
|
||||
id: Default
|
||||
path: /Textures/Interface/Default/
|
||||
colors:
|
||||
# Root
|
||||
rootBackground: "#000000"
|
||||
|
||||
# Windows
|
||||
windowBackground: "#111111"
|
||||
windowBorder: "#444444"
|
||||
windowHeader: "#001e3d"
|
||||
|
||||
windowCloseButton: "#FFFFFF"
|
||||
windowCloseButtonHover: "#FF7F7F"
|
||||
windowCloseButtonPressed: "#FF0000"
|
||||
|
||||
# Scrollbars
|
||||
scrollBarDefault: "#80808059"
|
||||
scrollBarHovered: "#8C8C8C59"
|
||||
scrollBarGrabbed: "#8C8C8C59"
|
||||
|
||||
# Buttons
|
||||
buttonBackground: "#171717"
|
||||
buttonBackgroundHovered: "#272727"
|
||||
buttonBackgroundPressed: "#173717"
|
||||
buttonBorder: "#444444"
|
||||
buttonBorderHovered: "#444444"
|
||||
buttonBorderPressed: "#447044"
|
||||
buttonBackgroundDisabled: "#333333"
|
||||
buttonBorderDisabled: "#222222"
|
||||
|
||||
# LineEdit
|
||||
lineEditUneditableText: "#444444"
|
||||
lineEditPlaceholderText: "#7d7d7d"
|
||||
lineEditBackground: "#000000"
|
||||
lineEditBorder: "#444444"
|
||||
|
||||
# TabContainer
|
||||
tabContainerBackground: "#000000"
|
||||
tabContainerBorder: "#444444"
|
||||
tabContainerActiveTabBackground: "#173717"
|
||||
tabContainerActiveTabBorder: "#447044"
|
||||
tabContainerInactiveTabBackground: "#171717"
|
||||
tabContainerInactiveTabBorder: "#444444"
|
||||
@@ -1,17 +0,0 @@
|
||||
# debug related entities
|
||||
- type: entityCategory
|
||||
id: debug
|
||||
name: entity-category-name-debug
|
||||
description: entity-category-desc-debug
|
||||
|
||||
# entities that spawn other entities
|
||||
- type: entityCategory
|
||||
id: spawner
|
||||
name: entity-category-name-spawner
|
||||
description: entity-category-desc-spawner
|
||||
|
||||
# entities that should be hidden from the spawn menu
|
||||
- type: entityCategory
|
||||
id: hideSpawnMenu
|
||||
name: entity-category-name-hide
|
||||
description: entity-category-desc-hide
|
||||
@@ -1,63 +0,0 @@
|
||||
# Used internally by the THE() function.
|
||||
zzzz-the = { PROPER($ent) ->
|
||||
*[false] the { $ent }
|
||||
[true] { $ent }
|
||||
}
|
||||
|
||||
# Used internally by the SUBJECT() function.
|
||||
zzzz-subject-pronoun = { GENDER($ent) ->
|
||||
[male] he
|
||||
[female] she
|
||||
[epicene] they
|
||||
*[neuter] it
|
||||
}
|
||||
|
||||
# Used internally by the OBJECT() function.
|
||||
zzzz-object-pronoun = { GENDER($ent) ->
|
||||
[male] him
|
||||
[female] her
|
||||
[epicene] them
|
||||
*[neuter] it
|
||||
}
|
||||
|
||||
# Used internally by the POSS-PRONOUN() function.
|
||||
zzzz-possessive-pronoun = { GENDER($ent) ->
|
||||
[male] his
|
||||
[female] hers
|
||||
[epicene] theirs
|
||||
*[neuter] its
|
||||
}
|
||||
|
||||
# Used internally by the POSS-ADJ() function.
|
||||
zzzz-possessive-adjective = { GENDER($ent) ->
|
||||
[male] his
|
||||
[female] her
|
||||
[epicene] their
|
||||
*[neuter] its
|
||||
}
|
||||
|
||||
# Used internally by the REFLEXIVE() function.
|
||||
zzzz-reflexive-pronoun = { GENDER($ent) ->
|
||||
[male] himself
|
||||
[female] herself
|
||||
[epicene] themselves
|
||||
*[neuter] itself
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-BE() function.
|
||||
zzzz-conjugate-be = { GENDER($ent) ->
|
||||
[epicene] are
|
||||
*[other] is
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-HAVE() function.
|
||||
zzzz-conjugate-have = { GENDER($ent) ->
|
||||
[epicene] have
|
||||
*[other] has
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-BASIC() function.
|
||||
zzzz-conjugate-basic = { GENDER($ent) ->
|
||||
[epicene] { $first }
|
||||
*[other] { $second }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
# Loc strings for various entity state & client-side PVS related commands
|
||||
|
||||
cmd-reset-ent-help = Usage: resetent <Entity UID>
|
||||
cmd-reset-ent-desc = Reset an entity to the most recently received server state. This will also reset entities that have been detached to null-space.
|
||||
|
||||
cmd-reset-all-ents-help = Usage: resetallents
|
||||
cmd-reset-all-ents-desc = Resets all entities to the most recently received server state. This only impacts entities that have not been detached to null-space.
|
||||
|
||||
cmd-detach-ent-help = Usage: detachent <Entity UID>
|
||||
cmd-detach-ent-desc = Detach an entity to null-space, as if it had left PVS range.
|
||||
|
||||
cmd-local-delete-help = Usage: localdelete <Entity UID>
|
||||
cmd-local-delete-desc = Deletes an entity. Unlike the normal delete command, this is CLIENT-SIDE. Unless the entity is a client-side entity, this will likely cause errors.
|
||||
|
||||
cmd-full-state-reset-help = Usage: fullstatereset
|
||||
cmd-full-state-reset-desc = Discards any entity state information and requests a full-state from the server.
|
||||
@@ -1,31 +1,22 @@
|
||||
### Localization for engine console commands
|
||||
|
||||
## generic command errors
|
||||
|
||||
cmd-invalid-arg-number-error = Invalid number of arguments.
|
||||
## generic
|
||||
|
||||
cmd-parse-failure-integer = {$arg} is not a valid integer.
|
||||
cmd-parse-failure-float = {$arg} is not a valid float.
|
||||
cmd-parse-failure-bool = {$arg} is not a valid bool.
|
||||
cmd-parse-failure-uid = {$arg} is not a valid entity UID.
|
||||
cmd-parse-failure-mapid = {$arg} is not a valid MapId.
|
||||
cmd-parse-failure-entity-exist = UID {$arg} does not correspond to an existing entity.
|
||||
|
||||
cmd-error-file-not-found = Could not find file: {$file}.
|
||||
cmd-error-dir-not-found = Could not find directory: {$dir}.
|
||||
|
||||
cmd-failure-no-attached-entity = There is no entity attached to this shell.
|
||||
|
||||
## 'help' command
|
||||
cmd-oldhelp-desc = Display general help or help text for a specific command
|
||||
cmd-oldhelp-help = Usage: help [command name]
|
||||
cmd-help-desc = Display general help or help text for a specific command
|
||||
cmd-help-help = Usage: help [command name]
|
||||
When no command name is provided, displays general-purpose help text. If a command name is provided, displays help text for that command.
|
||||
|
||||
cmd-oldhelp-no-args = To display help for a specific command, write 'help <command>'. To list all available commands, write 'list'. To search for commands, use 'list <filter>'.
|
||||
cmd-oldhelp-unknown = Unknown command: { $command }
|
||||
cmd-oldhelp-top = { $command } - { $description }
|
||||
cmd-oldhelp-invalid-args = Invalid amount of arguments.
|
||||
cmd-oldhelp-arg-cmdname = [command name]
|
||||
cmd-help-no-args = To display help for a specific command, write 'help <command>'. To list all available commands, write 'list'. To search for commands, use 'list <filter>'.
|
||||
cmd-help-unknown = Unknown command: { $command }
|
||||
cmd-help-top = { $command } - { $description }
|
||||
cmd-help-invalid-args = Invalid amount of arguments.
|
||||
cmd-help-arg-cmdname = [command name]
|
||||
|
||||
## 'cvar' command
|
||||
cmd-cvar-desc = Gets or sets a CVar.
|
||||
@@ -133,11 +124,6 @@ cmd-monitor-minus-all-hint = Hides all monitors
|
||||
cmd-monitor-plus-all-hint = Shows all monitors
|
||||
|
||||
|
||||
## 'setambientlight' command
|
||||
cmd-set-ambient-light-desc = Allows you to set the ambient light for the specified map, in SRGB.
|
||||
cmd-set-ambient-light-help = setambientlight [mapid] [r g b a]
|
||||
cmd-set-ambient-light-parse = Unable to parse args as a byte values for a color.
|
||||
|
||||
## Mapping commands
|
||||
|
||||
cmd-savemap-desc = Serializes a map to disk. Will not save a post-init map unless forced.
|
||||
@@ -161,403 +147,9 @@ cmd-hint-loadmap-y-position = [y-position]
|
||||
cmd-hint-loadmap-rotation = [rotation]
|
||||
cmd-hint-loadmap-uids = [float]
|
||||
|
||||
cmd-hint-savebp-id = <Grid EntityID>
|
||||
|
||||
## 'flushcookies' command
|
||||
# Note: the flushcookies command is from Robust.Client.WebView, it's not in the main engine code.
|
||||
|
||||
cmd-flushcookies-desc = Flush CEF cookie storage to disk
|
||||
cmd-flushcookies-help = This ensure cookies are properly saved to disk in the event of unclean shutdowns.
|
||||
Note that the actual operation is asynchronous.
|
||||
|
||||
cmd-ldrsc-desc = Pre-caches a resource.
|
||||
cmd-ldrsc-help = Usage: ldrsc <path> <type>
|
||||
|
||||
cmd-rldrsc-desc = Reloads a resource.
|
||||
cmd-rldrsc-help = Usage: rldrsc <path> <type>
|
||||
|
||||
cmd-gridtc-desc = Gets the tile count of a grid.
|
||||
cmd-gridtc-help = Usage: gridtc <gridId>
|
||||
|
||||
|
||||
# Client-side commands
|
||||
cmd-guidump-desc = Dump GUI tree to /guidump.txt in user data.
|
||||
cmd-guidump-help = Usage: guidump
|
||||
|
||||
cmd-uitest-desc = Open a dummy UI testing window
|
||||
cmd-uitest-help = Usage: uitest
|
||||
|
||||
## 'uitest2' command
|
||||
cmd-uitest2-desc = Opens a UI control testing OS window
|
||||
cmd-uitest2-help = Usage: uitest2 <tab>
|
||||
cmd-uitest2-arg-tab = <tab>
|
||||
cmd-uitest2-error-args = Expected at most one argument
|
||||
cmd-uitest2-error-tab = Invalid tab: '{$value}'
|
||||
cmd-uitest2-title = UITest2
|
||||
|
||||
|
||||
cmd-setclipboard-desc = Sets the system clipboard
|
||||
cmd-setclipboard-help = Usage: setclipboard <text>
|
||||
|
||||
cmd-getclipboard-desc = Gets the system clipboard
|
||||
cmd-getclipboard-help = Usage: Getclipboard
|
||||
|
||||
cmd-togglelight-desc = Toggles light rendering.
|
||||
cmd-togglelight-help = Usage: togglelight
|
||||
|
||||
cmd-togglefov-desc = Toggles fov for client.
|
||||
cmd-togglefov-help = Usage: togglefov
|
||||
|
||||
cmd-togglehardfov-desc = Toggles hard fov for client. (for debugging space-station-14#2353)
|
||||
cmd-togglehardfov-help = Usage: togglehardfov
|
||||
|
||||
cmd-toggleshadows-desc = Toggles shadow rendering.
|
||||
cmd-toggleshadows-help = Usage: toggleshadows
|
||||
|
||||
cmd-togglelightbuf-desc = Toggles lighting rendering. This includes shadows but not FOV.
|
||||
cmd-togglelightbuf-help = Usage: togglelightbuf
|
||||
|
||||
cmd-chunkinfo-desc = Gets info about a chunk under your mouse cursor.
|
||||
cmd-chunkinfo-help = Usage: chunkinfo
|
||||
|
||||
cmd-rldshader-desc = Reloads all shaders.
|
||||
cmd-rldshader-help = Usage: rldshader
|
||||
|
||||
cmd-cldbglyr-desc = Toggle fov and light debug layers.
|
||||
cmd-cldbglyr-help= Usage: cldbglyr <layer>: Toggle <layer>
|
||||
cldbglyr: Turn all Layers off
|
||||
|
||||
cmd-key-info-desc = Keys key info for a key.
|
||||
cmd-key-info-help = Usage: keyinfo <Key>
|
||||
|
||||
## 'bind' command
|
||||
cmd-bind-desc = Binds an input key combination to an input command.
|
||||
cmd-bind-help = Usage: bind { cmd-bind-arg-key } { cmd-bind-arg-mode } { cmd-bind-arg-command }
|
||||
Note that this DOES NOT automatically save bindings.
|
||||
Use the 'svbind' command to save binding configuration.
|
||||
|
||||
cmd-bind-arg-key = <KeyName>
|
||||
cmd-bind-arg-mode = <BindMode>
|
||||
cmd-bind-arg-command = <InputCommand>
|
||||
|
||||
cmd-net-draw-interp-desc = Toggles the debug drawing of the network interpolation.
|
||||
cmd-net-draw-interp-help = Usage: net_draw_interp
|
||||
|
||||
cmd-net-draw-interp-desc = Toggles the debug drawing of the network interpolation.
|
||||
cmd-net-draw-interp-help = Usage: net_draw_interp
|
||||
|
||||
cmd-net-watch-ent-desc = Dumps all network updates for an EntityId to the console.
|
||||
cmd-net-watch-ent-help = Usage: net_watchent <0|EntityUid>
|
||||
|
||||
cmd-net-refresh-desc = Requests a full server state.
|
||||
cmd-net-refresh-help = Usage: net_refresh
|
||||
|
||||
cmd-net-entity-report-desc = Toggles the net entity report panel.
|
||||
cmd-net-entity-report-help = Usage: net_entityreport
|
||||
|
||||
cmd-fill-desc = Fill up the console for debugging.
|
||||
cmd-fill-help = Fills the console with some nonsense for debugging.
|
||||
|
||||
cmd-cls-desc = Clears the console.
|
||||
cmd-cls-help = Clears the debug console of all messages.
|
||||
|
||||
cmd-sendgarbage-desc = Sends garbage to the server.
|
||||
cmd-sendgarbage-help = The server will reply with 'no u'
|
||||
|
||||
cmd-loadgrid-desc = Loads a grid from a file into an existing map.
|
||||
cmd-loadgrid-help = loadgrid <MapID> <Path> [x y] [rotation] [storeUids]
|
||||
|
||||
cmd-loc-desc = Prints the absolute location of the player's entity to console.
|
||||
cmd-loc-help = loc
|
||||
|
||||
cmd-tpgrid-desc = Teleports a grid to a new location.
|
||||
cmd-tpgrid-help = tpgrid <gridId> <X> <Y> [<MapId>]
|
||||
|
||||
cmd-rmgrid-desc = Removes a grid from a map. You cannot remove the default grid.
|
||||
cmd-rmgrid-help = rmgrid <gridId>
|
||||
|
||||
cmd-mapinit-desc = Runs map init on a map.
|
||||
cmd-mapinit-help = mapinit <mapID>
|
||||
|
||||
cmd-lsmap-desc = Lists maps.
|
||||
cmd-lsmap-help = lsmap
|
||||
|
||||
cmd-lsgrid-desc = Lists grids.
|
||||
cmd-lsgrid-help = lsgrid
|
||||
|
||||
cmd-addmap-desc = Adds a new empty map to the round. If the mapID already exists, this command does nothing.
|
||||
cmd-addmap-help = addmap <mapID> [initialize]
|
||||
|
||||
cmd-rmmap-desc = Removes a map from the world. You cannot remove nullspace.
|
||||
cmd-rmmap-help = rmmap <mapId>
|
||||
|
||||
cmd-savegrid-desc = Serializes a grid to disk.
|
||||
cmd-savegrid-help = savegrid <gridID> <Path>
|
||||
|
||||
cmd-testbed-desc = Loads a physics testbed on the specified map.
|
||||
cmd-testbed-help = testbed <mapid> <test>
|
||||
|
||||
cmd-saveconfig-desc = Saves the client configuration to the config file.
|
||||
cmd-saveconfig-help = saveconfig
|
||||
|
||||
## 'flushcookies' command
|
||||
# Note: the flushcookies command is from Robust.Client.WebView, it's not in the main engine code.
|
||||
|
||||
cmd-flushcookies-desc = Flush CEF cookie storage to disk
|
||||
cmd-flushcookies-help = This ensure cookies are properly saved to disk in the event of unclean shutdowns.
|
||||
Note that the actual operation is asynchronous.
|
||||
|
||||
## 'addcomp' command
|
||||
cmd-addcomp-desc = Adds a component to an entity.
|
||||
cmd-addcomp-help = addcomp <uid> <componentName>
|
||||
cmd-addcompc-desc = Adds a component to an entity on the client.
|
||||
cmd-addcompc-help = addcompc <uid> <componentName>
|
||||
|
||||
## 'rmcomp' command
|
||||
cmd-rmcomp-desc = Removes a component from an entity.
|
||||
cmd-rmcomp-help = rmcomp <uid> <componentName>
|
||||
cmd-rmcompc-desc = Removes a component from an entity on the client.
|
||||
cmd-rmcompc-help = rmcomp <uid> <componentName>
|
||||
|
||||
## 'addview' command
|
||||
cmd-addview-desc = Allows you to subscribe to an entity's view for debugging purposes.
|
||||
cmd-addview-help = addview <entityUid>
|
||||
cmd-addviewc-desc = Allows you to subscribe to an entity's view for debugging purposes.
|
||||
cmd-addviewc-help = addview <entityUid>
|
||||
|
||||
## 'removeview' command
|
||||
cmd-removeview-desc = Allows you to unsubscribe to an entity's view for debugging purposes.
|
||||
cmd-removeview-help = removeview <entityUid>
|
||||
|
||||
## 'loglevel' command
|
||||
cmd-loglevel-desc = Changes the log level for a provided sawmill.
|
||||
cmd-loglevel-help = Usage: loglevel <sawmill> <level>
|
||||
sawmill: A label prefixing log messages. This is the one you're setting the level for.
|
||||
level: The log level. Must match one of the values of the LogLevel enum.
|
||||
|
||||
cmd-testlog-desc = Writes a test log to a sawmill.
|
||||
cmd-testlog-help = Usage: testlog <sawmill> <level> <message>
|
||||
sawmill: A label prefixing the logged message.
|
||||
level: The log level. Must match one of the values of the LogLevel enum.
|
||||
message: The message to be logged. Wrap this in double quotes if you want to use spaces.
|
||||
|
||||
## 'vv' command
|
||||
cmd-vv-desc = Opens View Variables.
|
||||
cmd-vv-help = Usage: vv <entity ID|IoC interface name|SIoC interface name>
|
||||
|
||||
## 'showvelocities' command
|
||||
cmd-showvelocities-desc = Displays your angular and linear velocities.
|
||||
cmd-showvelocities-help = Usage: showvelocities
|
||||
|
||||
## 'setinputcontext' command
|
||||
cmd-setinputcontext-desc = Sets the active input context.
|
||||
cmd-setinputcontext-help = Usage: setinputcontext <context>
|
||||
|
||||
## 'forall' command
|
||||
cmd-forall-desc = Runs a command over all entities with a given component.
|
||||
cmd-forall-help = Usage: forall <bql query> do <command...>
|
||||
|
||||
## 'delete' command
|
||||
cmd-delete-desc = Deletes the entity with the specified ID.
|
||||
cmd-delete-help = delete <entity UID>
|
||||
|
||||
# System commands
|
||||
cmd-showtime-desc = Shows the server time.
|
||||
cmd-showtime-help = showtime
|
||||
|
||||
cmd-restart-desc = Gracefully restarts the server (not just the round).
|
||||
cmd-restart-help = restart
|
||||
|
||||
cmd-shutdown-desc = Gracefully shuts down the server.
|
||||
cmd-shutdown-help = shutdown
|
||||
|
||||
cmd-saveconfig-desc = Saves the server configuration to the config file.
|
||||
cmd-saveconfig-help = saveconfig
|
||||
|
||||
cmd-netaudit-desc = Prints into about NetMsg security.
|
||||
cmd-netaudit-help = netaudit
|
||||
|
||||
# Player commands
|
||||
cmd-tp-desc = Teleports a player to any location in the round.
|
||||
cmd-tp-help = tp <x> <y> [<mapID>]
|
||||
|
||||
cmd-tpto-desc = Teleports the current player or the specified players/entities to the location of the first player/entity.
|
||||
cmd-tpto-help = tpto <username|uid> [username|uid]...
|
||||
cmd-tpto-destination-hint = destination (uid or username)
|
||||
cmd-tpto-victim-hint = entity to teleport (uid or username)
|
||||
cmd-tpto-parse-error = Cant resolve entity or player: {$str}
|
||||
|
||||
cmd-listplayers-desc = Lists all players currently connected.
|
||||
cmd-listplayers-help = listplayers
|
||||
|
||||
cmd-kick-desc = Kicks a connected player out of the server, disconnecting them.
|
||||
cmd-kick-help = kick <PlayerIndex> [<Reason>]
|
||||
|
||||
# Spin command
|
||||
cmd-spin-desc = Causes an entity to spin. Default entity is the attached player's parent.
|
||||
cmd-spin-help = spin velocity [drag] [entityUid]
|
||||
|
||||
# Localization command
|
||||
cmd-rldloc-desc = Reloads localization (client & server).
|
||||
cmd-rldloc-help = Usage: rldloc
|
||||
|
||||
# Debug entity controls
|
||||
cmd-spawn-desc = Spawns an entity with specific type.
|
||||
cmd-spawn-help = spawn <prototype> OR spawn <prototype> <relative entity ID> OR spawn <prototype> <x> <y>
|
||||
cmd-cspawn-desc = Spawns a client-side entity with specific type at your feet.
|
||||
cmd-cspawn-help = cspawn <entity type>
|
||||
|
||||
cmd-scale-desc = Increases or decreases an entity's size naively.
|
||||
cmd-scale-help = scale <entityUid> <float>
|
||||
|
||||
cmd-dumpentities-desc = Dump entity list.
|
||||
cmd-dumpentities-help = Dumps entity list of UIDs and prototype.
|
||||
|
||||
cmd-getcomponentregistration-desc = Gets component registration information.
|
||||
cmd-getcomponentregistration-help = Usage: getcomponentregistration <componentName>
|
||||
|
||||
cmd-showrays-desc = Toggles debug drawing of physics rays. An integer for <raylifetime> must be provided.
|
||||
cmd-showrays-help = Usage: showrays <raylifetime>
|
||||
|
||||
cmd-disconnect-desc = Immediately disconnect from the server and go back to the main menu.
|
||||
cmd-disconnect-help = Usage: disconnect
|
||||
|
||||
cmd-entfo-desc = Displays verbose diagnostics for an entity.
|
||||
cmd-entfo-help = Usage: entfo <entityuid>
|
||||
The entity UID can be prefixed with 'c' to convert it to a client entity UID.
|
||||
|
||||
cmd-fuck-desc = Throws an exception
|
||||
cmd-fuck-help = Throws an exception
|
||||
|
||||
cmd-showpos-desc = Enables debug drawing over all entity positions in the game.
|
||||
cmd-showpos-help = Usage: showpos
|
||||
|
||||
cmd-sggcell-desc = Lists entities on a snap grid cell.
|
||||
cmd-sggcell-help = Usage: sggcell <gridID> <vector2i>\nThat vector2i param is in the form x<int>,y<int>.
|
||||
|
||||
cmd-overrideplayername-desc = Changes the name used when attempting to connect to the server.
|
||||
cmd-overrideplayername-help = Usage: overrideplayername <name>
|
||||
|
||||
cmd-showanchored-desc = Shows anchored entities on a particular tile
|
||||
cmd-showanchored-help = Usage: showanchored
|
||||
|
||||
cmd-dmetamem-desc = Dumps a type's members in a format suitable for the sandbox configuration file.
|
||||
cmd-dmetamem-help = Usage: dmetamem <type>
|
||||
|
||||
cmd-dmetamem-desc = Displays chunk bounds for the purposes of rendering.
|
||||
cmd-dmetamem-help = Usage: showchunkbb <type>
|
||||
|
||||
cmd-launchauth-desc = Load authentication tokens from launcher data to aid in testing of live servers.
|
||||
cmd-launchauth-help = Usage: launchauth <account name>
|
||||
|
||||
cmd-lightbb-desc = Toggles whether to show light bounding boxes.
|
||||
cmd-lightbb-help = Usage: lightbb
|
||||
|
||||
cmd-monitorinfo-desc = Monitors info
|
||||
cmd-monitorinfo-help = Usage: monitorinfo <id>
|
||||
|
||||
cmd-setmonitor-desc = Set monitor
|
||||
cmd-setmonitor-help = Usage: setmonitor <id>
|
||||
|
||||
cmd-physics-desc = Shows a debug physics overlay. The arg supplied specifies the overlay.
|
||||
cmd-physics-help = Usage: physics <aabbs / com / contactnormals / contactpoints / distance / joints / shapeinfo / shapes>
|
||||
|
||||
cmd-hardquit-desc = Kills the game client instantly.
|
||||
cmd-hardquit-help = Kills the game client instantly, leaving no traces. No telling the server goodbye.
|
||||
|
||||
cmd-quit-desc = Shuts down the game client gracefully.
|
||||
cmd-quit-help = Properly shuts down the game client, notifying the connected server and such.
|
||||
|
||||
cmd-csi-desc = Opens a C# interactive console.
|
||||
cmd-csi-help = Usage: csi
|
||||
|
||||
cmd-scsi-desc = Opens a C# interactive console on the server.
|
||||
cmd-scsi-help = Usage: scsi
|
||||
|
||||
cmd-watch-desc = Opens a variable watch window.
|
||||
cmd-watch-help = Usage: watch
|
||||
|
||||
cmd-showspritebb-desc = Toggle whether sprite bounds are shown
|
||||
cmd-showspritebb-help = Usage: showspritebb
|
||||
|
||||
cmd-togglelookup-desc = Shows / hides entitylookup bounds via an overlay.
|
||||
cmd-togglelookup-help = Usage: togglelookup
|
||||
|
||||
cmd-net_entityreport-desc = Toggles the net entity report panel.
|
||||
cmd-net_entityreport-help = Usage: net_entityreport
|
||||
|
||||
cmd-net_refresh-desc = Requests a full server state.
|
||||
cmd-net_refresh-help = Usage: net_refresh
|
||||
|
||||
cmd-net_graph-desc = Toggles the net statistics pannel.
|
||||
cmd-net_graph-help = Usage: net_graph
|
||||
|
||||
cmd-net_watchent-desc = Dumps all network updates for an EntityId to the console.
|
||||
cmd-net_watchent-help = Usage: net_watchent <0|EntityUid>
|
||||
|
||||
cmd-net_draw_interp-desc = Toggles the debug drawing of the network interpolation.
|
||||
cmd-net_draw_interp-help = Usage: net_draw_interp <0|EntityUid>
|
||||
|
||||
cmd-vram-desc = Displays video memory usage statics by the game.
|
||||
cmd-vram-help = Usage: vram
|
||||
|
||||
cmd-showislands-desc = Shows the current physics bodies involved in each physics island.
|
||||
cmd-showislands-help = Usage: showislands
|
||||
|
||||
cmd-showgridnodes-desc = Shows the nodes for grid split purposes.
|
||||
cmd-showgridnodes-help = Usage: showgridnodes
|
||||
|
||||
cmd-profsnap-desc = Make a profiling snapshot.
|
||||
cmd-profsnap-help = Usage: profsnap
|
||||
|
||||
cmd-devwindow-desc = Dev Window
|
||||
cmd-devwindow-help = Usage: devwindow
|
||||
|
||||
cmd-devwindow-desc = Open file
|
||||
cmd-devwindow-help = Usage: testopenfile
|
||||
|
||||
cmd-scene-desc = Immediately changes the UI scene/state.
|
||||
cmd-scene-help = Usage: scene <className>
|
||||
|
||||
cmd-szr_stats-desc = Report serializer statistics.
|
||||
cmd-szr_stats-help = Usage: szr_stats
|
||||
|
||||
cmd-hwid-desc = Returns the current HWID (HardWare ID).
|
||||
cmd-hwid-help = Usage: hwid
|
||||
|
||||
cmd-vvread-desc = Retrieve a path's value using VV (View Variables).
|
||||
cmd-vvread-desc = Usage: vvread <path>
|
||||
|
||||
cmd-vvwrite-desc = Modify a path's value using VV (View Variables).
|
||||
cmd-vvwrite-help = Usage: vvwrite <path>
|
||||
|
||||
cmd-vv-desc = Opens View Variables (VV).
|
||||
cmd-vv-help = Usage: vv <path|entity ID|guihover>
|
||||
|
||||
cmd-vvinvoke-desc = Invoke/Call a path with arguments using VV.
|
||||
cmd-vvinvoke-help = Usage: vvinvoke <path> [arguments...]
|
||||
|
||||
cmd-dump_dependency_injectors-desc = Dump IoCManager's dependency injector cache.
|
||||
cmd-dump_dependency_injectors-help = Usage: dump_dependency_injectors
|
||||
cmd-dump_dependency_injectors-total-count = Total count: { $total }
|
||||
|
||||
cmd-dump_netserializer_type_map-desc = Dump NetSerializer's type map and serializer hash.
|
||||
cmd-dump_netserializer_type_map-help = Usage: dump_netserializer_type_map
|
||||
|
||||
cmd-hub_advertise_now-desc = Immediately advertise to the master hub server
|
||||
cmd-hub_advertise_now-help = Usage: hub_advertise_now
|
||||
|
||||
cmd-echo-desc = Echo arguments back to the console
|
||||
cmd-echo-help = Usage: echo "<message>"
|
||||
|
||||
## 'vfs_ls' command
|
||||
cmd-vfs_ls-desc = List directory contents in the VFS.
|
||||
cmd-vfs_ls-help = Usage: vfs_list <path>
|
||||
Example:
|
||||
vfs_list /Assemblies
|
||||
|
||||
cmd-vfs_ls-err-args = Need exactly 1 argument.
|
||||
cmd-vfs_ls-hint-path = <path>
|
||||
|
||||
cmd-reloadtiletextures-desc = Reloads the tile texture atlas to allow hot reloading tile sprites
|
||||
cmd-reloadtiletextures-help = Usage: reloadtiletextures
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
entity-spawn-window-title = Entity Spawn Panel
|
||||
entity-spawn-window-search-bar-placeholder = search
|
||||
entity-spawn-window-clear-button = Clear
|
||||
entity-spawn-window-replace-button-text = Replace
|
||||
entity-spawn-window-erase-button-text = Erase Mode
|
||||
entity-spawn-window-override-menu-tooltip = Override placement
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
debug-builtin-connection-screen-invalid-username-with-reason = The given username is invalid: {$invalidreason}
|
||||
debug-builtin-connection-screen-invalid-username = Invalid Username.
|
||||
debug-builtin-connection-screen-failed-to-connect = Failed to connect: {$reason}
|
||||
@@ -1,5 +0,0 @@
|
||||
discord-rpc-in-main-menu = In Main Menu
|
||||
discord-rpc-in-main-menu-logo-text = I think coolsville SUCKS
|
||||
discord-rpc-character = Username: {$username}
|
||||
discord-rpc-on-server = On Server: {$servername}
|
||||
discord-rpc-players = Players: {$players}/{$maxplayers}
|
||||
@@ -1,8 +0,0 @@
|
||||
entity-category-name-debug = Debug
|
||||
entity-category-desc-debug = Entity prototypes intended for debugging & testing.
|
||||
|
||||
entity-category-name-spawner = Spawner
|
||||
entity-category-desc-spawner = Entity prototypes that spawn other entities.
|
||||
|
||||
entity-category-name-hide = Hidden
|
||||
entity-category-desc-hide = Entity prototypes that should be hidden from the spawn menu
|
||||
@@ -18,15 +18,6 @@ input-key-F12 = F12
|
||||
input-key-F13 = F13
|
||||
input-key-F14 = F14
|
||||
input-key-F15 = F15
|
||||
input-key-F16 = F16
|
||||
input-key-F17 = F17
|
||||
input-key-F18 = F18
|
||||
input-key-F19 = F19
|
||||
input-key-F20 = F20
|
||||
input-key-F21 = F21
|
||||
input-key-F22 = F22
|
||||
input-key-F23 = F23
|
||||
input-key-F24 = F24
|
||||
input-key-Pause = Pause
|
||||
input-key-Left = Left
|
||||
input-key-Up = Up
|
||||
@@ -34,22 +25,7 @@ input-key-Down = Down
|
||||
input-key-Right = Right
|
||||
input-key-Space = Space
|
||||
input-key-Return = Return
|
||||
input-key-NumpadEnter = Numpad Enter
|
||||
input-key-NumpadNum0 = Numpad 0
|
||||
input-key-NumpadNum1 = Numpad 1
|
||||
input-key-NumpadNum2 = Numpad 2
|
||||
input-key-NumpadNum3 = Numpad 3
|
||||
input-key-NumpadNum4 = Numpad 4
|
||||
input-key-NumpadNum5 = Numpad 5
|
||||
input-key-NumpadNum6 = Numpad 6
|
||||
input-key-NumpadNum7 = Numpad 7
|
||||
input-key-NumpadNum8 = Numpad 8
|
||||
input-key-NumpadNum9 = Numpad 9
|
||||
input-key-NumpadAdd = Numpad Add
|
||||
input-key-NumpadSubtract = Numpad Subtract
|
||||
input-key-NumpadDivide = Numpad Divide
|
||||
input-key-NumpadMultiply = Numpad Multiply
|
||||
input-key-NumpadDecimal = Numpad Decimal
|
||||
input-key-NumpadEnter = Num Enter
|
||||
input-key-BackSpace = Backspace
|
||||
input-key-Tab = Tab
|
||||
input-key-PageUp = Page Up
|
||||
|
||||
@@ -1 +1 @@
|
||||
cmd-midipanic-desc = Turns off every note for every active MIDI renderer.
|
||||
midi-panic-command-description = Turns off every note for every active MIDI renderer.
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# Playback Commands
|
||||
|
||||
cmd-replay-play-desc = Resume replay playback.
|
||||
cmd-replay-play-help = replay_play
|
||||
|
||||
cmd-replay-pause-desc = Pause replay playback
|
||||
cmd-replay-pause-help = replay_pause
|
||||
|
||||
cmd-replay-toggle-desc = Resume or pause replay playback.
|
||||
cmd-replay-toggle-help = replay_toggle
|
||||
|
||||
cmd-replay-stop-desc = Stop and unload a replay.
|
||||
cmd-replay-stop-help = replay_stop
|
||||
|
||||
cmd-replay-load-desc = Load and start a replay.
|
||||
cmd-replay-load-help = replay_load <replay folder>
|
||||
cmd-replay-load-hint = Replay folder
|
||||
|
||||
cmd-replay-skip-desc = Skip forwards or backwards in time.
|
||||
cmd-replay-skip-help = replay_skip <tick or timespan>
|
||||
cmd-replay-skip-hint = Ticks or timespan (HH:MM:SS).
|
||||
|
||||
cmd-replay-set-time-desc = Jump forwards or backwards to some specific time.
|
||||
cmd-replay-set-time-help = replay_set <tick or time>
|
||||
cmd-replay-set-time-hint = Tick or timespan (HH:MM:SS), starting from
|
||||
|
||||
cmd-replay-error-time = "{$time}" is not an integer or timespan.
|
||||
cmd-replay-error-args = Wrong number of arguments.
|
||||
cmd-replay-error-no-replay = Not currently playing a replay.
|
||||
cmd-replay-error-already-loaded = A replay is already loaded.
|
||||
cmd-replay-error-run-level = You cannot load a replay while connected to a server.
|
||||
|
||||
# Recording commands
|
||||
|
||||
cmd-replay-recording-start-desc = Starts a replay recording, optionally with some time limit.
|
||||
cmd-replay-recording-start-help = Usage: replay_recording_start [name] [overwrite] [time limit]
|
||||
cmd-replay-recording-start-success = Started recording a replay.
|
||||
cmd-replay-recording-start-already-recording = Already recording a replay.
|
||||
cmd-replay-recording-start-error = An error occurred while trying to start the recording.
|
||||
cmd-replay-recording-start-hint-time = [time limit (minutes)]
|
||||
cmd-replay-recording-start-hint-name = [name]
|
||||
cmd-replay-recording-start-hint-overwrite = [overwrite (bool)]
|
||||
|
||||
cmd-replay-recording-stop-desc = Stops a replay recording.
|
||||
cmd-replay-recording-stop-help = Usage: replay_recording_stop
|
||||
cmd-replay-recording-stop-success = Stopped recording a replay.
|
||||
cmd-replay-recording-stop-not-recording = Not currently recording a replay.
|
||||
|
||||
cmd-replay-recording-stats-desc = Displays information about the current replay recording.
|
||||
cmd-replay-recording-stats-help = Usage: replay_recording_stats
|
||||
cmd-replay-recording-stats-result = Duration: {$time} min, Ticks: {$ticks}, Size: {$size} MB, rate: {$rate} MB/min.
|
||||
|
||||
|
||||
# Time Control UI
|
||||
replay-time-box-scrubbing-label = Dynamic Scrubbing
|
||||
replay-time-box-replay-time-label = Recording Time: {$current} / {$end} ({$percentage}%)
|
||||
replay-time-box-server-time-label = Server Time: {$current} / {$end}
|
||||
replay-time-box-index-label = Index: {$current} / {$total}
|
||||
replay-time-box-tick-label = Tick: {$current} / {$total}
|
||||
@@ -1,423 +0,0 @@
|
||||
command-description-tpto =
|
||||
Teleport the given entities to some target entity.
|
||||
command-description-player-list =
|
||||
Returns a list of all player sessions.
|
||||
command-description-player-self =
|
||||
Returns the current player session.
|
||||
command-description-player-imm =
|
||||
Returns the session associated with the player given as argument.
|
||||
command-description-player-entity =
|
||||
Returns the entities of the input sessions.
|
||||
command-description-self =
|
||||
Returns the current attached entity.
|
||||
command-description-physics-velocity =
|
||||
Returns the velocity of the input entities.
|
||||
command-description-physics-angular-velocity =
|
||||
Returns the angular velocity of the input entities.
|
||||
command-description-buildinfo =
|
||||
Provides information about the build of the game.
|
||||
command-description-cmd-list =
|
||||
Returns a list of all commands, for this side.
|
||||
command-description-explain =
|
||||
Explains the given expression, providing command descriptions and signatures.
|
||||
command-description-search =
|
||||
Searches through the input for the provided value.
|
||||
command-description-stopwatch =
|
||||
Measures the execution time of the given expression.
|
||||
command-description-types-consumers =
|
||||
Provides all commands that can consume the given type.
|
||||
command-description-types-tree =
|
||||
Debug tool to return all types the command interpreter can downcast the input to.
|
||||
command-description-types-gettype =
|
||||
Returns the type of the input.
|
||||
command-description-types-fullname =
|
||||
Returns the full name of the input type according to CoreCLR.
|
||||
command-description-as =
|
||||
Casts the input to the given type.
|
||||
Effectively a type hint if you know the type but the interpreter does not.
|
||||
command-description-count =
|
||||
Counts the amount of entries in it's input, returning an integer.
|
||||
command-description-map =
|
||||
Maps the input over the given block, with the provided expected return type.
|
||||
This command may be modified to not need an explicit return type in the future.
|
||||
command-description-select =
|
||||
Selects N objects or N% of objects from the input.
|
||||
One can additionally invert this command with not to make it select everything except N objects instead.
|
||||
command-description-comp =
|
||||
Returns the given component from the input entities, discarding entities without that component.
|
||||
command-description-delete =
|
||||
Deletes the input entities.
|
||||
command-description-ent =
|
||||
Returns the provided entity ID.
|
||||
command-description-entities =
|
||||
Returns all entities on the server.
|
||||
command-description-paused =
|
||||
Filters the input entities by whether or not they are paused.
|
||||
This command can be inverted with not.
|
||||
command-description-with =
|
||||
Filters the input entities by whether or not they have the given component.
|
||||
This command can be inverted with not.
|
||||
command-description-fuck =
|
||||
Throws an exception.
|
||||
command-description-ecscomp-listty =
|
||||
Lists every type of component registered.
|
||||
command-description-cd =
|
||||
Changes the session's current directory to the given relative or absolute path.
|
||||
command-description-ls-here =
|
||||
Lists the contents of the current directory.
|
||||
command-description-ls-in =
|
||||
Lists the contents of the given relative or absolute path.
|
||||
command-description-methods-get =
|
||||
Returns all methods associated with the input type.
|
||||
command-description-methods-overrides =
|
||||
Returns all methods overriden on the input type.
|
||||
command-description-methods-overridesfrom =
|
||||
Returns all methods overriden from the given type on the input type.
|
||||
command-description-cmd-moo =
|
||||
Asks the important questions.
|
||||
command-description-cmd-descloc =
|
||||
Returns the localization string for a command's description.
|
||||
command-description-cmd-getshim =
|
||||
Returns a command's execution shim.
|
||||
command-description-help =
|
||||
Provides a quick rundown of how to use toolshed.
|
||||
command-description-ioc-registered =
|
||||
Returns all the types registered with IoCManager on the current thread (usually the game thread)
|
||||
command-description-ioc-get =
|
||||
Gets an instance of an IoC registration.
|
||||
command-description-loc-tryloc =
|
||||
Tries to get a localization string, returning null if unable.
|
||||
command-description-loc-loc =
|
||||
Gets a localization string, returning the unlocalized string if unable.
|
||||
command-description-physics-angular_velocity =
|
||||
Returns the angular velocity of the given entities.
|
||||
command-description-vars =
|
||||
Provides a list of all variables set in this session.
|
||||
command-description-any =
|
||||
Returns true if there's any values in the input, otherwise false.
|
||||
command-description-ArrowCommand =
|
||||
Assigns the input to a variable.
|
||||
command-description-isempty =
|
||||
Returns true if the input is empty, otherwise false.
|
||||
command-description-isnull =
|
||||
Returns true if the input is null, otherwise false.
|
||||
command-description-unique =
|
||||
Filters the input sequence for uniqueness, removing duplicate values.
|
||||
command-description-where =
|
||||
Given some input sequence IEnumerable<T>, takes a block of signature T -> bool that decides if each input value should be included in the output sequence.
|
||||
command-description-do =
|
||||
Backwards compatibility with BQL, applies the given old commands over the input sequence.
|
||||
command-description-named =
|
||||
Filters the input entities by their name, with the regex ^selector$.
|
||||
command-description-prototyped =
|
||||
Filters the input entities by their prototype.
|
||||
command-description-nearby =
|
||||
Creates a new list of all entities nearby the inputs within the given range.
|
||||
command-description-first =
|
||||
Returns the first entry of the given enumerable.
|
||||
command-description-splat =
|
||||
"Splats" a block, value, or variable, creating N copies of it in a list.
|
||||
command-description-val =
|
||||
Casts the given value, block, or variable to the given type. This is mostly a workaround for current limitations of variables.
|
||||
command-description-actor-controlled =
|
||||
Filters entities by whether or not they're actively controlled.
|
||||
command-description-actor-session =
|
||||
Returns the sessions associated with the input entities.
|
||||
command-description-physics-parent =
|
||||
Returns the parent(s) of the input entities.
|
||||
command-description-emplace =
|
||||
Runs the given block over it's inputs, with the input value placed into the variable $value within the block.
|
||||
Additionally breaks out $wx, $wy, $proto, $desc, $name, and $paused for entities.
|
||||
Can also have breakout values for other types, consult the documentation for that type for further info.
|
||||
command-description-AddCommand =
|
||||
Performs numeric addition.
|
||||
command-description-SubtractCommand =
|
||||
Performs numeric subtraction.
|
||||
command-description-MultiplyCommand =
|
||||
Performs numeric multiplication.
|
||||
command-description-DivideCommand =
|
||||
Performs numeric division.
|
||||
command-description-min =
|
||||
Returns the minimum of two values.
|
||||
command-description-max =
|
||||
Returns the maximum of two values.
|
||||
command-description-BitAndCommand =
|
||||
Performs bitwise AND.
|
||||
command-description-BitOrCommand =
|
||||
Performs bitwise OR.
|
||||
command-description-BitXorCommand =
|
||||
Performs bitwise XOR.
|
||||
command-description-neg =
|
||||
Negates the input.
|
||||
command-description-GreaterThanCommand =
|
||||
Performs a greater-than comparison, x > y.
|
||||
command-description-LessThanCommand =
|
||||
Performs a less-than comparison, x < y.
|
||||
command-description-GreaterThanOrEqualCommand =
|
||||
Performs a greater-than-or-equal comparison, x >= y.
|
||||
command-description-LessThanOrEqualCommand =
|
||||
Performs a less-than-or-equal comparison, x <= y.
|
||||
command-description-EqualCommand =
|
||||
Performs an equality comparison, returning true if the inputs are equal.
|
||||
command-description-NotEqualCommand =
|
||||
Performs an equality comparison, returning true if the inputs are not equal.
|
||||
command-description-append =
|
||||
Appends a value to the input enumerable.
|
||||
command-description-DefaultIfNullCommand =
|
||||
Replaces the input with the type's default value if it is null, albeit only for value types (not objects).
|
||||
command-description-OrValueCommand =
|
||||
If the input is null, uses the provided alternate value.
|
||||
command-description-DebugPrintCommand =
|
||||
Prints the given value transparently, for debug prints in a command run.
|
||||
command-description-i =
|
||||
Integer constant.
|
||||
command-description-f =
|
||||
Float constant.
|
||||
command-description-s =
|
||||
String constant.
|
||||
command-description-b =
|
||||
Bool constant.
|
||||
command-description-join =
|
||||
Joins two sequences together into one sequence.
|
||||
command-description-reduce =
|
||||
Given a block to use as a reducer, turns a sequence into a single value.
|
||||
The left hand side of the block is implied, and the right hand is stored in $value.
|
||||
command-description-rep =
|
||||
Repeats the input value N times to form a sequence.
|
||||
command-description-take =
|
||||
Takes N values from the input sequence
|
||||
command-description-spawn-at =
|
||||
Spawns an entity at the given coordinates.
|
||||
command-description-spawn-on =
|
||||
Spawns an entity on the given entity, at it's coordinates.
|
||||
command-description-spawn-attached =
|
||||
Spawns an entity attached to the given entity, at (0 0) relative to it.
|
||||
command-description-mappos =
|
||||
Returns an entity's coordinates relative to it's current map.
|
||||
command-description-pos =
|
||||
Returns an entity's coordinates.
|
||||
command-description-tp-coords =
|
||||
Teleports the target to the given coordinates.
|
||||
command-description-tp-to =
|
||||
Teleports the target to the given other entity.
|
||||
command-description-tp-into =
|
||||
Teleports the target "into" the given other entity, attaching it at (0 0) relative to it.
|
||||
command-description-comp-get =
|
||||
Gets the given component from the given entity.
|
||||
command-description-comp-add =
|
||||
Adds the given component to the given entity.
|
||||
command-description-comp-ensure =
|
||||
Ensures the given entity has the given component.
|
||||
command-description-comp-has =
|
||||
Check if the given entity has the given component.
|
||||
command-description-AddVecCommand =
|
||||
Adds a scalar (single value) to every element in the input.
|
||||
command-description-SubVecCommand =
|
||||
Subtracts a scalar (single value) from every element in the input.
|
||||
command-description-MulVecCommand =
|
||||
Multiplies a scalar (single value) by every element in the input.
|
||||
command-description-DivVecCommand =
|
||||
Divides every element in the input by a scalar (single value).
|
||||
command-description-rng-to =
|
||||
Returns a number from its input to its argument (i.e. n..m inclusive)
|
||||
command-description-rng-from =
|
||||
Returns a number to its input from its argument (i.e. m..n inclusive)
|
||||
command-description-rng-prob =
|
||||
Returns a boolean based on the input probability/chance (from 0 to 1)
|
||||
command-description-sum =
|
||||
Computes the sum of the input.
|
||||
command-description-bin =
|
||||
"Bins" the input, counting up how many times each unique element occurs.
|
||||
command-description-extremes =
|
||||
Returns the two extreme ends of a list, interwoven.
|
||||
command-description-sortby =
|
||||
Sorts the input least to greatest by the computed key.
|
||||
command-description-sortmapby =
|
||||
Sorts the input least to greatest by the computed key, replacing the value with it's computed key afterward.
|
||||
command-description-sort =
|
||||
Sorts the input least to greatest.
|
||||
command-description-sortdownby =
|
||||
Sorts the input greatest to least by the computed key.
|
||||
command-description-sortmapdownby =
|
||||
Sorts the input greatest to least by the computed key, replacing the value with it's computed key afterward.
|
||||
command-description-sortdown =
|
||||
Sorts the input greatest to least.
|
||||
command-description-iota =
|
||||
Returns a list of numbers 1 to N.
|
||||
command-description-to =
|
||||
Returns a list of numbers N to M.
|
||||
command-description-curtick =
|
||||
The current game tick.
|
||||
command-description-curtime =
|
||||
The current game time (a TimeSpan)
|
||||
command-description-realtime =
|
||||
The current realtime since startup (a TimeSpan)
|
||||
command-description-servertime =
|
||||
The current server game time, or zero if we are the server (a TimeSpan)
|
||||
command-description-replace =
|
||||
Replaces the input entities with the given prototype, preserving position and rotation (but nothing else)
|
||||
command-description-allcomps =
|
||||
Returns all components on the given entity.
|
||||
command-description-entitysystemupdateorder-tick =
|
||||
Lists the tick update order of entity systems.
|
||||
command-description-entitysystemupdateorder-frame =
|
||||
Lists the frame update order of entity systems.
|
||||
command-description-more =
|
||||
Prints the contents of $more, i.e. any extras that Toolshed didn't print from the last command.
|
||||
command-description-ModulusCommand =
|
||||
Computes the modulus of two values.
|
||||
This is usually remainder, check C#'s documentation for the type.
|
||||
command-description-ModVecCommand =
|
||||
Performs the modulus operation over the input with the given constant right-hand value.
|
||||
command-description-BitAndNotCommand =
|
||||
Performs bitwise AND-NOT over the input.
|
||||
command-description-BitOrNotCommand =
|
||||
Performs bitwise OR-NOT over the input.
|
||||
command-description-BitXnorCommand =
|
||||
Performs bitwise XNOR over the input.
|
||||
command-description-BitNotCommand =
|
||||
Performs bitwise NOT on the input.
|
||||
command-description-abs =
|
||||
Computes the absolute value of the input (removing the sign)
|
||||
command-description-average =
|
||||
Computes the average (arithmetic mean) of the input.
|
||||
command-description-bibytecount =
|
||||
Returns the size of the input in bytes, given that the input implements IBinaryInteger.
|
||||
This is NOT sizeof.
|
||||
command-description-shortestbitlength =
|
||||
Returns the minimum number of bits needed to represent the input value.
|
||||
command-description-countleadzeros =
|
||||
Counts the number of leading binary zeros in the input value.
|
||||
command-description-counttrailingzeros =
|
||||
Counts the number of trailing binary zeros in the input value.
|
||||
command-description-fpi =
|
||||
pi (3.14159...) as a float.
|
||||
command-description-fe =
|
||||
e (2.71828...) as a float.
|
||||
command-description-ftau =
|
||||
tau (6.28318...) as a float.
|
||||
command-description-fepsilon =
|
||||
The epsilon value for a float, exactly 1.4e-45.
|
||||
command-description-dpi =
|
||||
pi (3.14159...) as a double.
|
||||
command-description-de =
|
||||
e (2.71828...) as a double.
|
||||
command-description-dtau =
|
||||
tau (6.28318...) as a double.
|
||||
command-description-depsilon =
|
||||
The epsilon value for a double, exactly 4.9406564584124654E-324.
|
||||
command-description-hpi =
|
||||
pi (3.14...) as a half.
|
||||
command-description-he =
|
||||
e (2.71...) as a half.
|
||||
command-description-htau =
|
||||
tau (6.28...) as a half.
|
||||
command-description-hepsilon =
|
||||
The epsilon value for a half, exactly 5.9604645E-08.
|
||||
command-description-floor =
|
||||
Returns the floor of the input value (rounding toward zero).
|
||||
command-description-ceil =
|
||||
Returns the ceil of the input value (rounding away from zero).
|
||||
command-description-round =
|
||||
Rounds the input value.
|
||||
command-description-trunc =
|
||||
Truncates the input value.
|
||||
command-description-round2frac =
|
||||
Rounds the input value to the specified number of fractional digits.
|
||||
command-description-exponentbytecount =
|
||||
Returns the number of bytes required to store the exponent.
|
||||
command-description-significandbytecount =
|
||||
Returns the number of bytes required to store the significand.
|
||||
command-description-significandbitcount =
|
||||
Returns the exact bit length of the significand.
|
||||
command-description-exponentshortestbitcount =
|
||||
Returns the minimum number of bits to store the exponent.
|
||||
command-description-stepnext =
|
||||
Steps to the next float value, adding one to the significand with carry.
|
||||
command-description-stepprev =
|
||||
Steps to the previous float value, subtracting one from the significand with carry.
|
||||
command-description-checkedto =
|
||||
Converts from the input numeric type to the target, erroring if not possible.
|
||||
command-description-saturateto =
|
||||
Converts from the input numeric type to the target, saturating if the value is out of range.
|
||||
For example, converting 382 to a byte would saturate to 255 (the maximum value of a byte).
|
||||
command-description-truncto =
|
||||
Converts from the input numeric type to the target, with truncation.
|
||||
In the case of integers, this is a bit cast with sign extension.
|
||||
command-description-iscanonical =
|
||||
Returns whether the input is in canonical form.
|
||||
command-description-iscomplex =
|
||||
Returns whether the input is a complex number (by value, not by type)
|
||||
command-description-iseven =
|
||||
Returns whether the input is even.
|
||||
Not a javascript package.
|
||||
command-description-isodd =
|
||||
Returns whether the input is odd.
|
||||
command-description-isfinite =
|
||||
Returns whether the input is finite.
|
||||
command-description-isimaginary =
|
||||
Returns whether the input is purely imaginary (no real part).
|
||||
command-description-isinfinite =
|
||||
Returns whether the input is infinite.
|
||||
command-description-isinteger =
|
||||
Returns whether the input is an integer (by value, not by type)
|
||||
command-description-isnan =
|
||||
Returns whether the input is Not a Number (NaN).
|
||||
This is a special floating point value, so this is by value, not by type.
|
||||
command-description-isnegative =
|
||||
Returns whether the input is negative.
|
||||
command-description-ispositive =
|
||||
Returns whether the input is positive.
|
||||
command-description-isreal =
|
||||
Returns whether the input is purely real (no imaginary part).
|
||||
command-description-issubnormal =
|
||||
Returns whether the input is in sub-normal form.
|
||||
command-description-iszero =
|
||||
Returns whether the input is zero.
|
||||
command-description-pow =
|
||||
Computes the power of its lefthand to its righthand. x^y.
|
||||
command-description-sqrt =
|
||||
Computes the square root of its input.
|
||||
command-description-cbrt =
|
||||
Computes the cube root of its input.
|
||||
command-description-root =
|
||||
Computes the Nth root of its input.
|
||||
command-description-hypot =
|
||||
Computes the hypotenuse of a triangle with the given sides A and B.
|
||||
command-description-sin =
|
||||
Computes the sine of the input.
|
||||
command-description-sinpi =
|
||||
Computes the sine of the input multiplied by pi.
|
||||
command-description-asin =
|
||||
Computes the arcsine of the input.
|
||||
command-description-asinpi =
|
||||
Computes the arcsine of the input multiplied by pi.
|
||||
command-description-cos =
|
||||
Computes the cosine of the input.
|
||||
command-description-cospi =
|
||||
Computes the cosine of the input multiplied by pi.
|
||||
command-description-acos =
|
||||
Computes the arcosine of the input.
|
||||
command-description-acospi =
|
||||
Computes the arcosine of the input multiplied by pi.
|
||||
command-description-tan =
|
||||
Computes the tangent of the input.
|
||||
command-description-tanpi =
|
||||
Computes the tangent of the input multiplied by pi.
|
||||
command-description-atan =
|
||||
Computes the arctangent of the input.
|
||||
command-description-atanpi =
|
||||
Computes the arctangent of the input multiplied by pi.
|
||||
command-description-iterate =
|
||||
Iterates the given function over the input N times, returning a list of results.
|
||||
Think of this like successively applying the function to a value, tracking all the intermediate values.
|
||||
command-description-pick =
|
||||
Picks a random value from the input.
|
||||
command-description-tee =
|
||||
Tees the input into the given block, ignoring the block's result.
|
||||
This essentially lets you have a branch in your code to do multiple operations on one value.
|
||||
command-description-cmd-info =
|
||||
Returns a CommandSpec for the given command.
|
||||
On it's own, this means it'll print the comamnd's help message.
|
||||
command-description-comp-rm =
|
||||
Removes the given component from the entity.
|
||||
@@ -1,7 +0,0 @@
|
||||
uploadfolder-command-description = Uploads a folder from your UserData folder recursively to the server contentDB.
|
||||
uploadfolder-command-help = uploadfolder [folder you want to upload in userdata/UploadFolder]
|
||||
uploadfolder-command-wrong-args = Wrong number of arguments!
|
||||
uploadfolder-command-folder-not-found = Folder {$folder} not found!
|
||||
uploadfolder-command-resource-upload-disabled = Network Resource Uploading is currently disabled. check Server CVars.
|
||||
uploadfolder-command-file-too-big = File {$filename} above the current size limit! It must be smaller than {$sizeLimit} MB. skipping.
|
||||
uploadfolder-command-success = Uploaded {$fileCount} files
|
||||
@@ -1,63 +0,0 @@
|
||||
# Used internally by the THE() function.
|
||||
zzzz-the = { PROPER($ent) ->
|
||||
*[false] a { $ent }
|
||||
[true] { $ent }
|
||||
}
|
||||
|
||||
# Used internally by the SUBJECT() function.
|
||||
zzzz-subject-pronoun = { GENDER($ent) ->
|
||||
[male] ele
|
||||
[female] ela
|
||||
[epicene] eles
|
||||
*[neuter] ele
|
||||
}
|
||||
|
||||
# Used internally by the OBJECT() function.
|
||||
zzzz-object-pronoun = { GENDER($ent) ->
|
||||
[male] ele
|
||||
[female] ela
|
||||
[epicene] eles
|
||||
*[neuter] isso
|
||||
}
|
||||
|
||||
# Used internally by the POSS-PRONOUN() function.
|
||||
zzzz-possessive-pronoun = { GENDER($ent) ->
|
||||
[male] dele
|
||||
[female] dela
|
||||
[epicene] deles
|
||||
*[neuter] dele
|
||||
}
|
||||
|
||||
# Used internally by the POSS-ADJ() function.
|
||||
zzzz-possessive-adjective = { GENDER($ent) ->
|
||||
[male] dele
|
||||
[female] dela
|
||||
[epicene] deles
|
||||
*[neuter] dele
|
||||
}
|
||||
|
||||
# Used internally by the REFLEXIVE() function.
|
||||
zzzz-reflexive-pronoun = { GENDER($ent) ->
|
||||
[male] ele mesmo
|
||||
[female] ela mesmo
|
||||
[epicene] eles mesmos
|
||||
*[neuter] ele mesmo
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-BE() function.
|
||||
zzzz-conjugate-be = { GENDER($ent) ->
|
||||
[epicene] é
|
||||
*[other] é
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-HAVE() function.
|
||||
zzzz-conjugate-have = { GENDER($ent) ->
|
||||
[epicene] tenho
|
||||
*[other] tem
|
||||
}
|
||||
|
||||
# Used internally by the CONJUGATE-BASIC() function.
|
||||
zzzz-conjugate-basic = { GENDER($ent) ->
|
||||
[epicene] { $first }
|
||||
*[other] { $second }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
# Strings Loc para vários comandos relacionados ao estado da entidade e ao PVS do lado do cliente
|
||||
|
||||
cmd-reset-ent-help = Uso: resetent <Entity UID>
|
||||
cmd-reset-ent-desc = Redefina uma entidade para o estado do servidor recebido mais recentemente. Isso também redefinirá as entidades que foram desanexadas para espaço nulo.
|
||||
|
||||
cmd-reset-all-ents-help = Uso: resetallents
|
||||
cmd-reset-all-ents-desc = Redefine todas as entidades para o estado do servidor recebido mais recentemente. Isso afeta apenas as entidades que não foram desanexadas ao espaço nulo.
|
||||
|
||||
cmd-detach-ent-help = Uso: detachent <Entity UID>
|
||||
cmd-detach-ent-desc = Desanexar uma entidade para espaço nulo, como se tivesse saído do intervalo PVS.
|
||||
|
||||
cmd-local-delete-help = Uso: localdelete <Entity UID>
|
||||
cmd-local-delete-desc = Exclui uma entidade. Ao contrário do comando delete normal, este é CLIENT-SIDE. A menos que a entidade seja uma entidade do lado do cliente, isso provavelmente causará erros.
|
||||
|
||||
cmd-full-state-reset-help = Uso: fullstatereset
|
||||
cmd-full-state-reset-desc = Descarta qualquer informação de estado da entidade e solicita um estado completo do servidor.
|
||||
@@ -1,161 +0,0 @@
|
||||
### Localization for engine console commands
|
||||
|
||||
## generic
|
||||
|
||||
cmd-invalid-arg-number-error = Número inválido de argumentos.
|
||||
|
||||
cmd-parse-failure-integer = {$arg} não é um inteiro válido.
|
||||
cmd-parse-failure-float = {$arg} não é um float válido.
|
||||
cmd-parse-failure-bool = {$arg} não é um booleano válido.
|
||||
cmd-parse-failure-uid = {$arg} não é um UID de entidade válido.
|
||||
cmd-parse-failure-entity-exist = UID {$arg} não corresponde a uma entidade existente.
|
||||
|
||||
|
||||
## 'help' command
|
||||
cmd-help-desc = Exibir ajuda geral ou texto de ajuda para um comando específico
|
||||
cmd-help-help = Uso: help [command name]
|
||||
Quando nenhum nome de comando é fornecido, exibe o texto de ajuda geral. Se um nome de comando for fornecido, exibe o texto de ajuda para esse comando.
|
||||
|
||||
cmd-help-no-args = Para exibir a ajuda de um comando específico, escreva 'help <command>'. Para listar todos os comandos disponíveis, escreva 'list'. Para procurar comandos, use 'list <filter>'.
|
||||
cmd-help-unknown = Comando desconhecido: { $command }
|
||||
cmd-help-top = { $command } - { $description }
|
||||
cmd-help-invalid-args = Quantidade de argumentos inválida.
|
||||
cmd-help-arg-cmdname = [command name]
|
||||
|
||||
## 'cvar' command
|
||||
cmd-cvar-desc = Obtém ou define um CVar.
|
||||
cmd-cvar-help = Uso: cvar <name | ?> [value]
|
||||
Se um valor for passado, o valor será analisado e armazenado como o novo valor do CVar.
|
||||
Caso contrário, o valor atual do CVar é exibido.
|
||||
Use 'cvar ?' para obter uma lista de todos os CVars registrados.
|
||||
|
||||
cmd-cvar-invalid-args = Deve fornecer exatamente um ou dois argumentos.
|
||||
cmd-cvar-not-registered = CVar '{ $cvar }' não está registrado. Use 'cvar ?' para obter uma lista de todos os CVars registrados.
|
||||
cmd-cvar-parse-error = O valor de entrada está no formato incorreto para o tipo { $type }
|
||||
cmd-cvar-compl-list = Listar CVars disponíveis
|
||||
cmd-cvar-arg-name = <name | ?>
|
||||
cmd-cvar-value-hidden = <value hidden>
|
||||
|
||||
## 'list' command
|
||||
cmd-list-desc = Lista os comandos disponíveis, com filtro de pesquisa opcional
|
||||
cmd-list-help = Uso: list [filter]
|
||||
Lista todos os comandos disponíveis. Se um argumento for fornecido, ele será usado para filtrar comandos por nome.
|
||||
|
||||
cmd-list-heading = NOME DESC{"\u000A"}-------------------------{"\u000A"}
|
||||
|
||||
cmd-list-arg-filter = [filter]
|
||||
|
||||
## '>' command, aka remote exec
|
||||
cmd-remoteexec-desc = Executa comandos do lado do servidor
|
||||
cmd-remoteexec-help = Uso: > <command> [arg] [arg] [arg...]
|
||||
Executa um comando no servidor. Isso é necessário se um comando com o mesmo nome existir no cliente, pois a simples execução do comando executaria o comando do cliente primeiro.
|
||||
|
||||
## 'gc' command
|
||||
cmd-gc-desc = Execute o GC (coletor de lixo)
|
||||
cmd-gc-help = Uso: gc [generation]
|
||||
Usa GC.Collect() para executar o Garbage Collector.
|
||||
Se um argumento for fornecido, ele será analisado como um número de geração do GC e GC.Collect(int) será usado.
|
||||
Use o comando 'gfc' para fazer um GC completo compactando LOH.
|
||||
cmd-gc-failed-parse = Falha ao analisar o argumento.
|
||||
cmd-gc-arg-generation = [generation]
|
||||
|
||||
## 'gcf' command
|
||||
cmd-gcf-desc = Execute o GC, totalmente, compactando LOH e tudo.
|
||||
cmd-gcf-help = Uso: gcf
|
||||
Faz um GC.Collect(2, GCCollectionMode.Forced, true, true) completo enquanto também compacta LOH.
|
||||
Isso provavelmente será bloqueado por centenas de milissegundos, esteja avisado.
|
||||
|
||||
## 'gc_mode' command
|
||||
cmd-gc_mode-desc = Alterar/ler o modo de latência do GC
|
||||
cmd-gc_mode-help = Uso: gc_mode [type]
|
||||
Se nenhum argumento for fornecido, retornará o modo de latência do GC atual.
|
||||
Se um argumento for passado, ele será analisado como GCLatencyMode e definido como o modo de latência do GC.
|
||||
|
||||
cmd-gc_mode-current = modo de latência atual do gc: { $prevMode }
|
||||
cmd-gc_mode-possible = modos possíveis:
|
||||
cmd-gc_mode-option = - { $mode }
|
||||
cmd-gc_mode-unknown = modo de latência gc desconhecido: { $arg }
|
||||
cmd-gc_mode-attempt = tentando alterar o modo de latência do gc: { $prevMode } -> { $mode }
|
||||
cmd-gc_mode-result = modo de latência gc resultante: { $mode }
|
||||
cmd-gc_mode-arg-type = [type]
|
||||
|
||||
## 'mem' command
|
||||
cmd-mem-desc = Imprime informações de memória gerenciada
|
||||
cmd-mem-help = Uso: mem
|
||||
|
||||
cmd-mem-report = Tamanho da pilha: { TOSTRING($heapSize, "N0") }
|
||||
Total alocado: { TOSTRING($totalAllocated, "N0") }
|
||||
|
||||
## 'physics' command
|
||||
cmd-physics-overlay = {$overlay} não é uma sobreposição reconhecida
|
||||
|
||||
## 'lsasm' command
|
||||
cmd-lsasm-desc = Lista assemblies carregados por contexto de carregamento
|
||||
cmd-lsasm-help = Uso: lsasm
|
||||
|
||||
## 'exec' command
|
||||
cmd-exec-desc = Executa um arquivo de script dos dados de usuário graváveis do jogo
|
||||
cmd-exec-help = Uso: exec <fileName>
|
||||
Cada linha no arquivo é executada como um único comando, a menos que comece com um #
|
||||
|
||||
cmd-exec-arg-filename = <fileName>
|
||||
|
||||
## 'dump_net_comps' command
|
||||
cmd-dump_net_comps-desc = Imprime a tabela de componentes em rede.
|
||||
cmd-dump_net_comps-help = Uso: dump_net-comps
|
||||
|
||||
cmd-dump_net_comps-error-writeable = Registro ainda gravável, IDs de rede não foram gerados.
|
||||
cmd-dump_net_comps-header = Registros de componentes em rede:
|
||||
|
||||
## 'dump_event_tables' command
|
||||
cmd-dump_event_tables-desc = Imprime tabelas de eventos direcionados para uma entidade.
|
||||
cmd-dump_event_tables-help = Uso: dump_event_tables <entityUid>
|
||||
|
||||
cmd-dump_event_tables-missing-arg-entity = Argumento de entidade ausente
|
||||
cmd-dump_event_tables-error-entity = Entidade inválida
|
||||
cmd-dump_event_tables-arg-entity = <entityUid>
|
||||
|
||||
## 'monitor' command
|
||||
cmd-monitor-desc = Alterna um monitor de depuração no menu F3.
|
||||
cmd-monitor-help = Uso: monitor <name>
|
||||
Os monitores possíveis são: { $monitors }
|
||||
Você também pode usar os valores especiais "-all" e "+all" para ocultar ou mostrar todos os monitores, respectivamente.
|
||||
|
||||
cmd-monitor-arg-monitor = <monitor>
|
||||
cmd-monitor-invalid-name = Nome do monitor inválido
|
||||
cmd-monitor-arg-count = Argumento do monitor ausente
|
||||
cmd-monitor-minus-all-hint = Esconde todos os monitores
|
||||
cmd-monitor-plus-all-hint = Mostra todos os monitores
|
||||
|
||||
|
||||
## Mapping commands
|
||||
|
||||
cmd-savemap-desc = Serializa um mapa para o disco. Não salvará um mapa pós-inicialização a menos que seja forçado.
|
||||
cmd-savemap-help = savemap <MapID> <Path> [force]
|
||||
cmd-savemap-not-exist = O mapa de destino não existe.
|
||||
cmd-savemap-init-warning = Tentativa de salvar um mapa pós-inicialização sem forçar o salvamento.
|
||||
cmd-savemap-attempt = Tentando salvar o mapa {$mapId} em {$path}.
|
||||
cmd-savemap-success = Mapa salvo com sucesso.
|
||||
cmd-hint-savemap-id = <MapID>
|
||||
cmd-hint-savemap-path = <Path>
|
||||
cmd-hint-savemap-force = [bool]
|
||||
|
||||
cmd-loadmap-desc = Carrega um mapa do disco para o jogo.
|
||||
cmd-loadmap-help = loadmap <MapID> <Path> [x] [y] [rotation] [consistentUids]
|
||||
cmd-loadmap-nullspace = Você não pode carregar no mapa 0.
|
||||
cmd-loadmap-exists = Mapa {$mapId} já existe.
|
||||
cmd-loadmap-success = Mapa {$mapId} foi carregado em {$path}.
|
||||
cmd-loadmap-error = Ocorreu um erro ao carregar o mapa de {$path}.
|
||||
cmd-hint-loadmap-x-position = [x-position]
|
||||
cmd-hint-loadmap-y-position = [y-position]
|
||||
cmd-hint-loadmap-rotation = [rotation]
|
||||
cmd-hint-loadmap-uids = [float]
|
||||
|
||||
cmd-hint-savebp-id = <Grid EntityID>
|
||||
|
||||
## 'flushcookies' command
|
||||
# Note: the flushcookies command is from Robust.Client.WebView, it's not in the main engine code.
|
||||
|
||||
cmd-flushcookies-desc = Liberar o armazenamento de cookies CEF para o disco
|
||||
cmd-flushcookies-help = Isso garante que os cookies sejam salvos corretamente no disco no caso de desligamentos impróprios.
|
||||
Observe que a operação real é assíncrona.
|
||||
@@ -1,10 +0,0 @@
|
||||
color-selector-sliders-red = R
|
||||
color-selector-sliders-green = G
|
||||
color-selector-sliders-blue = B
|
||||
color-selector-sliders-hue = H
|
||||
color-selector-sliders-saturation = S
|
||||
color-selector-sliders-value = V
|
||||
color-selector-sliders-alpha = A
|
||||
|
||||
color-selector-sliders-rgb = RGB
|
||||
color-selector-sliders-hsv = HSV
|
||||
@@ -1,11 +0,0 @@
|
||||
## EntitySpawnWindow
|
||||
|
||||
entity-spawn-window-title = Painel de Criação de Entidade
|
||||
entity-spawn-window-search-bar-placeholder = pesquisar
|
||||
entity-spawn-window-clear-button = Limpar
|
||||
entity-spawn-window-erase-button-text = Modo Apagar
|
||||
entity-spawn-window-override-menu-tooltip = Substituir posicionamento
|
||||
|
||||
## Console
|
||||
|
||||
console-line-edit-placeholder = Comando aqui
|
||||
@@ -1 +0,0 @@
|
||||
defaultwindow-placeholder-title = Exemplo de título de janela aqui
|
||||
@@ -1,54 +0,0 @@
|
||||
input-key-Escape = Escape
|
||||
input-key-Control = Control
|
||||
input-key-Shift = Shift
|
||||
input-key-Alt = Alt
|
||||
input-key-Menu = Menu
|
||||
input-key-F1 = F1
|
||||
input-key-F2 = F2
|
||||
input-key-F3 = F3
|
||||
input-key-F4 = F4
|
||||
input-key-F5 = F5
|
||||
input-key-F6 = F6
|
||||
input-key-F7 = F7
|
||||
input-key-F8 = F8
|
||||
input-key-F9 = F9
|
||||
input-key-F10 = F10
|
||||
input-key-F11 = F11
|
||||
input-key-F12 = F12
|
||||
input-key-F13 = F13
|
||||
input-key-F14 = F14
|
||||
input-key-F15 = F15
|
||||
input-key-Pause = Pause
|
||||
input-key-Left = Left
|
||||
input-key-Up = Up
|
||||
input-key-Down = Down
|
||||
input-key-Right = Right
|
||||
input-key-Space = Space
|
||||
input-key-Return = Return
|
||||
input-key-NumpadEnter = Num Enter
|
||||
input-key-BackSpace = Backspace
|
||||
input-key-Tab = Tab
|
||||
input-key-PageUp = Page Up
|
||||
input-key-PageDown = Page Down
|
||||
input-key-End = End
|
||||
input-key-Home = Home
|
||||
input-key-Insert = Insert
|
||||
input-key-Delete = Delete
|
||||
input-key-MouseLeft = Mouse Left
|
||||
input-key-MouseRight = Mouse Right
|
||||
input-key-MouseMiddle = Mouse Middle
|
||||
input-key-MouseButton4 = Mouse 4
|
||||
input-key-MouseButton5 = Mouse 5
|
||||
input-key-MouseButton6 = Mouse 6
|
||||
input-key-MouseButton7 = Mouse 7
|
||||
input-key-MouseButton8 = Mouse 8
|
||||
input-key-MouseButton9 = Mouse 9
|
||||
|
||||
input-key-LSystem-win = Left Win
|
||||
input-key-RSystem-win = Right Win
|
||||
input-key-LSystem-mac = Left Cmd
|
||||
input-key-RSystem-mac = Right Cmd
|
||||
input-key-LSystem-linux = Left Meta
|
||||
input-key-RSystem-linux = Right Meta
|
||||
|
||||
input-key-unknown = <unknown key>
|
||||
@@ -1 +0,0 @@
|
||||
cmd-midipanic-desc = Desliga cada nota para cada renderizador MIDI ativo.
|
||||
@@ -1 +0,0 @@
|
||||
tab-container-not-tab-title-provided = Sem título
|
||||
@@ -1,11 +0,0 @@
|
||||
## ViewVariablesInstanceEntity
|
||||
|
||||
view-variable-instance-entity-server-components-add-component-button-placeholder = Adicionar Componente
|
||||
view-variable-instance-entity-client-variables-tab-title = Variávies do Cliente
|
||||
view-variable-instance-entity-client-components-tab-title = Componentes do Cliente
|
||||
view-variable-instance-entity-server-variables-tab-title = Variávies do Servidor
|
||||
view-variable-instance-entity-server-components-tab-title = Componentes do Servidor
|
||||
view-variable-instance-entity-client-components-search-bar-placeholder = Pesquisar
|
||||
view-variable-instance-entity-server-components-search-bar-placeholder = Pesquisar
|
||||
view-variable-instance-entity-add-window-server-components = Adicionar Componente [S]
|
||||
view-variable-instance-entity-add-window-client-components = Adicionar Componente [C]
|
||||
@@ -5,7 +5,6 @@ preset raw;
|
||||
#include "/Shaders/Internal/fov_shared.swsl"
|
||||
|
||||
const highp float g_MinVariance = 0.0;
|
||||
uniform highp vec4 occludeColor;
|
||||
|
||||
void fragment()
|
||||
{
|
||||
@@ -20,5 +19,5 @@ void fragment()
|
||||
discard;
|
||||
}
|
||||
|
||||
COLOR = vec4(occludeColor.rgb, 1.0 - occlusion);
|
||||
COLOR = vec4(0.0, 0.0, 0.0, 1.0 - occlusion);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ preset raw;
|
||||
#include "/Shaders/Internal/fov_shared.swsl"
|
||||
|
||||
const highp float g_MinVariance = 0.0;
|
||||
uniform highp vec4 occludeColor;
|
||||
|
||||
void fragment()
|
||||
{
|
||||
@@ -19,5 +18,5 @@ void fragment()
|
||||
discard;
|
||||
}
|
||||
|
||||
COLOR = vec4(occludeColor.rgb, 1.0);
|
||||
COLOR = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 637 B |
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
@@ -13,7 +12,6 @@ namespace Robust.Analyzers
|
||||
public class AccessAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string AccessAttributeType = "Robust.Shared.Analyzers.AccessAttribute";
|
||||
private const string RobustAutoGeneratedAttributeType = "Robust.Shared.Analyzers.RobustAutoGeneratedAttribute";
|
||||
private const string PureAttributeType = "System.Diagnostics.Contracts.PureAttribute";
|
||||
|
||||
[SuppressMessage("ReSharper", "RS2008")]
|
||||
@@ -75,20 +73,11 @@ namespace Robust.Analyzers
|
||||
|
||||
// Get the attributes
|
||||
var friendAttribute = context.Compilation.GetTypeByMetadataName(AccessAttributeType);
|
||||
var autoGenAttribute = context.Compilation.GetTypeByMetadataName(RobustAutoGeneratedAttributeType);
|
||||
|
||||
// Get the type that is containing this expression, or, the type where this is happening.
|
||||
if (context.ContainingSymbol?.ContainingType is not {} accessingType)
|
||||
return;
|
||||
|
||||
// Should we ignore the access attempt due to the accessing type being auto-generated?
|
||||
if (accessingType.GetAttributes().FirstOrDefault(a =>
|
||||
a.AttributeClass != null &&
|
||||
a.AttributeClass.Equals(autoGenAttribute, SymbolEqualityComparer.Default)) is { } attr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which type of access is happening here... Read, write or execute?
|
||||
var accessAttempt = DetermineAccess(context, targetAccess, operation);
|
||||
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
#nullable enable
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
using static Microsoft.CodeAnalysis.SymbolEqualityComparer;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string ByRefAttribute = "Robust.Shared.GameObjects.ByRefEventAttribute";
|
||||
|
||||
private static readonly DiagnosticDescriptor ByRefEventSubscribedByValueRule = new(
|
||||
Diagnostics.IdByRefEventSubscribedByValue,
|
||||
"By-ref event subscribed to by value",
|
||||
"Tried to subscribe to a by-ref event '{0}' by value.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure that methods subscribing to a ref event have the ref keyword for the event argument."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor ByValueEventSubscribedByRefRule = new(
|
||||
Diagnostics.IdValueEventRaisedByRef,
|
||||
"Value event subscribed to by-ref",
|
||||
"Tried to subscribe to a value event '{0}' by-ref.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure that methods subscribing to value events do not have the ref keyword for the event argument."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor ByRefEventRaisedByValueRule = new(
|
||||
Diagnostics.IdByRefEventRaisedByValue,
|
||||
"By-ref event raised by value",
|
||||
"Tried to raise a by-ref event '{0}' by value.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to use the ref keyword when raising ref events."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor ByValueEventRaisedByRefRule = new(
|
||||
Diagnostics.IdValueEventRaisedByRef,
|
||||
"Value event raised by-ref",
|
||||
"Tried to raise a value event '{0}' by-ref.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to not use the ref keyword when raising value events."
|
||||
);
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
|
||||
ByRefEventSubscribedByValueRule,
|
||||
ByValueEventSubscribedByRefRule,
|
||||
ByRefEventRaisedByValueRule,
|
||||
ByValueEventRaisedByRefRule
|
||||
);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||
context.EnableConcurrentExecution();
|
||||
context.RegisterOperationAction(CheckEventSubscription, OperationKind.Invocation);
|
||||
context.RegisterOperationAction(CheckEventRaise, OperationKind.Invocation);
|
||||
}
|
||||
|
||||
private void CheckEventSubscription(OperationAnalysisContext context)
|
||||
{
|
||||
if (context.Operation is not IInvocationOperation operation)
|
||||
return;
|
||||
|
||||
var subscribeMethods = context.Compilation
|
||||
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")?
|
||||
.GetMembers()
|
||||
.Where(m => m.Name.Contains("SubscribeLocalEvent"))
|
||||
.Cast<IMethodSymbol>();
|
||||
|
||||
if (subscribeMethods == null)
|
||||
return;
|
||||
|
||||
if (!subscribeMethods.Any(m => m.Equals(operation.TargetMethod.OriginalDefinition, Default)))
|
||||
return;
|
||||
|
||||
var typeArguments = operation.TargetMethod.TypeArguments;
|
||||
if (typeArguments.Length < 1 || typeArguments.Length > 2)
|
||||
return;
|
||||
|
||||
if (operation.Arguments.First().Value is not IDelegateCreationOperation delegateCreation)
|
||||
return;
|
||||
|
||||
if (delegateCreation.Target is not IMethodReferenceOperation methodReference)
|
||||
return;
|
||||
|
||||
var eventParameter = methodReference.Method.Parameters.LastOrDefault();
|
||||
if (eventParameter == null)
|
||||
return;
|
||||
|
||||
ITypeSymbol eventArgument;
|
||||
switch (typeArguments.Length)
|
||||
{
|
||||
case 1:
|
||||
eventArgument = typeArguments[0];
|
||||
break;
|
||||
case 2:
|
||||
eventArgument = typeArguments[1];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
var byRefAttribute = context.Compilation.GetTypeByMetadataName(ByRefAttribute);
|
||||
if (byRefAttribute == null)
|
||||
return;
|
||||
|
||||
var isByRefEventType = eventArgument
|
||||
.GetAttributes()
|
||||
.Any(attribute => attribute.AttributeClass?.Equals(byRefAttribute, Default) ?? false);
|
||||
var parameterIsRef = eventParameter.RefKind == RefKind.Ref;
|
||||
|
||||
if (isByRefEventType != parameterIsRef)
|
||||
{
|
||||
var descriptor = isByRefEventType ? ByRefEventSubscribedByValueRule : ByValueEventSubscribedByRefRule;
|
||||
var diagnostic = Diagnostic.Create(descriptor, operation.Syntax.GetLocation(), eventArgument);
|
||||
context.ReportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckEventRaise(OperationAnalysisContext context)
|
||||
{
|
||||
if (context.Operation is not IInvocationOperation operation)
|
||||
return;
|
||||
|
||||
var raiseMethods = context.Compilation
|
||||
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")?
|
||||
.GetMembers()
|
||||
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
|
||||
.Cast<IMethodSymbol>();
|
||||
|
||||
var busRaiseMethods = context.Compilation
|
||||
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntityEventBus")?
|
||||
.GetMembers()
|
||||
.Where(m => m.Name.Contains("RaiseLocalEvent") && m.Kind == SymbolKind.Method)
|
||||
.Cast<IMethodSymbol>();
|
||||
|
||||
if (raiseMethods == null)
|
||||
return;
|
||||
|
||||
if (busRaiseMethods != null)
|
||||
raiseMethods = raiseMethods.Concat(busRaiseMethods);
|
||||
|
||||
if (!raiseMethods.Any(m => m.Equals(operation.TargetMethod.OriginalDefinition, Default)))
|
||||
{
|
||||
// If you try to do this normally by concatenating like busRaiseMethods above
|
||||
// the analyzer does not run without any errors
|
||||
// I don't know man
|
||||
const string directedBusMethod = "Robust.Shared.GameObjects.IDirectedEventBus.RaiseLocalEvent";
|
||||
if (!operation.TargetMethod.ToString().StartsWith(directedBusMethod))
|
||||
return;
|
||||
}
|
||||
|
||||
var arguments = operation.Arguments;
|
||||
IArgumentOperation eventArgument;
|
||||
switch (arguments.Length)
|
||||
{
|
||||
case 1:
|
||||
eventArgument = arguments[0];
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
eventArgument = arguments[1];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
var eventParameter = eventArgument.Parameter;
|
||||
// TODO have a way to check generic type parameters
|
||||
if (eventParameter == null ||
|
||||
eventParameter.Type.SpecialType == SpecialType.System_Object ||
|
||||
eventParameter.Type.TypeKind == TypeKind.TypeParameter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var byRefAttribute = context.Compilation.GetTypeByMetadataName(ByRefAttribute);
|
||||
if (byRefAttribute == null)
|
||||
return;
|
||||
|
||||
var isByRefEventType = eventParameter.Type
|
||||
.GetAttributes()
|
||||
.Any(attribute => attribute.AttributeClass?.Equals(byRefAttribute, Default) ?? false);
|
||||
|
||||
var parameterIsRef = eventParameter.RefKind == RefKind.Ref;
|
||||
|
||||
if (isByRefEventType != parameterIsRef)
|
||||
{
|
||||
var descriptor = isByRefEventType ? ByRefEventRaisedByValueRule : ByValueEventRaisedByRefRule;
|
||||
var diagnostic = Diagnostic.Create(descriptor, eventArgument.Syntax.GetLocation(), eventParameter.Type);
|
||||
context.ReportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public sealed class DataDefinitionAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string DataDefinitionNamespace = "Robust.Shared.Serialization.Manager.Attributes.DataDefinitionAttribute";
|
||||
private const string ImplicitDataDefinitionNamespace = "Robust.Shared.Serialization.Manager.Attributes.ImplicitDataDefinitionForInheritorsAttribute";
|
||||
private const string DataFieldBaseNamespace = "Robust.Shared.Serialization.Manager.Attributes.DataFieldBaseAttribute";
|
||||
|
||||
private static readonly DiagnosticDescriptor DataDefinitionPartialRule = new(
|
||||
Diagnostics.IdDataDefinitionPartial,
|
||||
"Type must be partial",
|
||||
"Type {0} is a DataDefinition but is not partial.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to mark any type that is a data definition as partial."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor NestedDataDefinitionPartialRule = new(
|
||||
Diagnostics.IdNestedDataDefinitionPartial,
|
||||
"Type must be partial",
|
||||
"Type {0} contains nested data definition {1} but is not partial.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to mark any type containing a nested data definition as partial."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor DataFieldWritableRule = new(
|
||||
Diagnostics.IdDataFieldWritable,
|
||||
"Data field must not be readonly",
|
||||
"Data field {0} in data definition {1} is readonly.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to remove the readonly modifier."
|
||||
);
|
||||
|
||||
private static readonly DiagnosticDescriptor DataFieldPropertyWritableRule = new(
|
||||
Diagnostics.IdDataFieldPropertyWritable,
|
||||
"Data field property must have a setter",
|
||||
"Data field property {0} in data definition {1} does not have a setter.",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Make sure to add a setter."
|
||||
);
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
|
||||
DataDefinitionPartialRule, NestedDataDefinitionPartialRule, DataFieldWritableRule, DataFieldPropertyWritableRule
|
||||
);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);
|
||||
context.EnableConcurrentExecution();
|
||||
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataDefinition, SyntaxKind.ClassDeclaration);
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataDefinition, SyntaxKind.StructDeclaration);
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataDefinition, SyntaxKind.RecordDeclaration);
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataDefinition, SyntaxKind.RecordStructDeclaration);
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataDefinition, SyntaxKind.InterfaceDeclaration);
|
||||
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataField, SyntaxKind.FieldDeclaration);
|
||||
context.RegisterSyntaxNodeAction(AnalyzeDataFieldProperty, SyntaxKind.PropertyDeclaration);
|
||||
}
|
||||
|
||||
private void AnalyzeDataDefinition(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
if (context.Node is not TypeDeclarationSyntax declaration)
|
||||
return;
|
||||
|
||||
var type = context.SemanticModel.GetDeclaredSymbol(declaration)!;
|
||||
if (!IsDataDefinition(type))
|
||||
return;
|
||||
|
||||
if (!IsPartial(declaration))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(DataDefinitionPartialRule, declaration.Keyword.GetLocation(), type.Name));
|
||||
}
|
||||
|
||||
var containingType = type.ContainingType;
|
||||
while (containingType != null)
|
||||
{
|
||||
var containingTypeDeclaration = (TypeDeclarationSyntax) containingType.DeclaringSyntaxReferences[0].GetSyntax();
|
||||
if (!IsPartial(containingTypeDeclaration))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(NestedDataDefinitionPartialRule, containingTypeDeclaration.Keyword.GetLocation(), containingType.Name, type.Name));
|
||||
}
|
||||
|
||||
containingType = containingType.ContainingType;
|
||||
}
|
||||
}
|
||||
|
||||
private void AnalyzeDataField(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
if (context.Node is not FieldDeclarationSyntax field)
|
||||
return;
|
||||
|
||||
var typeDeclaration = field.FirstAncestorOrSelf<TypeDeclarationSyntax>();
|
||||
if (typeDeclaration == null)
|
||||
return;
|
||||
|
||||
var type = context.SemanticModel.GetDeclaredSymbol(typeDeclaration)!;
|
||||
if (!IsDataDefinition(type))
|
||||
return;
|
||||
|
||||
foreach (var variable in field.Declaration.Variables)
|
||||
{
|
||||
var fieldSymbol = context.SemanticModel.GetDeclaredSymbol(variable);
|
||||
if (fieldSymbol == null)
|
||||
continue;
|
||||
|
||||
if (IsReadOnlyDataField(type, fieldSymbol))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(DataFieldWritableRule, context.Node.GetLocation(), fieldSymbol.Name, type.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AnalyzeDataFieldProperty(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
if (context.Node is not PropertyDeclarationSyntax property)
|
||||
return;
|
||||
|
||||
var typeDeclaration = property.FirstAncestorOrSelf<TypeDeclarationSyntax>();
|
||||
if (typeDeclaration == null)
|
||||
return;
|
||||
|
||||
var type = context.SemanticModel.GetDeclaredSymbol(typeDeclaration)!;
|
||||
if (!IsDataDefinition(type) || type.IsRecord || type.IsValueType)
|
||||
return;
|
||||
|
||||
var propertySymbol = context.SemanticModel.GetDeclaredSymbol(property);
|
||||
if (propertySymbol == null)
|
||||
return;
|
||||
|
||||
if (IsReadOnlyDataField(type, propertySymbol))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(DataFieldPropertyWritableRule, context.Node.GetLocation(), propertySymbol.Name, type.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsReadOnlyDataField(ITypeSymbol type, ISymbol field)
|
||||
{
|
||||
if (!IsDataField(field, out _, out _))
|
||||
return false;
|
||||
|
||||
return IsReadOnlyMember(type, field);
|
||||
}
|
||||
|
||||
private static bool IsPartial(TypeDeclarationSyntax type)
|
||||
{
|
||||
return type.Modifiers.IndexOf(SyntaxKind.PartialKeyword) != -1;
|
||||
}
|
||||
|
||||
private static bool IsDataDefinition(ITypeSymbol? type)
|
||||
{
|
||||
if (type == null)
|
||||
return false;
|
||||
|
||||
return HasAttribute(type, DataDefinitionNamespace) ||
|
||||
IsImplicitDataDefinition(type);
|
||||
}
|
||||
|
||||
private static bool IsDataField(ISymbol member, out ITypeSymbol type, out AttributeData attribute)
|
||||
{
|
||||
// TODO data records and other attributes
|
||||
if (member is IFieldSymbol field)
|
||||
{
|
||||
foreach (var attr in field.GetAttributes())
|
||||
{
|
||||
if (attr.AttributeClass != null && Inherits(attr.AttributeClass, DataFieldBaseNamespace))
|
||||
{
|
||||
type = field.Type;
|
||||
attribute = attr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (member is IPropertySymbol property)
|
||||
{
|
||||
foreach (var attr in property.GetAttributes())
|
||||
{
|
||||
if (attr.AttributeClass != null && Inherits(attr.AttributeClass, DataFieldBaseNamespace))
|
||||
{
|
||||
type = property.Type;
|
||||
attribute = attr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type = null!;
|
||||
attribute = null!;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool Inherits(ITypeSymbol type, string parent)
|
||||
{
|
||||
foreach (var baseType in GetBaseTypes(type))
|
||||
{
|
||||
if (baseType.ToDisplayString() == parent)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsReadOnlyMember(ITypeSymbol type, ISymbol member)
|
||||
{
|
||||
if (member is IFieldSymbol field)
|
||||
{
|
||||
return field.IsReadOnly;
|
||||
}
|
||||
else if (member is IPropertySymbol property)
|
||||
{
|
||||
if (property.SetMethod == null)
|
||||
return true;
|
||||
|
||||
if (property.SetMethod.IsInitOnly)
|
||||
return type.IsReferenceType;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool HasAttribute(ITypeSymbol type, string attributeName)
|
||||
{
|
||||
foreach (var attribute in type.GetAttributes())
|
||||
{
|
||||
if (attribute.AttributeClass?.ToDisplayString() == attributeName)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsImplicitDataDefinition(ITypeSymbol type)
|
||||
{
|
||||
if (HasAttribute(type, ImplicitDataDefinitionNamespace))
|
||||
return true;
|
||||
|
||||
foreach (var baseType in GetBaseTypes(type))
|
||||
{
|
||||
if (HasAttribute(baseType, ImplicitDataDefinitionNamespace))
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var @interface in type.AllInterfaces)
|
||||
{
|
||||
if (IsImplicitDataDefinitionInterface(@interface))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsImplicitDataDefinitionInterface(ITypeSymbol @interface)
|
||||
{
|
||||
if (HasAttribute(@interface, ImplicitDataDefinitionNamespace))
|
||||
return true;
|
||||
|
||||
foreach (var subInterface in @interface.AllInterfaces)
|
||||
{
|
||||
if (HasAttribute(subInterface, ImplicitDataDefinitionNamespace))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IEnumerable<ITypeSymbol> GetBaseTypes(ITypeSymbol type)
|
||||
{
|
||||
var baseType = type.BaseType;
|
||||
while (baseType != null)
|
||||
{
|
||||
yield return baseType;
|
||||
baseType = baseType.BaseType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
#nullable enable
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeActions;
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxKind;
|
||||
using static Robust.Analyzers.Diagnostics;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
public sealed class DefinitionFixer : CodeFixProvider
|
||||
{
|
||||
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
|
||||
IdDataDefinitionPartial, IdNestedDataDefinitionPartial, IdDataFieldWritable, IdDataFieldPropertyWritable
|
||||
);
|
||||
|
||||
public override Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
foreach (var diagnostic in context.Diagnostics)
|
||||
{
|
||||
switch (diagnostic.Id)
|
||||
{
|
||||
case IdDataDefinitionPartial:
|
||||
return RegisterPartialTypeFix(context, diagnostic);
|
||||
case IdNestedDataDefinitionPartial:
|
||||
return RegisterPartialTypeFix(context, diagnostic);
|
||||
case IdDataFieldWritable:
|
||||
return RegisterDataFieldFix(context, diagnostic);
|
||||
case IdDataFieldPropertyWritable:
|
||||
return RegisterDataFieldPropertyFix(context, diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override FixAllProvider GetFixAllProvider()
|
||||
{
|
||||
return WellKnownFixAllProviders.BatchFixer;
|
||||
}
|
||||
|
||||
private static async Task RegisterPartialTypeFix(CodeFixContext context, Diagnostic diagnostic)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
|
||||
var span = diagnostic.Location.SourceSpan;
|
||||
var token = root?.FindToken(span.Start).Parent?.AncestorsAndSelf().OfType<TypeDeclarationSyntax>().First();
|
||||
|
||||
if (token == null)
|
||||
return;
|
||||
|
||||
context.RegisterCodeFix(CodeAction.Create(
|
||||
"Make type partial",
|
||||
c => MakeDataDefinitionPartial(context.Document, token, c),
|
||||
"Make type partial"
|
||||
), diagnostic);
|
||||
}
|
||||
|
||||
private static async Task<Document> MakeDataDefinitionPartial(Document document, TypeDeclarationSyntax declaration, CancellationToken cancellation)
|
||||
{
|
||||
var root = (CompilationUnitSyntax?) await document.GetSyntaxRootAsync(cancellation);
|
||||
var token = SyntaxFactory.Token(PartialKeyword);
|
||||
var newDeclaration = declaration.AddModifiers(token);
|
||||
|
||||
root = root!.ReplaceNode(declaration, newDeclaration);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
private static async Task RegisterDataFieldFix(CodeFixContext context, Diagnostic diagnostic)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
|
||||
var span = diagnostic.Location.SourceSpan;
|
||||
var field = root?.FindToken(span.Start).Parent?.AncestorsAndSelf().OfType<FieldDeclarationSyntax>().FirstOrDefault();
|
||||
|
||||
if (field == null)
|
||||
return;
|
||||
|
||||
context.RegisterCodeFix(CodeAction.Create(
|
||||
"Make data field writable",
|
||||
c => MakeFieldWritable(context.Document, field, c),
|
||||
"Make data field writable"
|
||||
), diagnostic);
|
||||
}
|
||||
|
||||
private static async Task RegisterDataFieldPropertyFix(CodeFixContext context, Diagnostic diagnostic)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
|
||||
var span = diagnostic.Location.SourceSpan;
|
||||
var property = root?.FindToken(span.Start).Parent?.AncestorsAndSelf().OfType<PropertyDeclarationSyntax>().FirstOrDefault();
|
||||
|
||||
if (property == null)
|
||||
return;
|
||||
|
||||
context.RegisterCodeFix(CodeAction.Create(
|
||||
"Make data field writable",
|
||||
c => MakePropertyWritable(context.Document, property, c),
|
||||
"Make data field writable"
|
||||
), diagnostic);
|
||||
}
|
||||
|
||||
private static async Task<Document> MakeFieldWritable(Document document, FieldDeclarationSyntax declaration, CancellationToken cancellation)
|
||||
{
|
||||
var root = (CompilationUnitSyntax?) await document.GetSyntaxRootAsync(cancellation);
|
||||
var token = declaration.Modifiers.First(t => t.IsKind(ReadOnlyKeyword));
|
||||
var newDeclaration = declaration.WithModifiers(declaration.Modifiers.Remove(token));
|
||||
|
||||
root = root!.ReplaceNode(declaration, newDeclaration);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
private static async Task<Document> MakePropertyWritable(Document document, PropertyDeclarationSyntax declaration, CancellationToken cancellation)
|
||||
{
|
||||
var root = (CompilationUnitSyntax?) await document.GetSyntaxRootAsync(cancellation);
|
||||
var newDeclaration = declaration;
|
||||
var privateSet = newDeclaration
|
||||
.AccessorList?
|
||||
.Accessors
|
||||
.FirstOrDefault(s => s.IsKind(SetAccessorDeclaration) || s.IsKind(InitAccessorDeclaration));
|
||||
|
||||
if (newDeclaration.AccessorList != null && privateSet != null)
|
||||
{
|
||||
newDeclaration = newDeclaration.WithAccessorList(
|
||||
newDeclaration.AccessorList.WithAccessors(
|
||||
newDeclaration.AccessorList.Accessors.Remove(privateSet)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
AccessorDeclarationSyntax setter;
|
||||
if (declaration.Modifiers.Any(m => m.IsKind(PrivateKeyword)))
|
||||
{
|
||||
setter = SyntaxFactory.AccessorDeclaration(
|
||||
SetAccessorDeclaration,
|
||||
default,
|
||||
default,
|
||||
SyntaxFactory.Token(SetKeyword),
|
||||
default,
|
||||
default,
|
||||
SyntaxFactory.Token(SemicolonToken)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
setter = SyntaxFactory.AccessorDeclaration(
|
||||
SetAccessorDeclaration,
|
||||
default,
|
||||
SyntaxFactory.TokenList(SyntaxFactory.Token(PrivateKeyword)),
|
||||
SyntaxFactory.Token(SetKeyword),
|
||||
default,
|
||||
default,
|
||||
SyntaxFactory.Token(SemicolonToken)
|
||||
);
|
||||
}
|
||||
|
||||
newDeclaration = newDeclaration.AddAccessorListAccessors(setter);
|
||||
|
||||
root = root!.ReplaceNode(declaration, newDeclaration);
|
||||
|
||||
return document.WithSyntaxRoot(root);
|
||||
}
|
||||
}
|
||||
@@ -9,22 +9,6 @@ public static class Diagnostics
|
||||
public const string IdAccess = "RA0002";
|
||||
public const string IdExplicitVirtual = "RA0003";
|
||||
public const string IdTaskResult = "RA0004";
|
||||
public const string IdUseGenericVariant = "RA0005";
|
||||
public const string IdUseGenericVariantInvalidUsage = "RA0006";
|
||||
public const string IdUseGenericVariantAttributeValueError = "RA0007";
|
||||
public const string IdNotNullableFlagNotSet = "RA0008";
|
||||
public const string IdInvalidNotNullableFlagValue = "RA0009";
|
||||
public const string IdInvalidNotNullableFlagImplementation = "RA0010";
|
||||
public const string IdInvalidNotNullableFlagType = "RA0011";
|
||||
public const string IdNotNullableFlagValueType = "RA0012";
|
||||
public const string IdByRefEventSubscribedByValue = "RA0013";
|
||||
public const string IdValueEventSubscribedByRef = "RA0014";
|
||||
public const string IdByRefEventRaisedByValue = "RA0015";
|
||||
public const string IdValueEventRaisedByRef = "RA0016";
|
||||
public const string IdDataDefinitionPartial = "RA0017";
|
||||
public const string IdNestedDataDefinitionPartial = "RA0018";
|
||||
public const string IdDataFieldWritable = "RA0019";
|
||||
public const string IdDataFieldPropertyWritable = "RA0020";
|
||||
|
||||
public static SuppressionDescriptor MeansImplicitAssignment =>
|
||||
new SuppressionDescriptor("RADC1000", "CS0649", "Marked as implicitly assigned.");
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public sealed class NotNullableFlagAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string Attribute = "Robust.Shared.Analyzers.NotNullableFlagAttribute";
|
||||
|
||||
private static readonly DiagnosticDescriptor NotNullableNotSetRule = new (
|
||||
Diagnostics.IdNotNullableFlagNotSet,
|
||||
"Not Nullable Flag not set",
|
||||
"Class type parameter {0} is not annotated as nullable and notNullableOverride is not set to true",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Assign true to notNullableOverride or specify the type parameter as nullable.");
|
||||
|
||||
private static readonly DiagnosticDescriptor InvalidNotNullableValueRule = new (
|
||||
Diagnostics.IdInvalidNotNullableFlagValue,
|
||||
"Not Nullable Flag wrongfully set",
|
||||
"Class type parameter {0} is annotated as nullable but notNullableOverride is set to true",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Remove the true assignment to notNullableOverride or remove the nullable specifier of the type parameter.");
|
||||
|
||||
private static readonly DiagnosticDescriptor InvalidNotNullableImplementationRule = new (
|
||||
Diagnostics.IdInvalidNotNullableFlagImplementation,
|
||||
"Invalid NotNullable flag implementation.",
|
||||
"NotNullable flag is either not typed as bool, or does not have a default value equaling false",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Ensure that the notNullable flag is typed bool and has false set as a default value.");
|
||||
|
||||
private static readonly DiagnosticDescriptor InvalidNotNullableTypeRule = new (
|
||||
Diagnostics.IdInvalidNotNullableFlagType,
|
||||
"Failed to resolve type parameter",
|
||||
"Failed to resolve type parameter \"{0}\".",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Use nameof to avoid typos.");
|
||||
|
||||
private static readonly DiagnosticDescriptor NotNullableFlagValueTypeRule = new (
|
||||
Diagnostics.IdNotNullableFlagValueType,
|
||||
"NotNullable flag not supported for value types.",
|
||||
"Value types as generic arguments are not supported for NotNullable flags",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Nullable value types are distinct at runtime when inspected with reflection. Therefore they are not supported for NotNullable flags.");
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
|
||||
ImmutableArray.Create(
|
||||
NotNullableNotSetRule,
|
||||
InvalidNotNullableValueRule,
|
||||
InvalidNotNullableImplementationRule,
|
||||
InvalidNotNullableTypeRule,
|
||||
NotNullableFlagValueTypeRule);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||
context.EnableConcurrentExecution();
|
||||
context.RegisterOperationAction(CheckNotNullableFlag, OperationKind.Invocation);
|
||||
}
|
||||
|
||||
private bool TryGetTypeArgument(IMethodSymbol methodSymbol, string typeParamName, out ITypeSymbol typeArgument)
|
||||
{
|
||||
for (var index = 0; index < methodSymbol.TypeParameters.Length; index++)
|
||||
{
|
||||
if (methodSymbol.TypeParameters[index].Name != typeParamName)
|
||||
continue;
|
||||
|
||||
typeArgument = methodSymbol.TypeArguments[index];
|
||||
return true;
|
||||
}
|
||||
|
||||
typeArgument = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CheckNotNullableFlag(OperationAnalysisContext context)
|
||||
{
|
||||
if (context.Operation is not IInvocationOperation invocationOperation || !invocationOperation.TargetMethod.IsGenericMethod)
|
||||
return;
|
||||
|
||||
var attribute = context.Compilation.GetTypeByMetadataName(Attribute);
|
||||
var @bool = context.Compilation.GetSpecialType(SpecialType.System_Boolean);
|
||||
|
||||
foreach (var argument in invocationOperation.Arguments)
|
||||
{
|
||||
if(argument.Parameter == null) continue;
|
||||
|
||||
foreach (var attributeData in argument.Parameter.GetAttributes())
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(attributeData.AttributeClass, attribute))
|
||||
continue;
|
||||
|
||||
if (!SymbolEqualityComparer.Default.Equals(argument.Parameter.Type, @bool) ||
|
||||
!argument.Parameter.HasExplicitDefaultValue ||
|
||||
argument.Parameter.ExplicitDefaultValue as bool? != false)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
InvalidNotNullableImplementationRule,
|
||||
argument.Parameter.Locations[0]));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!TryGetTypeArgument(invocationOperation.TargetMethod,
|
||||
attributeData.ConstructorArguments[0].Value as string, out var typeArgument))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
InvalidNotNullableTypeRule,
|
||||
argument.Parameter.Locations[0],
|
||||
attributeData.ConstructorArguments[0].Value as string));
|
||||
break;
|
||||
}
|
||||
|
||||
//until i find a way to implement it sanely, generic calls are exempt from this attribute
|
||||
if(typeArgument is ITypeParameterSymbol) break;
|
||||
|
||||
//dont ask me why, argument.ConstantValue just straight up doesnt work.
|
||||
//i still kept it in here as a fallback, incase it ever starts working again lol -<paul
|
||||
var constantValue = (argument.Value as ILiteralOperation)?.ConstantValue ?? argument.ConstantValue;
|
||||
|
||||
if (typeArgument.IsValueType)
|
||||
{
|
||||
if (argument.ArgumentKind != ArgumentKind.DefaultValue)
|
||||
{
|
||||
//todo diagnostic only use for struct types
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
NotNullableFlagValueTypeRule,
|
||||
argument.Syntax.GetLocation()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeArgument.NullableAnnotation == NullableAnnotation.None ||
|
||||
(argument.ArgumentKind != ArgumentKind.DefaultValue && !constantValue.HasValue))
|
||||
break;
|
||||
|
||||
var flagValue = argument.ArgumentKind != ArgumentKind.DefaultValue ||
|
||||
constantValue.Value as bool? == true;
|
||||
|
||||
var nullable = typeArgument.NullableAnnotation == NullableAnnotation.Annotated;
|
||||
|
||||
if (nullable && flagValue)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(InvalidNotNullableValueRule,
|
||||
argument.Syntax.GetLocation(),
|
||||
typeArgument));
|
||||
}
|
||||
else if (!nullable && !flagValue)
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(NotNullableNotSetRule,
|
||||
argument.Syntax.GetLocation(),
|
||||
typeArgument));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeActions;
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
|
||||
namespace Robust.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public sealed class PreferGenericVariantAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
private const string AttributeType = "Robust.Shared.Analyzers.PreferGenericVariantAttribute";
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
|
||||
UseGenericVariantDescriptor, UseGenericVariantInvalidUsageDescriptor,
|
||||
UseGenericVariantAttributeValueErrorDescriptor);
|
||||
|
||||
private static readonly DiagnosticDescriptor UseGenericVariantDescriptor = new(
|
||||
Diagnostics.IdUseGenericVariant,
|
||||
"Consider using the generic variant of this method",
|
||||
"Consider using the generic variant of this method to avoid potential allocations",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Warning,
|
||||
true,
|
||||
"Consider using the generic variant of this method to avoid potential allocations.");
|
||||
|
||||
private static readonly DiagnosticDescriptor UseGenericVariantInvalidUsageDescriptor = new(
|
||||
Diagnostics.IdUseGenericVariantInvalidUsage,
|
||||
"Invalid generic variant provided",
|
||||
"Generic variant provided mismatches the amount of type parameters of non-generic variant",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"The non-generic variant should have at least as many type parameter at the beginning of the method as there are generic type parameters on the generic variant.");
|
||||
|
||||
private static readonly DiagnosticDescriptor UseGenericVariantAttributeValueErrorDescriptor = new(
|
||||
Diagnostics.IdUseGenericVariantAttributeValueError,
|
||||
"Failed resolving generic variant value",
|
||||
"Failed resolving generic variant value: {0}",
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true,
|
||||
"Consider using nameof to avoid any typos.");
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics | GeneratedCodeAnalysisFlags.Analyze);
|
||||
context.EnableConcurrentExecution();
|
||||
context.RegisterOperationAction(CheckForGenericVariant, OperationKind.Invocation);
|
||||
}
|
||||
|
||||
private void CheckForGenericVariant(OperationAnalysisContext obj)
|
||||
{
|
||||
if(obj.Operation is not IInvocationOperation invocationOperation) return;
|
||||
|
||||
var preferGenericAttribute = obj.Compilation.GetTypeByMetadataName(AttributeType);
|
||||
|
||||
string genericVariant = null;
|
||||
AttributeData foundAttribute = null;
|
||||
foreach (var attribute in invocationOperation.TargetMethod.GetAttributes())
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, preferGenericAttribute))
|
||||
continue;
|
||||
|
||||
genericVariant = attribute.ConstructorArguments[0].Value as string ?? invocationOperation.TargetMethod.Name;
|
||||
foundAttribute = attribute;
|
||||
break;
|
||||
}
|
||||
|
||||
if(genericVariant == null) return;
|
||||
|
||||
var maxTypeParams = 0;
|
||||
var typeTypeSymbol = obj.Compilation.GetTypeByMetadataName("System.Type");
|
||||
foreach (var parameter in invocationOperation.TargetMethod.Parameters)
|
||||
{
|
||||
if(!SymbolEqualityComparer.Default.Equals(parameter.Type, typeTypeSymbol)) break;
|
||||
|
||||
maxTypeParams++;
|
||||
}
|
||||
|
||||
if (maxTypeParams == 0)
|
||||
{
|
||||
obj.ReportDiagnostic(
|
||||
Diagnostic.Create(UseGenericVariantInvalidUsageDescriptor,
|
||||
foundAttribute.ApplicationSyntaxReference?.GetSyntax().GetLocation()));
|
||||
return;
|
||||
}
|
||||
|
||||
IMethodSymbol genericVariantMethod = null;
|
||||
foreach (var member in invocationOperation.TargetMethod.ContainingType.GetMembers())
|
||||
{
|
||||
if (member is not IMethodSymbol methodSymbol
|
||||
|| methodSymbol.Name != genericVariant
|
||||
|| !methodSymbol.IsGenericMethod
|
||||
|| methodSymbol.TypeParameters.Length > maxTypeParams
|
||||
|| methodSymbol.Parameters.Length > invocationOperation.TargetMethod.Parameters.Length - methodSymbol.TypeParameters.Length
|
||||
) continue;
|
||||
|
||||
var typeParamCount = methodSymbol.TypeParameters.Length;
|
||||
var failedParamComparison = false;
|
||||
var objType = obj.Compilation.GetSpecialType(SpecialType.System_Object);
|
||||
for (int i = 0; i < methodSymbol.Parameters.Length; i++)
|
||||
{
|
||||
if (methodSymbol.Parameters[i].Type is ITypeParameterSymbol && SymbolEqualityComparer.Default.Equals(invocationOperation.TargetMethod.Parameters[i + typeParamCount].Type, objType))
|
||||
continue;
|
||||
|
||||
if (!SymbolEqualityComparer.Default.Equals(methodSymbol.Parameters[i].Type,
|
||||
invocationOperation.TargetMethod.Parameters[i + typeParamCount].Type))
|
||||
{
|
||||
failedParamComparison = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(failedParamComparison) continue;
|
||||
|
||||
genericVariantMethod = methodSymbol;
|
||||
}
|
||||
|
||||
if (genericVariantMethod == null)
|
||||
{
|
||||
obj.ReportDiagnostic(Diagnostic.Create(
|
||||
UseGenericVariantAttributeValueErrorDescriptor,
|
||||
foundAttribute.ApplicationSyntaxReference?.GetSyntax().GetLocation(),
|
||||
genericVariant));
|
||||
return;
|
||||
}
|
||||
|
||||
var typeOperands = new string[genericVariantMethod.TypeParameters.Length];
|
||||
for (var i = 0; i < genericVariantMethod.TypeParameters.Length; i++)
|
||||
{
|
||||
switch (invocationOperation.Arguments[i].Value)
|
||||
{
|
||||
//todo figure out if ILocalReferenceOperation, IPropertyReferenceOperation or IFieldReferenceOperation is referencing static typeof assignments
|
||||
case ITypeOfOperation typeOfOperation:
|
||||
typeOperands[i] = typeOfOperation.TypeOperand.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
continue;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
obj.ReportDiagnostic(Diagnostic.Create(
|
||||
UseGenericVariantDescriptor,
|
||||
invocationOperation.Syntax.GetLocation(),
|
||||
ImmutableDictionary.CreateRange(new Dictionary<string, string>()
|
||||
{
|
||||
{"typeOperands", string.Join(",", typeOperands)}
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
[ExportCodeFixProvider(LanguageNames.CSharp)]
|
||||
public class PreferGenericVariantCodeFixProvider : CodeFixProvider
|
||||
{
|
||||
private static string Title(string method, string[] types) => $"Use {method}<{string.Join(",", types)}>.";
|
||||
|
||||
public override FixAllProvider GetFixAllProvider()
|
||||
{
|
||||
return WellKnownFixAllProviders.BatchFixer;
|
||||
}
|
||||
|
||||
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
|
||||
{
|
||||
var root = await context.Document.GetSyntaxRootAsync();
|
||||
if(root == null) return;
|
||||
|
||||
foreach (var diagnostic in context.Diagnostics)
|
||||
{
|
||||
if (!diagnostic.Properties.TryGetValue("typeOperands", out var typeOperandsRaw)
|
||||
|| typeOperandsRaw == null) continue;
|
||||
|
||||
var node = root.FindNode(diagnostic.Location.SourceSpan);
|
||||
if (node is ArgumentSyntax argumentSyntax)
|
||||
node = argumentSyntax.Expression;
|
||||
|
||||
if(node is not InvocationExpressionSyntax invocationExpression)
|
||||
continue;
|
||||
|
||||
var typeOperands = typeOperandsRaw.Split(',');
|
||||
|
||||
context.RegisterCodeFix(
|
||||
CodeAction.Create(
|
||||
Title(invocationExpression.Expression.ToString(), typeOperands),
|
||||
c => FixAsync(context.Document, invocationExpression, typeOperands, c),
|
||||
Title(invocationExpression.Expression.ToString(), typeOperands)),
|
||||
diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Document> FixAsync(
|
||||
Document contextDocument,
|
||||
InvocationExpressionSyntax invocationExpression,
|
||||
string[] typeOperands,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var memberAccess = (MemberAccessExpressionSyntax)invocationExpression.Expression;
|
||||
|
||||
var root = (CompilationUnitSyntax) await contextDocument.GetSyntaxRootAsync(cancellationToken);
|
||||
|
||||
var arguments = new ArgumentSyntax[invocationExpression.ArgumentList.Arguments.Count - typeOperands.Length];
|
||||
var types = new TypeSyntax[typeOperands.Length];
|
||||
|
||||
for (int i = 0; i < typeOperands.Length; i++)
|
||||
{
|
||||
types[i] = ((TypeOfExpressionSyntax)invocationExpression.ArgumentList.Arguments[i].Expression).Type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Array.Copy(
|
||||
invocationExpression.ArgumentList.Arguments.ToArray(),
|
||||
typeOperands.Length,
|
||||
arguments,
|
||||
0,
|
||||
arguments.Length);
|
||||
|
||||
memberAccess = memberAccess.WithName(SyntaxFactory.GenericName(memberAccess.Name.Identifier,
|
||||
SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(types))));
|
||||
|
||||
root = root!.ReplaceNode(invocationExpression,
|
||||
invocationExpression.WithArgumentList(invocationExpression.ArgumentList.WithArguments(SyntaxFactory.SeparatedList(arguments)))
|
||||
.WithExpression(memberAccess));
|
||||
|
||||
return contextDocument.WithSyntaxRoot(root);
|
||||
}
|
||||
|
||||
public override ImmutableArray<string> FixableDiagnosticIds =>
|
||||
ImmutableArray.Create(Diagnostics.IdUseGenericVariant);
|
||||
}
|
||||
@@ -11,20 +11,10 @@
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Needed for NotNullableFlagAnalyzer. -->
|
||||
<Compile Include="..\Robust.Shared\Analyzers\NotNullableFlagAttribute.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Needed for FriendAnalyzer. -->
|
||||
<Compile Include="..\Robust.Shared\Analyzers\AccessAttribute.cs" />
|
||||
<Compile Include="..\Robust.Shared\Analyzers\AccessPermissions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Needed for PreferGenericVariantAnalyzer. -->
|
||||
<Compile Include="..\Robust.Shared\Analyzers\PreferGenericVariantAttribute.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -8,7 +8,7 @@ using Robust.UnitTesting.Server;
|
||||
namespace Robust.Benchmarks.EntityManager;
|
||||
|
||||
[Virtual]
|
||||
public partial class AddRemoveComponentBenchmark
|
||||
public class AddRemoveComponentBenchmark
|
||||
{
|
||||
private ISimulation _simulation = default!;
|
||||
private IEntityManager _entityManager = default!;
|
||||
@@ -48,7 +48,7 @@ public partial class AddRemoveComponentBenchmark
|
||||
}
|
||||
|
||||
[ComponentProtoName("A")]
|
||||
public sealed partial class A : Component
|
||||
public sealed class A : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.UnitTesting.Server;
|
||||
|
||||
namespace Robust.Benchmarks.EntityManager;
|
||||
|
||||
public partial class ComponentIteratorBenchmark
|
||||
{
|
||||
private ISimulation _simulation = default!;
|
||||
private IEntityManager _entityManager = default!;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Params(1, 10, 100, 1000)]
|
||||
public int N;
|
||||
|
||||
public A[] Comps = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
_simulation = RobustServerSimulation
|
||||
.NewSimulation()
|
||||
.RegisterComponents(f => f.RegisterClass<A>())
|
||||
.InitializeInstance();
|
||||
|
||||
_entityManager = _simulation.Resolve<IEntityManager>();
|
||||
|
||||
Comps = new A[N+2];
|
||||
|
||||
var coords = new MapCoordinates(0, 0, new MapId(1));
|
||||
_simulation.AddMap(coords.MapId);
|
||||
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
var uid = _entityManager.SpawnEntity(null, coords);
|
||||
_entityManager.AddComponent<A>(uid);
|
||||
}
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public A[] ComponentStructEnumerator()
|
||||
{
|
||||
var query = _entityManager.EntityQueryEnumerator<A>();
|
||||
var i = 0;
|
||||
|
||||
while (query.MoveNext(out var comp))
|
||||
{
|
||||
Comps[i] = comp;
|
||||
i++;
|
||||
}
|
||||
|
||||
return Comps;
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public A[] ComponentIEnumerable()
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
foreach (var comp in _entityManager.EntityQuery<A>())
|
||||
{
|
||||
Comps[i] = comp;
|
||||
i++;
|
||||
}
|
||||
|
||||
return Comps;
|
||||
}
|
||||
|
||||
[ComponentProtoName("A")]
|
||||
public sealed partial class A : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
using static Robust.Benchmarks.EntityManager.ArchetypeComponentAccessBenchmark;
|
||||
|
||||
namespace Robust.Benchmarks.EntityManager;
|
||||
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class ArrayAccessBenchmark
|
||||
{
|
||||
[Params(new[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})]
|
||||
public int[] Array = default!;
|
||||
|
||||
[Params(5)]
|
||||
public int Element;
|
||||
|
||||
[Params(500)]
|
||||
public int Handle;
|
||||
|
||||
public Archetype<int, int, int, int, int, int, int, int, int, int> Archetype = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
Archetype = new Archetype<int, int, int, int, int, int, int, int, int, int>(1000);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int? GetArrayElement()
|
||||
{
|
||||
return Consume();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int? GetExisting()
|
||||
{
|
||||
return Consume(Element);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int? GetArchetype()
|
||||
{
|
||||
return Consume(Archetype.GetComponentUnsafeHandle<int>(Handle));
|
||||
}
|
||||
|
||||
private int? Consume(int? value = null)
|
||||
{
|
||||
if (value == null)
|
||||
value = Array[5];
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Analyzers;
|
||||
@@ -8,7 +9,7 @@ using Robust.UnitTesting.Server;
|
||||
namespace Robust.Benchmarks.EntityManager;
|
||||
|
||||
[Virtual]
|
||||
public partial class GetComponentBenchmark
|
||||
public class GetComponentBenchmark
|
||||
{
|
||||
private ISimulation _simulation = default!;
|
||||
private IEntityManager _entityManager = default!;
|
||||
@@ -54,7 +55,7 @@ public partial class GetComponentBenchmark
|
||||
}
|
||||
|
||||
[ComponentProtoName("A")]
|
||||
public sealed partial class A : Component
|
||||
public sealed class A : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using Robust.UnitTesting.Server;
|
||||
namespace Robust.Benchmarks.EntityManager;
|
||||
|
||||
[Virtual]
|
||||
public partial class SpawnDeleteEntityBenchmark
|
||||
public class SpawnDeleteEntityBenchmark
|
||||
{
|
||||
private ISimulation _simulation = default!;
|
||||
private IEntityManager _entityManager = default!;
|
||||
@@ -56,7 +56,7 @@ public partial class SpawnDeleteEntityBenchmark
|
||||
}
|
||||
|
||||
[ComponentProtoName("A")]
|
||||
public sealed partial class A : Component
|
||||
public sealed class A : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,11 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using BenchmarkDotNet.Exporters;
|
||||
using BenchmarkDotNet.Loggers;
|
||||
using BenchmarkDotNet.Mathematics;
|
||||
using BenchmarkDotNet.Parameters;
|
||||
using BenchmarkDotNet.Reports;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
@@ -22,11 +20,6 @@ namespace Robust.Benchmarks.Exporters;
|
||||
|
||||
public sealed class SQLExporter : IExporter
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
|
||||
};
|
||||
|
||||
public static readonly IExporter Default = new SQLExporter();
|
||||
|
||||
private SQLExporter(){}
|
||||
@@ -81,13 +74,13 @@ public sealed class SQLExporter : IExporter
|
||||
{
|
||||
ctx.Database.OpenConnection();
|
||||
var con = (NpgsqlConnection) ctx.Database.GetDbConnection();
|
||||
con.TypeMapper.AddTypeResolverFactory(new JsonOverrideTypeHandlerResolverFactory(JsonSerializerOptions));
|
||||
con.TypeMapper.AddTypeResolverFactory(new JsonOverrideTypeHandlerResolverFactory(new JsonSerializerOptions
|
||||
{
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals
|
||||
}));
|
||||
|
||||
ctx.Database.Migrate();
|
||||
foreach (var run in BenchmarkRun.FromSummary(summary, gitHash))
|
||||
{
|
||||
ctx.BenchmarkRuns.Add(run);
|
||||
}
|
||||
ctx.BenchmarkRuns.Add(BenchmarkRun.FromSummary(summary, gitHash));
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
finally
|
||||
@@ -138,7 +131,6 @@ class JsonOverrideTypeHandlerResolverFactory : TypeHandlerResolverFactory
|
||||
=> null; // Let the built-in resolver do this
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DesignTimeContextFactoryPostgres : IDesignTimeDbContextFactory<BenchmarkContext>
|
||||
{
|
||||
public BenchmarkContext CreateDbContext(string[] args)
|
||||
@@ -162,66 +154,42 @@ public class BenchmarkRun
|
||||
public int Id { get; set; }
|
||||
public string GitHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(TypeName = "timestamptz")] public DateTime RunDate { get; set; }
|
||||
[Column(TypeName = "timestamptz")]
|
||||
public DateTime RunDate { get; set; }
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string? ParameterMapping { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public BenchmarkRunParameter[]? ParameterMappingJson { get; set; }
|
||||
public BenchmarkRunReport[] Reports { get; set; } = Array.Empty<BenchmarkRunReport>();
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public Statistics Statistics { get; set; } = default!;
|
||||
|
||||
public static IEnumerable<BenchmarkRun> FromSummary(Summary summary, string gitHash)
|
||||
public static BenchmarkRun FromSummary(Summary summary, string gitHash)
|
||||
{
|
||||
var runDate = DateTime.UtcNow;
|
||||
|
||||
foreach (var benchmarkReport in summary.Reports)
|
||||
return new BenchmarkRun
|
||||
{
|
||||
var paramString = new StringBuilder();
|
||||
var parametersItems = benchmarkReport.BenchmarkCase.Parameters.Items;
|
||||
var runParameters = new BenchmarkRunParameter[parametersItems.Count];
|
||||
for (var i = 0; i < parametersItems.Count; i++)
|
||||
Reports = summary.Reports.Select(r => new BenchmarkRunReport
|
||||
{
|
||||
runParameters[i] = new BenchmarkRunParameter(parametersItems[i]);
|
||||
paramString.Append(runParameters[i].ToString());
|
||||
if (i < parametersItems.Count - 1) paramString.Append(',');
|
||||
}
|
||||
|
||||
if (benchmarkReport.ResultStatistics == null)
|
||||
{
|
||||
Console.WriteLine($"err: No statistics available for {benchmarkReport.BenchmarkCase.Descriptor.DisplayInfo}!");
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return new BenchmarkRun
|
||||
{
|
||||
Name = benchmarkReport.BenchmarkCase.Descriptor.DisplayInfo,
|
||||
RunDate = runDate,
|
||||
GitHash = gitHash,
|
||||
ParameterMapping = runParameters.Length > 0 ? paramString.ToString() : null,
|
||||
ParameterMappingJson = runParameters.Length > 0 ? runParameters : null,
|
||||
Statistics = benchmarkReport.ResultStatistics
|
||||
};
|
||||
}
|
||||
Parameters = r.BenchmarkCase.Parameters.Items.Select(p => new BenchmarkRunParameter
|
||||
{
|
||||
Name = p.Name,
|
||||
Value = p.Value
|
||||
}).ToArray(),
|
||||
Statistics = r.ResultStatistics
|
||||
}).ToArray(),
|
||||
Name = summary.BenchmarksCases.First().FolderInfo,
|
||||
RunDate = DateTime.UtcNow,
|
||||
GitHash = gitHash
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public struct BenchmarkRunParameter
|
||||
public class BenchmarkRunReport
|
||||
{
|
||||
public BenchmarkRunParameter[] Parameters { get; set; } = Array.Empty<BenchmarkRunParameter>();
|
||||
public Statistics Statistics { get; set; } = default!;
|
||||
}
|
||||
|
||||
public class BenchmarkRunParameter
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public object Value { get; set; } = default!;
|
||||
|
||||
public BenchmarkRunParameter(ParameterInstance instance)
|
||||
{
|
||||
Name = instance.Name;
|
||||
Value = instance.Value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}={Value}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
[DbContext(typeof(BenchmarkContext))]
|
||||
[Migration("20220510131430_fix-pk")]
|
||||
partial class FixPK
|
||||
partial class fixpk
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
public partial class FixPK : Migration
|
||||
public partial class fixpk : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using BenchmarkDotNet.Mathematics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Robust.Benchmarks.Exporters;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
[DbContext(typeof(BenchmarkContext))]
|
||||
[Migration("20221009235705_db")]
|
||||
partial class DB
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Robust.Benchmarks.Exporters.BenchmarkRun", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("GitHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParameterMapping")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("RunDate")
|
||||
.HasColumnType("timestamptz");
|
||||
|
||||
b.Property<Statistics>("Statistics")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BenchmarkRuns");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
public partial class DB : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Reports",
|
||||
table: "BenchmarkRuns",
|
||||
newName: "Statistics");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "ParameterMapping",
|
||||
table: "BenchmarkRuns",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ParameterMapping",
|
||||
table: "BenchmarkRuns");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "Statistics",
|
||||
table: "BenchmarkRuns",
|
||||
newName: "Reports");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using BenchmarkDotNet.Mathematics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Robust.Benchmarks.Exporters;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
[DbContext(typeof(BenchmarkContext))]
|
||||
[Migration("20221010144620_param_work")]
|
||||
partial class ParamWork
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Robust.Benchmarks.Exporters.BenchmarkRun", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("GitHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParameterMapping")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<BenchmarkRunParameter[]>("ParameterMappingJson")
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.Property<DateTime>("RunDate")
|
||||
.HasColumnType("timestamptz");
|
||||
|
||||
b.Property<Statistics>("Statistics")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BenchmarkRuns");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Robust.Benchmarks.Exporters;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
public partial class ParamWork : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ParameterMapping",
|
||||
table: "BenchmarkRuns",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text");
|
||||
|
||||
migrationBuilder.AddColumn<BenchmarkRunParameter[]>(
|
||||
name: "ParameterMappingJson",
|
||||
table: "BenchmarkRuns",
|
||||
type: "jsonb",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ParameterMappingJson",
|
||||
table: "BenchmarkRuns");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "ParameterMapping",
|
||||
table: "BenchmarkRuns",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using BenchmarkDotNet.Mathematics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
@@ -18,7 +17,7 @@ namespace Robust.Benchmarks.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("ProductVersion", "6.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@@ -39,19 +38,13 @@ namespace Robust.Benchmarks.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParameterMapping")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<BenchmarkRunParameter[]>("ParameterMappingJson")
|
||||
b.Property<BenchmarkRunReport[]>("Reports")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.Property<DateTime>("RunDate")
|
||||
.HasColumnType("timestamptz");
|
||||
|
||||
b.Property<Statistics>("Statistics")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BenchmarkRuns");
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using BenchmarkDotNet.Mathematics;
|
||||
using Robust.Benchmarks.Exporters;
|
||||
|
||||
namespace Robust.Benchmarks.Migrations;
|
||||
|
||||
public class BenchmarkRunReport
|
||||
{
|
||||
public BenchmarkRunParameter[] Parameters { get; set; } = Array.Empty<BenchmarkRunParameter>();
|
||||
public Statistics Statistics { get; set; } = default!;
|
||||
}
|
||||
@@ -1,32 +1,33 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
|
||||
namespace Robust.Benchmarks.NumericsHelpers;
|
||||
|
||||
[Virtual]
|
||||
public class AddBenchmark
|
||||
namespace Robust.Benchmarks.NumericsHelpers
|
||||
{
|
||||
[Params(32, 128)]
|
||||
public int N { get; set; }
|
||||
|
||||
[Params(1,2)]
|
||||
public int T { get; set; }
|
||||
|
||||
private float[] _inputA = default!;
|
||||
private float[] _inputB = default!;
|
||||
private float[] _output = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
[Virtual]
|
||||
public class AddBenchmark
|
||||
{
|
||||
_inputA = new float[N];
|
||||
_inputB = new float[N];
|
||||
_output = new float[N];
|
||||
}
|
||||
[Params(32, 128)]
|
||||
public int N { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
public void Bench()
|
||||
{
|
||||
Shared.Maths.NumericsHelpers.Add(_inputA, _inputB, _output);
|
||||
[Params(1,2)]
|
||||
public int T { get; set; }
|
||||
|
||||
private float[] _inputA = default!;
|
||||
private float[] _inputB = default!;
|
||||
private float[] _output = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
_inputA = new float[N];
|
||||
_inputB = new float[N];
|
||||
_output = new float[N];
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void Bench()
|
||||
{
|
||||
Shared.Maths.NumericsHelpers.Add(_inputA, _inputB, _output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
|
||||
namespace Robust.Benchmarks.NumericsHelpers;
|
||||
|
||||
[Virtual]
|
||||
[DisassemblyDiagnoser()]
|
||||
public class HorizontalAddBenchmark
|
||||
{
|
||||
[Params(8, 32, 128)]
|
||||
public int N { get; set; }
|
||||
|
||||
private float[] _inputA = default!;
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
_inputA = new float[N];
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public float Bench()
|
||||
{
|
||||
return Shared.Maths.NumericsHelpers.HorizontalAdd(_inputA);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
#if DEBUG
|
||||
using BenchmarkDotNet.Configs;
|
||||
#endif
|
||||
using System;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Running;
|
||||
using System;
|
||||
using Robust.Benchmarks.Configs;
|
||||
using Robust.Benchmarks.Exporters;
|
||||
|
||||
namespace Robust.Benchmarks
|
||||
{
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\MSBuild\Robust.Engine.props" />
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<OutputPath>../bin/Benchmarks</OutputPath>
|
||||
<OutputType>Exe</OutputType>
|
||||
<NoWarn>RA0003</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Robust.Server\Robust.Server.csproj" />
|
||||
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
|
||||
<ProjectReference Include="..\Robust.UnitTesting\Robust.UnitTesting.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
<Import Project="..\MSBuild\Robust.Properties.targets" />
|
||||
<Import Project="..\MSBuild\Robust.Engine.props" />
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<OutputPath>../bin/Benchmarks</OutputPath>
|
||||
<OutputType>Exe</OutputType>
|
||||
<NoWarn>RA0003</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Robust.Server\Robust.Server.csproj" />
|
||||
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
|
||||
<ProjectReference Include="..\Robust.UnitTesting\Robust.UnitTesting.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.4" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\MSBuild\Robust.Engine.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Globalization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -9,7 +8,7 @@ using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
|
||||
namespace Robust.Benchmarks.Serialization
|
||||
{
|
||||
public sealed class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>, ITypeCopyCreator<int>
|
||||
public sealed class BenchmarkIntSerializer : ITypeSerializer<int, ValueDataNode>
|
||||
{
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
@@ -20,21 +19,19 @@ namespace Robust.Benchmarks.Serialization
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int _ = default)
|
||||
{
|
||||
return int.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, IDependencyCollection dependencies,
|
||||
bool alwaysWrite = false,
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, bool alwaysWrite = false,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new ValueDataNode(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
public int Copy(ISerializationManager serializationManager, int source, int target, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -27,7 +28,7 @@ namespace Robust.Benchmarks.Serialization.Copy
|
||||
|
||||
var seedMapping = yamlStream.Documents[0].RootNode.ToDataNodeCast<SequenceDataNode>().Cast<MappingDataNode>(0);
|
||||
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping, notNullableOverride: true);
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping);
|
||||
}
|
||||
|
||||
private const string String = "ABC";
|
||||
@@ -45,25 +46,25 @@ namespace Robust.Benchmarks.Serialization.Copy
|
||||
[Benchmark]
|
||||
public string? CreateCopyString()
|
||||
{
|
||||
return SerializationManager.CreateCopy(String, notNullableOverride: true);
|
||||
return SerializationManager.Copy(String);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int? CreateCopyInteger()
|
||||
{
|
||||
return SerializationManager.CreateCopy(Integer);
|
||||
return SerializationManager.Copy(Integer);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public DataDefinitionWithString? CreateCopyDataDefinitionWithString()
|
||||
{
|
||||
return SerializationManager.CreateCopy(DataDefinitionWithString, notNullableOverride: true);
|
||||
return SerializationManager.Copy(DataDefinitionWithString);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public SeedDataDefinition? CreateCopySeedDataDefinition()
|
||||
{
|
||||
return SerializationManager.CreateCopy(Seed, notNullableOverride: true);
|
||||
return SerializationManager.Copy(Seed);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@@ -108,7 +109,9 @@ namespace Robust.Benchmarks.Serialization.Copy
|
||||
copy.Potency = Seed.Potency;
|
||||
copy.Ligneous = Seed.Ligneous;
|
||||
|
||||
copy.PlantRsi = new ResPath(Seed.PlantRsi.ToString());
|
||||
copy.PlantRsi = Seed.PlantRsi == null
|
||||
? null!
|
||||
: new ResourcePath(Seed.PlantRsi.ToString(), Seed.PlantRsi.Separator);
|
||||
copy.PlantIconState = Seed.PlantIconState;
|
||||
copy.Bioluminescent = Seed.Bioluminescent;
|
||||
copy.BioluminescentColor = Seed.BioluminescentColor;
|
||||
@@ -121,21 +124,30 @@ namespace Robust.Benchmarks.Serialization.Copy
|
||||
[BenchmarkCategory("flag")]
|
||||
public object? CopyFlagZero()
|
||||
{
|
||||
return SerializationManager.CreateCopy<int, FlagSerializer<BenchmarkFlags>>((int) FlagZero);
|
||||
return SerializationManager.CopyWithTypeSerializer(
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
(int) FlagZero,
|
||||
(int) FlagZero);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public object? CopyFlagThirtyOne()
|
||||
{
|
||||
return SerializationManager.CreateCopy<int, FlagSerializer<BenchmarkFlags>>((int) FlagThirtyOne);
|
||||
return SerializationManager.CopyWithTypeSerializer(
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
(int) FlagThirtyOne,
|
||||
(int) FlagThirtyOne);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("customTypeSerializer")]
|
||||
public object? CopyIntegerCustomSerializer()
|
||||
{
|
||||
return SerializationManager.CreateCopy<int, BenchmarkIntSerializer>(Integer);
|
||||
return SerializationManager.CopyWithTypeSerializer(
|
||||
typeof(BenchmarkIntSerializer),
|
||||
Integer,
|
||||
Integer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
{
|
||||
[DataDefinition]
|
||||
[Virtual]
|
||||
public partial class DataDefinitionWithString
|
||||
public class DataDefinitionWithString
|
||||
{
|
||||
[DataField("string")]
|
||||
public string StringField { get; set; } = default!;
|
||||
public string StringField { get; init; } = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace Robust.Benchmarks.Serialization.Definitions
|
||||
{
|
||||
[DataDefinition]
|
||||
public sealed partial class SealedDataDefinitionWithString
|
||||
public sealed class SealedDataDefinitionWithString
|
||||
{
|
||||
[DataField("string")]
|
||||
public string StringField { get; private set; } = default!;
|
||||
public string StringField { get; init; } = default!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
@@ -11,7 +10,8 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
/// Arbitrarily large data definition for benchmarks.
|
||||
/// Taken from content.
|
||||
/// </summary>
|
||||
public sealed partial class SeedDataDefinition : Component
|
||||
[Prototype("seed")]
|
||||
public sealed class SeedDataDefinition : IPrototype
|
||||
{
|
||||
public const string Prototype = @"
|
||||
- type: seed
|
||||
@@ -87,7 +87,7 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
#endregion
|
||||
|
||||
#region Cosmetics
|
||||
[DataField("plantRsi", required: true)] public ResPath PlantRsi { get; set; } = default!;
|
||||
[DataField("plantRsi", required: true)] public ResourcePath PlantRsi { get; set; } = default!;
|
||||
[DataField("plantIconState")] public string PlantIconState { get; set; } = "produce";
|
||||
[DataField("bioluminescent")] public bool Bioluminescent { get; set; }
|
||||
[DataField("bioluminescentColor")] public Color BioluminescentColor { get; set; } = Color.White;
|
||||
@@ -106,7 +106,7 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
}
|
||||
|
||||
[DataDefinition]
|
||||
public partial struct SeedChemQuantity
|
||||
public struct SeedChemQuantity
|
||||
{
|
||||
[DataField("Min")]
|
||||
public int Min;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Robust.Benchmarks.Serialization.Read
|
||||
[Benchmark]
|
||||
public string ReadString()
|
||||
{
|
||||
return SerializationManager.Read<string>(StringNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<string>(StringNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@@ -55,34 +55,43 @@ namespace Robust.Benchmarks.Serialization.Read
|
||||
[Benchmark]
|
||||
public DataDefinitionWithString ReadDataDefinitionWithString()
|
||||
{
|
||||
return SerializationManager.Read<DataDefinitionWithString>(StringDataDefNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<DataDefinitionWithString>(StringDataDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public SeedDataDefinition ReadSeedDataDefinition()
|
||||
{
|
||||
return SerializationManager.Read<SeedDataDefinition>(SeedNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<SeedDataDefinition>(SeedNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public object? ReadFlagZero()
|
||||
{
|
||||
return SerializationManager.Read<int, ValueDataNode, FlagSerializer<BenchmarkFlags>>(FlagZero);
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
FlagZero);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public object? ReadThirtyOne()
|
||||
{
|
||||
return SerializationManager.Read<int, ValueDataNode, FlagSerializer<BenchmarkFlags>>(FlagThirtyOne);
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
FlagThirtyOne);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("customTypeSerializer")]
|
||||
public object? ReadIntegerCustomSerializer()
|
||||
{
|
||||
return SerializationManager.Read<int, ValueDataNode, BenchmarkIntSerializer>(IntNode);
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(BenchmarkIntSerializer),
|
||||
IntNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,84 +46,84 @@ namespace Robust.Benchmarks.Serialization
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadEmptyString()
|
||||
{
|
||||
return SerializationManager.Read<string[]>(EmptyNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<string[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadOneString()
|
||||
{
|
||||
return SerializationManager.Read<string[]>(OneIntNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<string[]>(OneIntNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadTenStrings()
|
||||
{
|
||||
return SerializationManager.Read<string[]>(TenIntsNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<string[]>(TenIntsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadEmptyInt()
|
||||
{
|
||||
return SerializationManager.Read<int[]>(EmptyNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<int[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadOneInt()
|
||||
{
|
||||
return SerializationManager.Read<int[]>(OneIntNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<int[]>(OneIntNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadTenInts()
|
||||
{
|
||||
return SerializationManager.Read<int[]>(TenIntsNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<int[]>(TenIntsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadEmptyStringDataDef()
|
||||
{
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(EmptyNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadOneStringDataDef()
|
||||
{
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(OneStringDefNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(OneStringDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadTenStringDataDefs()
|
||||
{
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(TenStringDefsNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(TenStringDefsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadEmptySealedStringDataDef()
|
||||
{
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(EmptyNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadOneSealedStringDataDef()
|
||||
{
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(OneStringDefNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(OneStringDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadTenSealedStringDataDefs()
|
||||
{
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(TenStringDefsNode, notNullableOverride: true);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(TenStringDefsNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace Robust.Benchmarks.Serialization
|
||||
{
|
||||
public SerializationBenchmark()
|
||||
{
|
||||
var deps = IoCManager.InitThread();
|
||||
ServerIoC.RegisterIoC(deps);
|
||||
deps.BuildGraph();
|
||||
IoCManager.InitThread();
|
||||
ServerIoC.RegisterIoC();
|
||||
IoCManager.BuildGraph();
|
||||
|
||||
var assemblies = new[]
|
||||
{
|
||||
@@ -25,12 +25,12 @@ namespace Robust.Benchmarks.Serialization
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
deps.Resolve<IConfigurationManagerInternal>().LoadCVarsFromAssembly(assembly);
|
||||
IoCManager.Resolve<IConfigurationManagerInternal>().LoadCVarsFromAssembly(assembly);
|
||||
}
|
||||
|
||||
deps.Resolve<IReflectionManager>().LoadAssemblies(assemblies);
|
||||
IoCManager.Resolve<IReflectionManager>().LoadAssemblies(assemblies);
|
||||
|
||||
SerializationManager = deps.Resolve<ISerializationManager>();
|
||||
SerializationManager = IoCManager.Resolve<ISerializationManager>();
|
||||
}
|
||||
|
||||
protected ISerializationManager SerializationManager { get; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.IO;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -27,7 +28,7 @@ namespace Robust.Benchmarks.Serialization.Write
|
||||
|
||||
var seedMapping = yamlStream.Documents[0].RootNode.ToDataNodeCast<SequenceDataNode>().Cast<MappingDataNode>(0);
|
||||
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping, notNullableOverride: true);
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping);
|
||||
}
|
||||
|
||||
private const string String = "ABC";
|
||||
@@ -45,7 +46,7 @@ namespace Robust.Benchmarks.Serialization.Write
|
||||
[Benchmark]
|
||||
public DataNode WriteString()
|
||||
{
|
||||
return SerializationManager.WriteValue(String, notNullableOverride: true);
|
||||
return SerializationManager.WriteValue(String);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@@ -57,13 +58,13 @@ namespace Robust.Benchmarks.Serialization.Write
|
||||
[Benchmark]
|
||||
public DataNode WriteDataDefinitionWithString()
|
||||
{
|
||||
return SerializationManager.WriteValue(DataDefinitionWithString, notNullableOverride: true);
|
||||
return SerializationManager.WriteValue(DataDefinitionWithString);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public DataNode WriteSeedDataDefinition()
|
||||
{
|
||||
return SerializationManager.WriteValue(Seed, notNullableOverride: true);
|
||||
return SerializationManager.WriteValue(Seed);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@@ -106,21 +107,30 @@ namespace Robust.Benchmarks.Serialization.Write
|
||||
[BenchmarkCategory("flag")]
|
||||
public DataNode WriteFlagZero()
|
||||
{
|
||||
return SerializationManager.WriteValue<int, FlagSerializer<BenchmarkFlags>>((int)FlagZero);
|
||||
return SerializationManager.WriteWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
FlagZero);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public DataNode WriteThirtyOne()
|
||||
{
|
||||
return SerializationManager.WriteValue<int, FlagSerializer<BenchmarkFlags>>((int)FlagThirtyOne);
|
||||
return SerializationManager.WriteWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(FlagSerializer<BenchmarkFlags>),
|
||||
FlagThirtyOne);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("customTypeSerializer")]
|
||||
public DataNode WriteIntegerCustomSerializer()
|
||||
{
|
||||
return SerializationManager.WriteValue<int, BenchmarkIntSerializer>(Integer);
|
||||
return SerializationManager.WriteWithTypeSerializer(
|
||||
typeof(int),
|
||||
typeof(BenchmarkIntSerializer),
|
||||
Integer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameStates;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.UnitTesting.Server;
|
||||
|
||||
namespace Robust.Benchmarks.Transform;
|
||||
|
||||
/// <summary>
|
||||
/// This benchmark tests various transform/move related functions with an entity that has many children.
|
||||
/// </summary>
|
||||
[Virtual, MemoryDiagnoser]
|
||||
public class RecursiveMoveBenchmark
|
||||
{
|
||||
private ISimulation _simulation = default!;
|
||||
private IEntityManager _entMan = default!;
|
||||
private SharedTransformSystem _transform = default!;
|
||||
private ContainerSystem _container = default!;
|
||||
private PvsSystem _pvs = default!;
|
||||
private EntityCoordinates _mapCoords;
|
||||
private EntityCoordinates _gridCoords;
|
||||
private EntityUid _ent;
|
||||
private EntityUid _child;
|
||||
private TransformComponent _childXform = default!;
|
||||
private EntityQuery<TransformComponent> _query;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
_simulation = RobustServerSimulation
|
||||
.NewSimulation()
|
||||
.InitializeInstance();
|
||||
|
||||
if (!_simulation.Resolve<IConfigurationManager>().GetCVar(CVars.NetPVS))
|
||||
throw new InvalidOperationException("PVS must be enabled");
|
||||
|
||||
_entMan = _simulation.Resolve<IEntityManager>();
|
||||
_transform = _entMan.System<SharedTransformSystem>();
|
||||
_container = _entMan.System<ContainerSystem>();
|
||||
_pvs = _entMan.System<PvsSystem>();
|
||||
_query = _entMan.GetEntityQuery<TransformComponent>();
|
||||
|
||||
// Create map & grid
|
||||
var mapMan = _simulation.Resolve<IMapManager>();
|
||||
var mapSys = _entMan.System<SharedMapSystem>();
|
||||
var mapId = mapMan.CreateMap();
|
||||
var map = mapMan.GetMapEntityId(mapId);
|
||||
var gridComp = mapMan.CreateGrid(mapId);
|
||||
var grid = gridComp.Owner;
|
||||
_gridCoords = new EntityCoordinates(grid, .5f, .5f);
|
||||
_mapCoords = new EntityCoordinates(map, 100, 100);
|
||||
mapSys.SetTile(grid, gridComp, Vector2i.Zero, new Tile(1));
|
||||
|
||||
// Next, we will spawn our test entity. This entity will have a complex transform/container hierarchy.
|
||||
// This is intended to be representative of a typical SS14 player entity, with organs. clothing, and a full backpack.
|
||||
_ent = _entMan.Spawn();
|
||||
|
||||
// Quick check that SetCoordinates actually changes the parent as expected
|
||||
// I.e., ensure that grid-traversal code doesn't just dump the entity on the map.
|
||||
_transform.SetCoordinates(_ent, _gridCoords);
|
||||
if (_query.GetComponent(_ent).ParentUid != _gridCoords.EntityId)
|
||||
throw new Exception("Grid traversal error.");
|
||||
|
||||
_transform.SetCoordinates(_ent, _mapCoords);
|
||||
if (_query.GetComponent(_ent).ParentUid != _mapCoords.EntityId)
|
||||
throw new Exception("Grid traversal error.");
|
||||
|
||||
// Add 5 direct children in slots to represent clothing.
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var id = $"inventory{i}";
|
||||
_container.EnsureContainer<ContainerSlot>(_ent, id);
|
||||
if (!_entMan.TrySpawnInContainer(null, _ent, id, out _))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
}
|
||||
|
||||
// body parts
|
||||
_container.EnsureContainer<Container>(_ent, "body");
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
// Simple organ
|
||||
if (!_entMan.TrySpawnInContainer(null, _ent, "body", out _))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
|
||||
// body part that has another body part / limb
|
||||
if (!_entMan.TrySpawnInContainer(null, _ent, "body", out var limb))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
|
||||
_container.EnsureContainer<ContainerSlot>(limb.Value, "limb");
|
||||
if (!_entMan.TrySpawnInContainer(null, limb.Value, "limb", out _))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
}
|
||||
|
||||
// Backpack
|
||||
_container.EnsureContainer<ContainerSlot>(_ent, "inventory-backpack");
|
||||
if (!_entMan.TrySpawnInContainer(null, _ent, "inventory-backpack", out var backpack))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
|
||||
// Misc backpack contents.
|
||||
var backpackStorage = _container.EnsureContainer<Container>(backpack.Value, "storage");
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
if (!_entMan.TrySpawnInContainer(null, backpack.Value, "storage", out _))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
}
|
||||
|
||||
// Emergency box inside of the backpack
|
||||
var box = backpackStorage.ContainedEntities.First();
|
||||
var boxContainer = _container.EnsureContainer<Container>(box, "storage");
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
if (!_entMan.TrySpawnInContainer(null, box, "storage", out _))
|
||||
throw new Exception($"Failed to setup entity");
|
||||
}
|
||||
|
||||
// Deepest child.
|
||||
_child = boxContainer.ContainedEntities.First();
|
||||
_childXform = _query.GetComponent(_child);
|
||||
|
||||
_pvs.ProcessCollections();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This implicitly measures move events, including PVS and entity lookups. Though given that most of the entities
|
||||
/// are in containers, this will bias the entity lookup aspect.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public void MoveEntity()
|
||||
{
|
||||
_transform.SetCoordinates(_ent, _gridCoords);
|
||||
_transform.SetCoordinates(_ent, _mapCoords);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Like <see cref="MoveEntity"/>, but also processes queued PVS chunk updates.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public void MoveAndUpdateChunks()
|
||||
{
|
||||
_transform.SetCoordinates(_ent, _gridCoords);
|
||||
_pvs.ProcessCollections();
|
||||
_transform.SetCoordinates(_ent, _mapCoords);
|
||||
_pvs.ProcessCollections();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public Vector2 GetWorldPos()
|
||||
{
|
||||
return _transform.GetWorldPosition(_childXform);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public EntityUid GetRootUid()
|
||||
{
|
||||
var xform = _childXform;
|
||||
while (xform.ParentUid.IsValid())
|
||||
{
|
||||
xform = _query.GetComponent(xform.ParentUid);
|
||||
}
|
||||
return xform.ParentUid;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Shared.Analyzers;
|
||||
|
||||
namespace Robust.Benchmarks.TypeMatching;
|
||||
|
||||
[MemoryDiagnoser]
|
||||
[Virtual]
|
||||
public class TypeSwitchBenchmark
|
||||
{
|
||||
private readonly Matcher<Struct> _matcher = new();
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkInt()
|
||||
{
|
||||
return _matcher.TypeToInt<int>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkString()
|
||||
{
|
||||
return _matcher.TypeToInt<string>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkStruct()
|
||||
{
|
||||
return _matcher.TypeToInt<Struct>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkDouble()
|
||||
{
|
||||
return _matcher.TypeToInt<double>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkFloat()
|
||||
{
|
||||
return _matcher.TypeToInt<float>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int BenchmarkClass()
|
||||
{
|
||||
return _matcher.TypeToInt<Class>();
|
||||
}
|
||||
|
||||
private class Matcher<T1>
|
||||
{
|
||||
public int TypeToInt<T>(T val = default!)
|
||||
{
|
||||
return val switch
|
||||
{
|
||||
int => 1,
|
||||
string => 2,
|
||||
double => 3,
|
||||
T1 => 4,
|
||||
Class => 5,
|
||||
_ => 6
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private struct Struct
|
||||
{
|
||||
}
|
||||
|
||||
private class Class
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
#pragma warning disable CS0612
|
||||
namespace Robust.Benchmarks.Utility;
|
||||
|
||||
[Virtual]
|
||||
public class ResourcePathBench
|
||||
{
|
||||
private string _path = default!;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Params(10, 100, 1000)]
|
||||
public int N;
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
_path = "/a/b/c/../test";
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public ResPath CreateWithSeparatorResPath()
|
||||
{
|
||||
ResPath res = default;
|
||||
for (var i = 0; i < N; i++)
|
||||
{
|
||||
res = new ResPath(_path);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
#pragma warning restore CS0612
|
||||
@@ -25,7 +25,7 @@ namespace Robust.Build.Tasks
|
||||
Single = ts.GetType("System.Single");
|
||||
Int32 = ts.GetType("System.Int32");
|
||||
|
||||
(Vector2, Vector2ConstructorFull) = GetNumericTypeInfo("System.Numerics.Vector2", Single, 2);
|
||||
(Vector2, Vector2ConstructorFull) = GetNumericTypeInfo("Robust.Shared.Maths.Vector2", Single, 2);
|
||||
(Vector2i, Vector2iConstructorFull) = GetNumericTypeInfo("Robust.Shared.Maths.Vector2i", Int32, 2);
|
||||
(Thickness, ThicknessConstructorFull) = GetNumericTypeInfo("Robust.Shared.Maths.Thickness", Single, 4);
|
||||
|
||||
|
||||
@@ -110,6 +110,25 @@ namespace Robust.Build.Tasks
|
||||
var compiler =
|
||||
new RobustXamlILCompiler(transformerconfig, emitConfig, true);
|
||||
|
||||
var loaderDispatcherDef = new TypeDefinition("CompiledRobustXaml", "!XamlLoader",
|
||||
TypeAttributes.Class, asm.MainModule.TypeSystem.Object);
|
||||
|
||||
var loaderDispatcherMethod = new MethodDefinition("TryLoad",
|
||||
MethodAttributes.Static | MethodAttributes.Public,
|
||||
asm.MainModule.TypeSystem.Object)
|
||||
{
|
||||
Parameters = {new ParameterDefinition(asm.MainModule.TypeSystem.String)}
|
||||
};
|
||||
loaderDispatcherDef.Methods.Add(loaderDispatcherMethod);
|
||||
asm.MainModule.Types.Add(loaderDispatcherDef);
|
||||
|
||||
var stringEquals = asm.MainModule.ImportReference(asm.MainModule.TypeSystem.String.Resolve().Methods.First(
|
||||
m =>
|
||||
m.IsStatic && m.Name == "Equals" && m.Parameters.Count == 2 &&
|
||||
m.ReturnType.FullName == "System.Boolean"
|
||||
&& m.Parameters[0].ParameterType.FullName == "System.String"
|
||||
&& m.Parameters[1].ParameterType.FullName == "System.String"));
|
||||
|
||||
bool CompileGroup(IResourceGroup group)
|
||||
{
|
||||
var typeDef = new TypeDefinition("CompiledRobustXaml", "!" + group.Name, TypeAttributes.Class,
|
||||
@@ -233,6 +252,31 @@ namespace Robust.Build.Tasks
|
||||
$"No call to RobustXamlLoader.Load(this) call found anywhere in the type {classType.FullName} and type seems to have custom constructors.");
|
||||
}
|
||||
}
|
||||
|
||||
//add compiled build method
|
||||
var compiledBuildMethod = typeSystem.GetTypeReference(builder).Resolve().Methods
|
||||
.First(m => m.Name == buildName);
|
||||
var parameterlessCtor = classTypeDefinition.GetConstructors()
|
||||
.FirstOrDefault(c => c.IsPublic && !c.IsStatic && !c.HasParameters);
|
||||
|
||||
if (compiledBuildMethod != null && parameterlessCtor != null)
|
||||
{
|
||||
var i = loaderDispatcherMethod.Body.Instructions;
|
||||
var nop = Instruction.Create(OpCodes.Nop);
|
||||
i.Add(Instruction.Create(OpCodes.Ldarg_0));
|
||||
i.Add(Instruction.Create(OpCodes.Ldstr, res.Uri));
|
||||
i.Add(Instruction.Create(OpCodes.Call, stringEquals));
|
||||
i.Add(Instruction.Create(OpCodes.Brfalse, nop));
|
||||
if (parameterlessCtor != null)
|
||||
i.Add(Instruction.Create(OpCodes.Newobj, parameterlessCtor));
|
||||
else
|
||||
{
|
||||
i.Add(Instruction.Create(OpCodes.Call, compiledBuildMethod));
|
||||
}
|
||||
|
||||
i.Add(Instruction.Create(OpCodes.Ret));
|
||||
i.Add(nop);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -249,6 +293,8 @@ namespace Robust.Build.Tasks
|
||||
return false;
|
||||
}
|
||||
|
||||
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull));
|
||||
loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace {nameSpace}
|
||||
"Usage",
|
||||
DiagnosticSeverity.Error,
|
||||
true),
|
||||
candidateClass.GetLocation()));
|
||||
Location.None));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Robust.Client.WebView.Cef
|
||||
var mainArgs = new CefMainArgs(argv);
|
||||
|
||||
// This will block executing until the subprocess is shut down.
|
||||
var code = CefRuntime.ExecuteProcess(mainArgs, new RobustCefApp(null), IntPtr.Zero);
|
||||
var code = CefRuntime.ExecuteProcess(mainArgs, new RobustCefApp(), IntPtr.Zero);
|
||||
|
||||
if (code != 0)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user