31 Commits
Author SHA1 Message Date
js6pak 1a7755b987 Localize Reactor with fluent 2022-10-26 13:08:44 +02:00
js6pak 67c89f99ed Update CI 2022-10-26 01:39:46 +02:00
js6pak 7155b45bef Push Reactor.Networking.Shared nightlies aswell 2022-10-25 23:59:55 +02:00
js6pak 6079ea8fd4 Remove epic workaround, it's no longer needed 2022-10-25 23:47:05 +02:00
AlexejheroYTBandjs6pak 0c8156aaf6 Add localization API (#64)
Co-authored-by: js6pak <kubastaron@hotmail.com>
2022-10-23 15:36:10 +02:00
js6pak f2da251ae5 Update to 2022.10.25 2022-10-23 15:14:36 +02:00
js6pak 128c4f436e Make KickWithReason effective only when sent from host 2022-10-23 15:08:31 +02:00
js6pak 8d67b08481 Update to 2022.10.18, build against steam only for now 2022-10-18 23:07:57 +02:00
js6pak 615f6b20e1 Add a pointer constructor back to StreamWrapper 2022-10-10 17:34:44 +02:00
js6pak da217c1627 Update CI 2022-10-09 21:55:53 +02:00
js6pak 2d148db013 Add xmldocs 2022-10-09 21:55:53 +02:00
js6pak ed05e563f0 Enable net analyzers and add stylecop 2022-10-09 16:09:02 +02:00
js6pak 81eea3eee2 Format whitespaces 2022-10-07 14:55:14 +02:00
AlexejheroYTBandjs6pak b7971d36a8 Refactor (#62)
Co-authored-by: js6pak <kubastaron@hotmail.com>
2022-10-06 18:47:40 +00:00
js6pak 5cc08363c7 Don't lock public toggle on local games 2022-10-04 21:57:23 +02:00
js6pak 6be7629187 Convert Reactor.Shared to a source-only nuget package 2022-10-04 21:53:19 +02:00
js6pak 04a32b486d Make Reactor.Benchmarks output needed dlls 2022-10-04 21:42:07 +02:00
js6pak 510711c184 Bump dependencies 2022-10-04 21:39:06 +02:00
js6pak 879c4181cc Patch only declared HandleRpc methods 2022-09-30 16:20:24 +02:00
js6pak af27afed80 Include mods loaded before reactor in modlist 2022-09-02 20:31:59 +02:00
js6pak d2bc7cce04 Fix handshake in local game 2022-09-02 20:31:44 +02:00
js6pak d01ea478f4 Protocol v3 2022-08-30 21:22:50 +02:00
js6pak f56aa32927 Update bepinex 2022-08-30 20:16:56 +02:00
js6pak 256f7617ad Add Reactor.Assets to the repo 2022-08-30 19:49:50 +02:00
js6pak 55c77a7651 Support instance method rpcs 2022-08-30 19:49:50 +02:00
js6pak f4631805f6 Add Ack callback support to custom rpcs 2022-08-30 19:49:50 +02:00
js6pak b751800b29 Global using logger 2022-08-30 19:49:50 +02:00
js6pak ffd58ddcd8 Update logger utility 2022-08-30 19:49:50 +02:00
js6pak 7fae71bdf2 Switch to coreclr bepinex 2022-08-30 19:49:50 +02:00
js6pak 5004ac8d5b Reformat code 2022-08-30 19:49:49 +02:00
js6pak c2047b033e Revert "Revert "Start working on http handshake support""
This reverts commit a6152f559c.
2022-08-23 20:59:19 +02:00
179 changed files with 10117 additions and 2996 deletions

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "1.1.0",
"version": "2.2.0",
"commands": [
"dotnet-cake"
]
+10
View File
@@ -149,6 +149,16 @@ dotnet_diagnostic.IDE0043.severity = warning
# IDE0044: Make field readonly
dotnet_diagnostic.IDE0044.severity = warning
dotnet_diagnostic.CA1000.severity = none
dotnet_diagnostic.CA1016.severity = none
dotnet_diagnostic.CA1711.severity = none
dotnet_diagnostic.CA1716.severity = none
dotnet_diagnostic.CA1720.severity = none
[Reactor.Benchmarks/*.cs]
dotnet_diagnostic.CA1707.severity = none
dotnet_diagnostic.CA1822.severity = none
# CSharp code style settings:
[*.cs]
# Newline settings
+19 -9
View File
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true
@@ -21,7 +21,7 @@ jobs:
${{ runner.os }}-nuget-
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.x
@@ -30,23 +30,33 @@ jobs:
with:
verbosity: Diagnostic
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
with:
name: Reactor.dll
path: Reactor/bin/Release/netstandard2.1/Reactor.dll
path: Reactor/bin/Release/net6.0/Reactor.dll
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
with:
name: Reactor.nupkg
path: Reactor/bin/Release/Reactor.*.nupkg
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
with:
name: Reactor.Networking.Shared.nupkg
path: Reactor.Networking.Shared/bin/Release/*.nupkg
- uses: actions/upload-artifact@v3
with:
name: Reactor.Debugger.dll
path: Reactor.Debugger/bin/Release/netstandard2.1/Reactor.Debugger.dll
path: Reactor.Debugger/bin/Release/net6.0/Reactor.Debugger.dll
- uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
if: github.ref_type == 'tag'
with:
draft: true
files: Reactor/bin/Release/netstandard2.1/Reactor.dll
files: Reactor/bin/Release/net6.0/Reactor.dll
- name: Push nightly NuGet package
if: github.repository == 'NuclearPowered/Reactor' && github.ref == 'refs/heads/master'
run: |
dotnet nuget push {Reactor/bin/Release/Reactor.*.nupkg,Reactor.Networking.Shared/bin/Release/*.nupkg} --source https://nuget.reactor.gg/v3/index.json --api-key ${{ secrets.REACTOR_NUGET_KEY }}
+44
View File
@@ -0,0 +1,44 @@
name: Unity
on:
push:
paths: [ "Reactor.Assets/**", "Reactor/Assets/*.bundle", ".github/workflows/unity.yml" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/Unity/Hub/Editor
~/.config/unityhub
key: unity-2020.3.22f1
- name: Setup Unity
uses: js6pak/setup-unity@master
with:
project-path: ./Reactor.Assets
unity-modules: windows-mono android
- name: Activate Unity
uses: js6pak/activate-unity@master
with:
unity-username: ${{ secrets.UNITY_USERNAME }}
unity-password: ${{ secrets.UNITY_PASSWORD }}
unity-authenticator-key: ${{ secrets.UNITY_AUTHENTICATOR_KEY }}
- name: Build
working-directory: ./Reactor.Assets
run: bash ./build.sh
- uses: actions/upload-artifact@v3
with:
name: bundles
path: ./Reactor/Assets/*.bundle
- name: Verify
run: if [[ $(git status --porcelain) ]]; then git status; git diff; exit 1; fi
+1
View File
@@ -6,3 +6,4 @@ riderModule.iml
.idea
/tools
.vscode
*.DotSettings.user
+4 -10
View File
@@ -1,16 +1,10 @@
<Project>
<PropertyGroup>
<GamePlatform Condition="'$(GamePlatform)' == ''">Steam</GamePlatform>
<GameVersion Condition="'$(GamePlatform)' == 'Steam'">2022.8.23</GameVersion>
<GameVersion Condition="'$(GamePlatform)' == 'Itch'">2022.8.23</GameVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BepInEx.IL2CPP" Version="6.0.0-be.570" />
<PackageReference Include="AmongUs.GameLibs.$(GamePlatform)" Version="$(GameVersion)" PrivateAssets="all" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.662" Private="false" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2022.10.25" PrivateAssets="all" />
<PackageReference Include="BepInEx.AutoPlugin" Version="1.0.1" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.0.1" PrivateAssets="all" ExcludeAssets="runtime" />
</ItemGroup>
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
+35 -1
View File
@@ -1,5 +1,39 @@
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<VersionPrefix>2.0.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<Authors>NuclearPowered</Authors>
<PackageIcon>icon.png</PackageIcon>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/NuclearPowered/Reactor</RepositoryUrl>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
</PropertyGroup>
</Project>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\assets\icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
<AnalysisMode>recommended</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="all" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)\stylecop.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>
+9
View File
@@ -0,0 +1,9 @@
*
!.gitignore
!Assets/
!Assets/**
!Packages/
!Packages/**
!ProjectSettings/
!ProjectSettings/ProjectVersion.txt
!build.sh
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ae7df23e94a4b0c83a418e20686437d1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5425e70810911f650b05cf41f536c339
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,116 @@
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "UI/Default"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile_local _ UNITY_UI_CLIP_RECT
#pragma multi_compile_local _ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
fixed4 _Color;
fixed4 _TextureSampleAdd;
float4 _ClipRect;
float4 _MainTex_ST;
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
OUT.color = v.color * _Color;
return OUT;
}
fixed4 frag(v2f IN) : SV_Target
{
half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
#ifdef UNITY_UI_CLIP_RECT
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#endif
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
ENDCG
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ba8fc08df3e3f060089297eca021e4d4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e90cbb1a99b248a86995ee7f3c98c535
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 68078bcc7def68b6088cdcf1eb1b4e9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: 65b1cd3c5eee8851e847e241c19b9255
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 200
spriteBorder: {x: 10, y: 10, z: 10, w: 10}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: d08be60d3e2df0be09c5425e53870ba2
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: eb30bbf806046ba1abf51bdd925e9647
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: a9d090601d3e0379b8075998ffd68c0a
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 200
spriteBorder: {x: 10, y: 10, z: 10, w: 10}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: bc8ea6103cf8330a999ba68b1990c144
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: 510b2bfc58b13bddd82690444d29a7f1
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 200
spriteBorder: {x: 10, y: 10, z: 10, w: 10}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

@@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: 63bb215422fe83002acfe2f01232904c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 200
spriteBorder: {x: 10, y: 10, z: 10, w: 10}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 100
crunchedCompression: 1
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
+102
View File
@@ -0,0 +1,102 @@
#if UNITY_EDITOR
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UnityEditor;
using Debug = UnityEngine.Debug;
internal static class Build
{
public static BuildTarget[] Targets { get; } =
{
BuildTarget.StandaloneWindows,
BuildTarget.Android,
};
public static Compression Compression => Compression.LZMA;
public static string OutputPath { get; } = Path.Combine("..", "Reactor", "Assets");
public static string AssetBundlesPath { get; } = Path.Combine("Assets", "AssetBundles");
public static string TempPath { get; } = Path.Combine("Temp", "AssetBundles");
[MenuItem("File/Build Asset Bundles")]
public static void BuildAssetBundles()
{
Directory.CreateDirectory(TempPath);
var ignoredExtensions = new[] { ".meta", ".manifest", ".dll", ".cs", ".exe", ".tps" };
var builds = Directory.GetDirectories(AssetBundlesPath)
.Select(directoryPath => new AssetBundleBuild
{
assetBundleName = Path.GetFileName(directoryPath),
assetNames = Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories).Where(p => !ignoredExtensions.Contains(Path.GetExtension(p))).ToArray(),
})
.ToArray();
Debug.Log($"Building {builds.Length} asset bundle(s) ({string.Join(", ", builds.Select(b => b.assetBundleName))})");
var options = BuildAssetBundleOptions.StrictMode;
switch (Compression)
{
case Compression.None:
options |= BuildAssetBundleOptions.UncompressedAssetBundle;
break;
case Compression.LZ4:
options |= BuildAssetBundleOptions.ChunkBasedCompression;
break;
}
foreach (var target in Targets)
{
var tempPath = Path.Combine(TempPath, target.ToString());
Directory.CreateDirectory(tempPath);
var stopwatch = Stopwatch.StartNew();
var manifest = BuildPipeline.BuildAssetBundles(tempPath, builds, options, target);
Debug.Log($"Built asset bundle(s) for {target} in {stopwatch.Elapsed}");
foreach (var assetBundleName in manifest.GetAllAssetBundles())
{
var destinationPath = Path.Combine(OutputPath, $"{assetBundleName}-{GetTargetName(target)}.bundle");
File.Delete(destinationPath);
File.Copy(Path.Combine(tempPath, assetBundleName), destinationPath);
}
}
}
private static string GetTargetName(BuildTarget target)
{
return target switch
{
BuildTarget.StandaloneWindows => "win-x86",
BuildTarget.StandaloneWindows64 => "win-x64",
BuildTarget.Android => "android",
BuildTarget.StandaloneLinux64 => "linux-x64",
_ => throw new ArgumentOutOfRangeException(nameof(target), target, null),
};
}
}
internal enum Compression
{
/// <summary>
/// Worst size, best load speed
/// </summary>
None,
/// <summary>
/// Best size, worst load speed
/// </summary>
LZMA,
/// <summary>
/// Okay size, okay load speed
/// </summary>
LZ4,
}
#endif
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d785823c2752b6812b292c93aa323bfa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+40
View File
@@ -0,0 +1,40 @@
{
"dependencies": {
"com.unity.2d.sprite": "1.0.0",
"com.unity.ide.rider": "2.0.7",
"com.unity.ide.visualstudio": "2.0.16",
"com.unity.ide.vscode": "1.2.5",
"com.unity.toolchain.linux-x86_64": "2.0.2",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}
+333
View File
@@ -0,0 +1,333 @@
{
"dependencies": {
"com.unity.2d.sprite": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.ext.nunit": {
"version": "1.0.6",
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "2.0.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.1"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.16",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.sysroot": {
"version": "2.0.3",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.sysroot.linux-x86_64": {
"version": "2.0.2",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.3"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.29",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.6",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.toolchain.linux-x86_64": {
"version": "2.0.2",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.3",
"com.unity.sysroot.linux-x86_64": "2.0.2"
},
"url": "https://packages.unity.com"
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.uielementsnative": "1.0.0"
}
},
"com.unity.modules.uielementsnative": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}
@@ -0,0 +1,2 @@
m_EditorVersion: 2020.3.22f1
m_EditorVersionWithRevision: 2020.3.22f1 (e1a7f79fd887)
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
UNITY_VERSION=2020.3.22f1
if [[ ! -v UNITY_PATH ]]; then
if command -v unityhub &>/dev/null; then
echo "Trying to get unity path from unityhub..."
UNITYHUB_INSTALL_PATH=$(unityhub --headless install-path)
UNITY_PATH="$UNITYHUB_INSTALL_PATH/$UNITY_VERSION/Editor/Unity"
if [[ ! -f $UNITY_PATH ]]; then
echo "Unity $UNITY_VERSION is not installed"
exit 1
fi
else
echo "UNITY_PATH is not set"
exit 1
fi
fi
echo "UNITY_PATH = $UNITY_PATH"
rm Library -rf # TODO figure out why having Library cached makes invalid bundles in batchmode
$UNITY_PATH -batchmode -nographics -quit -logFile "-" -projectPath $pwd -executeMethod Build.BuildAssetBundles
@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.IO;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BepInEx;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Reactor.Utilities;
using Reactor.Utilities.Extensions;
using UnityEngine;
namespace Reactor.Benchmarks;
[MemoryDiagnoser]
[StopOnFirstError, Config(typeof(Config))]
public class AssetBundleBenchmarks
{
private class Config : ManualConfig
{
public Config()
{
AddJob(Job.ShortRun.WithLaunchCount(1).WithWarmupCount(1).WithIterationCount(10).WithToolchain(SingleThreadedInProcessEmitToolchain.Instance));
}
}
[ParamsSource(nameof(ValuesForAssetBundleName))]
public string AssetBundleFileName { get; set; } = null!;
public static IEnumerable<string> ValuesForAssetBundleName()
{
yield return $"default-{AssetBundleManager.TargetName}{AssetBundleManager.BundleExtension}";
// yield return "submerged";
}
[IterationSetup]
public void IterationSetup()
{
AssetBundle.UnloadAllAssetBundles(true);
}
private AssetBundle LoadAll(AssetBundle assetBundle)
{
if (assetBundle == null) throw new ArgumentNullException(nameof(assetBundle));
assetBundle.LoadAllAssets();
return assetBundle;
}
private Stream GetResourceStream()
{
return typeof(ReactorPlugin).Assembly.GetManifestResourceStream("Reactor.Assets." + AssetBundleFileName)!;
}
[Benchmark]
public AssetBundle LoadFromStream()
{
using var stream = GetResourceStream();
return LoadAll(AssetBundle.LoadFromStream(stream.AsIl2Cpp()));
}
[Benchmark]
public AssetBundle LoadFromMemory_ReadFully()
{
using var stream = GetResourceStream();
return LoadAll(AssetBundle.LoadFromMemory(stream.ReadFully()));
}
[Benchmark]
public unsafe AssetBundle LoadFromMemory_ReadFullyFastCopy()
{
using var stream = GetResourceStream();
var array = stream.ReadFully();
var il2CppArray = new Il2CppStructArray<byte>(array.Length);
fixed (byte* arrayPtr = array) { Buffer.MemoryCopy(arrayPtr, IntPtr.Add(il2CppArray.Pointer, 4 * IntPtr.Size).ToPointer(), il2CppArray.Length, array.Length); }
return LoadAll(AssetBundle.LoadFromMemory(il2CppArray));
}
[Benchmark]
public AssetBundle LoadFromMemory_Span()
{
using var stream = GetResourceStream();
var length = (int) stream.Length;
var array = new Il2CppStructArray<byte>(length);
if (stream.Read(array.ToSpan()) < length) throw new IOException("Failed to read in full");
return LoadAll(AssetBundle.LoadFromMemory(array));
}
[Benchmark]
public AssetBundle LoadFromFile()
{
return LoadAll(AssetBundle.LoadFromFile(Path.Combine(Paths.PluginPath, AssetBundleFileName)));
}
}
+24
View File
@@ -0,0 +1,24 @@
using System.Diagnostics;
using BenchmarkDotNet.Running;
using BepInEx;
using BepInEx.Unity.IL2CPP;
namespace Reactor.Benchmarks;
[BepInAutoPlugin("gg.reactor.benchmarks")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
public partial class BenchmarksPlugin : BasePlugin
{
public override void Load()
{
try
{
BenchmarkRunner.Run<AssetBundleBenchmarks>();
}
finally
{
Process.GetCurrentProcess().Kill();
}
}
}
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>0.1.0</Version>
<Authors>NuclearPowered</Authors>
<EnableDynamicLoading>true</EnableDynamicLoading>
<SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Reactor\Reactor.csproj" Private="false" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
</ItemGroup>
<Import Project="../AmongUs.props" />
</Project>
@@ -0,0 +1,54 @@
#pragma warning disable SA1611, SA1615
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Toolchains.InProcess;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using BenchmarkDotNet.Toolchains.InProcess.Emit.Implementation;
using BenchmarkDotNet.Toolchains.Parameters;
using BenchmarkDotNet.Toolchains.Results;
using HarmonyLib;
namespace Reactor.Benchmarks;
public class SingleThreadedInProcessEmitToolchain : Toolchain
{
public static readonly IToolchain Instance = new SingleThreadedInProcessEmitToolchain(true);
public SingleThreadedInProcessEmitToolchain(bool logOutput)
: base(nameof(SingleThreadedInProcessEmitToolchain), new InProcessEmitGenerator(), new InProcessEmitBuilder(), new SingleThreadedInProcessEmitExecutor(logOutput))
{
}
}
public class SingleThreadedInProcessEmitExecutor : IExecutor
{
/// <summary>Initializes a new instance of the <see cref="SingleThreadedInProcessEmitExecutor" /> class.</summary>
/// <param name="logOutput"><c>true</c> if the output should be logged.</param>
public SingleThreadedInProcessEmitExecutor(bool logOutput)
{
LogOutput = logOutput;
}
/// <summary>Gets a value indicating whether the output should be logged.</summary>
/// <value><c>true</c> if the output should be logged; otherwise, <c>false</c>.</value>
public bool LogOutput { get; }
/// <summary>Executes the specified benchmark.</summary>
public ExecuteResult Execute(ExecuteParameters executeParameters)
{
var hostLogger = LogOutput ? executeParameters.Logger : NullLogger.Instance;
var host = new InProcessHost(executeParameters.BenchmarkCase, hostLogger, executeParameters.Diagnoser);
var exitCode = ExecuteCore(host, executeParameters);
return ((ExecuteResult) AccessTools.Method(typeof(ExecuteResult), "FromRunResults").Invoke(null, new object[] { host.RunResults, exitCode })!)!;
}
private int ExecuteCore(IHost host, ExecuteParameters parameters)
{
var generatedAssembly = ((InProcessEmitArtifactsPath) parameters.BuildResult.ArtifactsPaths).GeneratedAssembly;
return RunnableProgram.Run(parameters.BenchmarkId, generatedAssembly, parameters.BenchmarkCase, host);
}
}
File diff suppressed because it is too large. Load diff
+96 -96
View File
@@ -1,118 +1,118 @@
using System;
using System.Linq;
using AmongUs.Data;
using BepInEx;
using BepInEx.IL2CPP;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using InnerNet;
using Reactor.Extensions;
using UnhollowerBaseLib;
using UnhollowerBaseLib.Attributes;
using Reactor.Utilities.Attributes;
using Reactor.Utilities.ImGui;
using UnityEngine;
namespace Reactor.Debugger
namespace Reactor.Debugger;
[BepInAutoPlugin("gg.reactor.debugger")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
public partial class DebuggerPlugin : BasePlugin
{
[BepInAutoPlugin("gg.reactor.debugger")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
[ReactorPluginSide(PluginSide.ClientOnly)]
public partial class DebuggerPlugin : BasePlugin
public Harmony Harmony { get; } = new(Id);
public DebuggerComponent Component { get; private set; } = null!;
public override void Load()
{
public Harmony Harmony { get; } = new Harmony(Id);
public DebuggerComponent Component { get; private set; }
Component = this.AddComponent<DebuggerComponent>();
public override void Load()
GameOptionsData.MaxImpostors = GameOptionsData.RecommendedImpostors = Enumerable.Repeat((int) byte.MaxValue, byte.MaxValue).ToArray();
GameOptionsData.MinPlayers = Enumerable.Repeat(1, 4).ToArray();
Harmony.PatchAll();
}
[RegisterInIl2Cpp]
public class DebuggerComponent : MonoBehaviour
{
[HideFromIl2Cpp]
public bool DisableGameEnd { get; set; }
[HideFromIl2Cpp]
public DragWindow TestWindow { get; }
public DebuggerComponent(IntPtr ptr) : base(ptr)
{
Component = this.AddComponent<DebuggerComponent>();
TestWindow = new DragWindow(new Rect(20, 20, 0, 0), "Debugger", () =>
{
GUILayout.Label("Name: " + DataManager.Player.Customization.Name);
DisableGameEnd = GUILayout.Toggle(DisableGameEnd, "Disable game end");
GameOptionsData.MaxImpostors = GameOptionsData.RecommendedImpostors = Enumerable.Repeat((int) byte.MaxValue, byte.MaxValue).ToArray();
GameOptionsData.MinPlayers = Enumerable.Repeat(1, 4).ToArray();
if (ShipStatus.Instance && AmongUsClient.Instance.AmHost)
{
if (GUILayout.Button("Force game end"))
{
ShipStatus.Instance.enabled = false;
ShipStatus.RpcEndGame(GameOverReason.ImpostorDisconnect, false);
}
Harmony.PatchAll();
if (GUILayout.Button("Call a meeting"))
{
PlayerControl.LocalPlayer.CmdReportDeadBody(null);
}
}
if (TutorialManager.InstanceExists && PlayerControl.LocalPlayer)
{
var data = PlayerControl.LocalPlayer.Data;
var newIsImpostor = GUILayout.Toggle(data.Role.IsImpostor, "Is Impostor");
if (data.Role.IsImpostor != newIsImpostor)
{
PlayerControl.LocalPlayer.RpcSetRole(newIsImpostor ? RoleTypes.Impostor : RoleTypes.Crewmate);
}
if (GUILayout.Button("Spawn a dummy"))
{
var playerControl = Instantiate(TutorialManager.Instance.PlayerPrefab);
var i = playerControl.PlayerId = (byte) GameData.Instance.GetAvailableId();
GameData.Instance.AddPlayer(playerControl);
AmongUsClient.Instance.Spawn(playerControl, -2, SpawnFlags.None);
playerControl.transform.position = PlayerControl.LocalPlayer.transform.position;
playerControl.GetComponent<DummyBehaviour>().enabled = true;
playerControl.NetTransform.enabled = false;
playerControl.SetName($"{TranslationController.Instance.GetString(StringNames.Dummy, Array.Empty<Il2CppSystem.Object>())} {i}");
var color = (byte) (i % Palette.PlayerColors.Length);
playerControl.SetColor(color);
playerControl.SetHat(HatManager.Instance.allHats[i % HatManager.Instance.allHats.Count].ProdId, playerControl.Data.DefaultOutfit.ColorId);
playerControl.SetPet(HatManager.Instance.allPets[i % HatManager.Instance.allPets.Count].ProdId);
playerControl.SetSkin(HatManager.Instance.allSkins[i % HatManager.Instance.allSkins.Count].ProdId, color);
GameData.Instance.RpcSetTasks(playerControl.PlayerId, new Il2CppStructArray<byte>(0));
}
}
if (PlayerControl.LocalPlayer)
{
var position = PlayerControl.LocalPlayer.transform.position;
GUILayout.Label($"x: {position.x}");
GUILayout.Label($"y: {position.y}");
}
})
{
Enabled = false,
};
}
[RegisterInIl2Cpp]
public class DebuggerComponent : MonoBehaviour
private void Update()
{
[HideFromIl2Cpp]
public bool DisableGameEnd { get; set; }
[HideFromIl2Cpp]
public DragWindow TestWindow { get; }
public DebuggerComponent(IntPtr ptr) : base(ptr)
if (Input.GetKeyDown(KeyCode.F1))
{
TestWindow = new DragWindow(new Rect(20, 20, 0, 0), "Debugger", () =>
{
GUILayout.Label("Name: " + SaveManager.PlayerName);
DisableGameEnd = GUILayout.Toggle(DisableGameEnd, "Disable game end");
if (ShipStatus.Instance && AmongUsClient.Instance.AmHost)
{
if (GUILayout.Button("Force game end"))
{
ShipStatus.Instance.enabled = false;
ShipStatus.RpcEndGame(GameOverReason.ImpostorDisconnect, false);
}
if (GUILayout.Button("Call a meeting"))
{
PlayerControl.LocalPlayer.CmdReportDeadBody(null);
}
}
if (TutorialManager.InstanceExists && PlayerControl.LocalPlayer)
{
var data = PlayerControl.LocalPlayer.Data;
var newIsImpostor = GUILayout.Toggle(data.Role.IsImpostor, "Is Impostor");
if (data.Role.IsImpostor != newIsImpostor)
{
PlayerControl.LocalPlayer.RpcSetRole(newIsImpostor ? RoleTypes.Impostor : RoleTypes.Crewmate);
}
if (GUILayout.Button("Spawn a dummy"))
{
var playerControl = Instantiate(TutorialManager.Instance.PlayerPrefab);
var i = playerControl.PlayerId = (byte) GameData.Instance.GetAvailableId();
GameData.Instance.AddPlayer(playerControl);
AmongUsClient.Instance.Spawn(playerControl, -2, SpawnFlags.None);
playerControl.transform.position = PlayerControl.LocalPlayer.transform.position;
playerControl.GetComponent<DummyBehaviour>().enabled = true;
playerControl.NetTransform.enabled = false;
playerControl.SetName($"{TranslationController.Instance.GetString(StringNames.Dummy, Array.Empty<Il2CppSystem.Object>())} {i}");
var color = (byte) (i % Palette.PlayerColors.Length);
playerControl.SetColor(color);
playerControl.SetHat(HatManager.Instance.allHats[i % HatManager.Instance.allHats.Count].ProdId, playerControl.Data.DefaultOutfit.ColorId);
playerControl.SetPet(HatManager.Instance.allPets[i % HatManager.Instance.allPets.Count].ProdId);
playerControl.SetSkin(HatManager.Instance.allSkins[i % HatManager.Instance.allSkins.Count].ProdId, color);
GameData.Instance.RpcSetTasks(playerControl.PlayerId, new Il2CppStructArray<byte>(0));
}
}
if (PlayerControl.LocalPlayer)
{
var position = PlayerControl.LocalPlayer.transform.position;
GUILayout.Label($"x: {position.x}");
GUILayout.Label($"y: {position.y}");
}
})
{
Enabled = false
};
TestWindow.Enabled = !TestWindow.Enabled;
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F1))
{
TestWindow.Enabled = !TestWindow.Enabled;
}
}
private void OnGUI()
{
TestWindow.OnGUI();
}
private void OnGUI()
{
TestWindow.OnGUI();
}
}
}
+45 -45
View File
@@ -1,70 +1,70 @@
using System.Linq;
using HarmonyLib;
using UnhollowerBaseLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Reactor.Utilities;
using UnityEngine;
namespace Reactor.Debugger
namespace Reactor.Debugger;
internal static class Patches
{
internal static class Patches
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))]
public static class UpdatePatch
{
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))]
public static class UpdatePatch
public static void Prefix(GameStartManager __instance)
{
public static void Prefix(GameStartManager __instance)
{
__instance.MinPlayers = 1;
}
__instance.MinPlayers = 1;
}
}
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))]
public static class CountdownPatch
[HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))]
public static class CountdownPatch
{
public static void Prefix(GameStartManager __instance)
{
public static void Prefix(GameStartManager __instance)
{
__instance.countDownTimer = 0;
}
__instance.countDownTimer = 0;
}
}
[HarmonyPatch(typeof(StatsManager), nameof(StatsManager.AmBanned), MethodType.Getter)]
public static class AmBannedPatch
[HarmonyPatch(typeof(StatsManager), nameof(StatsManager.AmBanned), MethodType.Getter)]
public static class AmBannedPatch
{
public static void Postfix(out bool __result)
{
public static void Postfix(out bool __result)
{
__result = false;
}
__result = false;
}
}
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.CheckEndCriteria))]
[HarmonyPriority(Priority.First)]
public static class CheckEndCriteriaPatch
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.CheckEndCriteria))]
[HarmonyPriority(Priority.First)]
public static class CheckEndCriteriaPatch
{
public static bool Prefix()
{
public static bool Prefix()
{
return !PluginSingleton<DebuggerPlugin>.Instance.Component.DisableGameEnd;
}
return !PluginSingleton<DebuggerPlugin>.Instance.Component.DisableGameEnd;
}
}
[HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.Start))]
public static class GameSettingMenuPatch
[HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.Start))]
public static class GameSettingMenuPatch
{
public static void Prefix(GameSettingMenu __instance)
{
public static void Prefix(GameSettingMenu __instance)
{
// Unlocks map/impostor amount changing in online (for testing on your custom servers)
__instance.HideForOnline = new Il2CppReferenceArray<Transform>(0);
}
// Unlocks map/impostor amount changing in online (for testing on your custom servers)
__instance.HideForOnline = new Il2CppReferenceArray<Transform>(0);
}
}
[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Start))]
[HarmonyPriority(Priority.First)]
public static class GameOptionsMenuPatch
[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Start))]
[HarmonyPriority(Priority.First)]
public static class GameOptionsMenuPatch
{
public static void Postfix(GameOptionsMenu __instance)
{
public static void Postfix(GameOptionsMenu __instance)
{
__instance.Children
.Single(o => o.Title == StringNames.GameNumImpostors)
.Cast<NumberOption>()
.ValidRange = new FloatRange(0, byte.MaxValue);
}
__instance.Children
.Single(o => o.Title == StringNames.GameNumImpostors)
.Cast<NumberOption>()
.ValidRange = new FloatRange(0, byte.MaxValue);
}
}
}
+1 -4
View File
@@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Version>0.1.0</Version>
<Description>Debugging mod for Reactor</Description>
<Authors>NuclearPowered</Authors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Reactor\Reactor.csproj" />
<ProjectReference Include="..\Reactor\Reactor.csproj" Private="false" />
</ItemGroup>
<Import Project="../AmongUs.props" />
+476 -64
View File
@@ -1,59 +1,73 @@
{
"version": 1,
"dependencies": {
".NETStandard,Version=v2.1": {
"net6.0": {
"AmongUs.GameLibs.Steam": {
"type": "Direct",
"requested": "[2022.8.23, )",
"resolved": "2022.8.23",
"contentHash": "baY5JO6dbdOAZ0VTtGX0xre6/BlDdreJDAH8boCKZt3JTAcn+eeH+l8mUZRC9eCJOODUik2C0TTAt5AqBmYtZg=="
"requested": "[2022.10.25, )",
"resolved": "2022.10.25",
"contentHash": "PWgkH/VvMlShVhZB8G432q0tnMaNVZrbIdbEMCZN/fETUlT/ch+qQj4PdTcZhPHREbnJHH3ijHxlca1d7QMBcQ=="
},
"BepInEx.AutoPlugin": {
"type": "Direct",
"requested": "[1.0.1, )",
"resolved": "1.0.1",
"contentHash": "G4YpTHG9rtkDJof+ld7Er4E+sCOlgsjG4bJ1itx1ub7dgff6qqHLy9ksX1ehgO0AdBOPVyVl/GKJg9o7iNl8HA=="
},
"BepInEx.IL2CPP": {
"type": "Direct",
"requested": "[6.0.0-be.570, )",
"resolved": "6.0.0-be.570",
"contentHash": "JGkWFFGZTWQ+YlFQ17izlwfGNUyo/zfFGNYPX6XAeTkfM5RwXiPYNMNO6eWoxbKwaYlAylQq2YCRkkCnAr9nwQ==",
"dependencies": {
"BepInEx.Core": "6.0.0-be.570",
"BepInEx.Il2Cpp.TlsAdapter": "1.0.1",
"HarmonyX": "2.10.0",
"Iced": "1.17.0",
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3",
"Il2CppAssemblyUnhollower.BaseLib.Legacy": "0.4.33.3",
"Il2CppAssemblyUnhollower.Lib": "0.4.33.3",
"Il2CppDumper": "6.6.4",
"MonoMod.RuntimeDetour": "22.5.1.1",
"Samboy063.Cpp2IL.Core": "2022.0.5"
}
"requested": "[1.1.0, )",
"resolved": "1.1.0",
"contentHash": "/7Nmc1EA9lYlGBiyz6qPAaHvlcJHEjFZ1RFpGX+8EBj3GrgoX5kbpnZusuSHoOlLx0l+CnzKuQNE54B8UaGPyw=="
},
"BepInEx.IL2CPP.MSBuild": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "uUSo4TuamyEIVg+ICNeJMSSW/arKWHGpfBFINc4fdF5kppfHFrsDURKzNPmDvxivtLsiuGthck9J/5uPXgIcTg=="
"requested": "[2.0.1, )",
"resolved": "2.0.1",
"contentHash": "hUZjCV0t8dkw/Z/zq4Zl405QP7frBk/LVfMdUmUz+7XOhGd7lYPKrR48A5vbGl2QeHudMxlkXzAr9WM3Duq2SQ=="
},
"BepInEx.Unity.IL2CPP": {
"type": "Direct",
"requested": "[6.0.0-be.662, )",
"resolved": "6.0.0-be.662",
"contentHash": "fn7jQ88IBmjssoY9XjGBTg3cULkS+N/le/eUijYf2VV8raWok/6cU/GbU9bejkJS8g+2MvzIwnROAhAxvrGI2Q==",
"dependencies": {
"BepInEx.Core": "6.0.0-be.662",
"BepInEx.Unity.Common": "6.0.0-be.662",
"HarmonyX": "2.10.0",
"Iced": "1.17.0",
"Il2CppInterop.Generator": "1.3.0",
"Il2CppInterop.HarmonySupport": "1.3.0",
"Il2CppInterop.Runtime": "1.3.0",
"MonoMod.RuntimeDetour": "22.5.1.1",
"Samboy063.Cpp2IL.Core": "2022.0.7.2"
}
},
"StyleCop.Analyzers": {
"type": "Direct",
"requested": "[1.2.0-beta.435, )",
"resolved": "1.2.0-beta.435",
"contentHash": "TADk7vdGXtfTnYCV7GyleaaRTQjfoSfZXprQrVMm7cSJtJbFc1QIbWPyLvrgrfGdfHbGmUPvaN4ODKNxg2jgPQ==",
"dependencies": {
"StyleCop.Analyzers.Unstable": "1.2.0.435"
}
},
"AssetRipper.VersionUtilities": {
"type": "Transitive",
"resolved": "1.2.1",
"contentHash": "knQ/W1YwTZS2AbdaZh+nhyyBEZQPQDcahhSOnh88i+cdg4/FEoFJiCwaavgFvCMNuUeHTbcZc4qttF8WQ8xLIA=="
},
"BepInEx.Core": {
"type": "Transitive",
"resolved": "6.0.0-be.570",
"contentHash": "kygIunLrK1HMGcRo2E/7e4ZEAA0xewuB/j5mPoMi7Xk58GUi43XnclBJHif9x05a55s0kFkfKOrpwIRmjd0cDw==",
"resolved": "6.0.0-be.662",
"contentHash": "VVBeCD/KQVy0/TK3V6SD8QZ/es35Xb1mEz/+PbBs3ST1yUC1r7k2JOymhSnmghVqf6UsvlMglOO9pljqhuE/Pw==",
"dependencies": {
"HarmonyX": "2.10.0",
"MonoMod.Utils": "22.3.23.4",
"MonoMod.Utils": "22.5.1.1",
"SemanticVersioning": "2.0.2"
}
},
"BepInEx.Il2Cpp.TlsAdapter": {
"BepInEx.Unity.Common": {
"type": "Transitive",
"resolved": "1.0.1",
"contentHash": "kTfX6312X0Fvwks+t7Ul3YO2jMSbqNS2Jx/85Cgl6lbAjEJnKzsmx7Krmd66dbnx0eY/QMjaV2r6LyWmQARtdA==",
"resolved": "6.0.0-be.662",
"contentHash": "BgETw6+snwY//3xjQxLiiEAFRmXaMTcSkg+1UQz6fVBG0YA5Usm/m4GflhTc3nwF61KO3Iznn1AORi5CwLJoUw==",
"dependencies": {
"HarmonyX": "2.3.1"
"AssetRipper.VersionUtilities": "1.2.1",
"MonoMod.Utils": "22.5.1.1"
}
},
"HarmonyX": {
@@ -70,38 +84,41 @@
"resolved": "1.17.0",
"contentHash": "8x+HCVTl/HHTGpscH3vMBhV8sknN/muZFw9s3TsI8SA6+c43cOTCi2+jE4KsU8pNLbJ++iF2ZFcpcXHXtDglnw=="
},
"Il2CppAssemblyUnhollower.BaseLib": {
"Il2CppInterop.Common": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "CH91M6Asz4iwennTa8cLg5wqROJY1JvnsfRetyOvs0cy8o/YAikvm8uuNgZv6UiTO/qoyy/QrBE1qSZDvs8bLw==",
"resolved": "1.3.0",
"contentHash": "IR3BrZXvL2nvJAn4pruPMgC78Y87hVa5xTYZCuHN67OzRD6WDl5dTO55vtvTl8dXFALKvlN+spja2tXhVuquOw==",
"dependencies": {
"Iced": "1.15.0"
"Iced": "1.17.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.1",
"System.Net.Http": "4.3.4"
}
},
"Il2CppAssemblyUnhollower.BaseLib.Legacy": {
"Il2CppInterop.Generator": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "6yIJg8lkayBDevPwcdcV3LWTdHt8VAZVY0wQwuXH4POOo0Kzc6Cshy9kLCxH3AC6EQg0G/v+Albs6RZgwszXMQ==",
"resolved": "1.3.0",
"contentHash": "FuhPxbh/K4K94U3xac/ClMaaBp+MZ4aIaqi5dR0QihyGQoombT+OM/A22RwAIzbaCTbFbvabWaAuOSgB69ZwWQ==",
"dependencies": {
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3"
}
},
"Il2CppAssemblyUnhollower.Lib": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "tdu4OnMxodkWwoImNDaycaLY1L3qJOazb5UaLAt1ncRpWyu6xvKuKe5NM6OcBXONpkYsJQeQZjD6syeFl5MCQA==",
"dependencies": {
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3",
"Il2CppAssemblyUnhollower.BaseLib.Legacy": "0.4.33.3",
"Il2CppInterop.Common": "1.3.0",
"Mono.Cecil": "0.11.3"
}
},
"Il2CppDumper": {
"Il2CppInterop.HarmonySupport": {
"type": "Transitive",
"resolved": "6.6.4",
"contentHash": "aqjmlyigdZ5FS9ElMNlaCExlgSmAiho4BeIcVwkmzHGnomBzopjOCxqIX9vc/575TQ87TKoaGW2KP+3b5xI15A==",
"resolved": "1.3.0",
"contentHash": "VppBnXtbMNGFhX8a1gg/85E883t2pW/+FZyV7eOaOXMNQyorg++u+kUFOIYwNpzTVqxWmMeoPS0DH0toVpjoKA==",
"dependencies": {
"Mono.Cecil": "0.11.3"
"HarmonyX": "2.10.0",
"Il2CppInterop.Runtime": "1.3.0"
}
},
"Il2CppInterop.Runtime": {
"type": "Transitive",
"resolved": "1.3.0",
"contentHash": "8A+N2yvja960Ap+s2RpW7Nb6HSpyuXJy2ipIlU+1erYU9SWHMyU9JZzUZGOhwWXJChKGvRmDdTZAg12k1+72dg==",
"dependencies": {
"Iced": "1.17.0",
"Il2CppInterop.Common": "1.3.0"
}
},
"IndexRange": {
@@ -114,10 +131,37 @@
"resolved": "2.1.0",
"contentHash": "YYpq7NM50bSSVUDjXyV/eiITk6syXqItPjKBOb3jEWS6RFsk0DNhpWMPW6b3hKDmArARuWDU6S2pVu1IeVrvIA=="
},
"Linguini.Bundle": {
"type": "Transitive",
"resolved": "0.3.1",
"contentHash": "k3D0IBSsS91T0G9rYACRYtAS27NDTGz4T3ygHhbhaFdA9i3cCfCpR39MqYEpoA1Ark3lzmvklHePmRCX5EQi1A==",
"dependencies": {
"Linguini.Shared": "0.3.0",
"Linguini.Syntax": "0.3.0"
}
},
"Linguini.Shared": {
"type": "Transitive",
"resolved": "0.3.0",
"contentHash": "rEYA9jWU1Nc9iDuPKar+4IVXjFbGrcNyYZCeU6hiWQoS4nA2UecHu36Rp4bxzasvRGda4FB2JZqty75m4e26VQ=="
},
"Linguini.Syntax": {
"type": "Transitive",
"resolved": "0.3.0",
"contentHash": "v8YV3xPFZfP+OSWjMd6yysp+o7cNnQXxq/slN8Yekoi+dFjsTNF0YiQWJIwg1j2FUbs6claJxY9R1FFlc4s6MA==",
"dependencies": {
"Linguini.Shared": "0.3.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "6.0.1",
"contentHash": "dzB2Cgg+JmrouhjkcQGzSFjjvpwlq353i8oBQO2GWNjCXSzhbtBRUf28HSauWe7eib3wYOdb3tItdjRwAdwCSg=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
"resolved": "1.1.1",
"contentHash": "TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ=="
},
"Microsoft.NETCore.Targets": {
"type": "Transitive",
@@ -158,16 +202,114 @@
"System.Reflection.TypeExtensions": "4.7.0"
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g=="
},
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw=="
},
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg=="
},
"runtime.native.System": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
"dependencies": {
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
}
},
"runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==",
"dependencies": {
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
}
},
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ=="
},
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w=="
},
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg=="
},
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw=="
},
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w=="
},
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg=="
},
"Samboy063.Cpp2IL.Core": {
"type": "Transitive",
"resolved": "2022.0.5",
"contentHash": "5JipfyEmJWePqLLnvwzxWx9dQXxNfgN0wcZ4IcmuabWKVvk4gA5Rux4vgDh9NrWf8q9LzkizWHkrnMaG1niF7g==",
"resolved": "2022.0.7.2",
"contentHash": "e17CAhKSxdAp7vFcYEVxjSc7t7rcvVGBipGhgE9tAjRXY85wZXLlHEVO0AEvMRkLmf9U+if4wK/nZEC1AX6VqQ==",
"dependencies": {
"HarmonyX": "2.5.5",
"Iced": "1.11.1",
"IndexRange": "1.0.0",
"Mono.Cecil": "0.11.4",
"Samboy063.LibCpp2IL": "2022.0.5",
"Samboy063.LibCpp2IL": "2022.0.7.2",
"System.Runtime.InteropServices": "4.3.0",
"System.ValueTuple": "4.5.0",
"js6pak.Gee.External.Capstone": "2.1.0"
@@ -175,8 +317,8 @@
},
"Samboy063.LibCpp2IL": {
"type": "Transitive",
"resolved": "2022.0.5",
"contentHash": "eH+/FBclsKDxboa9N/tFoiM8kwvietVX0FtXYxvcexSp/geYCyTt2XUGOQjinqd3Yqg/QxmpIqBO7qy4MQHrhw==",
"resolved": "2022.0.7.2",
"contentHash": "DpVeU0dQkUJCpbw0f1xKOG8vimdK2oYhrVABC7HDE3/ikGjhnMZd3i5b1joKDHZ+AiL90TWOaEXPcy24rCZ0dA==",
"dependencies": {
"IndexRange": "1.0.0",
"Samboy063.WasmDisassembler": "2022.0.2"
@@ -192,6 +334,11 @@
"resolved": "2.0.2",
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
},
"StyleCop.Analyzers.Unstable": {
"type": "Transitive",
"resolved": "1.2.0.435",
"contentHash": "ouwPWZxbOV3SmCZxIRqHvljkSzkCyi1tDoMzQtDb/bRP8ctASV/iRJr+A2Gdj0QLaLmWnqTWDrH82/iP+X80Lg=="
},
"System.Collections": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -202,6 +349,23 @@
"System.Runtime": "4.3.0"
}
},
"System.Collections.Concurrent": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Collections.NonGeneric": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -279,6 +443,28 @@
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.DiagnosticSource": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Diagnostics.Tracing": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -289,6 +475,17 @@
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Calendars": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Globalization": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -314,6 +511,21 @@
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -334,6 +546,50 @@
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.4",
"contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.1",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.DiagnosticSource": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Extensions": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
}
},
"System.Net.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Reflection": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -441,6 +697,161 @@
"System.Runtime.Handles": "4.3.0"
}
},
"System.Runtime.Numerics": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
"dependencies": {
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Security.Cryptography.Algorithms": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.Apple": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Cng": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Security.Cryptography.Csp": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Security.Cryptography.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
"dependencies": {
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Security.Cryptography.X509Certificates": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Calendars": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Cng": "4.3.0",
"System.Security.Cryptography.Csp": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Text.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -478,7 +889,8 @@
"reactor": {
"type": "Project",
"dependencies": {
"BepInEx.IL2CPP": "6.0.0-be.570"
"BepInEx.Unity.IL2CPP": "[6.0.0-be.662, )",
"Linguini.Bundle": "[0.3.1, )"
}
}
}
+5 -6
View File
@@ -1,8 +1,7 @@
namespace Reactor.Example
namespace Reactor.Example;
public enum CustomRpcCalls : uint
{
public enum CustomRpcCalls : uint
{
Example,
MethodRpcExample
}
Example,
MethodRpcExample,
}
@@ -0,0 +1,26 @@
using Reactor.Localization;
namespace Reactor.Example;
public class ExampleLocalizationProvider : LocalizationProvider
{
public override bool TryGetText(StringNames stringName, out string? result)
{
if (stringName == (StringNames) 1337)
{
switch (CurrentLanguage)
{
case SupportedLangs.English:
result = "Cringe English";
return true;
default:
result = "Based " + CurrentLanguage;
return true;
}
}
result = null;
return false;
}
}
+70 -29
View File
@@ -1,59 +1,100 @@
using System;
using System;
using BepInEx;
using BepInEx.IL2CPP;
using Reactor.Extensions;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Attributes;
using Reactor.Localization;
using Reactor.Localization.Utilities;
using Reactor.Networking;
using Reactor.Networking.MethodRpc;
using UnhollowerBaseLib.Attributes;
using Reactor.Networking.Attributes;
using Reactor.Networking.Rpc;
using Reactor.Utilities;
using Reactor.Utilities.Attributes;
using Reactor.Utilities.ImGui;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Reactor.Example
namespace Reactor.Example;
[BepInAutoPlugin("gg.reactor.Example")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
[ReactorModFlags(ModFlags.RequireOnAllClients)]
public partial class ExamplePlugin : BasePlugin
{
[BepInAutoPlugin("gg.reactor.Example")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
public partial class ExamplePlugin : BasePlugin
private static StringNames _helloStringName;
public override void Load()
{
public override void Load()
{
this.AddComponent<ExampleComponent>();
}
this.AddComponent<ExampleComponent>();
[RegisterInIl2Cpp]
public class ExampleComponent : MonoBehaviour
{
public ExampleComponent(IntPtr ptr) : base(ptr)
{
}
_helloStringName = CustomStringName.CreateAndRegister("Hello!");
LocalizationManager.Register(new ExampleLocalizationProvider());
}
private void Update()
[RegisterInIl2Cpp]
public class ExampleComponent : MonoBehaviour
{
[HideFromIl2Cpp]
public DragWindow TestWindow { get; }
public ExampleComponent(IntPtr ptr) : base(ptr)
{
TestWindow = new DragWindow(new Rect(60, 20, 0, 0), "Example", () =>
{
if (GUILayout.Button("Log CustomStringName"))
{
Logger<ExamplePlugin>.Info(TranslationController.Instance.GetString(_helloStringName));
}
if (GUILayout.Button("Log localized string"))
{
Logger<ExamplePlugin>.Info(TranslationController.Instance.GetString((StringNames) 1337));
}
if (AmongUsClient.Instance && PlayerControl.LocalPlayer)
{
if (Input.GetKeyDown(KeyCode.F3))
if (GUILayout.Button("Send ExampleRpc"))
{
var name = PlayerControl.LocalPlayer.Data.PlayerName;
Rpc<ExampleRpc>.Instance.Send(new ExampleRpc.Data($"Send: from {name}"));
var playerName = PlayerControl.LocalPlayer.Data.PlayerName;
Rpc<ExampleRpc>.Instance.Send(new ExampleRpc.Data($"Send: from {playerName}"), ackCallback: () =>
{
Logger<ExamplePlugin>.Info("Got an acknowledgement for example rpc");
});
if (!AmongUsClient.Instance.AmHost)
{
Rpc<ExampleRpc>.Instance.SendTo(AmongUsClient.Instance.HostId, new ExampleRpc.Data($"SendTo: from {name} to host"));
Rpc<ExampleRpc>.Instance.SendTo(AmongUsClient.Instance.HostId, new ExampleRpc.Data($"SendTo: from {playerName} to host"));
}
}
if (Input.GetKeyDown(KeyCode.F4))
if (GUILayout.Button("Send MethodExampleRpc"))
{
RpcSay(PlayerControl.LocalPlayer, "Hello from method rpc", Random.value, PlayerControl.LocalPlayer);
}
}
})
{
Enabled = false,
};
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F2))
{
TestWindow.Enabled = !TestWindow.Enabled;
}
}
[MethodRpc((uint) CustomRpcCalls.MethodRpcExample)]
public static void RpcSay(PlayerControl player, string text, float number, PlayerControl testPlayer)
private void OnGUI()
{
Logger<ExamplePlugin>.Info($"{player.Data.PlayerName} text: {text} number: {number} testPlayer: {testPlayer.NetId}");
TestWindow.OnGUI();
}
}
[MethodRpc((uint) CustomRpcCalls.MethodRpcExample)]
public static void RpcSay(PlayerControl player, string text, float number, PlayerControl testPlayer)
{
Logger<ExamplePlugin>.Info($"{player.Data.PlayerName} text: {text} number: {number} testPlayer: {testPlayer.NetId}");
}
}
+21 -29
View File
@@ -1,40 +1,32 @@
using Hazel;
using Reactor.Networking;
using Reactor.Networking.Attributes;
using Reactor.Networking.Rpc;
namespace Reactor.Example
namespace Reactor.Example;
[RegisterCustomRpc((uint) CustomRpcCalls.Example)]
public class ExampleRpc : PlayerCustomRpc<ExamplePlugin, ExampleRpc.Data>
{
[RegisterCustomRpc((uint) CustomRpcCalls.Example)]
public class ExampleRpc : PlayerCustomRpc<ExamplePlugin, ExampleRpc.Data>
public ExampleRpc(ExamplePlugin plugin, uint id) : base(plugin, id)
{
public ExampleRpc(ExamplePlugin plugin, uint id) : base(plugin, id)
{
}
}
public readonly struct Data
{
public readonly string Message;
public readonly record struct Data(string Message);
public Data(string message)
{
Message = message;
}
}
public override RpcLocalHandling LocalHandling => RpcLocalHandling.None;
public override RpcLocalHandling LocalHandling => RpcLocalHandling.None;
public override void Write(MessageWriter writer, Data data)
{
writer.Write(data.Message);
}
public override void Write(MessageWriter writer, Data data)
{
writer.Write(data.Message);
}
public override Data Read(MessageReader reader)
{
return new Data(reader.ReadString());
}
public override Data Read(MessageReader reader)
{
return new Data(reader.ReadString());
}
public override void Handle(PlayerControl innerNetObject, Data data)
{
Plugin.Log.LogWarning($"Handle: {innerNetObject.Data.PlayerName} sent \"{data.Message}\"");
}
public override void Handle(PlayerControl innerNetObject, Data data)
{
Plugin.Log.LogWarning($"Handle: {innerNetObject.Data.PlayerName} sent \"{data.Message}\"");
}
}
+1 -5
View File
@@ -1,16 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<Version>0.1.0</Version>
<Description>Example mod using Reactor</Description>
<Authors>NuclearPowered</Authors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Reactor\Reactor.csproj" />
<ProjectReference Include="..\Reactor\Reactor.csproj" Private="false" />
</ItemGroup>
<Import Project="../AmongUs.props" />
+476 -64
View File
@@ -1,59 +1,73 @@
{
"version": 1,
"dependencies": {
".NETStandard,Version=v2.1": {
"net6.0": {
"AmongUs.GameLibs.Steam": {
"type": "Direct",
"requested": "[2022.8.23, )",
"resolved": "2022.8.23",
"contentHash": "baY5JO6dbdOAZ0VTtGX0xre6/BlDdreJDAH8boCKZt3JTAcn+eeH+l8mUZRC9eCJOODUik2C0TTAt5AqBmYtZg=="
"requested": "[2022.10.25, )",
"resolved": "2022.10.25",
"contentHash": "PWgkH/VvMlShVhZB8G432q0tnMaNVZrbIdbEMCZN/fETUlT/ch+qQj4PdTcZhPHREbnJHH3ijHxlca1d7QMBcQ=="
},
"BepInEx.AutoPlugin": {
"type": "Direct",
"requested": "[1.0.1, )",
"resolved": "1.0.1",
"contentHash": "G4YpTHG9rtkDJof+ld7Er4E+sCOlgsjG4bJ1itx1ub7dgff6qqHLy9ksX1ehgO0AdBOPVyVl/GKJg9o7iNl8HA=="
},
"BepInEx.IL2CPP": {
"type": "Direct",
"requested": "[6.0.0-be.570, )",
"resolved": "6.0.0-be.570",
"contentHash": "JGkWFFGZTWQ+YlFQ17izlwfGNUyo/zfFGNYPX6XAeTkfM5RwXiPYNMNO6eWoxbKwaYlAylQq2YCRkkCnAr9nwQ==",
"dependencies": {
"BepInEx.Core": "6.0.0-be.570",
"BepInEx.Il2Cpp.TlsAdapter": "1.0.1",
"HarmonyX": "2.10.0",
"Iced": "1.17.0",
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3",
"Il2CppAssemblyUnhollower.BaseLib.Legacy": "0.4.33.3",
"Il2CppAssemblyUnhollower.Lib": "0.4.33.3",
"Il2CppDumper": "6.6.4",
"MonoMod.RuntimeDetour": "22.5.1.1",
"Samboy063.Cpp2IL.Core": "2022.0.5"
}
"requested": "[1.1.0, )",
"resolved": "1.1.0",
"contentHash": "/7Nmc1EA9lYlGBiyz6qPAaHvlcJHEjFZ1RFpGX+8EBj3GrgoX5kbpnZusuSHoOlLx0l+CnzKuQNE54B8UaGPyw=="
},
"BepInEx.IL2CPP.MSBuild": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "uUSo4TuamyEIVg+ICNeJMSSW/arKWHGpfBFINc4fdF5kppfHFrsDURKzNPmDvxivtLsiuGthck9J/5uPXgIcTg=="
"requested": "[2.0.1, )",
"resolved": "2.0.1",
"contentHash": "hUZjCV0t8dkw/Z/zq4Zl405QP7frBk/LVfMdUmUz+7XOhGd7lYPKrR48A5vbGl2QeHudMxlkXzAr9WM3Duq2SQ=="
},
"BepInEx.Unity.IL2CPP": {
"type": "Direct",
"requested": "[6.0.0-be.662, )",
"resolved": "6.0.0-be.662",
"contentHash": "fn7jQ88IBmjssoY9XjGBTg3cULkS+N/le/eUijYf2VV8raWok/6cU/GbU9bejkJS8g+2MvzIwnROAhAxvrGI2Q==",
"dependencies": {
"BepInEx.Core": "6.0.0-be.662",
"BepInEx.Unity.Common": "6.0.0-be.662",
"HarmonyX": "2.10.0",
"Iced": "1.17.0",
"Il2CppInterop.Generator": "1.3.0",
"Il2CppInterop.HarmonySupport": "1.3.0",
"Il2CppInterop.Runtime": "1.3.0",
"MonoMod.RuntimeDetour": "22.5.1.1",
"Samboy063.Cpp2IL.Core": "2022.0.7.2"
}
},
"StyleCop.Analyzers": {
"type": "Direct",
"requested": "[1.2.0-beta.435, )",
"resolved": "1.2.0-beta.435",
"contentHash": "TADk7vdGXtfTnYCV7GyleaaRTQjfoSfZXprQrVMm7cSJtJbFc1QIbWPyLvrgrfGdfHbGmUPvaN4ODKNxg2jgPQ==",
"dependencies": {
"StyleCop.Analyzers.Unstable": "1.2.0.435"
}
},
"AssetRipper.VersionUtilities": {
"type": "Transitive",
"resolved": "1.2.1",
"contentHash": "knQ/W1YwTZS2AbdaZh+nhyyBEZQPQDcahhSOnh88i+cdg4/FEoFJiCwaavgFvCMNuUeHTbcZc4qttF8WQ8xLIA=="
},
"BepInEx.Core": {
"type": "Transitive",
"resolved": "6.0.0-be.570",
"contentHash": "kygIunLrK1HMGcRo2E/7e4ZEAA0xewuB/j5mPoMi7Xk58GUi43XnclBJHif9x05a55s0kFkfKOrpwIRmjd0cDw==",
"resolved": "6.0.0-be.662",
"contentHash": "VVBeCD/KQVy0/TK3V6SD8QZ/es35Xb1mEz/+PbBs3ST1yUC1r7k2JOymhSnmghVqf6UsvlMglOO9pljqhuE/Pw==",
"dependencies": {
"HarmonyX": "2.10.0",
"MonoMod.Utils": "22.3.23.4",
"MonoMod.Utils": "22.5.1.1",
"SemanticVersioning": "2.0.2"
}
},
"BepInEx.Il2Cpp.TlsAdapter": {
"BepInEx.Unity.Common": {
"type": "Transitive",
"resolved": "1.0.1",
"contentHash": "kTfX6312X0Fvwks+t7Ul3YO2jMSbqNS2Jx/85Cgl6lbAjEJnKzsmx7Krmd66dbnx0eY/QMjaV2r6LyWmQARtdA==",
"resolved": "6.0.0-be.662",
"contentHash": "BgETw6+snwY//3xjQxLiiEAFRmXaMTcSkg+1UQz6fVBG0YA5Usm/m4GflhTc3nwF61KO3Iznn1AORi5CwLJoUw==",
"dependencies": {
"HarmonyX": "2.3.1"
"AssetRipper.VersionUtilities": "1.2.1",
"MonoMod.Utils": "22.5.1.1"
}
},
"HarmonyX": {
@@ -70,38 +84,41 @@
"resolved": "1.17.0",
"contentHash": "8x+HCVTl/HHTGpscH3vMBhV8sknN/muZFw9s3TsI8SA6+c43cOTCi2+jE4KsU8pNLbJ++iF2ZFcpcXHXtDglnw=="
},
"Il2CppAssemblyUnhollower.BaseLib": {
"Il2CppInterop.Common": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "CH91M6Asz4iwennTa8cLg5wqROJY1JvnsfRetyOvs0cy8o/YAikvm8uuNgZv6UiTO/qoyy/QrBE1qSZDvs8bLw==",
"resolved": "1.3.0",
"contentHash": "IR3BrZXvL2nvJAn4pruPMgC78Y87hVa5xTYZCuHN67OzRD6WDl5dTO55vtvTl8dXFALKvlN+spja2tXhVuquOw==",
"dependencies": {
"Iced": "1.15.0"
"Iced": "1.17.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.1",
"System.Net.Http": "4.3.4"
}
},
"Il2CppAssemblyUnhollower.BaseLib.Legacy": {
"Il2CppInterop.Generator": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "6yIJg8lkayBDevPwcdcV3LWTdHt8VAZVY0wQwuXH4POOo0Kzc6Cshy9kLCxH3AC6EQg0G/v+Albs6RZgwszXMQ==",
"resolved": "1.3.0",
"contentHash": "FuhPxbh/K4K94U3xac/ClMaaBp+MZ4aIaqi5dR0QihyGQoombT+OM/A22RwAIzbaCTbFbvabWaAuOSgB69ZwWQ==",
"dependencies": {
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3"
}
},
"Il2CppAssemblyUnhollower.Lib": {
"type": "Transitive",
"resolved": "0.4.33.3",
"contentHash": "tdu4OnMxodkWwoImNDaycaLY1L3qJOazb5UaLAt1ncRpWyu6xvKuKe5NM6OcBXONpkYsJQeQZjD6syeFl5MCQA==",
"dependencies": {
"Il2CppAssemblyUnhollower.BaseLib": "0.4.33.3",
"Il2CppAssemblyUnhollower.BaseLib.Legacy": "0.4.33.3",
"Il2CppInterop.Common": "1.3.0",
"Mono.Cecil": "0.11.3"
}
},
"Il2CppDumper": {
"Il2CppInterop.HarmonySupport": {
"type": "Transitive",
"resolved": "6.6.4",
"contentHash": "aqjmlyigdZ5FS9ElMNlaCExlgSmAiho4BeIcVwkmzHGnomBzopjOCxqIX9vc/575TQ87TKoaGW2KP+3b5xI15A==",
"resolved": "1.3.0",
"contentHash": "VppBnXtbMNGFhX8a1gg/85E883t2pW/+FZyV7eOaOXMNQyorg++u+kUFOIYwNpzTVqxWmMeoPS0DH0toVpjoKA==",
"dependencies": {
"Mono.Cecil": "0.11.3"
"HarmonyX": "2.10.0",
"Il2CppInterop.Runtime": "1.3.0"
}
},
"Il2CppInterop.Runtime": {
"type": "Transitive",
"resolved": "1.3.0",
"contentHash": "8A+N2yvja960Ap+s2RpW7Nb6HSpyuXJy2ipIlU+1erYU9SWHMyU9JZzUZGOhwWXJChKGvRmDdTZAg12k1+72dg==",
"dependencies": {
"Iced": "1.17.0",
"Il2CppInterop.Common": "1.3.0"
}
},
"IndexRange": {
@@ -114,10 +131,37 @@
"resolved": "2.1.0",
"contentHash": "YYpq7NM50bSSVUDjXyV/eiITk6syXqItPjKBOb3jEWS6RFsk0DNhpWMPW6b3hKDmArARuWDU6S2pVu1IeVrvIA=="
},
"Linguini.Bundle": {
"type": "Transitive",
"resolved": "0.3.1",
"contentHash": "k3D0IBSsS91T0G9rYACRYtAS27NDTGz4T3ygHhbhaFdA9i3cCfCpR39MqYEpoA1Ark3lzmvklHePmRCX5EQi1A==",
"dependencies": {
"Linguini.Shared": "0.3.0",
"Linguini.Syntax": "0.3.0"
}
},
"Linguini.Shared": {
"type": "Transitive",
"resolved": "0.3.0",
"contentHash": "rEYA9jWU1Nc9iDuPKar+4IVXjFbGrcNyYZCeU6hiWQoS4nA2UecHu36Rp4bxzasvRGda4FB2JZqty75m4e26VQ=="
},
"Linguini.Syntax": {
"type": "Transitive",
"resolved": "0.3.0",
"contentHash": "v8YV3xPFZfP+OSWjMd6yysp+o7cNnQXxq/slN8Yekoi+dFjsTNF0YiQWJIwg1j2FUbs6claJxY9R1FFlc4s6MA==",
"dependencies": {
"Linguini.Shared": "0.3.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "6.0.1",
"contentHash": "dzB2Cgg+JmrouhjkcQGzSFjjvpwlq353i8oBQO2GWNjCXSzhbtBRUf28HSauWe7eib3wYOdb3tItdjRwAdwCSg=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
"resolved": "1.1.1",
"contentHash": "TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ=="
},
"Microsoft.NETCore.Targets": {
"type": "Transitive",
@@ -158,16 +202,114 @@
"System.Reflection.TypeExtensions": "4.7.0"
}
},
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "7VSGO0URRKoMEAq0Sc9cRz8mb6zbyx/BZDEWhgPdzzpmFhkam3fJ1DAGWFXBI4nGlma+uPKpfuMQP5LXRnOH5g=="
},
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "0oAaTAm6e2oVH+/Zttt0cuhGaePQYKII1dY8iaqP7CvOpVKgLybKRFvQjXR2LtxXOXTVPNv14j0ot8uV+HrUmw=="
},
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "G24ibsCNi5Kbz0oXWynBoRgtGvsw5ZSVEWjv13/KiCAM8C6wz9zzcCniMeQFIkJ2tasjo2kXlvlBZhplL51kGg=="
},
"runtime.native.System": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==",
"dependencies": {
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0"
}
},
"runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "QR1OwtwehHxSeQvZKXe+iSd+d3XZNkEcuWMFYa2i0aG1l+lR739HPicKMlTbJst3spmeekDVBUS7SeS26s4U/g==",
"dependencies": {
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2",
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
}
},
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "I+GNKGg2xCHueRd1m9PzeEW7WLbNNLznmTuEi8/vZX71HudUbx1UTwlGkiwMri7JLl8hGaIAWnA/GONhu+LOyQ=="
},
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "1Z3TAq1ytS1IBRtPXJvEUZdVsfWfeNEhBkbiOCGEl9wwAfsjP2lz3ZFDx5tq8p60/EqbS0HItG5piHuB71RjoA=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ=="
},
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "6mU/cVmmHtQiDXhnzUImxIcDL48GbTk+TsptXyJA+MIOG9LRjPoAQC/qBFB7X+UNyK86bmvGwC8t+M66wsYC8w=="
},
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "vjwG0GGcTW/PPg6KVud8F9GLWYuAV1rrw1BKAqY0oh4jcUqg15oYF1+qkGR2x2ZHM4DQnWKQ7cJgYbfncz/lYg=="
},
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "7KMFpTkHC/zoExs+PwP8jDCWcrK9H6L7soowT80CUx3e+nxP/AFnq0AQAW5W76z2WYbLAYCRyPfwYFG6zkvQRw=="
},
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "xrlmRCnKZJLHxyyLIqkZjNXqgxnKdZxfItrPkjI+6pkRo5lHX8YvSZlWrSI5AVwLMi4HbNWP7064hcAWeZKp5w=="
},
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.2",
"contentHash": "leXiwfiIkW7Gmn7cgnNcdtNAU70SjmKW3jxGj1iKHOvdn0zRWsgv/l2OJUO5zdGdiv2VRFnAsxxhDgMzofPdWg=="
},
"Samboy063.Cpp2IL.Core": {
"type": "Transitive",
"resolved": "2022.0.5",
"contentHash": "5JipfyEmJWePqLLnvwzxWx9dQXxNfgN0wcZ4IcmuabWKVvk4gA5Rux4vgDh9NrWf8q9LzkizWHkrnMaG1niF7g==",
"resolved": "2022.0.7.2",
"contentHash": "e17CAhKSxdAp7vFcYEVxjSc7t7rcvVGBipGhgE9tAjRXY85wZXLlHEVO0AEvMRkLmf9U+if4wK/nZEC1AX6VqQ==",
"dependencies": {
"HarmonyX": "2.5.5",
"Iced": "1.11.1",
"IndexRange": "1.0.0",
"Mono.Cecil": "0.11.4",
"Samboy063.LibCpp2IL": "2022.0.5",
"Samboy063.LibCpp2IL": "2022.0.7.2",
"System.Runtime.InteropServices": "4.3.0",
"System.ValueTuple": "4.5.0",
"js6pak.Gee.External.Capstone": "2.1.0"
@@ -175,8 +317,8 @@
},
"Samboy063.LibCpp2IL": {
"type": "Transitive",
"resolved": "2022.0.5",
"contentHash": "eH+/FBclsKDxboa9N/tFoiM8kwvietVX0FtXYxvcexSp/geYCyTt2XUGOQjinqd3Yqg/QxmpIqBO7qy4MQHrhw==",
"resolved": "2022.0.7.2",
"contentHash": "DpVeU0dQkUJCpbw0f1xKOG8vimdK2oYhrVABC7HDE3/ikGjhnMZd3i5b1joKDHZ+AiL90TWOaEXPcy24rCZ0dA==",
"dependencies": {
"IndexRange": "1.0.0",
"Samboy063.WasmDisassembler": "2022.0.2"
@@ -192,6 +334,11 @@
"resolved": "2.0.2",
"contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA=="
},
"StyleCop.Analyzers.Unstable": {
"type": "Transitive",
"resolved": "1.2.0.435",
"contentHash": "ouwPWZxbOV3SmCZxIRqHvljkSzkCyi1tDoMzQtDb/bRP8ctASV/iRJr+A2Gdj0QLaLmWnqTWDrH82/iP+X80Lg=="
},
"System.Collections": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -202,6 +349,23 @@
"System.Runtime": "4.3.0"
}
},
"System.Collections.Concurrent": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Collections.NonGeneric": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -279,6 +443,28 @@
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.DiagnosticSource": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==",
"dependencies": {
"System.Collections": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Reflection": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Diagnostics.Tracing": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -289,6 +475,17 @@
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Calendars": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Globalization": "4.3.0",
"System.Runtime": "4.3.0"
}
},
"System.Globalization.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -314,6 +511,21 @@
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.IO": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.IO.FileSystem.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -334,6 +546,50 @@
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Net.Http": {
"type": "Transitive",
"resolved": "4.3.4",
"contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.1",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.DiagnosticSource": "4.3.0",
"System.Diagnostics.Tracing": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Extensions": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.Net.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Security.Cryptography.X509Certificates": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.2"
}
},
"System.Net.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Runtime": "4.3.0",
"System.Runtime.Handles": "4.3.0"
}
},
"System.Reflection": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -441,6 +697,161 @@
"System.Runtime.Handles": "4.3.0"
}
},
"System.Runtime.Numerics": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==",
"dependencies": {
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0"
}
},
"System.Security.Cryptography.Algorithms": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.Apple": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Cng": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0"
}
},
"System.Security.Cryptography.Csp": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.IO": "4.3.0",
"System.Reflection": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0"
}
},
"System.Security.Cryptography.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Collections.Concurrent": "4.3.0",
"System.Linq": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.OpenSsl": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==",
"dependencies": {
"System.Collections": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Security.Cryptography.Primitives": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==",
"dependencies": {
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.IO": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Threading": "4.3.0",
"System.Threading.Tasks": "4.3.0"
}
},
"System.Security.Cryptography.X509Certificates": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Globalization.Calendars": "4.3.0",
"System.IO": "4.3.0",
"System.IO.FileSystem": "4.3.0",
"System.IO.FileSystem.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Runtime.Handles": "4.3.0",
"System.Runtime.InteropServices": "4.3.0",
"System.Runtime.Numerics": "4.3.0",
"System.Security.Cryptography.Algorithms": "4.3.0",
"System.Security.Cryptography.Cng": "4.3.0",
"System.Security.Cryptography.Csp": "4.3.0",
"System.Security.Cryptography.Encoding": "4.3.0",
"System.Security.Cryptography.OpenSsl": "4.3.0",
"System.Security.Cryptography.Primitives": "4.3.0",
"System.Text.Encoding": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0",
"runtime.native.System.Net.Http": "4.3.0",
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
}
},
"System.Text.Encoding": {
"type": "Transitive",
"resolved": "4.3.0",
@@ -478,7 +889,8 @@
"reactor": {
"type": "Project",
"dependencies": {
"BepInEx.IL2CPP": "6.0.0-be.570"
"BepInEx.Unity.IL2CPP": "[6.0.0-be.662, )",
"Linguini.Bundle": "[0.3.1, )"
}
}
}
@@ -0,0 +1,36 @@
using System.Text;
using System.Text.RegularExpressions;
using Linguini.Syntax.Ast;
namespace Reactor.Linguinitor;
internal static class FluentCommentParser
{
private static readonly Regex _variableCommentRegex = new(@"^\$(?<id>[\w-]+) \((?<type>String|Number|Date)\)( - (?<description>.+))?$", RegexOptions.Compiled);
public static MessageInfo Parse(AstComment astComment)
{
var descriptionBuilder = new StringBuilder();
var variables = new Dictionary<string, VariableInfo>();
foreach (var s in astComment.AsStr().Split("\n"))
{
var line = s.Trim();
if (_variableCommentRegex.Match(line) is { Success: true } match)
{
variables.Add(match.Groups["id"].Value, new VariableInfo(match.Groups["type"].Value, match.Groups["description"].Value));
}
else
{
descriptionBuilder.AppendLine(line);
}
}
return new MessageInfo(descriptionBuilder.ToString(), variables);
}
public record MessageInfo(string Description, Dictionary<string, VariableInfo> Variables);
public record VariableInfo(string Type, string? Description);
}
+166
View File
@@ -0,0 +1,166 @@
using CSharpPoet;
using Linguini.Syntax.Ast;
using Linguini.Syntax.Parser;
using Microsoft.CodeAnalysis;
namespace Reactor.Linguinitor;
[Generator(LanguageNames.CSharp)]
public class LinguinitorGenerator : IIncrementalGenerator
{
private static CSharpFile CreateTranslateFile(string @namespace, params CSharpType.IMember[] members)
{
return new CSharpFile(@namespace)
{
new CSharpClass(Visibility.Internal, "Translate")
{
IsStatic = true,
IsPartial = true,
Members = members,
},
};
}
private static IEnumerable<Identifier> GetVariables(AstMessage astMessage)
{
foreach (var placeable in astMessage.Value!.Elements.OfType<Placeable>())
{
switch (placeable.Expression)
{
case VariableReference variableReference:
yield return variableReference.Id;
break;
}
}
}
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var rootNamespaceProvider =
context.AnalyzerConfigOptionsProvider
.Select((options, _) => options.GlobalOptions.TryGetValue("build_property.RootNamespace", out var rootNamespace) ? rootNamespace : throw new InvalidOperationException("Failed to get RootNamespace"));
context.RegisterSourceOutput(rootNamespaceProvider, (spc, rootNamespace) =>
{
const string ProviderType = "Reactor.Localization.Providers.FluentLocalizationProvider";
spc.AddSource("Translate", CreateTranslateFile(
rootNamespace,
new CSharpField(Visibility.Private, ProviderType + "?", "_provider") { IsStatic = true },
new CSharpProperty(ProviderType, "Provider")
{
IsStatic = true,
Getter = new CSharpProperty.Accessor
{
Body = writer => writer.Write("_provider ?? throw new System.InvalidOperationException(\"Provider must be set before using Translate\");"),
},
Setter = new CSharpProperty.Accessor
{
Body = writer => writer.Write("_provider = value;"),
},
}
).ToString());
});
var textFiles = context.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".ftl", StringComparison.Ordinal));
var namesAndContents = textFiles.Select((text, cancellationToken) => (
Name: Path.GetFileNameWithoutExtension(text.Path),
Content: text.GetText(cancellationToken)!.ToString()
));
context.RegisterSourceOutput(namesAndContents.Combine(rootNamespaceProvider), (spc, pair) =>
{
var ((name, content), rootNamespace) = pair;
var fixedName = name.ToPascalCase();
var idsClass = new CSharpClass("Ids")
{
IsStatic = true,
};
var fileClass = new CSharpClass(fixedName)
{
IsStatic = true,
Members = { idsClass },
};
var resource = new LinguiniParser(content).ParseWithComments();
foreach (var message in resource.Entries.OfType<AstMessage>())
{
var id = message.GetId();
var fixedId = id.ToPascalCase();
idsClass.Members.Add(new CSharpField(Visibility.Public, "string", fixedId)
{
IsConst = true,
DefaultValue = $"\"{id}\"",
});
var messageInfo = message.Comment != null ? FluentCommentParser.Parse(message.Comment) : null;
var variables = GetVariables(message).Select(m => m.ToString()).ToDictionary(
m => m,
m =>
{
if (messageInfo != null && messageInfo.Variables.TryGetValue(m, out var variableInfo))
{
return variableInfo.Type switch
{
"String" => "string",
"Number" => "double",
_ => throw new NotSupportedException($"Variable type {variableInfo.Type} is not supported"),
};
}
return "string";
}
);
void WriteComment(CodeWriter writer)
{
if (messageInfo == null) return;
writer.WriteLine("<summary>");
foreach (var line in messageInfo.Description.Trim().Split("\n"))
{
writer.WriteLine(line);
}
writer.WriteLine("</summary>");
foreach (var (variableId, info) in messageInfo.Variables)
{
writer.WriteLine($"<param name=\"{variableId}\">{info.Description}</param>");
}
}
if (variables.Count <= 0)
{
fileClass.Members.Add(new CSharpProperty("string", fixedId)
{
XmlComment = WriteComment,
IsStatic = true,
Getter = new CSharpProperty.Accessor
{
Body = writer => writer.Write($"Provider.GetText(Ids.{fixedId});"),
},
});
}
else
{
fileClass.Members.Add(new CSharpMethod("string", fixedId)
{
XmlComment = WriteComment,
IsStatic = true,
Parameters = variables.Select(v => new CSharpParameter(v.Value, v.Key)).ToArray(),
BodyType = BodyType.Expression,
Body = writer => writer.WriteLine($"Provider.GetText(Ids.{fixedId}, {string.Join(", ", variables.Select(v => $"(\"{v.Key}\", {v.Key.ToCamelCase()})"))});"),
});
}
}
spc.AddSource("Translate." + fixedName, CreateTranslateFile(rootNamespace, fileClass).ToString());
});
}
}
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net472</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CSharpPoet" Version="0.2.0-dev" Private="true" GeneratePathProperty="true" />
<PackageReference Include="Linguini.Shared" Version="0.3.0" Private="true" GeneratePathProperty="true" />
<PackageReference Include="Linguini.Syntax" Version="0.3.0" Private="true" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" PrivateAssets="all" />
</ItemGroup>
<PropertyGroup>
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>
<Target Name="GetDependencyTargetPaths">
<PropertyGroup>
<_LinguiniTargetFramework Condition="'$(TargetFramework)' == 'net6.0'">netstandard2.1</_LinguiniTargetFramework>
<_LinguiniTargetFramework Condition="'$(TargetFramework)' == 'net472'">net451</_LinguiniTargetFramework>
</PropertyGroup>
<ItemGroup>
<TargetPathWithTargetPlatformMoniker Include="$(PkgCSharpPoet)\lib\netstandard2.0\CSharpPoet.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PkgLinguini_Shared)\lib\$(_LinguiniTargetFramework)\Linguini.Shared.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PkgLinguini_Syntax)\lib\$(_LinguiniTargetFramework)\Linguini.Syntax.dll" IncludeRuntimeDependency="false" />
</ItemGroup>
</Target>
</Project>
+38
View File
@@ -0,0 +1,38 @@
using System.Text;
namespace Reactor.Linguinitor;
internal static class StringExtensions
{
private static string ToCase(this string value, bool capitalizeFirst)
{
var stringBuilder = new StringBuilder();
for (var i = 0; i < value.Length; i++)
{
var c = value[i];
if (c == '-')
{
i++;
stringBuilder.Append(char.ToUpperInvariant(value[i]));
}
else
{
stringBuilder.Append(capitalizeFirst && i == 0 ? char.ToUpperInvariant(c) : c);
}
}
return stringBuilder.ToString();
}
public static string ToPascalCase(this string value)
{
return value.ToCase(true);
}
public static string ToCamelCase(this string value)
{
return value.ToCase(false);
}
}
+105
View File
@@ -0,0 +1,105 @@
{
"version": 1,
"dependencies": {
"net6.0": {
"CSharpPoet": {
"type": "Direct",
"requested": "[0.2.0-dev, )",
"resolved": "0.2.0-dev"
},
"Linguini.Shared": {
"type": "Direct",
"requested": "[0.3.0, )",
"resolved": "0.3.0",
"contentHash": "rEYA9jWU1Nc9iDuPKar+4IVXjFbGrcNyYZCeU6hiWQoS4nA2UecHu36Rp4bxzasvRGda4FB2JZqty75m4e26VQ=="
},
"Linguini.Syntax": {
"type": "Direct",
"requested": "[0.3.0, )",
"resolved": "0.3.0",
"contentHash": "v8YV3xPFZfP+OSWjMd6yysp+o7cNnQXxq/slN8Yekoi+dFjsTNF0YiQWJIwg1j2FUbs6claJxY9R1FFlc4s6MA==",
"dependencies": {
"Linguini.Shared": "0.3.0"
}
},
"Microsoft.CodeAnalysis.CSharp": {
"type": "Direct",
"requested": "[4.3.1, )",
"resolved": "4.3.1",
"contentHash": "5C9VHvahL98tumlyaT/loB5rW+K/6q0UU7uLyT1Dv15YjZraRkqML9u2t2e8GaO7XqEOtBVqK/SlxXOPqwzxog==",
"dependencies": {
"Microsoft.CodeAnalysis.Common": "[4.3.1]"
}
},
"StyleCop.Analyzers": {
"type": "Direct",
"requested": "[1.2.0-beta.435, )",
"resolved": "1.2.0-beta.435",
"contentHash": "TADk7vdGXtfTnYCV7GyleaaRTQjfoSfZXprQrVMm7cSJtJbFc1QIbWPyLvrgrfGdfHbGmUPvaN4ODKNxg2jgPQ==",
"dependencies": {
"StyleCop.Analyzers.Unstable": "1.2.0.435"
}
},
"Microsoft.CodeAnalysis.Analyzers": {
"type": "Transitive",
"resolved": "3.3.3",
"contentHash": "j/rOZtLMVJjrfLRlAMckJLPW/1rze9MT1yfWqSIbUPGRu1m1P0fuo9PmqapwsmePfGB5PJrudQLvmUOAMF0DqQ=="
},
"Microsoft.CodeAnalysis.Common": {
"type": "Transitive",
"resolved": "4.3.1",
"contentHash": "wexpJffSEEwptwe6UTMxRDZCCtz+XubI4Qewl4JECnNhcQrtb0anhSUEV9Nz7WkoNfWkx1fptR8xh1egoxYrqw==",
"dependencies": {
"Microsoft.CodeAnalysis.Analyzers": "3.3.3",
"System.Collections.Immutable": "6.0.0",
"System.Memory": "4.5.4",
"System.Reflection.Metadata": "5.0.0",
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encoding.CodePages": "6.0.0",
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"StyleCop.Analyzers.Unstable": {
"type": "Transitive",
"resolved": "1.2.0.435",
"contentHash": "ouwPWZxbOV3SmCZxIRqHvljkSzkCyi1tDoMzQtDb/bRP8ctASV/iRJr+A2Gdj0QLaLmWnqTWDrH82/iP+X80Lg=="
},
"System.Collections.Immutable": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw=="
},
"System.Reflection.Metadata": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
},
"System.Text.Encoding.CodePages": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
}
}
}
}
+122
View File
@@ -0,0 +1,122 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
namespace Reactor.Networking;
/// <summary>
/// Represents a Reactor.Protocol mod.
/// </summary>
public readonly struct Mod : IEquatable<Mod>
{
/// <summary>
/// Initializes a new instance of the <see cref="Mod"/> struct.
/// </summary>
/// <param name="id">The id of the mod.</param>
/// <param name="version">The version of the mod.</param>
/// <param name="flags">The flags of the mod.</param>
/// <param name="name">The name of the mod.</param>
public Mod(string id, string version, ModFlags flags, string? name = null)
{
Id = id;
Version = version;
Flags = flags;
Name = name;
}
/// <summary>
/// Gets the id of the mod.
/// </summary>
public string Id { get; }
/// <summary>
/// Gets the version of the mod.
/// </summary>
public string Version { get; }
/// <summary>
/// Gets the flags of the mod.
/// </summary>
public ModFlags Flags { get; }
/// <summary>
/// Gets the name of the mod.
/// </summary>
public string? Name { get; }
/// <summary>
/// Gets a value indicating whether the mod is required on all clients.
/// </summary>
public bool IsRequiredOnAllClients => (Flags & ModFlags.RequireOnAllClients) != 0;
/// <inheritdoc />
public bool Equals(Mod other)
{
return Id == other.Id && Version == other.Version;
}
/// <inheritdoc />
public override bool Equals(object? obj)
{
return obj is Mod other && Equals(other);
}
/// <inheritdoc />
public static bool operator ==(Mod left, Mod right)
{
return left.Equals(right);
}
/// <inheritdoc />
public static bool operator !=(Mod left, Mod right)
{
return !(left == right);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Id, Version);
}
/// <inheritdoc />
public override string ToString()
{
return $"{Name ?? Id} ({Version})";
}
internal static bool Validate(IReadOnlyCollection<Mod> clientMods, IReadOnlyCollection<Mod> hostMods, [NotNullWhen(false)] out string? reason)
{
var clientMissing = hostMods.Where(mod => mod.IsRequiredOnAllClients && !clientMods.Contains(mod)).ToArray();
var hostMissing = clientMods.Where(mod => mod.IsRequiredOnAllClients && !hostMods.Contains(mod)).ToArray();
if (clientMissing.Any() || hostMissing.Any())
{
var message = new StringBuilder();
if (clientMissing.Any())
{
message.Append("You are missing: ");
message.AppendJoin(", ", clientMissing.Select(x => x.ToString()));
message.AppendLine();
}
if (hostMissing.Any())
{
message.Append("Host is missing: ");
message.AppendJoin(", ", hostMissing.Select(x => x.ToString()));
message.AppendLine();
}
reason = message.ToString();
return false;
}
reason = null;
return true;
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
namespace Reactor.Networking;
/// <summary>
/// Represents flags of the mod.
/// </summary>
[Flags]
public enum ModFlags : ushort
{
/// <summary>
/// No flags.
/// </summary>
None = 0,
/// <summary>
/// Requires all clients in a lobby to have the mod.
/// </summary>
RequireOnAllClients = 1 << 0,
/// <summary>
/// Requires the server to have a plugin that handles the mod.
/// </summary>
RequireOnServer = 1 << 1,
/// <summary>
/// Requires the host of the lobby to have the mod.
/// </summary>
RequireOnHost = 1 << 2,
}
@@ -0,0 +1,35 @@
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Reactor.Networking</RootNamespace>
<Description>Shared sources for Reactor.Networking (Reactor and Reactor.Impostor)</Description>
<ContentTargetFolders>contentFiles</ContentTargetFolders>
<IsPackable>true</IsPackable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<NoBuild>true</NoBuild>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Update="@(Compile)">
<Pack>true</Pack>
<PackagePath>$(ContentTargetFolders)\cs\any\$(PackageId)\%(RecursiveDir)\</PackagePath>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Remove="@(PackageReference)" />
</ItemGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Target Name="CopyFilesToOutputDirectory" />
</Project>
@@ -0,0 +1,12 @@
namespace Reactor.Networking;
/// <summary>
/// Represents a GameData flag for Reactor messages.
/// </summary>
public enum ReactorGameDataFlag : byte
{
/// <summary>
/// KickWithReason GameData message.
/// </summary>
SetKickReason,
}
@@ -0,0 +1,12 @@
namespace Reactor.Networking;
/// <summary>
/// Represents a message flag for Reactor messages.
/// </summary>
public enum ReactorMessageFlags : byte
{
/// <summary>
/// Handshake message.
/// </summary>
Handshake,
}
@@ -0,0 +1,22 @@
namespace Reactor.Networking;
/// <summary>
/// Version of the Reactor.Networking protocol format.
/// </summary>
public enum ReactorProtocolVersion : byte
{
/// <summary>
/// First public Reactor Protocol version.
/// </summary>
V2 = 1,
/// <summary>
/// Version introducing vanilla server support, syncer concept and registries.
/// </summary>
V3 = 2,
/// <summary>
/// Latest version.
/// </summary>
Latest = V3,
}
@@ -0,0 +1,6 @@
{
"version": 1,
"dependencies": {
"net6.0": {}
}
}
-40
View File
@@ -1,40 +0,0 @@
#nullable enable
using System;
namespace Reactor.Networking
{
public class Mod
{
public Mod(uint netId, string id, string version, PluginSide side)
{
NetId = netId;
Id = id;
Version = version;
Side = side;
}
public uint NetId { get; }
public string Id { get; }
public string Version { get; }
public PluginSide Side { get; }
protected bool Equals(Mod other)
{
return Id == other.Id && Version == other.Version;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Mod) obj);
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Version);
}
}
}
@@ -1,9 +0,0 @@
namespace Reactor.Networking
{
public enum ReactorMessageFlags : byte
{
Handshake,
ModDeclaration,
PluginDeclaration
}
}
@@ -1,18 +0,0 @@
namespace Reactor.Networking
{
/// <summary>
/// Version of the Reactor.Net protocol format.
/// </summary>
public enum ReactorProtocolVersion : byte
{
/// <summary>
/// Initial version.
/// </summary>
Initial = 1,
/// <summary>
/// Latest version.
/// </summary>
Latest = Initial,
}
}
-18
View File
@@ -1,18 +0,0 @@
namespace Reactor
{
/// <summary>
/// Plugin side used in modded handshake
/// </summary>
public enum PluginSide : byte
{
/// <summary>
/// Required by both sides, reject connection if missing on the other side
/// </summary>
Both,
/// <summary>
/// Required only by client
/// </summary>
ClientOnly
}
}
-5
View File
@@ -1,5 +0,0 @@
<Project>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)**\*.cs" />
</ItemGroup>
</Project>
-3
View File
@@ -1,3 +0,0 @@
<Project>
<Import Project="Reactor.Shared.projitems" Label="Shared" />
</Project>
+26 -1
View File
@@ -5,7 +5,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Debugger", "Reactor
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Example", "Reactor.Example\Reactor.Example.csproj", "{26A83466-26FE-4383-A35C-B8629902F909}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Reactor.Shared", "Reactor.Shared\Reactor.Shared.shproj", "{8C1EEFE9-EF8A-47C4-810E-6D9BA1E7218B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Benchmarks", "Reactor.Benchmarks\Reactor.Benchmarks.csproj", "{99B87307-3AEB-4A6A-BF45-871768308FDD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution Files", "{4BBF0A80-F6E6-4FDD-ADD0-8CB4F28F88A4}"
ProjectSection(SolutionItems) = preProject
AmongUs.props = AmongUs.props
Directory.Build.props = Directory.Build.props
nuget.config = nuget.config
stylecop.json = stylecop.json
stylecop.ruleset = stylecop.ruleset
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Networking.Shared", "Reactor.Networking.Shared\Reactor.Networking.Shared.csproj", "{1E68CA20-22EB-4E57-B525-81970BE6363D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Linguinitor", "Reactor.Linguinitor\Reactor.Linguinitor.csproj", "{B4740F75-B657-4515-A8F6-8A84D64E8814}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,6 +38,18 @@ Global
{26A83466-26FE-4383-A35C-B8629902F909}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26A83466-26FE-4383-A35C-B8629902F909}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26A83466-26FE-4383-A35C-B8629902F909}.Release|Any CPU.Build.0 = Release|Any CPU
{99B87307-3AEB-4A6A-BF45-871768308FDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99B87307-3AEB-4A6A-BF45-871768308FDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99B87307-3AEB-4A6A-BF45-871768308FDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99B87307-3AEB-4A6A-BF45-871768308FDD}.Release|Any CPU.Build.0 = Release|Any CPU
{1E68CA20-22EB-4E57-B525-81970BE6363D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E68CA20-22EB-4E57-B525-81970BE6363D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E68CA20-22EB-4E57-B525-81970BE6363D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E68CA20-22EB-4E57-B525-81970BE6363D}.Release|Any CPU.Build.0 = Release|Any CPU
{B4740F75-B657-4515-A8F6-8A84D64E8814}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4740F75-B657-4515-A8F6-8A84D64E8814}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4740F75-B657-4515-A8F6-8A84D64E8814}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4740F75-B657-4515-A8F6-8A84D64E8814}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
@@ -0,0 +1,10 @@
-for-more-info-see = For more info see https://reactor.gg/handshake
vanilla-server-warning =
This server doesn't support Reactor protocol.
The lobbies shown may not be compatible with your current mods.
{ -for-more-info-see }
public-lobby-warning =
You can't make public lobbies on servers that don't support Reactor protocol.
{ -for-more-info-see }
@@ -0,0 +1,10 @@
-for-more-info-see = Voor meer informatie, zie https://reactor.gg/handshake
vanilla-server-warning =
Deze server ondersteunt het Reactor protocol niet.
De lobbies die je ziet passen mogelijk niet bij jouw huidige mods.
{ -for-more-info-see }
public-lobby-warning =
Je kan geen publieke lobbies maken op servers die het Reactor protocol niet ondersteunen.
{ -for-more-info-see }
@@ -0,0 +1,10 @@
-for-more-info-see = Dla więcej informacji, zobacz https://reactor.gg/handshake
vanilla-server-warning =
Ten serwer nie wspiera protokołu Reactor.
Pokazane gry mogą nie być kompatibline z twoimi modami.
{ -for-more-info-see }
public-lobby-warning =
Nie możesz tworzyć publicznych gier w serwerach, które nie wspierają protokołu Reactor.
{ -for-more-info-see }
Binary file not shown.
Binary file not shown.
Binary file not shown.
-34
View File
@@ -1,34 +0,0 @@
using System.Collections.Generic;
using System.Reflection.Emit;
using BepInEx.IL2CPP;
using HarmonyLib;
namespace Reactor
{
public static class ChainloaderHooks
{
public delegate void PluginLoadHandler(BasePlugin plugin);
public static event PluginLoadHandler? PluginLoad;
internal static void OnPluginLoad(BasePlugin plugin)
{
PluginLoad?.Invoke(plugin);
}
[HarmonyPatch(typeof(IL2CPPChainloader), nameof(IL2CPPChainloader.LoadPlugin))]
private static class LoadPluginPatch
{
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return new CodeMatcher(instructions)
.MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BasePlugin), nameof(BasePlugin.Load))))
.Insert(
new CodeInstruction(OpCodes.Dup),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ChainloaderHooks), nameof(OnPluginLoad)))
)
.InstructionEnumeration();
}
}
}
}
+13
View File
@@ -0,0 +1,13 @@
// ReSharper disable CheckNamespace
namespace System.Runtime.CompilerServices;
/// <summary>
/// This attribute is required by the compiler for the "unmanaged" generic type constraint.
/// It should be generated automatically, but for whatever reason its not.
/// </summary>
[Obsolete("Do not use directly.", true)]
[AttributeUsage(AttributeTargets.All)]
internal sealed class IsUnmanagedAttribute : Attribute
{
}
-53
View File
@@ -1,53 +0,0 @@
using System;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using BepInEx.IL2CPP.Utils;
using UnityEngine;
namespace Reactor
{
public static class Coroutines
{
[RegisterInIl2Cpp]
internal class Component : MonoBehaviour
{
internal static Component? Instance { get; set; }
public Component(IntPtr ptr) : base(ptr)
{
}
private void Awake()
{
Instance = this;
}
private void OnDestroy()
{
Instance = null;
}
}
private static readonly ConditionalWeakTable<IEnumerator, Coroutine> _ourCoroutineStore = new();
[return: NotNullIfNotNull("routine")]
public static IEnumerator? Start(IEnumerator? routine)
{
if (routine != null)
{
_ourCoroutineStore.AddOrUpdate(routine, Component.Instance!.StartCoroutine(routine));
}
return routine;
}
public static void Stop(IEnumerator? enumerator)
{
if (enumerator != null && _ourCoroutineStore.TryGetValue(enumerator, out var routine))
{
Component.Instance!.StopCoroutine(routine);
}
}
}
}
-54
View File
@@ -1,54 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using UnhollowerBaseLib;
namespace Reactor
{
public class CustomStringName
{
private static int _lastId = -1;
private static readonly List<CustomStringName> _list = new List<CustomStringName>();
public static IReadOnlyList<CustomStringName> List => _list.AsReadOnly();
public static CustomStringName Register(string value)
{
var customStringName = new CustomStringName(_lastId--, value);
_list.Add(customStringName);
return customStringName;
}
public int Id { get; }
public string Value { get; }
private CustomStringName(int id, string value)
{
Id = id;
Value = value;
}
public static implicit operator StringNames(CustomStringName name) => (StringNames) name.Id;
public static explicit operator CustomStringName?(StringNames name) => List.SingleOrDefault(x => x.Id == (int) name);
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(StringNames), typeof(Il2CppReferenceArray<Il2CppSystem.Object>))]
private static class GetStringPatch
{
public static bool Prefix(StringNames id, Il2CppReferenceArray<Il2CppSystem.Object> parts, ref string __result)
{
var customStringName = (CustomStringName?) id;
if (customStringName != null)
{
__result = string.Format(customStringName.Value, parts);
return false;
}
return true;
}
}
}
}
-123
View File
@@ -1,123 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using Il2CppType = UnhollowerRuntimeLib.Il2CppType;
namespace Reactor.Extensions
{
/// <summary>
/// General utilities
/// </summary>
public static class Extensions
{
/// <summary>
/// Adds a delegate to get one notification when a scene has loaded.
/// </summary>
public static void once_sceneLoaded(Action<Scene, LoadSceneMode> value)
{
UnityAction<Scene, LoadSceneMode>? unityAction = null;
unityAction = (Action<Scene, LoadSceneMode>) ((scene, loadMode) =>
{
SceneManager.remove_sceneLoaded(unityAction);
value.Invoke(scene, loadMode);
});
SceneManager.add_sceneLoaded(unityAction);
}
/// <summary>
/// Returns random <typeparamref name="T"/> from <paramref name="input"/>
/// </summary>
public static T? Random<T>(this IEnumerable<T> input)
{
var list = input as IList<T> ?? input.ToList();
return list.Count == 0 ? default : list[UnityEngine.Random.Range(0, list.Count)];
}
/// <summary>
/// Returns the color as a hexadecimal string in the format "RRGGBBAA".
/// </summary>
/// <param name="color">The color to be converted.</param>
/// <returns>Hexadecimal string representing the color.</returns>
/// <remarks>https://docs.unity3d.com/ScriptReference/ColorUtility.ToHtmlStringRGBA.html</remarks>
public static string ToHtmlStringRGBA(this Color32 color)
{
return $"{color.r:X2}{color.g:X2}{color.b:X2}{color.a:X2}";
}
/// <inheritdoc cref="ToHtmlStringRGBA(UnityEngine.Color32)"/>
public static string ToHtmlStringRGBA(this Color color)
{
return ((Color32) color).ToHtmlStringRGBA();
}
/// <summary>
/// Fully read <paramref name="input"/> stream, can be used as workaround for il2cpp streams.
/// </summary>
public static byte[] ReadFully(this Stream input)
{
using (var ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
/// <summary>
/// Sends <see cref="UnityWebRequest"/> and return task that finishes on <paramref name="request"/> completion.
/// </summary>
public static Task SendAsync(this UnityWebRequest request)
{
var task = new TaskCompletionSource<object?>();
request.Send().m_completeCallback = (Action<AsyncOperation>) (_ =>
{
task.SetResult(null);
});
return task.Task;
}
private static readonly int _outline = Shader.PropertyToID("_Outline");
private static readonly int _outlineColor = Shader.PropertyToID("_OutlineColor");
private static readonly int _addColor = Shader.PropertyToID("_AddColor");
/// <summary>
/// Sets color outline for renderers using default Among Us shader
/// </summary>
public static void SetOutline(this Renderer renderer, Color? color)
{
renderer.material.SetFloat(_outline, color.HasValue ? 1 : 0);
if (color.HasValue)
{
renderer.material.SetColor(_outlineColor, color.Value);
renderer.material.SetColor(_addColor, color.Value);
}
}
public static IEnumerable<MethodBase> GetMethods(this Type type, BindingFlags bindingAttr, Type returnType, params Type[] parameterTypes)
{
return type.GetMethods(bindingAttr).Where(x => x.ReturnType == returnType && x.GetParameters().Select(x => x.ParameterType).SequenceEqual(parameterTypes));
}
public static IEnumerable<MethodBase> GetMethods(this Type type, Type returnType, params Type[] parameterTypes)
{
return type.GetMethods(AccessTools.all, returnType, parameterTypes);
}
public static T? LoadAsset<T>(this AssetBundle assetBundle, string name) where T : UnityEngine.Object
{
return assetBundle.LoadAsset(name, Il2CppType.Of<T>())?.Cast<T>();
}
}
}
@@ -1,49 +0,0 @@
using System;
using Hazel;
using Hazel.Udp;
using UnityEngine;
namespace Reactor.Extensions
{
public static class ExtraMessageExtensions
{
private const float MIN = -50f;
private const float MAX = 50f;
private static float ReverseLerp(float t)
{
return Mathf.Clamp((t - MIN) / (MAX - MIN), 0f, 1f);
}
public static void Write(this MessageWriter writer, Vector2 value)
{
var x = (ushort) (ReverseLerp(value.x) * ushort.MaxValue);
var y = (ushort) (ReverseLerp(value.y) * ushort.MaxValue);
writer.Write(x);
writer.Write(y);
}
public static Vector2 ReadVector2(this MessageReader reader)
{
var x = reader.ReadUInt16() / (float) ushort.MaxValue;
var y = reader.ReadUInt16() / (float) ushort.MaxValue;
return new Vector2(Mathf.Lerp(MIN, MAX, x), Mathf.Lerp(MIN, MAX, y));
}
public static void Send(this UdpConnection connection, MessageWriter msg, Action ackCallback)
{
if (msg.SendOption != SendOption.Reliable)
throw new InvalidOperationException("Message SendOption has to be Reliable.");
var buffer = new byte[msg.Length];
Buffer.BlockCopy(msg.Buffer, 0, buffer, 0, msg.Length);
connection.ResetKeepAliveTimer();
connection.AttachReliableID(buffer, 1, ackCallback);
connection.WriteBytesToConnection(buffer, buffer.Length);
}
}
}
-149
View File
@@ -1,149 +0,0 @@
using System;
using UnhollowerBaseLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Reactor.Extensions
{
/// <summary>
/// GUI utilities
/// </summary>
public static class GUIExtensions
{
/// <summary>
/// Shortcut for empty texture
/// </summary>
public static Texture2D CreateEmptyTexture(int width = 0, int height = 0)
{
return new Texture2D(width, height, TextureFormat.RGBA32, Texture.GenerateAllMips, false, IntPtr.Zero);
}
/// <summary>
/// Clamp Rect to screen size
/// </summary>
public static Rect ClampScreen(this Rect rect)
{
rect.x = Mathf.Clamp(rect.x, 0, Screen.width - rect.width);
rect.y = Mathf.Clamp(rect.y, 0, Screen.height - rect.height);
return rect;
}
/// <summary>
/// Reset Rect size
/// </summary>
public static Rect ResetSize(this Rect rect)
{
rect.width = rect.height = 0;
return rect;
}
/// <summary>
/// Create <see cref="Sprite"/> from <paramref name="tex"/>
/// </summary>
public static Sprite CreateSprite(this Texture2D tex)
{
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100f);
}
public static DefaultControls.Resources StandardResources { get; internal set; } = null!;
public static GameObject CreateCanvas()
{
var gameObject = new GameObject("Canvas");
var canvas = gameObject.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
var canvasScaler = gameObject.AddComponent<CanvasScaler>();
canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
canvasScaler.referencePixelsPerUnit = 100f;
gameObject.AddComponent<GraphicRaycaster>();
return gameObject;
}
public static GameObject CreateEventSystem()
{
var gameObject = new GameObject("EventSystem");
gameObject.AddComponent<EventSystem>();
gameObject.AddComponent<StandaloneInputModule>();
gameObject.AddComponent<BaseInput>();
return gameObject;
}
public static void SetSize(this RectTransform rectTransform, float width, float height)
{
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
}
}
public class Window
{
private static int _lastWindowId;
public static int NextWindowId()
{
return _lastWindowId++;
}
public int Id { get; set; } = NextWindowId();
public bool Enabled { get; set; } = true;
public Rect Rect { get; set; }
public Action<int> Func { get; set; }
public string Title { get; set; }
public Window(Rect rect, string title, Action<int> func)
{
Rect = rect;
Title = title;
Func = func;
}
public Window(Rect rect, string title, Action func) : this(rect, title, id => func())
{
}
public void OnGUI()
{
if (Enabled)
{
if (Event.current.type == EventType.Layout)
{
Rect = Rect.ResetSize();
}
Rect = GUILayout.Window(Id, Rect, Func, Title);
if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) && Rect.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y)))
{
Input.ResetInputAxes();
}
}
}
}
public class DragWindow : Window
{
public DragWindow(Rect rect, string title, Action<int> func) : base(rect, title, func)
{
Func = id =>
{
func(id);
GUI.DragWindow(new Rect(0, 0, 10000, 20));
Rect = Rect.ClampScreen();
};
}
public DragWindow(Rect rect, string title, Action func) : this(rect, title, id => func())
{
}
}
}
-23
View File
@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Reactor.Extensions;
public static class RandomExtensions
{
/// <summary>
/// Returns random <typeparamref name="T"/> from <paramref name="input"/> using <paramref name="random"/>
/// </summary>
public static T? Random<T>(this IEnumerable<T> input, Random random)
{
var list = input as IList<T> ?? input.ToList();
return list.Count == 0 ? default : list[random.Next(0, list.Count)];
}
/// <summary>Returns a random double that is within a specified range.</summary>
public static double NextDouble(this Random random, double minValue, double maxValue)
{
return random.NextDouble() * (maxValue - minValue) + minValue;
}
}
@@ -1,43 +0,0 @@
using UnityEngine;
namespace Reactor.Extensions
{
public static class UnityObjectExtensions
{
/// <summary>
/// Stops <paramref name="obj"/> from being destroyed
/// </summary>
/// <param name="obj">Object to stop from being destroyed</param>
/// <returns>Passed <paramref name="obj"/></returns>
public static T DontDestroy<T>(this T obj) where T : Object
{
obj.hideFlags |= HideFlags.HideAndDontSave;
return obj.DontDestroyOnLoad();
}
public static T DontUnload<T>(this T obj) where T : Object
{
obj.hideFlags |= HideFlags.DontUnloadUnusedAsset;
return obj;
}
public static T DontDestroyOnLoad<T>(this T obj) where T : Object
{
Object.DontDestroyOnLoad(obj);
return obj;
}
public static void Destroy(this Object obj)
{
Object.Destroy(obj);
}
public static void DestroyImmediate(this Object obj)
{
Object.DestroyImmediate(obj);
}
}
}
-38
View File
@@ -1,38 +0,0 @@
using System.Collections.Generic;
using Il2CppSystem.Runtime.CompilerServices;
namespace Reactor
{
public sealed class Il2CppEqualityComparer<T> : IEqualityComparer<T> where T : Il2CppSystem.Object
{
private static Il2CppEqualityComparer<T>? _instance;
public static Il2CppEqualityComparer<T> Instance
{
get
{
_instance ??= new Il2CppEqualityComparer<T>();
return _instance;
}
}
private Il2CppEqualityComparer()
{
}
public int GetHashCode(T value)
{
return RuntimeHelpers.GetHashCode(value);
}
public bool Equals(T? left, T? right)
{
if (left == null || right == null)
{
return left == null && right == null;
}
return left.Equals(right);
}
}
}
-11
View File
@@ -1,11 +0,0 @@
// https://stackoverflow.com/questions/64749385/predefined-type-system-runtime-compilerservices-isexternalinit-is-not-defined?noredirect=1&lq=1
// IsExternalInit is not included with netstandard2.1 even tho it could
// ReSharper disable CheckNamespace
namespace System.Runtime.CompilerServices
{
public static class IsExternalInit
{
}
}
@@ -0,0 +1,39 @@
using System;
using System.Globalization;
namespace Reactor.Localization.Extensions;
/// <summary>
/// Provides extension methods for <see cref="SupportedLangs"/>.
/// </summary>
public static class SupportedLangsExtensions
{
/// <summary>
/// Gets a <see cref="CultureInfo"/> from the specified <paramref name="language"/>.
/// </summary>
/// <param name="language">The <see cref="SupportedLangs"/>.</param>
/// <returns>a <see cref="CultureInfo"/>.</returns>
public static CultureInfo ToCultureInfo(this SupportedLangs language)
{
return language switch
{
SupportedLangs.English => CultureInfo.GetCultureInfo("en"),
SupportedLangs.Latam => CultureInfo.GetCultureInfo("es"),
SupportedLangs.Brazilian => CultureInfo.GetCultureInfo("pt-BR"),
SupportedLangs.Portuguese => CultureInfo.GetCultureInfo("pt"),
SupportedLangs.Korean => CultureInfo.GetCultureInfo("ko"),
SupportedLangs.Russian => CultureInfo.GetCultureInfo("ru"),
SupportedLangs.Dutch => CultureInfo.GetCultureInfo("nl"),
SupportedLangs.Filipino => CultureInfo.GetCultureInfo("fil"),
SupportedLangs.French => CultureInfo.GetCultureInfo("fr"),
SupportedLangs.German => CultureInfo.GetCultureInfo("de"),
SupportedLangs.Italian => CultureInfo.GetCultureInfo("it"),
SupportedLangs.Japanese => CultureInfo.GetCultureInfo("ja"),
SupportedLangs.Spanish => CultureInfo.GetCultureInfo("es"),
SupportedLangs.SChinese => CultureInfo.GetCultureInfo("zh-Hans"),
SupportedLangs.TChinese => CultureInfo.GetCultureInfo("zh-Hant"),
SupportedLangs.Irish => CultureInfo.GetCultureInfo("ga"),
_ => throw new ArgumentOutOfRangeException(nameof(language), language, null),
};
}
}
+111
View File
@@ -0,0 +1,111 @@
using System.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
namespace Reactor.Localization;
/// <summary>
/// Handles custom <see cref="StringNames"/> localization.
/// </summary>
public static class LocalizationManager
{
private static readonly List<LocalizationProvider> _providers = new();
/// <summary>
/// Gets registered <see cref="LocalizationProvider"/>s.
/// </summary>
public static IReadOnlyList<LocalizationProvider> Providers { get; } = _providers.AsReadOnly();
/// <summary>
/// Registers a new <see cref="LocalizationProvider"/> to be used for obtaining translations.
/// </summary>
/// <param name="provider">A <see cref="LocalizationProvider"/> instance.</param>
public static void Register(LocalizationProvider provider)
{
if (!_providers.Contains(provider))
{
_providers.Add(provider);
if (TranslationController.InstanceExists)
{
provider.SetLanguage(TranslationController.Instance.currentLanguage.languageID);
}
_providers.Sort((a, b) => b.Priority - a.Priority);
}
}
/// <summary>
/// Unregisters a <see cref="LocalizationProvider"/>.
/// </summary>
/// <param name="provider">The <see cref="LocalizationProvider"/> to unregister.</param>
public static void Unregister(LocalizationProvider provider)
{
_providers.Remove(provider);
}
internal static bool TryGetTextFormatted(StringNames stringName, Il2CppReferenceArray<Il2CppSystem.Object> parts, out string text)
{
foreach (var provider in _providers)
{
if (provider.TryGetTextFormatted(stringName, parts, out text!))
{
return true;
}
}
text = string.Empty;
return false;
}
internal static bool TryGetText(StringNames stringName, out string text)
{
foreach (var provider in _providers)
{
if (provider.TryGetText(stringName, out text!))
{
return true;
}
}
text = string.Empty;
return false;
}
internal static bool TryGetStringName(SystemTypes systemType, out StringNames stringName)
{
foreach (var provider in _providers)
{
if (provider.TryGetStringName(systemType, out var stringNameNullable))
{
stringName = stringNameNullable!.Value;
return true;
}
}
stringName = default;
return false;
}
internal static bool TryGetStringName(TaskTypes taskTypes, out StringNames stringName)
{
foreach (var provider in _providers)
{
if (provider.TryGetStringName(taskTypes, out var stringNameNullable))
{
stringName = stringNameNullable!.Value;
return true;
}
}
stringName = default;
return false;
}
internal static void OnLanguageChanged(SupportedLangs newLanguage)
{
foreach (var provider in _providers)
{
provider.SetLanguage(newLanguage);
}
}
}
@@ -0,0 +1,90 @@
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Reactor.Utilities;
namespace Reactor.Localization;
/// <summary>
/// The required implementation of a localization provider class.
/// </summary>
public abstract class LocalizationProvider
{
/// <summary>
/// Gets the current language Among Us is set to.
/// <br/>
/// If used from <see cref="OnLanguageChanged"/>, this property will return the old language, not the new one.
/// </summary>
public SupportedLangs? CurrentLanguage { get; private set; }
/// <summary>
/// Gets the priority of this <see cref="LocalizationProvider"/>.
/// The higher the priority is, the earlier it will be invoked in relation to other providers.
/// <br/>
/// You can use the <see cref="ReactorPriority"/> class for this value if you want to make this easier.
/// </summary>
public virtual int Priority => 0;
/// <summary>
/// Returns the localized text for the given <see cref="StringNames"/>.
/// </summary>
/// <param name="stringName">The <see cref="StringNames"/> to localize.</param>
/// <param name="result">The <see cref="string"/> representation of the given <see cref="StringNames"/>.</param>
/// <returns>Whether or not this <see cref="LocalizationProvider"/> can handle this <see cref="StringNames"/>.</returns>
public virtual bool TryGetText(StringNames stringName, out string? result)
{
result = null;
return false;
}
/// <summary>
/// Returns the localized text for the given <see cref="StringNames"/>.
/// </summary>
/// <param name="stringName">The <see cref="StringNames"/> to localize.</param>
/// <param name="parts">The arguments used for formatting.</param>
/// <param name="result">The <see cref="string"/> representation of the given <see cref="StringNames"/>.</param>
/// <returns>Whether or not this <see cref="LocalizationProvider"/> can handle this <see cref="StringNames"/>.</returns>
public virtual bool TryGetTextFormatted(StringNames stringName, Il2CppReferenceArray<Il2CppSystem.Object> parts, out string? result)
{
if (!TryGetText(stringName, out result)) return false;
result = Il2CppSystem.String.Format(result, parts);
return true;
}
/// <summary>
/// Returns the <see cref="StringNames"/> equivalent for the given <see cref="SystemTypes"/>.
/// </summary>
/// <param name="systemType">The <see cref="SystemTypes"/> value.</param>
/// <param name="result">The <see cref="string"/> representation of the given <see cref="StringNames"/>.</param>
/// <returns>Whether or not this <see cref="LocalizationProvider"/> can handle this <see cref="StringNames"/>.</returns>
public virtual bool TryGetStringName(SystemTypes systemType, out StringNames? result)
{
result = null;
return false;
}
/// <summary>
/// Returns the <see cref="StringNames"/> equivalent for the given <see cref="TaskTypes"/>.
/// </summary>
/// <param name="taskType">The <see cref="TaskTypes"/> value.</param>
/// <param name="result">The <see cref="string"/> representation of the given <see cref="StringNames"/>.</param>
/// <returns>Whether or not this <see cref="LocalizationProvider"/> can handle this <see cref="StringNames"/>.</returns>
public virtual bool TryGetStringName(TaskTypes taskType, out StringNames? result)
{
result = null;
return false;
}
/// <summary>
/// This method is called when the Among Us language is changed by the user.
/// </summary>
/// <param name="newLanguage">The new language that Among Us has been set to.</param>
public virtual void OnLanguageChanged(SupportedLangs newLanguage)
{
}
internal void SetLanguage(SupportedLangs newLanguage)
{
OnLanguageChanged(newLanguage);
CurrentLanguage = newLanguage;
}
}
@@ -0,0 +1,85 @@
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
namespace Reactor.Localization.Patches;
[HarmonyPatch]
internal static class GetStringPatch
{
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(StringNames), typeof(Il2CppReferenceArray<Il2CppSystem.Object>))]
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetStringWithDefault), typeof(StringNames), typeof(string), typeof(Il2CppReferenceArray<Il2CppSystem.Object>))]
[HarmonyPrefix]
public static bool StringNamesPatch(StringNames id, Il2CppReferenceArray<Il2CppSystem.Object> parts, out string __result)
{
if (LocalizationManager.TryGetTextFormatted(id, parts, out __result))
{
return false;
}
return true;
}
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(SystemTypes))]
[HarmonyPrefix]
public static bool SystemTypesStringPatch(TranslationController __instance, SystemTypes room, ref string __result)
{
if (LocalizationManager.TryGetStringName(room, out var stringName))
{
if (LocalizationManager.TryGetText(stringName, out var text))
{
__result = text;
return false;
}
__result = __instance.GetString(stringName);
return false;
}
return true;
}
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetSystemName))]
[HarmonyPrefix]
public static bool SystemTypesStringNamesPatch(SystemTypes room, ref StringNames __result)
{
if (LocalizationManager.TryGetStringName(room, out var stringName))
{
__result = stringName;
return false;
}
return true;
}
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(TaskTypes))]
[HarmonyPrefix]
public static bool TaskTypesStringPatch(TranslationController __instance, TaskTypes task, ref string __result)
{
if (LocalizationManager.TryGetStringName(task, out var stringName))
{
if (LocalizationManager.TryGetText(stringName, out var text))
{
__result = text;
return false;
}
__result = __instance.GetString(stringName);
return false;
}
return true;
}
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetTaskName))]
[HarmonyPrefix]
public static bool TaskTypesStringNamesPatch(TaskTypes task, ref StringNames __result)
{
if (LocalizationManager.TryGetStringName(task, out var stringName))
{
__result = stringName;
return false;
}
return true;
}
}
@@ -0,0 +1,22 @@
using HarmonyLib;
namespace Reactor.Localization.Patches;
[HarmonyPatch]
internal static class LanguageChangedPatch
{
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.Initialize))]
[HarmonyPostfix]
public static void Initialize(TranslationController __instance)
{
if (TranslationController.Instance.GetInstanceID() == __instance.GetInstanceID())
LocalizationManager.OnLanguageChanged(__instance.currentLanguage.languageID);
}
[HarmonyPatch(typeof(TranslationController), nameof(TranslationController.SetLanguage))]
[HarmonyPostfix]
public static void SetLanguage(TranslationController __instance)
{
LocalizationManager.OnLanguageChanged(__instance.currentLanguage.languageID);
}
}
@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Linguini.Bundle;
using Linguini.Bundle.Builder;
using Linguini.Bundle.Errors;
using Linguini.Shared.Types.Bundle;
using Linguini.Syntax.Ast;
using Reactor.Localization.Extensions;
using Reactor.Localization.Utilities;
using Reactor.Utilities;
using Object = Il2CppSystem.Object;
namespace Reactor.Localization.Providers;
/// <summary>
/// Represents a localization provider that uses Fluent.
/// </summary>
public class FluentLocalizationProvider : LocalizationProvider
{
private readonly Func<CultureInfo, IEnumerable<Resource>> _loadResources;
private readonly List<FluentBundle> _bundles = new();
private readonly Dictionary<StringNames, string> _ids = new();
private readonly Dictionary<StringNames, string[]> _arguments = new();
/// <summary>
/// Gets or sets the fallback language.
/// </summary>
public SupportedLangs FallbackLanguage { get; set; } = SupportedLangs.English;
/// <summary>
/// Initializes a new instance of the <see cref="FluentLocalizationProvider"/> class.
/// </summary>
/// <param name="loadResources">The implementation of resource loading.</param>
public FluentLocalizationProvider(Func<CultureInfo, IEnumerable<Resource>> loadResources)
{
_loadResources = loadResources;
}
/// <summary>
/// Initializes a new instance of the <see cref="FluentLocalizationProvider"/> class that loads resources from the calling assembly.
/// </summary>
/// <param name="prefix">The prefix of resource file names to load.</param>
/// <returns>a <see cref="FluentLocalizationProvider"/>.</returns>
public static FluentLocalizationProvider FromEmbeddedResources(string prefix) => FromEmbeddedResources(Assembly.GetCallingAssembly(), prefix);
/// <summary>
/// Initializes a new instance of the <see cref="FluentLocalizationProvider"/> class that loads resources from the specified <paramref name="assembly"/>.
/// </summary>
/// <param name="assembly">The assembly to load resources from.</param>
/// <param name="prefix">The prefix of resource file names to load.</param>
/// <returns>a <see cref="FluentLocalizationProvider"/>.</returns>
public static FluentLocalizationProvider FromEmbeddedResources(Assembly assembly, string prefix)
{
return new FluentLocalizationProvider(cultureInfo =>
{
return assembly.GetManifestResourceNames()
.Where(n => n.StartsWith($"{prefix}.{cultureInfo.Name}.", StringComparison.Ordinal) && n.EndsWith(".ftl", StringComparison.Ordinal))
.Select(n => (Resource) new StreamReader(assembly.GetManifestResourceStream(n)!));
});
}
/// <summary>
/// Registers a <see cref="StringNames"/> for use with base game apis.
/// </summary>
/// <param name="id">The id of a Fluent message.</param>
/// <returns>A <see cref="StringNames"/>.</returns>
public StringNames Register(string id)
{
var stringNames = CustomStringName.Create();
_ids[stringNames] = id;
return stringNames;
}
/// <summary>
/// Registers a <see cref="StringNames"/> for use with base game apis with overriden format argument names.
/// </summary>
/// <param name="id">The id of a Fluent message.</param>
/// <param name="argumentNames">An array of Fluent variable names in the same order as format arguments.</param>
/// <returns>A <see cref="StringNames"/>.</returns>
public StringNames Register(string id, params string[] argumentNames)
{
var stringNames = Register(id);
_arguments[stringNames] = argumentNames;
return stringNames;
}
/// <inheritdoc/>
public override int Priority => ReactorPriority.Normal;
/// <inheritdoc />
public override void OnLanguageChanged(SupportedLangs newLanguage)
{
if (CurrentLanguage == newLanguage) return;
_bundles.Clear();
_bundles.Add(Load(newLanguage.ToCultureInfo()));
if (newLanguage != FallbackLanguage) _bundles.Add(Load(FallbackLanguage.ToCultureInfo()));
}
private FluentBundle Load(CultureInfo culture)
{
return LinguiniBuilder.Builder()
.CultureInfo(culture)
.AddResources(_loadResources(culture))
.SetUseIsolating(false)
.UncheckedBuild();
}
private string GetMsg(string id, IDictionary<string, IFluentType>? args)
{
foreach (var bundle in _bundles)
{
if (bundle.TryGetMsg(id, null, args, out var errors, out var message))
{
if (errors.Count > 0)
{
throw new LinguiniException(errors);
}
return message;
}
}
throw new KeyNotFoundException();
}
private static bool Is<T>(Il2CppObjectBase o)
{
return IL2CPP.il2cpp_class_is_assignable_from(Il2CppClassPointerStore<T>.NativeClassPtr, IL2CPP.il2cpp_object_get_class(o.Pointer));
}
private static bool TryUnbox<T>(Il2CppObjectBase o, [NotNullWhen(true)] out T? result) where T : unmanaged
{
if (!Is<T>(o))
{
result = null;
return false;
}
result = o.Unbox<T>();
return true;
}
private static IFluentType ToFluentType(Object o)
{
if (Is<string>(o)) return new FluentString(IL2CPP.Il2CppStringToManaged(o.Pointer));
if (TryUnbox<byte>(o, out var @byte)) return (FluentNumber) @byte;
if (TryUnbox<sbyte>(o, out var @sbyte)) return (FluentNumber) @sbyte;
if (TryUnbox<short>(o, out var @short)) return (FluentNumber) @short;
if (TryUnbox<int>(o, out var @int)) return (FluentNumber) @int;
if (TryUnbox<long>(o, out var @long)) return (FluentNumber) @long;
if (TryUnbox<ushort>(o, out var @ushort)) return (FluentNumber) @ushort;
if (TryUnbox<uint>(o, out var @uint)) return (FluentNumber) @uint;
if (TryUnbox<ulong>(o, out var @ulong)) return (FluentNumber) @ulong;
if (TryUnbox<float>(o, out var @float)) return (FluentNumber) @float;
if (TryUnbox<double>(o, out var @double)) return (FluentNumber) @double;
return new FluentString(o.ToString());
}
private static IFluentType ToFluentType(object o)
{
return o switch
{
string str => (FluentString) str,
byte num => (FluentNumber) num,
sbyte num => (FluentNumber) num,
short num => (FluentNumber) num,
ushort num => (FluentNumber) num,
int num => (FluentNumber) num,
uint num => (FluentNumber) num,
long num => (FluentNumber) num,
ulong num => (FluentNumber) num,
double num => (FluentNumber) num,
float num => (FluentNumber) num,
_ => (FluentString) o.ToString()!,
};
}
/// <summary>
/// Returns the localized text for the given fluent message <paramref name="id"/>.
/// </summary>
/// <param name="id">The id of the message.</param>
/// <param name="args">The arguments used for formatting.</param>
/// <returns>Text localized and formatted by fluent.</returns>
public string GetText(string id, params (string, object)[] args)
{
var fluentArgs = new Dictionary<string, IFluentType>(args.Length);
foreach (var (key, value) in args)
{
fluentArgs[key] = ToFluentType(value);
}
return GetMsg(id, fluentArgs);
}
/// <inheritdoc/>
public override bool TryGetTextFormatted(StringNames stringName, Il2CppReferenceArray<Object> parts, [NotNullWhen(true)] out string? result)
{
if (_ids.TryGetValue(stringName, out var id))
{
var hasArgumentsOverride = _arguments.TryGetValue(stringName, out var arguments);
if (hasArgumentsOverride)
{
if (arguments!.Length != parts.Length)
throw new InvalidOperationException($"Arguments override for {id} has an invalid count of arguments");
}
var args = new Dictionary<string, IFluentType>(parts.Length);
for (var i = 0; i < parts.Count; i++)
{
var part = parts[i];
if (hasArgumentsOverride)
{
args[arguments![i]] = ToFluentType(part);
}
else
{
// Fluent doesn't allow positional variables nor starting variable names with numbers so we have to use a,b,c,d... instead
if (i > 25) throw new InvalidOperationException("Too many format parts");
var c = (char) ('a' + i);
args[c.ToString()] = ToFluentType(part);
}
}
result = GetMsg(id, args);
return true;
}
result = null;
return false;
}
/// <inheritdoc/>
public override bool TryGetText(StringNames stringName, [NotNullWhen(true)] out string? result)
{
if (_ids.TryGetValue(stringName, out var id))
{
result = GetMsg(id, null);
return true;
}
result = null;
return false;
}
}
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using Reactor.Utilities;
namespace Reactor.Localization.Providers;
/// <summary>
/// Utility for adding hard-coded localization.
/// </summary>
public sealed class HardCodedLocalizationProvider : LocalizationProvider
{
private static readonly Dictionary<StringNames, string> _strings = new();
/// <summary>
/// Adds a custom, hard-coded translation for a <see cref="StringNames"/>.
/// </summary>
/// <param name="stringName">The <see cref="StringNames"/>.</param>
/// <param name="value">The text.</param>
public static void Register(StringNames stringName, string value)
{
if (_strings.ContainsKey(stringName))
{
Warning($"Registering StringName {stringName} that already exists");
}
_strings[stringName] = value;
}
/// <inheritdoc/>
public override int Priority => ReactorPriority.Low;
/// <inheritdoc/>
public override bool TryGetText(StringNames stringName, out string? result)
{
return _strings.TryGetValue(stringName, out result);
}
}
@@ -0,0 +1,33 @@
using Reactor.Localization.Providers;
namespace Reactor.Localization.Utilities;
/// <summary>
/// Provides a way to use custom static <see cref="StringNames"/>.
/// </summary>
public static class CustomStringName
{
private static int _lastId = int.MinValue + 1;
/// <summary>
/// Creates an returns a unique <see cref="StringNames"/> value.
/// </summary>
/// <returns>A unique <see cref="StringNames"/>.</returns>
public static StringNames Create()
{
var id = _lastId++;
return (StringNames) id;
}
/// <summary>
/// Creates, registeres and returns a unique <see cref="StringNames"/> value.
/// </summary>
/// <param name="text">The text.</param>
/// <returns>A unique <see cref="StringNames"/>.</returns>
public static StringNames CreateAndRegister(string text)
{
var stringName = Create();
HardCodedLocalizationProvider.Register(stringName, text);
return stringName;
}
}
-28
View File
@@ -1,28 +0,0 @@
using BepInEx.IL2CPP;
using BepInEx.Logging;
namespace Reactor
{
public static class Logger<T> where T : BasePlugin
{
public static ManualLogSource Instance => PluginSingleton<T>.Instance.Log;
/// <inheritdoc cref="ManualLogSource.LogFatal"/>
public static void Fatal(object data) => Instance.LogFatal(data);
/// <inheritdoc cref="ManualLogSource.LogError"/>
public static void Error(object data) => Instance.LogError(data);
/// <inheritdoc cref="ManualLogSource.LogWarning"/>
public static void Warning(object data) => Instance.LogWarning(data);
/// <inheritdoc cref="ManualLogSource.LogMessage"/>
public static void Message(object data) => Instance.LogMessage(data);
/// <inheritdoc cref="ManualLogSource.LogInfo"/>
public static void Info(object data) => Instance.LogInfo(data);
/// <inheritdoc cref="ManualLogSource.LogDebug"/>
public static void Debug(object data) => Instance.LogDebug(data);
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Reactor.Networking.Serialization;
namespace Reactor.Networking.Attributes;
/// <summary>
/// Automatically registers a <see cref="MessageConverter{T}"/>.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class MessageConverterAttribute : Attribute
{
private static readonly HashSet<Assembly> _registeredAssemblies = new();
/// <summary>
/// Registers all <see cref="MessageConverter{T}"/>s annotated with <see cref="MessageConverterAttribute"/> in the specified <paramref name="assembly"/>.
/// </summary>
/// <remarks>This is called automatically on plugin assemblies so you probably don't need to call this.</remarks>
/// <param name="assembly">The assembly to search.</param>
public static void Register(Assembly assembly)
{
if (_registeredAssemblies.Contains(assembly)) return;
_registeredAssemblies.Add(assembly);
foreach (var type in assembly.GetTypes())
{
var attribute = type.GetCustomAttribute<MessageConverterAttribute>();
if (attribute != null)
{
if (!type.IsSubclassOf(typeof(UnsafeMessageConverter)))
{
throw new InvalidOperationException($"Type {type.FullDescription()} has {nameof(MessageConverterAttribute)} but doesn't extend {nameof(UnsafeMessageConverter)}.");
}
try
{
var messageConverter = (UnsafeMessageConverter) Activator.CreateInstance(type)!;
MessageSerializer.Register(messageConverter);
}
catch (Exception e)
{
Warning($"Failed to register {type.FullDescription()}: {e}");
}
}
}
}
internal static void Initialize()
{
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, _) => Register(assembly);
}
}
@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Hazel;
using Reactor.Networking.Rpc;
using Reactor.Utilities;
namespace Reactor.Networking.Attributes;
/// <summary>
/// Automatically registers a method rpc.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class MethodRpcAttribute : Attribute
{
private static readonly HashSet<Assembly> _registeredAssemblies = new();
/// <summary>
/// Gets the id of the rpc.
/// </summary>
public uint Id { get; }
/// <summary>
/// Gets or sets the send option of the rpc.
/// </summary>
public SendOption SendOption { get; set; } = SendOption.Reliable;
/// <summary>
/// Gets or sets the local handling of the rpc.
/// </summary>
public RpcLocalHandling LocalHandling { get; set; } = RpcLocalHandling.Before;
/// <summary>
/// Gets or sets a value indicating whether the rpc should be sent immediately.
/// </summary>
public bool SendImmediately { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MethodRpcAttribute"/> class.
/// </summary>
/// <param name="id">The id of the rpc.</param>
public MethodRpcAttribute(uint id)
{
Id = id;
}
/// <summary>
/// Registers all method rpc's annotated with <see cref="MethodRpcAttribute"/> in the specified <paramref name="assembly"/>.
/// </summary>
/// <remarks>This is called automatically on plugin assemblies so you probably don't need to call this.</remarks>
/// <param name="assembly">The assembly to search.</param>
/// <param name="plugin">The plugin to register the rpc to.</param>
public static void Register(Assembly assembly, BasePlugin plugin)
{
if (_registeredAssemblies.Contains(assembly)) return;
_registeredAssemblies.Add(assembly);
var methods = assembly.GetTypes()
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
foreach (var method in methods)
{
var attribute = method.GetCustomAttribute<MethodRpcAttribute>();
if (attribute == null)
{
continue;
}
try
{
var customRpc = new MethodRpc(plugin, method, attribute.Id, attribute.SendOption, attribute.LocalHandling, attribute.SendImmediately);
PluginSingleton<ReactorPlugin>.Instance.CustomRpcManager.Register(customRpc);
}
catch (Exception e)
{
Warning($"Failed to register {method.FullDescription()}: {e}");
}
}
}
internal static void Initialize()
{
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, plugin) => Register(assembly, plugin);
}
}
@@ -0,0 +1,43 @@
using System;
using System.Linq;
using System.Reflection;
namespace Reactor.Networking.Attributes;
/// <summary>
/// Describes the <see cref="ModFlags"/> of the annotated plugin class.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class ReactorModFlagsAttribute : Attribute
{
/// <summary>
/// Gets flags of the mod.
/// </summary>
public ModFlags Flags { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ReactorModFlagsAttribute"/> class.
/// </summary>
/// <param name="flags">Flags of the mod.</param>
public ReactorModFlagsAttribute(ModFlags flags)
{
Flags = flags;
}
internal static ModFlags GetModFlags(Type type)
{
var attribute = type.GetCustomAttribute<ReactorModFlagsAttribute>();
if (attribute != null)
{
return attribute.Flags;
}
var metadataAttribute = type.Assembly.GetCustomAttributes<AssemblyMetadataAttribute>().SingleOrDefault(x => x.Key == "Reactor.ModFlags");
if (metadataAttribute is { Value: not null })
{
return Enum.Parse<ModFlags>(metadataAttribute.Value);
}
return ModFlags.None;
}
}
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Reactor.Networking.Rpc;
using Reactor.Utilities;
namespace Reactor.Networking.Attributes;
/// <summary>
/// Automatically registers a rpc.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class RegisterCustomRpcAttribute : Attribute
{
private static readonly HashSet<Assembly> _registeredAssemblies = new();
/// <summary>
/// Gets the id of the rpc.
/// </summary>
public uint Id { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RegisterCustomRpcAttribute"/> class.
/// </summary>
/// <param name="id">The id of the rpc.</param>
public RegisterCustomRpcAttribute(uint id)
{
Id = id;
}
/// <summary>
/// Registers all rpc's annotated with <see cref="RegisterCustomRpcAttribute"/> in the specified <paramref name="assembly"/>.
/// </summary>
/// <remarks>This is called automatically on plugin assemblies so you probably don't need to call this.</remarks>
/// <param name="assembly">The assembly to search.</param>
/// <param name="plugin">The plugin to register the rpc to.</param>
public static void Register(Assembly assembly, BasePlugin plugin)
{
if (_registeredAssemblies.Contains(assembly)) return;
_registeredAssemblies.Add(assembly);
foreach (var type in assembly.GetTypes())
{
var attribute = type.GetCustomAttribute<RegisterCustomRpcAttribute>();
if (attribute != null)
{
if (!type.IsSubclassOf(typeof(UnsafeCustomRpc)))
{
throw new InvalidOperationException($"Type {type.FullDescription()} has {nameof(RegisterCustomRpcAttribute)} but doesn't extend {nameof(UnsafeCustomRpc)}.");
}
var customRpc = (UnsafeCustomRpc) Activator.CreateInstance(type, plugin, attribute.Id)!;
PluginSingleton<ReactorPlugin>.Instance.CustomRpcManager.Register(customRpc);
}
}
}
internal static void Initialize()
{
IL2CPPChainloader.Instance.PluginLoad += (_, assembly, plugin) => Register(assembly, plugin);
}
}
-82
View File
@@ -1,82 +0,0 @@
using System;
using BepInEx.IL2CPP;
using Hazel;
using InnerNet;
namespace Reactor.Networking
{
public abstract class CustomRpc<TPlugin, TInnerNetObject, TData> : UnsafeCustomRpc where TPlugin : BasePlugin where TInnerNetObject : InnerNetObject
{
protected CustomRpc(TPlugin plugin, uint id) : base(plugin, id)
{
}
public TPlugin Plugin => (TPlugin) UnsafePlugin;
public override Type InnerNetObjectType => typeof(TInnerNetObject);
public abstract void Write(MessageWriter writer, TData? data);
public abstract TData Read(MessageReader reader);
public abstract void Handle(TInnerNetObject innerNetObject, TData? data);
public override void UnsafeWrite(MessageWriter writer, object? data)
{
Write(writer, (TData?) data);
}
public override object? UnsafeRead(MessageReader reader)
{
return Read(reader);
}
public override void UnsafeHandle(InnerNetObject innerNetObject, object? data)
{
Handle((TInnerNetObject) innerNetObject, (TData?) data);
}
public void Send(InnerNetObject netObject, TData data, bool immediately = false)
{
UnsafeSend(netObject, data, immediately);
}
public void SendTo(InnerNetObject netObject, int targetId, TData data)
{
UnsafeSend(netObject, data, true, targetId);
}
}
public abstract class CustomRpc<TPlugin, TInnerNetObject> : UnsafeCustomRpc where TPlugin : BasePlugin where TInnerNetObject : InnerNetObject
{
protected CustomRpc(TPlugin plugin, uint id) : base(plugin, id)
{
}
public TPlugin Plugin => (TPlugin) UnsafePlugin;
public override Type InnerNetObjectType => typeof(TInnerNetObject);
public abstract void Handle(TInnerNetObject innerNetObject);
public override void UnsafeWrite(MessageWriter writer, object? data)
{
}
public override object? UnsafeRead(MessageReader reader)
{
return null;
}
public override void UnsafeHandle(InnerNetObject innerNetObject, object? data)
{
Handle((TInnerNetObject) innerNetObject);
}
public void Send(InnerNetObject netObject, bool immediately = false)
{
UnsafeSend(netObject, immediately);
}
public void SendTo(InnerNetObject netObject, int targetId)
{
UnsafeSend(netObject, null, true, targetId);
}
}
}
-118
View File
@@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using HarmonyLib;
using Hazel;
using InnerNet;
namespace Reactor.Networking
{
public enum RpcLocalHandling
{
None,
Before,
After
}
public class CustomRpcManager
{
public const byte CallId = byte.MaxValue;
private readonly List<UnsafeCustomRpc> _list = new List<UnsafeCustomRpc>();
private readonly Dictionary<Type, List<UnsafeCustomRpc>> _map = new Dictionary<Type, List<UnsafeCustomRpc>>();
public IReadOnlyList<UnsafeCustomRpc> List => _list.AsReadOnly();
public ILookup<Type, UnsafeCustomRpc> Map =>
_map.SelectMany(pair => pair.Value, (pair, value) => new { pair.Key, Value = value })
.ToLookup(pair => pair.Key, pair => pair.Value);
public CustomRpcManager()
{
foreach (var type in HandleRpcPatch.InnerNetObjectTypes)
{
_map[type] = new List<UnsafeCustomRpc>();
}
}
public UnsafeCustomRpc Register(UnsafeCustomRpc customRpc)
{
if (_list.Any(x => x.UnsafePlugin == customRpc.UnsafePlugin && x.Id == customRpc.Id))
{
throw new ArgumentException("Rpc with that id was already registered");
}
customRpc.Manager = this;
_list.Add(customRpc);
_map[customRpc.InnerNetObjectType].Add(customRpc);
if (customRpc.IsSingleton)
{
typeof(Rpc<>).MakeGenericType(customRpc.GetType()).GetProperty("Instance")!.SetValue(null, customRpc);
}
return customRpc;
}
[HarmonyPatch]
private static class HandleRpcPatch
{
internal static List<Type> InnerNetObjectTypes { get; } = typeof(InnerNetObject).Assembly.GetTypes().Where(x => x.IsSubclassOf(typeof(InnerNetObject)) && x != typeof(LobbyBehaviour)).ToList();
public static IEnumerable<MethodBase> TargetMethods()
{
return InnerNetObjectTypes.Select(x => x.GetMethod(nameof(InnerNetObject.HandleRpc), AccessTools.all));
}
public static bool Prefix(InnerNetObject __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (callId == CallId)
{
var manager = PluginSingleton<ReactorPlugin>.Instance.CustomRpcManager;
var customRpcs = manager.Map[__instance.GetType()];
var pluginNetId = reader.ReadPackedUInt32();
var id = reader.ReadPackedUInt32();
var pluginId = ModList.GetByNetId(pluginNetId).Id;
var customRpc = customRpcs.Single(x => x.PluginId == pluginId && x.Id == id);
customRpc.UnsafeHandle(__instance, customRpc.UnsafeRead(reader.ReadMessage()));
return false;
}
return true;
}
}
}
public static class Rpc<T> where T : UnsafeCustomRpc
{
private static T? _instance;
public static T Instance
{
get
{
if (_instance == null)
{
throw new Exception($"{typeof(T).FullName} isn't registered");
}
return _instance;
}
internal set
{
if (_instance != null)
{
throw new Exception($"{typeof(T).FullName} is already registered");
}
_instance = value;
}
}
}
}
Loaded 100 of 179 files, more files were not shown because too many files have changed in this diff. Show more