Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 64d8df148b | |||
| d2316bac96 | |||
| 920875f56b | |||
| cb1dd8b4c6 | |||
| 2b73125f8e | |||
| 23eac84782 | |||
| 274288e453 | |||
| caa4dae8b3 | |||
| f81069f658 | |||
| a9be72693c | |||
| 416e49d6d7 | |||
| 6249f07788 | |||
| 640245cdd5 | |||
| d4c5e84404 | |||
| 1eb6628a37 | |||
| fcea383739 |
@@ -1,2 +1,129 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
# https://github.com/alexkaratarakis/gitattributes/blob/master/Unity.gitattributes
|
||||
# Unity
|
||||
*.cginc text
|
||||
*.cs text diff=csharp
|
||||
*.shader text
|
||||
|
||||
# Unity YAML
|
||||
*.mat merge=unityyamlmerge eol=lf
|
||||
*.anim merge=unityyamlmerge eol=lf
|
||||
*.unity merge=unityyamlmerge eol=lf
|
||||
*.prefab merge=unityyamlmerge eol=lf
|
||||
*.asset merge=unityyamlmerge eol=lf
|
||||
*.meta merge=unityyamlmerge eol=lf
|
||||
*.controller merge=unityyamlmerge eol=lf
|
||||
|
||||
# "physic" for 3D but "physics" for 2D
|
||||
*.physicMaterial2D merge=unityyamlmerge eol=lf
|
||||
*.physicMaterial merge=unityyamlmerge eol=lf
|
||||
*.physicsMaterial2D merge=unityyamlmerge eol=lf
|
||||
*.physicsMaterial merge=unityyamlmerge eol=lf
|
||||
|
||||
# Using Git LFS
|
||||
# Add diff=lfs merge=lfs to the binary files
|
||||
|
||||
# Unity LFS
|
||||
*.cubemap binary
|
||||
*.unitypackage binary
|
||||
|
||||
# 3D models
|
||||
*.3dm binary
|
||||
*.3ds binary
|
||||
*.blend binary
|
||||
*.c4d binary
|
||||
*.collada binary
|
||||
*.dae binary
|
||||
*.dxf binary
|
||||
*.FBX binary
|
||||
*.fbx binary
|
||||
*.jas binary
|
||||
*.lws binary
|
||||
*.lxo binary
|
||||
*.ma binary
|
||||
*.max binary
|
||||
*.mb binary
|
||||
*.obj binary
|
||||
*.ply binary
|
||||
*.skp binary
|
||||
*.stl binary
|
||||
*.ztl binary
|
||||
|
||||
# Audio
|
||||
*.aif binary
|
||||
*.aiff binary
|
||||
*.it binary
|
||||
*.mod binary
|
||||
*.mp3 binary
|
||||
*.ogg binary
|
||||
*.s3m binary
|
||||
*.wav binary
|
||||
*.xm binary
|
||||
|
||||
# Video
|
||||
*.asf binary
|
||||
*.avi binary
|
||||
*.flv binary
|
||||
*.mov binary
|
||||
*.mp4 binary
|
||||
*.mpeg binary
|
||||
*.mpg binary
|
||||
*.ogv binary
|
||||
*.wmv binary
|
||||
|
||||
# Images
|
||||
*.bmp binary
|
||||
*.exr binary
|
||||
*.gif binary
|
||||
*.hdr binary
|
||||
*.iff binary
|
||||
*.jpeg binary
|
||||
*.jpg binary
|
||||
*.pict binary
|
||||
*.png binary
|
||||
*.psd binary
|
||||
*.tga binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.webp binary
|
||||
|
||||
# Compressed Archive
|
||||
*.7z binary
|
||||
*.bz2 binary
|
||||
*.gz binary
|
||||
*.rar binary
|
||||
*.tar binary
|
||||
*.zip binary
|
||||
|
||||
# Compiled Dynamic Library
|
||||
*.dll binary
|
||||
*.pdb binary
|
||||
*.so binary
|
||||
|
||||
# Fonts
|
||||
*.otf binary
|
||||
*.ttf binary
|
||||
|
||||
# Executable/Installer
|
||||
*.apk binary
|
||||
*.exe binary
|
||||
|
||||
# Documents
|
||||
*.pdf binary
|
||||
|
||||
# ETC
|
||||
*.a binary
|
||||
*.rns binary
|
||||
*.reason binary
|
||||
|
||||
# Collapse Unity-generated files on GitHub
|
||||
*.asset linguist-generated
|
||||
*.mat linguist-generated
|
||||
*.meta linguist-generated
|
||||
*.prefab linguist-generated
|
||||
*.unity linguist-generated
|
||||
|
||||
# Spine export file for Unity
|
||||
*.skel.bytes binary
|
||||
|
||||
# Ignore stuff in the Alloy folder
|
||||
Assets/Alloy/** linguist-vendored
|
||||
|
||||
@@ -71,6 +71,7 @@ crashlytics-build.properties
|
||||
|
||||
# I like Rider
|
||||
/.idea/
|
||||
/[Aa]ssets/Editor.meta
|
||||
|
||||
# Built asset bundles
|
||||
AssetBundles/
|
||||
@@ -79,13 +80,14 @@ AssetBundles/
|
||||
ImportedBundles/
|
||||
|
||||
# MeatKit stuffs
|
||||
/[Aa]ssets/MeatKit/Managed/DinoFracture.*
|
||||
/[Aa]ssets/MeatKit/Managed/ES2.*
|
||||
/[Aa]ssets/MeatKit/Managed/H3VRCode*
|
||||
/[Aa]ssets/MeatKit/Managed/Atlas.*
|
||||
/[Aa]ssets/MeatKit/Managed/OtherLoader.*
|
||||
/[Aa]ssets/MeatKit/Managed/ReadOnlyCollectionsInterfaces.*
|
||||
/[Aa]ssets/MeatKit/Managed/Stratum.*
|
||||
/[Aa]ssets/Managed/*
|
||||
!/[Aa]ssets/Managed/0Harmony.*
|
||||
!/[Aa]ssets/Managed/BepInEx.*
|
||||
!/[Aa]ssets/Managed/DotNetZip.*
|
||||
!/[Aa]ssets/Managed/Mono.Cecil*
|
||||
!/[Aa]ssets/Managed/MonoMod.*
|
||||
!/[Aa]ssets/Managed/Sodalite.*
|
||||
!/[Aa]ssets/Managed/Valve.Newtonsoft.Json.*
|
||||
|
||||
# No Bakery 4 U
|
||||
/[Aa]ssets/Bakery/
|
||||
@@ -94,17 +96,14 @@ ImportedBundles/
|
||||
/[Aa]ssets/Editor/x64.meta
|
||||
/[Aa]ssets/BakeryLightmaps/
|
||||
/[Aa]ssets/BakeryLightmaps.meta
|
||||
/[Aa]ssets/Settings
|
||||
/[Aa]ssets/Settings.meta
|
||||
/bakery_times.log
|
||||
|
||||
# Ignore Samples
|
||||
Assets/Samples/
|
||||
|
||||
# Ignore any imported build items
|
||||
/[Aa]ssets/MeatKit/Editor/BuildPipeline/BuildItems/*.cs
|
||||
/[Aa]ssets/MeatKit/Editor/BuildPipeline/BuildItems/*.meta
|
||||
!/[Aa]ssets/MeatKit/Editor/BuildPipeline/BuildItems/PreloadAssetsBuildItem.*
|
||||
!/[Aa]ssets/MeatKit/Editor/BuildPipeline/BuildItems/StoreFilesBuildItem.*
|
||||
/[Aa]ssets/MeatKit/Editor/BuildPipeline/OtherLoaderBuildRootEditor.*
|
||||
/[Aa]ssets/MeatKit/Editor/BuildPipeline/SpawnerEntryEditor.*
|
||||
# Ignore packages
|
||||
/[Aa]ssets/Packages/
|
||||
/[Aa]ssets/Packages.meta
|
||||
|
||||
# Cache
|
||||
/meatkit.json
|
||||
MeatKitUpdate.unitypackage
|
||||
@@ -13,18 +13,18 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
PackageName: TNH_Quality_of_Life_Improvements
|
||||
Author: muskit
|
||||
Version: 1.0.1
|
||||
Icon: {fileID: 2800000, guid: 785b7946398f5314b95bf593d2d77d67, type: 3}
|
||||
ReadMe: {fileID: 102900000, guid: ab1d6dea017447a48ac348db588a6f35, type: 3}
|
||||
Version: 1.2.4
|
||||
Icon: {fileID: 2800000, guid: af542f3f6d6914f4e96d0326e8b296cc, type: 3}
|
||||
ReadMe: {fileID: 102900000, guid: efa2d6091ed77bd4b879a74bd81d6cbc, type: 3}
|
||||
WebsiteURL: https://github.com/muskit/TNH-Quality-of-Life-Improvements
|
||||
Description: Quality of life improvements to the Take and Hold experience.
|
||||
AdditionalDependencies:
|
||||
- BepInEx-BepInExPack_H3VR-5.4.1700
|
||||
StripNamespaces: 1
|
||||
AdditionalNamespaces:
|
||||
- TNHQoLImprovements
|
||||
- nrgill28-Sodalite-1.3.5
|
||||
StripNamespaces: 0
|
||||
AdditionalNamespaces: []
|
||||
ApplyHarmonyPatches: 1
|
||||
BuildItems:
|
||||
- {fileID: 11400000, guid: ccaff18373cd99848b344316974e6d46, type: 2}
|
||||
BundleCompressionType: 2
|
||||
BuildAction: 2
|
||||
OutputProfile:
|
||||
OutputProfile: C:/Users/Alex/AppData/Roaming/r2modmanPlus-local/H3VR/profiles/dev
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b545caf63c55b0143bd5c4ce2e5eef7c
|
||||
timeCreated: 1642332594
|
||||
guid: 02926509e1e56c64d8258b04e03b04a4
|
||||
timeCreated: 1690411169
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
@@ -1,7 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67b0d6a5c1b85824bbcb13aefd6b9879
|
||||
guid: 929add3db6d432e4da84149d3edb456a
|
||||
folderAsset: yes
|
||||
timeCreated: 1640644671
|
||||
timeCreated: 1649520255
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -1,18 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3aa429e1ebaddb41ad13211560ea5e8
|
||||
guid: 0b1eb8075ae1d824aaea163aa5cb832c
|
||||
timeCreated: 1645982992
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 5
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
@@ -28,13 +27,10 @@ TextureImporter:
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
@@ -46,31 +42,34 @@ TextureImporter:
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -1,18 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18223d49715730347b997e6682fe49e5
|
||||
guid: 72bfff337624ec0459c46aebab5e81a1
|
||||
timeCreated: 1645983392
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 5
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
@@ -28,13 +27,10 @@ TextureImporter:
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
@@ -46,31 +42,34 @@ TextureImporter:
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad1e4c81a2272e44a8af9382cea6a7be
|
||||
timeCreated: 1645983392
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f999bddab1821b94691466e97cc6891f
|
||||
timeCreated: 1642657287
|
||||
guid: 15e3f33b1d6057a44ac91a0ea5a0dc66
|
||||
timeCreated: 1649523457
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
@@ -19,7 +19,7 @@ TextureImporter:
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 1
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4779e6e9e7b58184d8d3d3b7778378bf
|
||||
timeCreated: 1649539868
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85fde4e7120e9a641a99b572cd27b3df
|
||||
timeCreated: 1649523715
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c3a24284d096224b909935965898746
|
||||
timeCreated: 1640061322
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3441405f7f92f014a87ed402b6daa9a6
|
||||
timeCreated: 1649523141
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1045227fdd9d09944a071eb719a7a4e3
|
||||
timeCreated: 1649520892
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a43ada798740864459253d240a47493a
|
||||
timeCreated: 1640061322
|
||||
licenseType: Pro
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a3610de08282ff4ba061142a7370a3c
|
||||
timeCreated: 1649540118
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: 2
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 437f9ab4673f34e4f96969e0db002b45
|
||||
timeCreated: 1641675729
|
||||
guid: 82e22a718bb54ac3d5dec469e4f08d3f
|
||||
timeCreated: 1655418961
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 2
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 903902f7b3dcdd94cb58f9fbdfee66f3
|
||||
timeCreated: 1641675222
|
||||
guid: 3f9863d03507a51b39b6c8a900141759
|
||||
timeCreated: 1655418961
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 2
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7399badb939ce1137fff9ef0738fd1aa
|
||||
timeCreated: 1637991225
|
||||
timeCreated: 1655418961
|
||||
licenseType: Pro
|
||||
PluginImporter:
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,186 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 6389bd26f6b33074ba8afe182d11c33d, type: 3}
|
||||
m_Name: DefaultPathReplacements
|
||||
m_EditorClassIdentifier:
|
||||
ReplacementPaths:
|
||||
- ScriptableObjectName: FistVR.MainMenuSceneDef
|
||||
NewPath: Misc/MainMenuSceneDef
|
||||
NewDefaultName: MainMenuSceneDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ZosigMoodPreset
|
||||
NewPath: Sosig/Zosig/MoodPreset
|
||||
NewDefaultName: MoodPreset
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ZBldgTileList
|
||||
NewPath: Sosig/Zosig/zBldgTileList
|
||||
NewDefaultName: zBldgTileList
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ZosigEnemyTemplate
|
||||
NewPath: Sosig/Zosig/ZosigEnemyTemplate
|
||||
NewDefaultName: ZosigEnemyTemplate
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ZosigItemSpawnTable
|
||||
NewPath: Sosig/Zosig/ZosigItemSpawnTable
|
||||
NewDefaultName: ZosigItemSpawnTable
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ZosigNPCProfile
|
||||
NewPath: Sosig/Zosig/ZosigNPCProfile
|
||||
NewDefaultName: ZosigNPCProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.HangableDef
|
||||
NewPath: Misc/HangableDef
|
||||
NewDefaultName: HangableDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.AutoMeaterFirearmSoundProfile
|
||||
NewPath: Misc/AutoMeaterFirearmSoundProfile
|
||||
NewDefaultName: AutoMeaterFirearmSoundProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.wwBotWurstGunSoundConfig
|
||||
NewPath: Misc/wwBotWurstGunSoundConfig
|
||||
NewDefaultName: wwBotWurstGunSoundConfig
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.DestructibleChunkProfile
|
||||
NewPath: Destruction/DestructibleChunkProfile
|
||||
NewDefaultName: DestructibleChunkProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.BreakableGlassPattern
|
||||
NewPath: Destruction/BreakableGlassPattern
|
||||
NewDefaultName: BreakableGlassPattern
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.CubeGameWaveType
|
||||
NewPath: Misc/CubeGameWaveType
|
||||
NewDefaultName: CubeGameWaveType
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.CubeGameWaveElement
|
||||
NewPath: Misc/CubeGameWaveElement
|
||||
NewDefaultName: CubeGameWaveElement
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.CubeGameWaveSequence
|
||||
NewPath: Misc/CubeGameWaveSequence
|
||||
NewDefaultName: CubeGameWaveSequence
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.UberShatterableDamageConfig
|
||||
NewPath: Destruction/UberShatterableDamageConfig
|
||||
NewDefaultName: UberShatterableDamageConfig
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.UberShatterableMeshDecalConfig
|
||||
NewPath: Destruction/UberShatterableMeshDecalConfig
|
||||
NewDefaultName: UberShatterableMeshDecalConfig
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.BallisticChart
|
||||
NewPath: Ballistics/BallisticChart
|
||||
NewDefaultName: BallisticChart
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.PMaterialDefinition
|
||||
NewPath: Misc/PMaterialDefinition
|
||||
NewDefaultName: PMaterialDefinition
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.MatDef
|
||||
NewPath: Misc/MatDef
|
||||
NewDefaultName: MatDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.FVRControllerDefinition
|
||||
NewPath: Misc/FVRControllerDefinition
|
||||
NewDefaultName: FVRControllerDefinition
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.FVREntityFlagUsage
|
||||
NewPath: Misc/FVREntityFlagUsage
|
||||
NewDefaultName: FVREntityFlagUsage
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.FVREntityDefinition
|
||||
NewPath: Misc/FVREntityDefinition
|
||||
NewDefaultName: FVREntityDefinition
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.HG_ModeProfile
|
||||
NewPath: Misc/HG_ModeProfile
|
||||
NewDefaultName: HG_ModeProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.MF_SquadDefinition
|
||||
NewPath: Misc/MF_SquadDefinition
|
||||
NewDefaultName: MF_SquadDefinition
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.MG_EventAIConfig
|
||||
NewPath: Misc/MG_EventAIConfig
|
||||
NewDefaultName: MG_EventAIConfig
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.MG_IncidenceChart
|
||||
NewPath: Misc/MG_IncidenceChart
|
||||
NewDefaultName: MG_IncidenceChart
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.OmniSequencerSequenceDefinition
|
||||
NewPath: Misc/OmniSequencerSequenceDefinition
|
||||
NewDefaultName: OmniSequencerSequenceDefinition
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.SV_LootTable
|
||||
NewPath: Misc/SV_LootTable
|
||||
NewDefaultName: SV_LootTable
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.wwBotWurstConfig
|
||||
NewPath: Misc/wwBotWurstConfig
|
||||
NewDefaultName: wwBotWurstConfig
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.wwMagicKeypadHash
|
||||
NewPath: Misc/wwMagicKeypadHash
|
||||
NewDefaultName: wwMagicKeypadHash
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.SlideSequenceDef
|
||||
NewPath: Misc/SlideSequenceDef
|
||||
NewDefaultName: SlideSequenceDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.PTargetCategoryDic
|
||||
NewPath: Misc/PTargetCategoryDic
|
||||
NewDefaultName: PTargetCategoryDic
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ReticleColorProgression
|
||||
NewPath: Misc/ReticleColorProgression
|
||||
NewDefaultName: ReticleColorProgression
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.FVRHapticBuzzProfile
|
||||
NewPath: Misc/FVRHapticBuzzProfile
|
||||
NewDefaultName: FVRHapticBuzzProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ItemSpawnerCategoryDefinitionsV2
|
||||
NewPath: ItemSpawner/ItemSpawnerCategoryDefinitionsV2
|
||||
NewDefaultName: ItemSpawnerCategoryDefinitionsV2
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ItemSpawnerNewItemManifest
|
||||
NewPath: ItemSpawner/ItemSpawnerNewItemManifest
|
||||
NewDefaultName: ItemSpawnerNewItemManifest
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ItemSpawnerV2TagCatDef
|
||||
NewPath: ItemSpawner/ItemSpawnerV2TagCatDef
|
||||
NewDefaultName: ItemSpawnerV2TagCatDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.EquipmentPoolDef
|
||||
NewPath: TNH/EquipmentPoolDef
|
||||
NewDefaultName: EquipmentPoolDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.TNH_CharacterDef
|
||||
NewPath: TNH/TNH_CharacterDef
|
||||
NewDefaultName: TNH_CharacterDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.ObjectTableDef
|
||||
NewPath: TNH/ObjectTableDef
|
||||
NewDefaultName: ObjectTableDef
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.TNH_PointSequence
|
||||
NewPath: TNH/TNH_PointSequence
|
||||
NewDefaultName: TNH_PointSequence
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.PTargetProfile
|
||||
NewPath: Misc/PTargetProfile
|
||||
NewDefaultName: PTargetProfile
|
||||
NewOrder: 0
|
||||
- ScriptableObjectName: FistVR.TutorialBlock
|
||||
NewPath: ItemSpawner/TutorialBlock
|
||||
NewDefaultName: TutorialBlock
|
||||
NewOrder: 0
|
||||
@@ -1,7 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4e6f6c2117595b4697d03c8b3545474
|
||||
timeCreated: 1629140350
|
||||
licenseType: Pro
|
||||
guid: ef60ed33189250d4c8b65b237758ad95
|
||||
timeCreated: 1645904809
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
@@ -1,126 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
public static partial class MeatKit
|
||||
{
|
||||
private const string EditorAssemblyPath = "Library/ScriptAssemblies/";
|
||||
public const string BundleOutputPath = "AssetBundles/";
|
||||
|
||||
private static void ExportEditorAssembly(string folder)
|
||||
{
|
||||
if (!File.Exists(EditorAssemblyPath + AssemblyName + ".dll")) return;
|
||||
|
||||
// Delete the old file
|
||||
var settings = BuildWindow.SelectedProfile;
|
||||
var exportPath = folder + settings.PackageName + ".dll";
|
||||
if (File.Exists(exportPath)) File.Delete(exportPath);
|
||||
|
||||
var rParams = new ReaderParameters
|
||||
{
|
||||
AssemblyResolver =
|
||||
new RedirectedAssemblyResolver(Path.GetDirectoryName(typeof(UnityEngine.Object).Assembly.Location))
|
||||
};
|
||||
|
||||
// Get the MeatKitPlugin class and rename it
|
||||
string tempFile = Path.GetTempFileName();
|
||||
File.Copy(EditorAssemblyPath + AssemblyName + ".dll", tempFile, true);
|
||||
using (var asm = AssemblyDefinition.ReadAssembly(tempFile, rParams))
|
||||
{
|
||||
var plugin = asm.MainModule.GetType("MeatKitPlugin");
|
||||
plugin.Name = settings.PackageName + "Plugin";
|
||||
|
||||
// This is some quantum bullshit.
|
||||
// If you don't enumerate the constructor arguments for attributes their values aren't updated correctly.
|
||||
foreach (var x in GetAllCustomAttributes(asm).SelectMany(a => a.ConstructorArguments))
|
||||
{
|
||||
}
|
||||
|
||||
// Get the BepInPlugin attribute and replace the values in it with our own
|
||||
var str = asm.MainModule.TypeSystem.String;
|
||||
var guid = settings.Author + "." + settings.PackageName;
|
||||
var pluginAttribute = plugin.CustomAttributes.First(a => a.AttributeType.Name == "BepInPlugin");
|
||||
pluginAttribute.ConstructorArguments[0] = new CustomAttributeArgument(str, guid);
|
||||
pluginAttribute.ConstructorArguments[1] = new CustomAttributeArgument(str, settings.PackageName);
|
||||
pluginAttribute.ConstructorArguments[2] = new CustomAttributeArgument(str, settings.Version);
|
||||
|
||||
// Get the LoadAssets method and make a new body for it
|
||||
var loadAssetsMethod = plugin.Methods.First(m => m.Name == "LoadAssets");
|
||||
loadAssetsMethod.Body = new MethodBody(loadAssetsMethod);
|
||||
var il = loadAssetsMethod.Body.GetILProcessor();
|
||||
|
||||
// Let any build items insert their own code in here
|
||||
foreach (var item in settings.BuildItems)
|
||||
item.GenerateLoadAssets(plugin, il);
|
||||
|
||||
// Insert a ret at the end so it's valid
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
// Module name needs to be changed away from Assembly-CSharp.dll because it is a reserved name.
|
||||
asm.Name = new AssemblyNameDefinition(settings.PackageName, asm.Name.Version);
|
||||
asm.MainModule.Name = settings.PackageName + ".dll";
|
||||
|
||||
// References to renamed unity code must be swapped out.
|
||||
foreach (var ii in asm.MainModule.AssemblyReferences)
|
||||
switch (ii.Name)
|
||||
{
|
||||
case AssemblyRename:
|
||||
ii.Name = AssemblyName;
|
||||
break;
|
||||
case AssemblyFirstpassRename:
|
||||
ii.Name = AssemblyFirstpassName;
|
||||
break;
|
||||
}
|
||||
|
||||
if (BuildWindow.SelectedProfile.StripNamespaces)
|
||||
{
|
||||
// Remove types not in an allowed namespace or the global namespace
|
||||
string[] allowedNamespaces = BuildWindow.SelectedProfile.GetAllAllowedNamespaces();
|
||||
List<TypeDefinition> typesToRemove = new List<TypeDefinition>();
|
||||
foreach (var type in asm.MainModule.Types)
|
||||
{
|
||||
if (type.Namespace == "" || allowedNamespaces.Any(x => type.Namespace.Contains(x)))
|
||||
continue;
|
||||
typesToRemove.Add(type);
|
||||
}
|
||||
|
||||
foreach (var type in typesToRemove) asm.MainModule.Types.Remove(type);
|
||||
}
|
||||
|
||||
// Remove the same types we didn't want to import. This cannot be skipped.
|
||||
foreach (var type in StripAssemblyTypes
|
||||
.Select(x => asm.MainModule.GetType(x))
|
||||
.Where(x => x != null))
|
||||
asm.MainModule.Types.Remove(type);
|
||||
|
||||
try
|
||||
{
|
||||
// Save it
|
||||
asm.Write(exportPath);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new MeatKitBuildException("Unable to write exported scripts file. This is likely due to namespace stripping being enabled and a required namespace is not whitelisted.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temp file now that we're done.
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
private static IEnumerable<CustomAttribute> GetAllCustomAttributes(AssemblyDefinition asm)
|
||||
{
|
||||
foreach (var type in asm.MainModule.Types)
|
||||
{
|
||||
foreach (var attrib in type.CustomAttributes) yield return attrib;
|
||||
foreach (CustomAttribute attrib in type.Methods.SelectMany(method => method.CustomAttributes))
|
||||
yield return attrib;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
fileFormatVersion: 2
|
||||
guid: c7e21420a1d84ca5947b2fd9eb9db6d8
|
||||
timeCreated: 1628213934
|
||||
timeCreated: 1649523855
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
[CreateAssetMenu(menuName = "MeatKit/Assembly Editors/Path Replacer", fileName = "New Path Replacer")]
|
||||
public class CreatePathModifier : AssemblyModifier
|
||||
{
|
||||
[Tooltip("The new path replacements")]
|
||||
public ReplacementPath[] ReplacementPaths = new ReplacementPath[0];
|
||||
|
||||
public override void ApplyModification(AssemblyDefinition assembly)
|
||||
{
|
||||
TypeReference stringRef = assembly.MainModule.TypeSystem.String;
|
||||
TypeReference intRef = assembly.MainModule.TypeSystem.Int32;
|
||||
if (stringRef == null || intRef == null) return;
|
||||
|
||||
foreach (ReplacementPath replacementPath in ReplacementPaths)
|
||||
{
|
||||
TypeReference type = assembly.MainModule.GetType(replacementPath.ScriptableObjectName);
|
||||
if (type == null) continue;
|
||||
|
||||
TypeDefinition definition = type.Resolve();
|
||||
CustomAttribute createMenuAttribute = GetCreateAssetMenuAttribute(definition);
|
||||
|
||||
if (createMenuAttribute == null)
|
||||
{
|
||||
Debug.LogWarning("Could not get CreateAssetMenuAttribute for scriptable object: " + replacementPath.ScriptableObjectName);
|
||||
continue;
|
||||
}
|
||||
|
||||
CustomAttributeArgument pathArgumentValue = new CustomAttributeArgument(stringRef, replacementPath.NewPath);
|
||||
CustomAttributeArgument fileNameArgumentValue = new CustomAttributeArgument(stringRef, replacementPath.NewDefaultName);
|
||||
CustomAttributeArgument orderArgumentValue = new CustomAttributeArgument(intRef, replacementPath.NewOrder);
|
||||
|
||||
CustomAttributeNamedArgument pathArgument = new CustomAttributeNamedArgument("menuName", pathArgumentValue);
|
||||
CustomAttributeNamedArgument fileNameArgument = new CustomAttributeNamedArgument("fileName", fileNameArgumentValue);
|
||||
CustomAttributeNamedArgument orderArgument = new CustomAttributeNamedArgument("order", orderArgumentValue);
|
||||
|
||||
createMenuAttribute.Properties.Clear();
|
||||
createMenuAttribute.Properties.Add(pathArgument);
|
||||
createMenuAttribute.Properties.Add(fileNameArgument);
|
||||
createMenuAttribute.Properties.Add(orderArgument);
|
||||
}
|
||||
|
||||
Applied = true;
|
||||
}
|
||||
|
||||
private CustomAttribute GetCreateAssetMenuAttribute(TypeDefinition definition)
|
||||
{
|
||||
CustomAttribute[] foundAttributes = definition.CustomAttributes.Where(ca => ca.AttributeType.FullName.Contains("CreateAssetMenuAttribute")).ToArray();
|
||||
|
||||
if(foundAttributes.Length > 0)
|
||||
{
|
||||
return foundAttributes[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public struct ReplacementPath
|
||||
{
|
||||
[Tooltip("Specify the FULL NAME of the scriptable object you wish to modify. e.g. Sub.Namespace.Type")]
|
||||
public string ScriptableObjectName;
|
||||
|
||||
[Tooltip("The new create asset path of the scriptable object")]
|
||||
public string NewPath;
|
||||
|
||||
[Tooltip("The new default name of the scriptable object when created")]
|
||||
public string NewDefaultName;
|
||||
|
||||
[Tooltip("The new ordering of the scriptable object in menu")]
|
||||
public int NewOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4607bcf07fdb67428d41b6bd2f9b2fb
|
||||
timeCreated: 1640645560
|
||||
guid: 6389bd26f6b33074ba8afe182d11c33d
|
||||
timeCreated: 1649523850
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -18,8 +19,28 @@ namespace MeatKit
|
||||
|
||||
public override void ApplyModification(AssemblyDefinition assembly)
|
||||
{
|
||||
// Try to get this type from the assembly. If it doesn't exist, we can just skip.
|
||||
TypeReference type = assembly.MainModule.GetType(EnumName);
|
||||
// Try to get the enum type. If it contains a '+' in the name, it's nested and we have to do a bit of extra stuff
|
||||
TypeDefinition type;
|
||||
if (EnumName.Contains("+"))
|
||||
{
|
||||
|
||||
string[] parts = EnumName.Split('+');
|
||||
type = assembly.MainModule.GetType(parts[0]);
|
||||
if (type != null)
|
||||
{
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
{
|
||||
Debug.Log(type);
|
||||
type = type.NestedTypes.FirstOrDefault(x => x.Name == parts[i]);
|
||||
if (type == null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we can just grab it directly if it isn't nested
|
||||
else type = assembly.MainModule.GetType(EnumName);
|
||||
|
||||
// If we can't find the type, skip.
|
||||
if (type == null) return;
|
||||
|
||||
var definition = type.Resolve();
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
fileFormatVersion: 2
|
||||
guid: 486e27304e8449efb6c6136482952c4d
|
||||
timeCreated: 1628213734
|
||||
timeCreated: 1649523858
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -12,8 +12,10 @@ namespace MeatKit
|
||||
"FistVR.FireArmRoundType",
|
||||
"FistVR.FireArmRoundClass",
|
||||
"FistVR.FireArmMagazineType",
|
||||
"FistVR.ItemSpawnerObjectDefinition.ItemSpawnerCategory",
|
||||
"FistVR.SosigEnemyID"
|
||||
"FistVR.ItemSpawnerObjectDefinition+ItemSpawnerCategory",
|
||||
"FistVR.SosigEnemyID",
|
||||
"FistVR.FVRFireArmAttachementMountType",
|
||||
"FistVR.FireArmClipType"
|
||||
};
|
||||
|
||||
private SerializedProperty _addedValues;
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
fileFormatVersion: 2
|
||||
guid: 4980597d341c4eed913ae30680f3f9f3
|
||||
timeCreated: 1628218472
|
||||
timeCreated: 1649523860
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
@@ -14,6 +14,8 @@ namespace MeatKit
|
||||
{
|
||||
public static void DoBuild()
|
||||
{
|
||||
BuildLog.StartNew();
|
||||
|
||||
try
|
||||
{
|
||||
DoBuildInternal();
|
||||
@@ -23,13 +25,17 @@ namespace MeatKit
|
||||
string message = e.Message;
|
||||
if (e.InnerException != null) message += "\n\n" + e.InnerException.Message;
|
||||
EditorUtility.DisplayDialog("Build failed", message, "Ok.");
|
||||
BuildLog.SetCompletionStatus(true, "MeatKit Build Exception", e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Build failed with unknown error",
|
||||
"Error message: " + e.Message + "\n\nCheck console for full exception text.", "Ok.");
|
||||
Debug.LogException(e);
|
||||
BuildLog.SetCompletionStatus(true, "Unexpected exception during build", e);
|
||||
}
|
||||
|
||||
BuildLog.Finish();
|
||||
}
|
||||
|
||||
private static void DoBuildInternal()
|
||||
@@ -41,6 +47,8 @@ namespace MeatKit
|
||||
BuildProfile profile = BuildWindow.SelectedProfile;
|
||||
if (!profile) return;
|
||||
|
||||
string bundleOutputPath = profile.ExportPath;
|
||||
|
||||
// Start a stopwatch to time the build
|
||||
Stopwatch sw = Stopwatch.StartNew();
|
||||
|
||||
@@ -48,39 +56,66 @@ namespace MeatKit
|
||||
if (!profile.EnsureValidForEditor()) return;
|
||||
|
||||
// Clean the output folder
|
||||
CleanBuild();
|
||||
BuildLog.WriteLine("Cleaning build folder");
|
||||
CleanBuild(profile);
|
||||
|
||||
// And export the assembly to the folder
|
||||
ExportEditorAssembly(BundleOutputPath);
|
||||
|
||||
// Then get their asset bundle configurations
|
||||
var bundles = profile.BuildItems.SelectMany(x => x.ConfigureBuild()).ToArray();
|
||||
|
||||
BuildPipeline.BuildAssetBundles(BundleOutputPath, bundles, BuildAssetBundleOptions.None,
|
||||
BuildTarget.StandaloneWindows64);
|
||||
|
||||
// Cleanup the unused files created with building the bundles
|
||||
foreach (var file in Directory.GetFiles(BundleOutputPath, "*.manifest"))
|
||||
File.Delete(file);
|
||||
File.Delete(Path.Combine(BundleOutputPath, "AssetBundles"));
|
||||
|
||||
// With the bundles done building we can process them
|
||||
// Make a copy of the editor assembly because when we build an asset bundle, Unity will delete it
|
||||
string editorAssembly = EditorAssemblyPath + AssemblyName + ".dll";
|
||||
string tempAssemblyFile = Path.GetTempFileName();
|
||||
BuildLog.WriteLine("Copying editor assembly: " + editorAssembly + " -> " + tempAssemblyFile);
|
||||
File.Copy(editorAssembly, tempAssemblyFile, true);
|
||||
|
||||
// Make sure we have the virtual reality supported checkbox enabled
|
||||
// If this is not set to true when we build our asset bundles, the shaders will not compile correctly
|
||||
BuildLog.WriteLine("Forcing VR support on");
|
||||
bool wasVirtualRealitySupported = PlayerSettings.virtualRealitySupported;
|
||||
PlayerSettings.virtualRealitySupported = true;
|
||||
|
||||
// Create a map of assembly names to what we want to rename them to, then enable bundle processing
|
||||
var replaceMap = new Dictionary<string, string>
|
||||
{
|
||||
{"Assembly-CSharp.dll", profile.PackageName + ".dll"},
|
||||
{"Assembly-CSharp-firstpass.dll", profile.PackageName + "-firstpass.dll"},
|
||||
{"H3VRCode-CSharp.dll", "Assembly-CSharp.dll"},
|
||||
{"H3VRCode-CSharp-firstpass.dll", "Assembly-CSharp-firstpass.dll"}
|
||||
{AssemblyName + ".dll", profile.PackageName + ".dll"},
|
||||
{AssemblyFirstpassName + ".dll", profile.PackageName + "-firstpass.dll"},
|
||||
{AssemblyRename + ".dll", AssemblyName + ".dll"},
|
||||
{AssemblyFirstpassRename + ".dll", AssemblyFirstpassName + ".dll"}
|
||||
};
|
||||
BuildLog.WriteLine("Enabling bundle processing.");
|
||||
BuildLog.WriteLine("Replace map:");
|
||||
foreach (var key in replaceMap.Keys)
|
||||
BuildLog.WriteLine(" " + key + " -> " + replaceMap[key]);
|
||||
BuildLog.WriteLine("Ignored types (Assembly-CSharp.dll):");
|
||||
foreach (var type in StripAssemblyTypes)
|
||||
BuildLog.WriteLine(" " + type);
|
||||
AssetBundleIO.EnableProcessing(replaceMap, false, true);
|
||||
|
||||
foreach (var bundle in bundles)
|
||||
{
|
||||
var path = Path.Combine(BundleOutputPath, bundle.assetBundleName);
|
||||
ProcessBundle(path, path, replaceMap, profile.BundleCompressionType);
|
||||
}
|
||||
|
||||
// Get the list of asset bundle configurations and build them
|
||||
BuildLog.WriteLine("Collecting bundles from build items");
|
||||
var bundles = profile.BuildItems.SelectMany(x => x.ConfigureBuild()).ToArray();
|
||||
BuildLog.WriteLine(bundles.Length + " bundles to build. Building bundles.");
|
||||
BuildPipeline.BuildAssetBundles(bundleOutputPath, bundles, BuildAssetBundleOptions.ChunkBasedCompression,
|
||||
BuildTarget.StandaloneWindows64);
|
||||
|
||||
// Disable bundle processing now that we're done with it.
|
||||
AssetBundleIO.DisableProcessing();
|
||||
var requiredScripts = AssetBundleIO.SerializedScriptNames;
|
||||
BuildLog.WriteLine("Bundles built");
|
||||
|
||||
// Cleanup the unused files created with building the bundles
|
||||
BuildLog.WriteLine("Cleaning unused files");
|
||||
foreach (var file in Directory.GetFiles(bundleOutputPath, "*.manifest"))
|
||||
File.Delete(file);
|
||||
File.Delete(Path.Combine(bundleOutputPath, profile.Version));
|
||||
|
||||
// Reset the virtual reality supported checkbox, so if the user had it disabled it will stay disabled
|
||||
PlayerSettings.virtualRealitySupported = wasVirtualRealitySupported;
|
||||
|
||||
// And export the assembly to the folder
|
||||
BuildLog.WriteLine("Exporting editor assembly");
|
||||
ExportEditorAssembly(bundleOutputPath, tempAssemblyFile, requiredScripts);
|
||||
|
||||
// Now we can write the Thunderstore stuff to the folder
|
||||
profile.WriteThunderstoreManifest(BundleOutputPath + "manifest.json");
|
||||
BuildLog.WriteLine("Writing Thunderstore manifest");
|
||||
profile.WriteThunderstoreManifest(bundleOutputPath + "manifest.json");
|
||||
|
||||
// Check if the icon is already 256x256
|
||||
Texture2D icon = profile.Icon;
|
||||
@@ -90,6 +125,7 @@ namespace MeatKit
|
||||
if (!importSettings.isReadable ||
|
||||
importSettings.textureCompression != TextureImporterCompression.Uncompressed)
|
||||
{
|
||||
BuildLog.WriteLine("Fixing icon import settings");
|
||||
importSettings.isReadable = true;
|
||||
importSettings.textureCompression = TextureImporterCompression.Uncompressed;
|
||||
importSettings.SaveAndReimport();
|
||||
@@ -98,41 +134,48 @@ namespace MeatKit
|
||||
if (profile.Icon.width != 256 || profile.Icon.height != 256)
|
||||
{
|
||||
// Resize it for the build
|
||||
BuildLog.WriteLine("Icon was not 256x256, resizing");
|
||||
icon = icon.ScaleTexture(256, 256);
|
||||
}
|
||||
|
||||
// Write the texture to file
|
||||
File.WriteAllBytes(BundleOutputPath + "icon.png", icon.EncodeToPNG());
|
||||
BuildLog.WriteLine("Saving icon");
|
||||
File.WriteAllBytes(bundleOutputPath + "icon.png", icon.EncodeToPNG());
|
||||
|
||||
// Copy the readme
|
||||
File.Copy(AssetDatabase.GetAssetPath(profile.ReadMe), BundleOutputPath + "README.md");
|
||||
BuildLog.WriteLine("Copying readme");
|
||||
File.Copy(AssetDatabase.GetAssetPath(profile.ReadMe), bundleOutputPath + "README.md");
|
||||
|
||||
string packageName = profile.Author + "-" + profile.PackageName;
|
||||
if (profile.BuildAction == BuildAction.CopyToProfile)
|
||||
{
|
||||
BuildLog.WriteLine("Copying built files to profile");
|
||||
string pluginFolder = Path.Combine(profile.OutputProfile, "BepInEx/plugins/" + packageName);
|
||||
if (Directory.Exists(pluginFolder)) Directory.Delete(pluginFolder, true);
|
||||
Directory.CreateDirectory(pluginFolder);
|
||||
Extensions.CopyFilesRecursively(BundleOutputPath, pluginFolder);
|
||||
Extensions.CopyFilesRecursively(bundleOutputPath, pluginFolder);
|
||||
}
|
||||
else if (profile.BuildAction == BuildAction.CreateThunderstorePackage)
|
||||
{
|
||||
BuildLog.WriteLine("Zipping built files");
|
||||
using (var zip = new ZipFile())
|
||||
{
|
||||
zip.AddDirectory(BundleOutputPath, "");
|
||||
zip.Save(Path.Combine(BundleOutputPath, packageName + ".zip"));
|
||||
zip.AddDirectory(bundleOutputPath, "");
|
||||
zip.Save(Path.Combine(bundleOutputPath, packageName + "-" + profile.Version + ".zip"));
|
||||
}
|
||||
}
|
||||
|
||||
// End the stopwatch and save the time
|
||||
BuildLog.SetCompletionStatus(false, "", null);
|
||||
MeatKitCache.LastBuildDuration = sw.Elapsed;
|
||||
MeatKitCache.LastBuildTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public static void CleanBuild()
|
||||
public static void CleanBuild(BuildProfile profile)
|
||||
{
|
||||
if (Directory.Exists(BundleOutputPath)) Directory.Delete(BundleOutputPath, true);
|
||||
Directory.CreateDirectory(BundleOutputPath);
|
||||
string outputPath = profile.ExportPath;
|
||||
if (Directory.Exists(outputPath)) Directory.Delete(outputPath, true);
|
||||
Directory.CreateDirectory(outputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d18106ea7c52411db45cabd362f21f16
|
||||
timeCreated: 1640061580
|
||||
licenseType: Pro
|
||||
timeCreated: 1649523901
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 151c1f5398ee70041a49c417b23f1846, type: 3}
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6d6db4144b34551885c304840edfb62
|
||||
timeCreated: 1640061353
|
||||
licenseType: Pro
|
||||
timeCreated: 1649523904
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 6fae6dfd178cd184180013acef55632c, type: 3}
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
public static class BuildLog
|
||||
{
|
||||
private static StringWriter _temp;
|
||||
private static Stopwatch _sw;
|
||||
private static DateTime _startTime;
|
||||
private static bool _failed;
|
||||
private static string _completionMessage;
|
||||
private static Exception _exception;
|
||||
|
||||
public static void StartNew()
|
||||
{
|
||||
_temp = new StringWriter();
|
||||
_sw = Stopwatch.StartNew();
|
||||
_startTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public static void WriteLine(string text)
|
||||
{
|
||||
if (_temp == null) return;
|
||||
_temp.WriteLine(text);
|
||||
}
|
||||
|
||||
public static void SetCompletionStatus(bool failed, string message, Exception exception)
|
||||
{
|
||||
_failed = failed;
|
||||
_completionMessage = message;
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public static void Finish()
|
||||
{
|
||||
_sw.Stop();
|
||||
|
||||
StreamWriter output = new StreamWriter("AssetBundles/buildlog.txt", false);
|
||||
|
||||
WriteProfileInfo(output);
|
||||
output.WriteLine();
|
||||
output.WriteLine("--- MeatKit Build Log ---");
|
||||
output.WriteLine("Start Time: " + _startTime.ToString("dddd, dd MMMM yyyy HH:mm:ssK"));
|
||||
output.WriteLine("Duration : " + _sw.Elapsed.GetReadableTimespan());
|
||||
output.WriteLine("Status : " + (_failed ? "FAILED" : "COMPLETED"));
|
||||
if (!string.IsNullOrEmpty(_completionMessage))
|
||||
output.WriteLine("Message : " + _completionMessage);
|
||||
if (_exception != null)
|
||||
{
|
||||
output.WriteLine("Exception :");
|
||||
output.WriteLine(_exception.ToString());
|
||||
}
|
||||
|
||||
output.WriteLine("\n--- Full build log ---");
|
||||
output.Write(_temp.ToString());
|
||||
|
||||
output.Close();
|
||||
output.Dispose();
|
||||
_temp = null;
|
||||
}
|
||||
|
||||
private static void WriteProfileInfo(StreamWriter output)
|
||||
{
|
||||
var profile = BuildWindow.SelectedProfile;
|
||||
var implicitDependencies = profile.GetRequiredDependencies();
|
||||
|
||||
output.WriteLine("--- Selected Build Profile ---");
|
||||
output.WriteLine("Thunderstore Metadata");
|
||||
output.WriteLine(" Package Name: " + profile.PackageName);
|
||||
output.WriteLine(" Author : " + profile.Author);
|
||||
output.WriteLine(" Version : " + profile.Version);
|
||||
output.WriteLine(" Icon Set : " + (profile.Icon == null ? "No" : "Yes"));
|
||||
output.WriteLine(" Readme Set : " + (profile.ReadMe == null ? "No" : "Yes"));
|
||||
output.WriteLine(" Website URL : " + profile.WebsiteURL);
|
||||
output.WriteLine(" Description : " + profile.Description);
|
||||
output.WriteLine(" Implicit Dependencies : (" + implicitDependencies.Length + ")");
|
||||
foreach (var dependency in implicitDependencies)
|
||||
output.WriteLine(" " + dependency);
|
||||
output.WriteLine(" Additional Dependencies: (" + profile.AdditionalDependencies.Length + ")");
|
||||
foreach (var dependency in profile.AdditionalDependencies)
|
||||
output.WriteLine(" " + dependency);
|
||||
|
||||
output.WriteLine("Script Options");
|
||||
output.WriteLine(" Strip Namespaces : " + profile.StripNamespaces);
|
||||
output.WriteLine(" Additional Namespaces: (" + profile.AdditionalNamespaces.Length + ")");
|
||||
foreach (var @namespace in profile.AdditionalNamespaces)
|
||||
output.WriteLine(" " + @namespace);
|
||||
output.WriteLine(" Apply Harmony Patches: " + profile.ApplyHarmonyPatches);
|
||||
|
||||
output.WriteLine("Export Options");
|
||||
output.WriteLine(" Build Items: (" + profile.BuildItems.Length + ")");
|
||||
foreach (var buildItem in profile.BuildItems)
|
||||
output.WriteLine(" " + buildItem);
|
||||
output.WriteLine(" Build Action: " + profile.BuildAction);
|
||||
output.WriteLine(" Export Path : " + profile.ExportPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f474df2cd776465d8cc9d2f7f52f77c7
|
||||
timeCreated: 1664853706
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AssetsTools.NET;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
@@ -18,6 +17,8 @@ namespace MeatKit
|
||||
[CreateAssetMenu(menuName = "MeatKit/Build Profile")]
|
||||
public class BuildProfile : ScriptableObject, IValidatable
|
||||
{
|
||||
private const string BaseOutputPath = "AssetBundles/";
|
||||
|
||||
[Header("Thunderstore Metadata")]
|
||||
public string PackageName = "";
|
||||
public string Author = "";
|
||||
@@ -31,10 +32,10 @@ namespace MeatKit
|
||||
[Header("Script Options")]
|
||||
public bool StripNamespaces = true;
|
||||
public string[] AdditionalNamespaces = new string[0];
|
||||
|
||||
public bool ApplyHarmonyPatches = true;
|
||||
|
||||
[Header("Export Options")]
|
||||
public BuildItem[] BuildItems = new BuildItem[0];
|
||||
public AssetBundleCompressionType BundleCompressionType = AssetBundleCompressionType.LZ4;
|
||||
public BuildAction BuildAction = BuildAction.JustBuildFiles;
|
||||
|
||||
[HideInInspector]
|
||||
@@ -49,6 +50,11 @@ namespace MeatKit
|
||||
messages["PackageName"] =
|
||||
BuildMessage.Error("Package name can only contain letters, numbers, and underscores.");
|
||||
|
||||
// Author needs to match regex
|
||||
if (!Regex.IsMatch(Author, @"^[a-zA-Z_0-9]+$"))
|
||||
messages["Author"] =
|
||||
BuildMessage.Error("Author can only contain letters, numbers, and underscores.");
|
||||
|
||||
// Make sure the version number is a valid x.x.x
|
||||
if (!Regex.IsMatch(Version, @"^\d+\.\d+\.\d+$"))
|
||||
messages["Version"] = BuildMessage.Error("Version number must be in format 'x.x.x'.");
|
||||
@@ -65,18 +71,8 @@ namespace MeatKit
|
||||
|
||||
if (!ReadMe)
|
||||
messages["ReadMe"] = BuildMessage.Error("Missing readme.");
|
||||
|
||||
switch (BundleCompressionType)
|
||||
{
|
||||
case AssetBundleCompressionType.NONE:
|
||||
messages["BundleCompressionType"] = BuildMessage.Warning(
|
||||
"Uncompressed bundles are not recommended for publication. They can and will be very large.");
|
||||
break;
|
||||
case AssetBundleCompressionType.LZMA:
|
||||
messages["BundleCompressionType"] = BuildMessage.Info(
|
||||
"LZMA can take longer to compress than LZ4, however it will result in smaller file sizes usually.");
|
||||
break;
|
||||
}
|
||||
else if (!AssetDatabase.GetAssetPath(ReadMe).EndsWith(".md", StringComparison.InvariantCultureIgnoreCase))
|
||||
messages["ReadMe"] = BuildMessage.Warning("Are you sure this is a Markdown file? It doesn't have the .md file extension.");
|
||||
|
||||
switch (BuildAction)
|
||||
{
|
||||
@@ -109,11 +105,32 @@ namespace MeatKit
|
||||
|
||||
public bool EnsureValidForEditor()
|
||||
{
|
||||
// Go over each build item
|
||||
BuildLog.WriteLine("Starting build profile check...");
|
||||
|
||||
// Check ourselves
|
||||
bool hasErrors = false, hasWarnings = false;
|
||||
foreach (var item in BuildItems)
|
||||
// Check if it has any validation messages
|
||||
foreach (var message in Validate().Values)
|
||||
{
|
||||
// Log them
|
||||
switch (message.Type)
|
||||
{
|
||||
case MessageType.Error:
|
||||
Debug.LogError(AssetDatabase.GetAssetPath(this) + ": " + message.Message);
|
||||
hasErrors = true;
|
||||
break;
|
||||
case MessageType.Warning:
|
||||
Debug.LogWarning(AssetDatabase.GetAssetPath(this) + ": " + message.Message);
|
||||
hasWarnings = true;
|
||||
break;
|
||||
}
|
||||
|
||||
BuildLog.WriteLine(" " + message.Type + ": " + this + ": " + message.Message);
|
||||
}
|
||||
|
||||
// Go over each build item and check for any validation messages
|
||||
foreach (var item in BuildItems.Where(x => x != null))
|
||||
foreach (var message in item.Validate().Values)
|
||||
{
|
||||
// Log them
|
||||
switch (message.Type)
|
||||
{
|
||||
@@ -125,45 +142,54 @@ namespace MeatKit
|
||||
Debug.LogWarning(AssetDatabase.GetAssetPath(item) + ": " + message.Message);
|
||||
hasWarnings = true;
|
||||
break;
|
||||
case MessageType.Info:
|
||||
Debug.Log(AssetDatabase.GetAssetPath(item) + ": " + message.Message);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
BuildLog.WriteLine(" " + message.Type + ": " + item + ": " + message.Message);
|
||||
}
|
||||
|
||||
|
||||
// If there's errors don't let anything continue
|
||||
if (hasErrors)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Build errors",
|
||||
"There were errors validating your build items. Please check the console for more info.", "Ok.");
|
||||
BuildLog.SetCompletionStatus(true, "Build profile failed one or more checks", null);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there's only warnings, let the user decide if they want to continue
|
||||
if (hasWarnings)
|
||||
return EditorUtility.DisplayDialog("Build warnings",
|
||||
{
|
||||
var continueAnyway = EditorUtility.DisplayDialog("Build warnings",
|
||||
"Some build items validated with warnings. Continue with build anyway?", "Yes", "No");
|
||||
|
||||
// Otherwise continue
|
||||
return true;
|
||||
BuildLog.WriteLine("Build profile has one or more warnings.");
|
||||
BuildLog.WriteLine(" Continue anyway? " + continueAnyway);
|
||||
BuildLog.SetCompletionStatus(true, "User canceled build", null);
|
||||
|
||||
return continueAnyway;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise continue
|
||||
BuildLog.WriteLine(" Build profile passed all checks!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetRequiredDependencies()
|
||||
{
|
||||
return BuildItems
|
||||
.Where(x => x != null)
|
||||
.SelectMany(x => x.RequiredDependencies).ToArray();
|
||||
.SelectMany(x => x.RequiredDependencies)
|
||||
.Distinct().ToArray();
|
||||
}
|
||||
|
||||
public string MainNamespace
|
||||
{
|
||||
get
|
||||
{
|
||||
return Author + "." + PackageName;
|
||||
}
|
||||
get { return Author + "." + PackageName; }
|
||||
}
|
||||
|
||||
|
||||
public string[] GetRequiredNamespaces()
|
||||
{
|
||||
return new[] {MainNamespace};
|
||||
@@ -173,7 +199,12 @@ namespace MeatKit
|
||||
{
|
||||
return GetRequiredNamespaces().Concat(AdditionalNamespaces).ToArray();
|
||||
}
|
||||
|
||||
|
||||
public string ExportPath
|
||||
{
|
||||
get { return Path.Combine(BaseOutputPath, Path.Combine(PackageName, Version)) + Path.DirectorySeparatorChar; }
|
||||
}
|
||||
|
||||
public void WriteThunderstoreManifest(string location)
|
||||
{
|
||||
#if H3VR_IMPORTED
|
||||
@@ -187,7 +218,7 @@ namespace MeatKit
|
||||
// ReSharper disable once CoVariantArrayConversion
|
||||
obj["dependencies"] = new JArray(GetRequiredDependencies().Concat(AdditionalDependencies).ToArray());
|
||||
|
||||
File.WriteAllText(location, JsonConvert.SerializeObject(obj));
|
||||
File.WriteAllText(location, JsonConvert.SerializeObject(obj,Formatting.Indented));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -198,4 +229,4 @@ namespace MeatKit
|
||||
CopyToProfile,
|
||||
CreateThunderstorePackage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
fileFormatVersion: 2
|
||||
guid: afed54a239594b8abd631a8047a54987
|
||||
timeCreated: 1635004125
|
||||
timeCreated: 1649524426
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- Icon: {instanceID: 0}
|
||||
- ReadMe: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@@ -4,9 +4,12 @@ namespace MeatKit
|
||||
{
|
||||
public class MeatKitBuildException : Exception
|
||||
{
|
||||
public MeatKitBuildException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public MeatKitBuildException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AssetsTools.NET;
|
||||
using AssetsTools.NET.Extra;
|
||||
using UnityEditor;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
public static partial class MeatKit
|
||||
{
|
||||
private static void ProcessBundle(string source, string destination, IDictionary<string, string> replaceMap,
|
||||
AssetBundleCompressionType recompressAs)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Step 1: Load the asset bundle.
|
||||
EditorUtility.DisplayProgressBar("Processing bundle", "Loading asset bundle...", 0f);
|
||||
var am = new AssetsManager();
|
||||
var bundle = am.LoadBundleFile(source);
|
||||
var assets = am.LoadAssetsFileFromBundle(bundle, 0);
|
||||
|
||||
// Step 2: For each MonoScript asset, alter it's assembly name
|
||||
EditorUtility.DisplayProgressBar("Processing bundle", "Modifying assets...", 0.33f);
|
||||
var modifications = new List<AssetsReplacer>();
|
||||
foreach (AssetFileInfoEx assetInfo in assets.table.assetFileInfo)
|
||||
{
|
||||
// We only want MonoScripts (type 115)
|
||||
if (assetInfo.curFileType != 115) continue;
|
||||
|
||||
// Get the field for this asset
|
||||
var field = am.GetTypeInstance(assets, assetInfo).GetBaseField();
|
||||
var assemblyNameValue = field["m_AssemblyName"].GetValue();
|
||||
|
||||
// Check if we want to replace this name
|
||||
var asmName = assemblyNameValue.AsString();
|
||||
if (replaceMap.ContainsKey(asmName))
|
||||
{
|
||||
// Modify it's assembly name
|
||||
assemblyNameValue.Set(replaceMap[asmName]);
|
||||
|
||||
// Write the modifications to the list
|
||||
var newBytes = field.WriteToByteArray();
|
||||
modifications.Add(new AssetsReplacerFromMemory(0, assetInfo.index, (int) assetInfo.curFileType,
|
||||
0xFFFF, newBytes));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Write the modified assets back into an uncompressed bundle
|
||||
EditorUtility.DisplayProgressBar("Processing bundle", "Saving changes...", 0.66f);
|
||||
using (var fileStream = new FileStream(destination + ".uncompressed", FileMode.Create))
|
||||
{
|
||||
var bunRepl = new BundleReplacerFromAssets(assets.name, assets.name, assets.file, modifications);
|
||||
var bunWriter = new AssetsFileWriter(fileStream);
|
||||
bundle.file.Write(bunWriter, new List<BundleReplacer> {bunRepl});
|
||||
}
|
||||
|
||||
// Unload the existing bundle
|
||||
am.UnloadAll();
|
||||
|
||||
// Step 4: Re-compress the bundle if requested
|
||||
EditorUtility.DisplayProgressBar("Processing bundle", "Recompressing bundle...", 1f);
|
||||
if (recompressAs != AssetBundleCompressionType.NONE)
|
||||
{
|
||||
var compressedBundle = am.LoadBundleFile(destination + ".uncompressed");
|
||||
using (var fs = File.OpenWrite(destination))
|
||||
using (var writer = new AssetsFileWriter(fs))
|
||||
{
|
||||
compressedBundle.file.Pack(compressedBundle.file.reader, writer, recompressAs);
|
||||
}
|
||||
|
||||
am.UnloadAll();
|
||||
File.Delete(destination + ".uncompressed");
|
||||
}
|
||||
else File.Move(destination + ".uncompressed", destination);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69efae90f6bb4c3eadcd9e7c4af6ec67
|
||||
timeCreated: 1617337071
|
||||
@@ -1,8 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fd76bb12fd5fae48a3e952d8020bef4
|
||||
guid: 0b75c98df00b4b55b3642b3aed976883
|
||||
folderAsset: yes
|
||||
timeCreated: 1655428806
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BepInEx;
|
||||
using HarmonyLib;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using MethodBody = Mono.Cecil.Cil.MethodBody;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
public static partial class MeatKit
|
||||
{
|
||||
private const string EditorAssemblyPath = "Library/ScriptAssemblies/";
|
||||
|
||||
private static void ExportEditorAssembly(string folder, string tempFile = null,
|
||||
Dictionary<string, List<string>> requiredScripts = null)
|
||||
{
|
||||
// Make a copy of the file if we aren't already given one
|
||||
string editorAssembly = EditorAssemblyPath + AssemblyName + ".dll";
|
||||
if (!File.Exists(editorAssembly) && !File.Exists(tempFile))
|
||||
{
|
||||
throw new MeatKitBuildException("Editor assembly missing! Can't export scripts.");
|
||||
}
|
||||
if (string.IsNullOrEmpty(tempFile))
|
||||
{
|
||||
tempFile = Path.GetTempFileName();
|
||||
File.Copy(editorAssembly, tempFile, true);
|
||||
}
|
||||
|
||||
// Delete the old file
|
||||
var settings = BuildWindow.SelectedProfile;
|
||||
var exportPath = folder + settings.PackageName + ".dll";
|
||||
if (File.Exists(exportPath)) File.Delete(exportPath);
|
||||
|
||||
var rParams = new ReaderParameters
|
||||
{
|
||||
AssemblyResolver =
|
||||
new RedirectedAssemblyResolver(Path.GetDirectoryName(typeof(UnityEngine.Object).Assembly.Location), ManagedDirectory)
|
||||
};
|
||||
|
||||
// Get the MeatKitPlugin class and rename it
|
||||
using (var asm = AssemblyDefinition.ReadAssembly(tempFile, rParams))
|
||||
{
|
||||
// Locate the plugin class for this profile and set it's name and namespace
|
||||
string mainNamespace = BuildWindow.SelectedProfile.MainNamespace;
|
||||
var plugin = FindPluginClass(asm.MainModule, mainNamespace);
|
||||
BuildLog.WriteLine("Using plugin class " + plugin.FullName);
|
||||
plugin.Namespace = mainNamespace;
|
||||
plugin.Name = settings.PackageName + "Plugin";
|
||||
|
||||
// Watermark the plugin just in case it's useful to someone
|
||||
BuildLog.WriteLine("Watermarking plugin class");
|
||||
var str = asm.MainModule.TypeSystem.String;
|
||||
var descriptionAttributeConstructor = typeof(DescriptionAttribute).GetConstructor(new[] {typeof(string)});
|
||||
var descriptionAttributeRef = asm.MainModule.ImportReference(descriptionAttributeConstructor);
|
||||
var descriptionAttribute = new CustomAttribute(descriptionAttributeRef);
|
||||
descriptionAttribute.ConstructorArguments.Add(new CustomAttributeArgument(str, "Built with MeatKit"));
|
||||
plugin.CustomAttributes.Add(descriptionAttribute);
|
||||
|
||||
// This is some quantum bullshit.
|
||||
// If you don't enumerate the constructor arguments for attributes their values aren't updated correctly.
|
||||
BuildLog.WriteLine("Performing quantum bullshit");
|
||||
foreach (var x in GetAllCustomAttributes(asm).SelectMany(a => a.ConstructorArguments))
|
||||
{
|
||||
}
|
||||
|
||||
// Get the BepInPlugin attribute and replace the values in it with our own
|
||||
BuildLog.WriteLine("Applying BepInPlugin attribute params");
|
||||
var guid = settings.Author + "." + settings.PackageName;
|
||||
var pluginAttribute = plugin.CustomAttributes.First(a => a.AttributeType.Name == "BepInPlugin");
|
||||
pluginAttribute.ConstructorArguments[0] = new CustomAttributeArgument(str, guid);
|
||||
pluginAttribute.ConstructorArguments[1] = new CustomAttributeArgument(str, settings.PackageName);
|
||||
pluginAttribute.ConstructorArguments[2] = new CustomAttributeArgument(str, settings.Version);
|
||||
|
||||
// Get the LoadAssets method and make a new body for it
|
||||
BuildLog.WriteLine("Generating LoadAssets()");
|
||||
var loadAssetsMethod = plugin.Methods.First(m => m.Name == "LoadAssets");
|
||||
loadAssetsMethod.Body = new MethodBody(loadAssetsMethod);
|
||||
var il = loadAssetsMethod.Body.GetILProcessor();
|
||||
|
||||
// If we're automatically applying Harmony patches, do that now
|
||||
// This IL translates to Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "PluginGuid");
|
||||
if (settings.ApplyHarmonyPatches)
|
||||
{
|
||||
BuildLog.WriteLine(" Code to apply harmony patches");
|
||||
var assemblyGetExecutingAssembly = typeof(Assembly).GetMethod("GetExecutingAssembly");
|
||||
var harmonyCreateAndPatchALl = typeof(Harmony).GetMethod("CreateAndPatchAll", new[] {typeof(Assembly), typeof(string)});
|
||||
il.Emit(OpCodes.Call, plugin.Module.ImportReference(assemblyGetExecutingAssembly));
|
||||
il.Emit(OpCodes.Ldstr, guid);
|
||||
il.Emit(OpCodes.Call, plugin.Module.ImportReference(harmonyCreateAndPatchALl));
|
||||
il.Emit(OpCodes.Pop);
|
||||
}
|
||||
|
||||
// Let any build items insert their own code in here
|
||||
foreach (var item in settings.BuildItems)
|
||||
{
|
||||
BuildLog.WriteLine(" " + item);
|
||||
item.GenerateLoadAssets(plugin, il);
|
||||
}
|
||||
|
||||
// Insert a ret at the end so it's valid
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
// Module name needs to be changed away from Assembly-CSharp.dll because it is a reserved name.
|
||||
string newAssemblyName = settings.PackageName + ".dll";
|
||||
BuildLog.WriteLine("Renaming assembly (" + newAssemblyName + ")");
|
||||
asm.Name = new AssemblyNameDefinition(settings.PackageName, asm.Name.Version);
|
||||
asm.MainModule.Name = newAssemblyName;
|
||||
|
||||
// References to renamed unity code must be swapped out.
|
||||
BuildLog.WriteLine("Renaming assembly references");
|
||||
foreach (var ii in asm.MainModule.AssemblyReferences)
|
||||
{
|
||||
// Rename any references to the game's code
|
||||
if (ii.Name.Contains("H3VRCode-CSharp"))
|
||||
{
|
||||
var newReference = ii.Name.Replace("H3VRCode-CSharp", "Assembly-CSharp");
|
||||
BuildLog.WriteLine(" " + ii.Name + " -> " + newReference);
|
||||
ii.Name = newReference;
|
||||
}
|
||||
|
||||
// And also if we're referencing a MonoMod DLL, we need to fix reference too
|
||||
if (ii.Name.EndsWith(".mm"))
|
||||
{
|
||||
// What the name currently is:
|
||||
// Assembly-CSharp.PatchName.mm
|
||||
// What we want:
|
||||
// Assembly-CSharp
|
||||
// So just lop off anything past the second to last dot
|
||||
int idx = ii.Name.LastIndexOf('.', ii.Name.Length - 4);
|
||||
var newReference = ii.Name.Substring(0, idx);
|
||||
BuildLog.WriteLine(" " + ii.Name + " -> " + newReference);
|
||||
ii.Name = newReference;
|
||||
}
|
||||
}
|
||||
|
||||
if (BuildWindow.SelectedProfile.StripNamespaces)
|
||||
{
|
||||
// Remove types not in an allowed namespace or the global namespace
|
||||
BuildLog.WriteLine("Stripping namespaces");
|
||||
string[] allowedNamespaces = BuildWindow.SelectedProfile.GetAllAllowedNamespaces();
|
||||
List<TypeDefinition> typesToRemove = new List<TypeDefinition>();
|
||||
foreach (var type in asm.MainModule.Types)
|
||||
{
|
||||
if (type.Namespace == "" || allowedNamespaces.Any(x => type.Namespace.Contains(x)))
|
||||
continue;
|
||||
BuildLog.WriteLine(" " + type.FullName);
|
||||
typesToRemove.Add(type);
|
||||
}
|
||||
|
||||
foreach (var type in typesToRemove) asm.MainModule.Types.Remove(type);
|
||||
}
|
||||
|
||||
// Remove the same types we didn't want to import. This cannot be skipped.
|
||||
foreach (var type in StripAssemblyTypes
|
||||
.Select(x => asm.MainModule.GetType(x))
|
||||
.Where(x => x != null)) asm.MainModule.Types.Remove(type);
|
||||
|
||||
// Check if we're now missing any scripts from the export
|
||||
BuildLog.WriteLine("Checking for missing types");
|
||||
List<string> missing = new List<string>();
|
||||
string originalAssemblyName = AssemblyName + ".dll";
|
||||
if (requiredScripts != null && requiredScripts.ContainsKey(originalAssemblyName))
|
||||
{
|
||||
missing.AddRange(requiredScripts[originalAssemblyName]
|
||||
.Where(typeName => !StripAssemblyTypes.Contains(typeName) && asm.MainModule.GetType(typeName) == null));
|
||||
}
|
||||
|
||||
// If we're missing anything, fail the build.
|
||||
if (missing.Count > 0)
|
||||
{
|
||||
string missingTypes = string.Join("\n", missing.ToArray());
|
||||
throw new MeatKitBuildException(
|
||||
"Exported objects reference scripts which do not exist in the exported assembly... Did you forget to allow a namespace?\n\nMissing types:\n" +
|
||||
missingTypes, null);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Save it
|
||||
asm.Write(exportPath);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new MeatKitBuildException(
|
||||
"Unable to write exported scripts file. This is likely due to namespace stripping being enabled and a required namespace is not whitelisted.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete temp file now that we're done.
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
|
||||
private static TypeDefinition FindPluginClass(ModuleDefinition module, string mainNamespace)
|
||||
{
|
||||
// Get the default MeatKitPlugin class from the module
|
||||
var pluginClass = module.GetType("MeatKitPlugin");
|
||||
|
||||
// Try and locate any alternative plugin classes
|
||||
foreach (var type in module.Types)
|
||||
{
|
||||
// We're looking for types that extend the BaseUnityPlugin class and is in the main namespace of our mod
|
||||
if (type.IsSubtypeOf(typeof(BaseUnityPlugin)) && type.Namespace == mainNamespace)
|
||||
{
|
||||
pluginClass = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pluginClass;
|
||||
}
|
||||
|
||||
private static IEnumerable<CustomAttribute> GetAllCustomAttributes(AssemblyDefinition asm)
|
||||
{
|
||||
foreach (var type in asm.MainModule.Types)
|
||||
{
|
||||
foreach (var attrib in type.CustomAttributes) yield return attrib;
|
||||
foreach (CustomAttribute attrib in type.Methods.SelectMany(method => method.CustomAttributes))
|
||||
yield return attrib;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,13 @@ namespace MeatKit
|
||||
/// </summary>
|
||||
public static partial class MeatKit
|
||||
{
|
||||
private const string AssemblyName = "Assembly-CSharp";
|
||||
private const string AssemblyRename = "H3VRCode-CSharp";
|
||||
private const string AssemblyFirstpassName = "Assembly-CSharp-firstpass";
|
||||
private const string AssemblyFirstpassRename = "H3VRCode-CSharp-passfirst";
|
||||
|
||||
public const string AssemblyName = "Assembly-CSharp";
|
||||
public const string AssemblyRename = "H3VRCode-CSharp";
|
||||
public const string AssemblyFirstpassName = "Assembly-CSharp-firstpass";
|
||||
public const string AssemblyFirstpassRename = "H3VRCode-CSharp-firstpass";
|
||||
|
||||
// Types we want to strip from the main Unity assembly
|
||||
private static readonly string[] StripAssemblyTypes =
|
||||
public static readonly string[] StripAssemblyTypes =
|
||||
{
|
||||
// Alloy classes
|
||||
"MaterialMapChannelPackerDefinition",
|
||||
@@ -139,6 +139,9 @@ namespace MeatKit
|
||||
// Publicize assembly
|
||||
AssemblyStripper.MakePublic(mainAssembly, new string[0], false, false);
|
||||
|
||||
// Apply help URLs
|
||||
ApplyWikiHelpAttribute(mainAssembly);
|
||||
|
||||
// Write the main assembly out into the destination folder and dispose it
|
||||
mainAssembly.Write(Path.Combine(destinationDirectory, AssemblyRename + ".dll"));
|
||||
}
|
||||
@@ -169,23 +172,53 @@ namespace MeatKit
|
||||
new RedirectedAssemblyResolver(Path.GetDirectoryName(assemblyPath), destinationDirectory)
|
||||
};
|
||||
|
||||
// We just want to rename the references to the game's assemblies here
|
||||
// If this assembly uses the Assembly-CSharp name at all for any reason, replace it with H3VRCode-CSharp
|
||||
// This would probably only be done on MonoMod patches but is required to make Unity shut up
|
||||
var asm = AssemblyDefinition.ReadAssembly(assemblyPath, rParams);
|
||||
string name = asm.Name.Name;
|
||||
if (name.Contains("Assembly-CSharp"))
|
||||
{
|
||||
name = name.Replace("Assembly-CSharp", "H3VRCode-CSharp");
|
||||
asm.Name = new AssemblyNameDefinition(name, asm.Name.Version);
|
||||
asm.MainModule.Name = name + ".dll";
|
||||
}
|
||||
|
||||
// Replace all occurrences to references of Assembly-CSharp with H3VRCode-CSharp
|
||||
foreach (var reference in asm.MainModule.AssemblyReferences)
|
||||
switch (reference.Name)
|
||||
{
|
||||
if (reference.Name.Contains("Assembly-CSharp"))
|
||||
{
|
||||
case AssemblyName:
|
||||
reference.Name = AssemblyRename;
|
||||
break;
|
||||
case AssemblyFirstpassName:
|
||||
reference.Name = AssemblyFirstpassRename;
|
||||
break;
|
||||
reference.Name = reference.Name.Replace("Assembly-CSharp", "H3VRCode-CSharp");
|
||||
}
|
||||
}
|
||||
|
||||
asm.Write(Path.Combine(destinationDirectory, Path.GetFileName(assemblyPath)));
|
||||
asm.Write(Path.Combine(destinationDirectory, asm.MainModule.Name));
|
||||
NormalizeMetaFileGUIDs();
|
||||
}
|
||||
|
||||
private static void ApplyWikiHelpAttribute(AssemblyDefinition asm)
|
||||
{
|
||||
// For convenience, we can add the Unity HelpURL attribute to the components from the game assembly.
|
||||
// We'll point the url at the wiki and just append the full type name at the end
|
||||
|
||||
// Iterate over every type in the assembly and just stick the attribute on it
|
||||
// Probably doesn't matter if types that don't need it have it.
|
||||
foreach (var type in asm.MainModule.Types)
|
||||
{
|
||||
// If the type doesn't already have this attribute, add it.
|
||||
if (type.CustomAttributes.Any(a => a.AttributeType.Name == "HelpURLAttribute")) continue;
|
||||
|
||||
string helpUrl = "https://h3vr-modding.github.io/wiki/docs/h3vr/" + type.FullName + ".html";
|
||||
|
||||
var str = asm.MainModule.TypeSystem.String;
|
||||
var attributeConstructor = typeof(HelpURLAttribute).GetConstructor(new[] {typeof(string)});
|
||||
var attributeRef = asm.MainModule.ImportReference(attributeConstructor);
|
||||
var attribute = new CustomAttribute(attributeRef);
|
||||
attribute.ConstructorArguments.Add(new CustomAttributeArgument(str, helpUrl));
|
||||
type.CustomAttributes.Add(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
private static void NormalizeMetaFileGUIDs()
|
||||
{
|
||||
// This is a really important step. We need to make sure that the meta files for the assemblies are generated
|
||||
@@ -241,7 +274,6 @@ namespace MeatKit
|
||||
try
|
||||
{
|
||||
var asmPath = Path.Combine(path, name.Name + ".dll");
|
||||
Debug.Log("Assembly path: " + asmPath);
|
||||
if (File.Exists(asmPath))
|
||||
asm = AssemblyDefinition.ReadAssembly(asmPath,
|
||||
new ReaderParameters {AssemblyResolver = this});
|
||||
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class AssetBundleIO
|
||||
{
|
||||
// Toggles for keeping track if we're processing reads and/or writes
|
||||
public static bool ProcessingEnabledRead { get; private set; }
|
||||
public static bool ProcessingEnabledWrite { get; private set; }
|
||||
|
||||
// Output dictionaries for remembering what scripts got modified.
|
||||
public static Dictionary<string, List<string>> SerializedScriptNames { get; private set; }
|
||||
public static Dictionary<string, List<string>> DeserializedScriptNames { get; private set; }
|
||||
|
||||
private static Dictionary<string, string> _replaceMap;
|
||||
|
||||
static AssetBundleIO()
|
||||
{
|
||||
if (!EditorVersion.IsSupportedVersion) return;
|
||||
|
||||
// Apply the one hook we need here
|
||||
OrigMonoScriptTransferWrite = NativeHookManager.ApplyEditorDetour<MonoScriptTransferWrite>(EditorVersion.Current.FunctionOffsets.MonoScriptTransferWrite, new MonoScriptTransferWrite(OnMonoScriptTransferWrite));
|
||||
OrigMonoScriptTransferRead = NativeHookManager.ApplyEditorDetour<MonoScriptTransferRead>(EditorVersion.Current.FunctionOffsets.MonoScriptTransferRead, new MonoScriptTransferRead(OnMonoScriptTransferRead));
|
||||
}
|
||||
|
||||
public static void EnableProcessing(Dictionary<string, string> replaceMap, bool read, bool write)
|
||||
{
|
||||
_replaceMap = replaceMap;
|
||||
SerializedScriptNames = new Dictionary<string, List<string>>();
|
||||
DeserializedScriptNames = new Dictionary<string, List<string>>();
|
||||
ProcessingEnabledRead = read;
|
||||
ProcessingEnabledWrite = write;
|
||||
}
|
||||
|
||||
public static void DisableProcessing()
|
||||
{
|
||||
ProcessingEnabledRead = false;
|
||||
ProcessingEnabledWrite = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a detour on some of the native Unity editor code which is part of writing data to asset bundles.
|
||||
/// When Unity goes to serialize a MonoScript struct, we want to pre-process it a bit before it actually
|
||||
/// writes the data to the bundle.
|
||||
///
|
||||
/// Our processing includes building a list of used scripts so we can verify the user has their exports setup
|
||||
/// properly, as well as remapping the assembly names for some scripts so that references are maintained
|
||||
/// correctly when loaded in the game.
|
||||
/// </summary>
|
||||
private static void OnMonoScriptTransferWrite(IntPtr monoScript, IntPtr streamedBinaryWrite)
|
||||
{
|
||||
// If processing is disabled just run the original and skip.
|
||||
if (!ProcessingEnabledWrite)
|
||||
{
|
||||
OrigMonoScriptTransferWrite(monoScript, streamedBinaryWrite);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a couple variables for later
|
||||
var applied = false;
|
||||
|
||||
// Read the assembly name and class name from memory
|
||||
var className = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptClassName);
|
||||
var assemblyName = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptAssemblyName);
|
||||
var namespaceName = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptNamespace);
|
||||
var fullName = string.IsNullOrEmpty(namespaceName) ? className : (namespaceName + "." + className);
|
||||
|
||||
// Add it to the scripts usage dictionary
|
||||
if (!SerializedScriptNames.ContainsKey(assemblyName)) SerializedScriptNames[assemblyName] = new List<string>();
|
||||
SerializedScriptNames[assemblyName].Add(fullName);
|
||||
|
||||
// Prepare some debugging string
|
||||
string debug = " " + assemblyName + " " + fullName + ": ";
|
||||
|
||||
// Check if we want to remap this assembly name
|
||||
string newAssemblyName;
|
||||
if (_replaceMap.TryGetValue(assemblyName, out newAssemblyName))
|
||||
{
|
||||
// If we're processing a type that should exist in the main game assembly, skip translation
|
||||
if (assemblyName != MeatKit.AssemblyName + ".dll" || !MeatKit.StripAssemblyTypes.Contains(fullName))
|
||||
{
|
||||
// Write the new assembly name into memory
|
||||
UnityNativeHelper.WriteNativeString(monoScript, MonoScriptAssemblyName, newAssemblyName);
|
||||
applied = true;
|
||||
debug += "ReplaceMap";
|
||||
}
|
||||
else
|
||||
{
|
||||
debug += "Ignored";
|
||||
}
|
||||
}
|
||||
|
||||
// If it didn't exist in the replace map, check if it contains H3VRCode-CSharp. This is for MonoMod assemblies.
|
||||
else if (assemblyName.Contains(MeatKit.AssemblyRename))
|
||||
{
|
||||
// Write the new assembly name into memory
|
||||
UnityNativeHelper.WriteNativeString(monoScript, MonoScriptAssemblyName, assemblyName.Replace(MeatKit.AssemblyRename, MeatKit.AssemblyName));
|
||||
applied = true;
|
||||
debug += "MonoMod";
|
||||
}
|
||||
else
|
||||
{
|
||||
debug += "Unchanged";
|
||||
}
|
||||
|
||||
BuildLog.WriteLine(debug);
|
||||
|
||||
// Let the original method run
|
||||
OrigMonoScriptTransferWrite(monoScript, streamedBinaryWrite);
|
||||
|
||||
// If we didn't apply any remapping, skip this last part.
|
||||
if (!applied) return;
|
||||
|
||||
// Cleanup by writing the original value back to memory and freeing the memory allocated for the new name.
|
||||
UnityNativeHelper.WriteNativeString(monoScript, MonoScriptAssemblyName, assemblyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Any time the editor reads from an asset bundle, we want to apply our remapping so that references from
|
||||
/// the game can be properly deserialized.
|
||||
/// </summary>
|
||||
private static long OnMonoScriptTransferRead(IntPtr monoScript, IntPtr streamedBinaryRead)
|
||||
{
|
||||
// Run the original method and return the result if processing is disabled.
|
||||
long result = OrigMonoScriptTransferRead(monoScript, streamedBinaryRead);
|
||||
if (!ProcessingEnabledRead) return result;
|
||||
|
||||
// Read the assembly name and class name from memory
|
||||
var className = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptClassName);
|
||||
var assemblyName = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptAssemblyName);
|
||||
var namespaceName = UnityNativeHelper.ReadNativeString(monoScript, MonoScriptNamespace);
|
||||
var fullName = string.IsNullOrEmpty(namespaceName) ? className : (namespaceName + "." + className);
|
||||
|
||||
// Add it to the scripts usage dictionary
|
||||
if (!DeserializedScriptNames.ContainsKey(assemblyName)) DeserializedScriptNames[assemblyName] = new List<string>();
|
||||
DeserializedScriptNames[assemblyName].Add(fullName);
|
||||
|
||||
// Check if we want to remap this assembly name
|
||||
string newAssemblyName;
|
||||
if (_replaceMap.TryGetValue(assemblyName, out newAssemblyName))
|
||||
{
|
||||
// If we're processing a type that should exist in the main game assembly, skip translation
|
||||
if (assemblyName != MeatKit.AssemblyName || !MeatKit.StripAssemblyTypes.Contains(fullName))
|
||||
// Write the new assembly name into memory
|
||||
UnityNativeHelper.WriteNativeString(monoScript, MonoScriptAssemblyName, newAssemblyName);
|
||||
}
|
||||
|
||||
// If it didn't exist in the replace map, check if it contains H3VRCode-CSharp. This is for MonoMod assemblies.
|
||||
else if (assemblyName.Contains(MeatKit.AssemblyName))
|
||||
{
|
||||
// Write the new assembly name into memory
|
||||
UnityNativeHelper.WriteNativeString(monoScript, MonoScriptAssemblyName, assemblyName.Replace(MeatKit.AssemblyName, MeatKit.AssemblyRename));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Actual name: MonoScript::Transfer<StreamedBinaryWrite<0>>(StreamedBinaryWrite<0> &)
|
||||
private delegate void MonoScriptTransferWrite(IntPtr monoScript, IntPtr streamedBinaryWrite);
|
||||
|
||||
private static readonly MonoScriptTransferWrite OrigMonoScriptTransferWrite;
|
||||
|
||||
// Actual name: MonoScript::Transfer<StreamedBinaryRead<1>>(StreamedBinaryRead<1> &)
|
||||
private delegate long MonoScriptTransferRead(IntPtr monoScript, IntPtr streamedBinaryRead);
|
||||
|
||||
private static readonly MonoScriptTransferRead OrigMonoScriptTransferRead;
|
||||
|
||||
private const int MonoScriptClassName = 224;
|
||||
|
||||
private const int MonoScriptNamespace = 272;
|
||||
|
||||
private const int MonoScriptAssemblyName = 320;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3994182a62444e7e97029b92adc131f5
|
||||
timeCreated: 1655415474
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using AssetsTools.NET;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
@@ -9,7 +7,7 @@ namespace MeatKit
|
||||
{
|
||||
public static partial class MeatKit
|
||||
{
|
||||
private static readonly string ManagedDirectory = Path.Combine(Application.dataPath, "MeatKit/Managed/");
|
||||
private static readonly string ManagedDirectory = Path.Combine(Application.dataPath, "Managed/");
|
||||
|
||||
private static bool ShowErrorIfH3VRNotImported()
|
||||
{
|
||||
@@ -28,13 +26,35 @@ namespace MeatKit
|
||||
var gameManagedLocation = MeatKitCache.GameManagedLocation;
|
||||
if (string.IsNullOrEmpty(gameManagedLocation) || !Directory.Exists(gameManagedLocation))
|
||||
{
|
||||
gameManagedLocation = EditorUtility.OpenFolderPanel("Select H3VR Managed directory", string.Empty, "Managed");
|
||||
MeatKitCache.GameManagedLocation = gameManagedLocation;
|
||||
// Cache wasn't set or directory doesn't exist. Lets see if we can find it automatically via Steam
|
||||
gameManagedLocation = SteamAppLocator.LocateGame();
|
||||
if (string.IsNullOrEmpty(gameManagedLocation))
|
||||
{
|
||||
// Still nope. Ask the user for it directly.
|
||||
gameManagedLocation =
|
||||
EditorUtility.OpenFolderPanel("Select H3VR Managed directory", string.Empty, "Managed");
|
||||
}
|
||||
else gameManagedLocation = Path.Combine(gameManagedLocation, "h3vr_Data/Managed");
|
||||
}
|
||||
|
||||
// If it's _still_ empty, the user must have cancelled.
|
||||
// If it's _still_ empty, the user must have cancelled the input prompt, so cancel the import.
|
||||
if (string.IsNullOrEmpty(gameManagedLocation)) return;
|
||||
|
||||
// Also, check if the path is even valid
|
||||
if (!File.Exists(Path.Combine(gameManagedLocation, "Assembly-CSharp.dll")))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error",
|
||||
"Looks like the path you selected is invalid. Make sure you are selecting the h3vr_Data/Managed folder in the game directory.",
|
||||
"Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
// Import the assemblies and update the cache so we can find it in the future
|
||||
ImportAssemblies(gameManagedLocation, ManagedDirectory);
|
||||
MeatKitCache.GameManagedLocation = gameManagedLocation;
|
||||
|
||||
// Let the user know we've completed the action
|
||||
EditorUtility.DisplayDialog("Success", "Game scripts imported", "Ok");
|
||||
}
|
||||
|
||||
[MenuItem("MeatKit/Scripts/Import Single", priority = 0)]
|
||||
@@ -66,38 +86,10 @@ namespace MeatKit
|
||||
{
|
||||
// Make sure the scripts are imported and there are no errors before exporting
|
||||
if (ShowErrorIfH3VRNotImported()) return;
|
||||
if (!BuildWindow.SelectedProfile) return;
|
||||
|
||||
if (!BuildWindow.SelectedProfile.EnsureValidForEditor()) return;
|
||||
ExportEditorAssembly(BundleOutputPath);
|
||||
}
|
||||
|
||||
|
||||
[MenuItem("MeatKit/Asset Bundle/Export", priority = 1)]
|
||||
public static void ExportBundle()
|
||||
{
|
||||
var assetBundlePath = EditorUtility.OpenFilePanel("Select asset bundle", Application.dataPath, "");
|
||||
var settings = BuildWindow.SelectedProfile;
|
||||
var replaceMap = new Dictionary<string, string>
|
||||
{
|
||||
{"Assembly-CSharp.dll", settings.PackageName + ".dll"},
|
||||
{"Assembly-CSharp-firstpass.dll", settings.PackageName + "-firstpass.dll"},
|
||||
{"H3VRCode-CSharp.dll", "Assembly-CSharp.dll"},
|
||||
{"H3VRCode-CSharp-firstpass.dll", "Assembly-CSharp-firstpass.dll"}
|
||||
};
|
||||
|
||||
ProcessBundle(assetBundlePath, assetBundlePath, replaceMap, AssetBundleCompressionType.LZ4);
|
||||
}
|
||||
|
||||
[MenuItem("MeatKit/Asset Bundle/Import", priority = 1)]
|
||||
public static void ImportBundle()
|
||||
{
|
||||
var assetBundlePath = EditorUtility.OpenFilePanel("Select asset bundle", Application.dataPath, "");
|
||||
var replaceMap = new Dictionary<string, string>
|
||||
{
|
||||
{"Assembly-CSharp.dll", "H3VRCode-CSharp.dll"},
|
||||
{"Assembly-CSharp-firstpass.dll", "H3VRCode-CSharp-firstpass.dll"}
|
||||
};
|
||||
|
||||
ProcessBundle(assetBundlePath, assetBundlePath + "-imported", replaceMap, AssetBundleCompressionType.NONE);
|
||||
ExportEditorAssembly(BuildWindow.SelectedProfile.ExportPath);
|
||||
}
|
||||
|
||||
public static void ClearCache()
|
||||
@@ -110,4 +102,4 @@ namespace MeatKit
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace MeatKit
|
||||
|
||||
[SerializeField]
|
||||
private string _lastSelectedProfileGuid;
|
||||
|
||||
[SerializeField]
|
||||
private string _lastUpdateCheckTime = default(DateTime).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
private static string CacheFilePath
|
||||
{
|
||||
@@ -108,5 +111,15 @@ namespace MeatKit
|
||||
WriteCache();
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime LastUpdateCheckTime
|
||||
{
|
||||
get { return DateTime.Parse(Instance._lastUpdateCheckTime); }
|
||||
set
|
||||
{
|
||||
Instance._lastUpdateCheckTime = value.ToString(CultureInfo.InvariantCulture);
|
||||
WriteCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,17 @@ public class EnumPicker : PropertyDrawer
|
||||
{
|
||||
Array valuesRaw = null;
|
||||
Type enumType = fieldInfo.FieldType;
|
||||
if (enumType.IsArray) enumType = enumType.GetElementType(); //this turns the enum array into just the enum to prevent issues with arrays of enums
|
||||
|
||||
// Check if the property is an array or a list
|
||||
if (enumType.IsArray) enumType = enumType.GetElementType();
|
||||
else if (enumType.IsGenericType && enumType.GetGenericTypeDefinition() == typeof(List<>))
|
||||
enumType = enumType.GetGenericArguments()[0];
|
||||
|
||||
if (enumType == null || !enumType.IsEnum)
|
||||
{
|
||||
Debug.LogError("Can't determine how to draw a field for " + fieldInfo.FieldType);
|
||||
return;
|
||||
}
|
||||
|
||||
valuesRaw = Enum.GetValues(enumType);
|
||||
if (valuesRaw.Length <= 0)
|
||||
@@ -175,6 +185,7 @@ public class EnumPicker : PropertyDrawer
|
||||
[CustomPropertyDrawer(typeof(ItemSpawnerID.ESubCategory))]
|
||||
[CustomPropertyDrawer(typeof(FireArmRoundType))]
|
||||
[CustomPropertyDrawer(typeof(SosigEnemyID))]
|
||||
[CustomPropertyDrawer(typeof(FVRFireArmAttachementMountType))]
|
||||
public class EnumDrawers : EnumPicker
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using MeatKit;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class PrefabLoader : EditorWindow
|
||||
{
|
||||
private AssetBundle _bundle;
|
||||
private string[] _assets = new string[0];
|
||||
private int _selectedAsset = 0;
|
||||
|
||||
private static readonly Dictionary<string, string> AssemblyNameReplaceMap = new Dictionary<string, string>
|
||||
{
|
||||
{MeatKit.MeatKit.AssemblyName + ".dll", MeatKit.MeatKit.AssemblyRename + ".dll"},
|
||||
{MeatKit.MeatKit.AssemblyFirstpassName + ".dll", MeatKit.MeatKit.AssemblyFirstpassRename + ".dll"}
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, AssetBundle> LoadedAssetBundles = new Dictionary<string, AssetBundle>();
|
||||
|
||||
[MenuItem("MeatKit/Prefab Loader")]
|
||||
private static void Init()
|
||||
{
|
||||
GetWindow<PrefabLoader>().Show();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (GUILayout.Button("Select Asset Bundle"))
|
||||
{
|
||||
// If there's already a bundle loaded, unload it.
|
||||
if (_bundle) _bundle = null;
|
||||
|
||||
// Ask for the new bundle, load it, and get its assets
|
||||
string assetBundlePath = EditorUtility.OpenFilePanel("Select Asset Bundle", string.Empty, string.Empty);
|
||||
|
||||
// Make sure the user actually selected a file
|
||||
if (!string.IsNullOrEmpty(assetBundlePath))
|
||||
{
|
||||
// Check if we already loaded it
|
||||
if (!LoadedAssetBundles.TryGetValue(assetBundlePath, out _bundle))
|
||||
{
|
||||
_bundle = AssetBundle.LoadFromFile(assetBundlePath);
|
||||
LoadedAssetBundles[assetBundlePath] = _bundle;
|
||||
}
|
||||
|
||||
// Make sure a valid bundle was selected
|
||||
if (_bundle != null)
|
||||
{
|
||||
_assets = _bundle.GetAllAssetNames();
|
||||
_selectedAsset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only show spawn button if there's at least one asset
|
||||
if (_bundle != null && _assets.Length > 0)
|
||||
{
|
||||
_selectedAsset = EditorGUILayout.Popup(_selectedAsset, _assets);
|
||||
if (GUILayout.Button("Spawn"))
|
||||
{
|
||||
AssetBundleIO.EnableProcessing(AssemblyNameReplaceMap, true, false);
|
||||
Instantiate(_bundle.LoadAsset(_assets[_selectedAsset]));
|
||||
AssetBundleIO.DisableProcessing();
|
||||
}
|
||||
|
||||
// Warn the user about the play mode thing
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorGUILayout.HelpBox("References on a prefab loaded object will break after a restart of the editor unless you enter play mode first.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7972e859acde43c3983695df50bff302
|
||||
timeCreated: 1684891967
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class AsyncDownloader
|
||||
{
|
||||
private static readonly Dictionary<UnityWebRequest, Action<UnityWebRequest>> ActiveRequests = new Dictionary<UnityWebRequest, Action<UnityWebRequest>>();
|
||||
|
||||
static AsyncDownloader()
|
||||
{
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
public static void WaitForCompletion(UnityWebRequest request, Action<UnityWebRequest> callback)
|
||||
{
|
||||
if (request == null) throw new ArgumentException("Request cannot be null", "request");
|
||||
request.Send();
|
||||
ActiveRequests.Add(request, callback);
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
foreach (var kv in ActiveRequests.ToArray())
|
||||
{
|
||||
UnityWebRequest request = kv.Key;
|
||||
Action<UnityWebRequest> callback = kv.Value;
|
||||
if (!request.isDone) continue;
|
||||
if (callback != null) callback(request);
|
||||
ActiveRequests.Remove(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd989610b12e49edbdc6f03afc4b598f
|
||||
timeCreated: 1684959395
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MeatKit
|
||||
{
|
||||
public static class CreateUpdatePackage
|
||||
{
|
||||
private static readonly string[] ExportAssets =
|
||||
{
|
||||
"Assets/MeatKit",
|
||||
"Assets/Managed/0Harmony.dll",
|
||||
"Assets/Managed/BepInEx.dll",
|
||||
"Assets/Managed/DotNetZip.dll",
|
||||
"Assets/Managed/Mono.Cecil.dll",
|
||||
"Assets/Managed/MonoMod.RuntimeDetour.dll",
|
||||
"Assets/Managed/MonoMod.Utils.dll",
|
||||
"Assets/Managed/Sodalite.dll",
|
||||
"Assets/Managed/Valve.Newtonsoft.Json.dll",
|
||||
};
|
||||
|
||||
[MenuItem("MeatKit/Developer/Create update package")]
|
||||
public static void Create()
|
||||
{
|
||||
AssetDatabase.ExportPackage(ExportAssets, Updater.UpdatePackageName, ExportPackageOptions.Recurse);
|
||||
Debug.Log("Exported an update package to " + Path.Combine(Path.GetDirectoryName(Application.dataPath) , Updater.UpdatePackageName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9075e2699d46423fbc049d02942b6f09
|
||||
timeCreated: 1684962211
|
||||