Merge branch 'prefab-redo' of https://github.com/misternebula/quantum-space-buddies into prefab-redo

This commit is contained in:
Mister_Nebula 2022-02-03 09:30:18 +00:00
commit 34e67dad6d
44 changed files with 320 additions and 552 deletions

76
.gitignore vendored
View File

@ -1,20 +1,12 @@
# Created by https://www.gitignore.io/api/visualstudio
# Edit at https://www.gitignore.io/?templates=visualstudio
### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
.idea
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
!*.csproj.user
*.userosscache
*.sln.docstates
@ -31,12 +23,14 @@ mono_crash.*
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
@ -68,6 +62,9 @@ project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
@ -76,6 +73,7 @@ StyleCopReport.xml
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
@ -92,6 +90,7 @@ StyleCopReport.xml
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
@ -133,9 +132,6 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
@ -146,6 +142,11 @@ _TeamCity*
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
@ -293,6 +294,17 @@ node_modules/
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
@ -349,24 +361,46 @@ ASALocalRun/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# End of https://www.gitignore.io/api/visualstudio
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
.idea
# Unecessary asset bundle file
QSB/AssetBundles/AssetBundles*
QSB.csproj.user
GameAssets/
Chert/
Riebeck/
IgnoreInGithub/
OWML.Config.json
WeavedFiles/QSB.dll
WeavedFiles/QSB.dll.mdb
QSB/AssetBundles/*.manifest
qsb-unityproject
# User specific locations

View File

@ -3,6 +3,6 @@
<PropertyGroup>
<GameDir>C:\Program Files\Epic Games\OuterWilds</GameDir>
<OwmlDir>$(AppData)\OuterWildsModManager\OWML</OwmlDir>
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets</UnityAssetsDir>
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets\DLLs</UnityAssetsDir>
</PropertyGroup>
</Project>

View File

@ -21,7 +21,7 @@
<PropertyGroup Label="Default Locations" Condition="!Exists('$(DevEnvLoc)')">
<GameDir>C:\Program Files\Epic Games\OuterWilds</GameDir>
<OwmlDir>$(AppData)\OuterWildsModManager\OWML</OwmlDir>
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets</UnityAssetsDir>
<UnityAssetsDir>$(SolutionDir)\qsb-unityproject\Assets\DLLs</UnityAssetsDir>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,7 +4,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
<Reference Include="../UnityEngine/UnityEngine.CoreModule.dll"/>
<Reference Include="../UnityEngine/UnityEngine.CoreModule.dll" />
<Reference Include="../Mirror/*.dll" />
</ItemGroup>
</Project>

View File

@ -7,14 +7,10 @@ namespace Mirror.Weaver
{
public static class Extensions
{
public static bool Is(this TypeReference td, Type t)
{
if (t.IsGenericType)
{
return td.GetElementType().FullName == t.FullName;
}
return td.FullName == t.FullName;
}
public static bool Is(this TypeReference td, Type type) =>
type.IsGenericType
? td.GetElementType().FullName == type.FullName
: td.FullName == type.FullName;
public static bool Is<T>(this TypeReference td) => Is(td, typeof(T));

View File

@ -78,7 +78,9 @@ namespace Mirror.Weaver
*/
public static MethodDefinition ProcessCommandInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition method, MethodDefinition cmdCallFunc, ref bool WeavingFailed)
{
MethodDefinition cmd = new MethodDefinition(Weaver.InvokeRpcPrefix + method.Name,
string cmdName = Weaver.GenerateMethodName(Weaver.InvokeRpcPrefix, method);
MethodDefinition cmd = new MethodDefinition(cmdName,
MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
weaverTypes.Import(typeof(void)));

View File

@ -7,32 +7,18 @@ namespace Mirror.Weaver
{
const string RpcPrefix = "UserCode_";
// creates a method substitute
// For example, if we have this:
// public void CmdThrust(float thrusting, int spin)
// {
// xxxxx
// }
// For a function like
// [ClientRpc] void RpcTest(int value),
// Weaver substitutes the method and moves the code to a new method:
// UserCode_RpcTest(int value) <- contains original code
// RpcTest(int value) <- serializes parameters, sends the message
//
// it will substitute the method and move the code to a new method with a provided name
// for example:
//
// public void CmdTrust(float thrusting, int spin)
// {
// }
//
// public void <newName>(float thrusting, int spin)
// {
// xxxxx
// }
//
// Note that all the calls to the method remain untouched
//
// the original method definition loses all code
// this returns the newly created method with all the user provided code
// Note that all the calls to the method remain untouched.
// FixRemoteCallToBaseMethod replaces them afterwards.
public static MethodDefinition SubstituteMethod(Logger Log, TypeDefinition td, MethodDefinition md, ref bool WeavingFailed)
{
string newName = RpcPrefix + md.Name;
string newName = Weaver.GenerateMethodName(RpcPrefix, md);
MethodDefinition cmd = new MethodDefinition(newName, md.Attributes, md.ReturnType);
// force the substitute method to be protected.
@ -70,8 +56,16 @@ namespace Mirror.Weaver
return cmd;
}
// Finds and fixes call to base methods within remote calls
//For example, changes `base.CmdDoSomething` to `base.CallCmdDoSomething` within `this.CallCmdDoSomething`
// For a function like
// [ClientRpc] void RpcTest(int value),
// Weaver substitutes the method and moves the code to a new method:
// UserCode_RpcTest(int value) <- contains original code
// RpcTest(int value) <- serializes parameters, sends the message
//
// FixRemoteCallToBaseMethod replaces all calls to
// RpcTest(value)
// with
// UserCode_RpcTest(value)
public static void FixRemoteCallToBaseMethod(Logger Log, TypeDefinition type, MethodDefinition method, ref bool WeavingFailed)
{
string callName = method.Name;
@ -86,28 +80,43 @@ namespace Mirror.Weaver
foreach (Instruction instruction in method.Body.Instructions)
{
// if call to base.CmdDoSomething within this.CallCmdDoSomething
if (IsCallToMethod(instruction, out MethodDefinition calledMethod) &&
calledMethod.Name == baseRemoteCallName)
// is this instruction a Call to a method?
// if yes, output the method so we can check it.
if (IsCallToMethod(instruction, out MethodDefinition calledMethod))
{
TypeDefinition baseType = type.BaseType.Resolve();
MethodDefinition baseMethod = baseType.GetMethodInBaseType(callName);
if (baseMethod == null)
// when considering if 'calledMethod' is a call to 'method',
// we originally compared .Name.
//
// to fix IL2CPP build bugs with overloaded Rpcs, we need to
// generated rpc names like
// RpcTest(string value) => RpcTestString(strig value)
// RpcTest(int value) => RpcTestInt(int value)
// to make them unique.
//
// calledMethod.Name is still "RpcTest", so we need to
// convert this to the generated name as well before comparing.
string calledMethodName_Generated = Weaver.GenerateMethodName("", calledMethod);
if (calledMethodName_Generated == baseRemoteCallName)
{
Log.Error($"Could not find base method for {callName}", method);
WeavingFailed = true;
return;
}
TypeDefinition baseType = type.BaseType.Resolve();
MethodDefinition baseMethod = baseType.GetMethodInBaseType(callName);
if (!baseMethod.IsVirtual)
{
Log.Error($"Could not find base method that was virtual {callName}", method);
WeavingFailed = true;
return;
}
if (baseMethod == null)
{
Log.Error($"Could not find base method for {callName}", method);
WeavingFailed = true;
return;
}
instruction.Operand = baseMethod;
if (!baseMethod.IsVirtual)
{
Log.Error($"Could not find base method that was virtual {callName}", method);
WeavingFailed = true;
return;
}
instruction.Operand = baseMethod;
}
}
}
}

View File

@ -8,10 +8,10 @@ namespace Mirror.Weaver
{
public static MethodDefinition ProcessRpcInvoke(WeaverTypes weaverTypes, Writers writers, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
{
MethodDefinition rpc = new MethodDefinition(
Weaver.InvokeRpcPrefix + md.Name,
MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
weaverTypes.Import(typeof(void)));
string rpcName = Weaver.GenerateMethodName(Weaver.InvokeRpcPrefix, md);
MethodDefinition rpc = new MethodDefinition(rpcName, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
weaverTypes.Import(typeof(void)));
ILProcessor worker = rpc.Body.GetILProcessor();
Instruction label = worker.Create(OpCodes.Nop);

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
namespace Mirror.Weaver
{
@ -148,6 +150,15 @@ namespace Mirror.Weaver
return get;
}
// for [SyncVar] health, weaver generates
//
// NetworkHealth
// {
// get => health;
// set => GeneratedSyncVarSetter(...)
// }
//
// the setter used to be manually IL generated, but we moved it to C# :)
public MethodDefinition GenerateSyncVarSetter(TypeDefinition td, FieldDefinition fd, string originalName, long dirtyBit, FieldDefinition netFieldId, ref bool WeavingFailed)
{
//Create the set method
@ -164,135 +175,92 @@ namespace Mirror.Weaver
// NOTE: SyncVar...Equal functions are static.
// don't Emit Ldarg_0 aka 'this'.
// new value to set
worker.Emit(OpCodes.Ldarg_1);
// call WeaverSyncVarSetter<T>(T value, ref T field, ulong dirtyBit, Action<T, T> OnChanged = null)
// IL_0000: ldarg.0
// IL_0001: ldarg.1
// IL_0002: ldarg.0
// IL_0003: ldflda int32 Mirror.Examples.Tanks.Tank::health
// IL_0008: ldc.i4.1
// IL_0009: conv.i8
// IL_000a: ldnull
// IL_000b: call instance void [Mirror]Mirror.NetworkBehaviour::GeneratedSyncVarSetter<int32>(!!0, !!0&, uint64, class [netstandard]System.Action`2<!!0, !!0>)
// IL_0010: ret
// reference to field to set
// make generic version of SetSyncVar with field type
if (fd.FieldType.Is<UnityEngine.GameObject>())
{
// reference to netId Field to set
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldfld, netFieldId);
worker.Emit(OpCodes.Call, weaverTypes.syncVarGameObjectEqualReference);
}
else if (fd.FieldType.Is<NetworkIdentity>())
{
// reference to netId Field to set
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldfld, netFieldId);
worker.Emit(OpCodes.Call, weaverTypes.syncVarNetworkIdentityEqualReference);
}
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>())
{
// reference to netId Field to set
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldfld, netFieldId);
MethodReference getFunc = weaverTypes.syncVarNetworkBehaviourEqualReference.MakeGeneric(assembly.MainModule, fd.FieldType);
worker.Emit(OpCodes.Call, getFunc);
}
else
{
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldflda, fd);
GenericInstanceMethod syncVarEqualGm = new GenericInstanceMethod(weaverTypes.syncVarEqualReference);
syncVarEqualGm.GenericArguments.Add(fd.FieldType);
worker.Emit(OpCodes.Call, syncVarEqualGm);
}
worker.Emit(OpCodes.Brtrue, endOfMethod);
// T oldValue = value;
// TODO for GO/NI we need to backup the netId don't we?
VariableDefinition oldValue = new VariableDefinition(fd.FieldType);
set.Body.Variables.Add(oldValue);
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldfld, fd);
worker.Emit(OpCodes.Stloc, oldValue);
// this
// 'this.' for the call
worker.Emit(OpCodes.Ldarg_0);
// new value to set
// first push 'value'
worker.Emit(OpCodes.Ldarg_1);
// reference to field to set
// push 'ref T this.field'
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldflda, fd);
// dirty bit
// 8 byte integer aka long
// push the dirty bit for this SyncVar
worker.Emit(OpCodes.Ldc_I8, dirtyBit);
// hook?
MethodDefinition hookMethod = GetHookMethod(td, fd, ref WeavingFailed);
if (hookMethod != null)
{
// IL_000a: ldarg.0
// IL_000b: ldftn instance void Mirror.Examples.Tanks.Tank::ExampleHook(int32, int32)
// IL_0011: newobj instance void class [netstandard]System.Action`2<int32, int32>::.ctor(object, native int)
// this.
worker.Emit(OpCodes.Ldarg_0);
// the function
worker.Emit(OpCodes.Ldftn, hookMethod);
// call 'new Action<T,T>()' constructor to convert the function to an action
// we need to make an instance of the generic Action<T,T>.
//
// TODO this allocates a new 'Action' for every SyncVar hook call.
// we should allocate it once and store it somewhere in the future.
// hooks are only called on the client though, so it's not too bad for now.
TypeReference actionRef = assembly.MainModule.ImportReference(typeof(Action<,>));
GenericInstanceType genericInstance = actionRef.MakeGenericInstanceType(fd.FieldType, fd.FieldType);
worker.Emit(OpCodes.Newobj, weaverTypes.ActionT_T.MakeHostInstanceGeneric(assembly.MainModule, genericInstance));
}
// pass 'null' as hook
else worker.Emit(OpCodes.Ldnull);
// call GeneratedSyncVarSetter<T>.
// special cases for GameObject/NetworkIdentity/NetworkBehaviour
// passing netId too for persistence.
if (fd.FieldType.Is<UnityEngine.GameObject>())
{
// reference to netId Field to set
// GameObject setter needs one more parameter: netId field ref
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldflda, netFieldId);
worker.Emit(OpCodes.Call, weaverTypes.setSyncVarGameObjectReference);
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarSetter_GameObject);
}
else if (fd.FieldType.Is<NetworkIdentity>())
{
// reference to netId Field to set
// NetworkIdentity setter needs one more parameter: netId field ref
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldflda, netFieldId);
worker.Emit(OpCodes.Call, weaverTypes.setSyncVarNetworkIdentityReference);
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarSetter_NetworkIdentity);
}
// TODO this only uses the persistent netId for types DERIVED FROM NB.
// not if the type is just 'NetworkBehaviour'.
// this is what original implementation did too. fix it after.
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>())
{
// reference to netId Field to set
// NetworkIdentity setter needs one more parameter: netId field ref
// (actually its a NetworkBehaviourSyncVar type)
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldflda, netFieldId);
MethodReference getFunc = weaverTypes.setSyncVarNetworkBehaviourReference.MakeGeneric(assembly.MainModule, fd.FieldType);
// make generic version of GeneratedSyncVarSetter_NetworkBehaviour<T>
MethodReference getFunc = weaverTypes.generatedSyncVarSetter_NetworkBehaviour_T.MakeGeneric(assembly.MainModule, fd.FieldType);
worker.Emit(OpCodes.Call, getFunc);
}
else
{
// make generic version of SetSyncVar with field type
GenericInstanceMethod gm = new GenericInstanceMethod(weaverTypes.setSyncVarReference);
gm.GenericArguments.Add(fd.FieldType);
// invoke SetSyncVar
worker.Emit(OpCodes.Call, gm);
}
MethodDefinition hookMethod = GetHookMethod(td, fd, ref WeavingFailed);
if (hookMethod != null)
{
//if (NetworkServer.localClientActive && !getSyncVarHookGuard(dirtyBit))
Instruction label = worker.Create(OpCodes.Nop);
worker.Emit(OpCodes.Call, weaverTypes.NetworkServerGetLocalClientActive);
worker.Emit(OpCodes.Brfalse, label);
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldc_I8, dirtyBit);
worker.Emit(OpCodes.Call, weaverTypes.getSyncVarHookGuard);
worker.Emit(OpCodes.Brtrue, label);
// setSyncVarHookGuard(dirtyBit, true);
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldc_I8, dirtyBit);
worker.Emit(OpCodes.Ldc_I4_1);
worker.Emit(OpCodes.Call, weaverTypes.setSyncVarHookGuard);
// call hook (oldValue, newValue)
// Generates: OnValueChanged(oldValue, value);
WriteCallHookMethodUsingArgument(worker, hookMethod, oldValue);
// setSyncVarHookGuard(dirtyBit, false);
worker.Emit(OpCodes.Ldarg_0);
worker.Emit(OpCodes.Ldc_I8, dirtyBit);
worker.Emit(OpCodes.Ldc_I4_0);
worker.Emit(OpCodes.Call, weaverTypes.setSyncVarHookGuard);
worker.Append(label);
// make generic version of GeneratedSyncVarSetter<T>
MethodReference generic = weaverTypes.generatedSyncVarSetter.MakeGeneric(assembly.MainModule, fd.FieldType);
worker.Emit(OpCodes.Call, generic);
}
worker.Append(endOfMethod);
@ -415,11 +383,6 @@ namespace Mirror.Weaver
return (syncVars, syncVarNetIds);
}
public void WriteCallHookMethodUsingArgument(ILProcessor worker, MethodDefinition hookMethod, VariableDefinition oldValue)
{
WriteCallHookMethod(worker, hookMethod, oldValue, null);
}
public void WriteCallHookMethodUsingField(ILProcessor worker, MethodDefinition hookMethod, VariableDefinition oldValue, FieldDefinition newValue, ref bool WeavingFailed)
{
if (newValue == null)

View File

@ -15,7 +15,9 @@ namespace Mirror.Weaver
public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
{
MethodDefinition rpc = new MethodDefinition(Weaver.InvokeRpcPrefix + md.Name, MethodAttributes.Family |
string trgName = Weaver.GenerateMethodName(Weaver.InvokeRpcPrefix, md);
MethodDefinition rpc = new MethodDefinition(trgName, MethodAttributes.Family |
MethodAttributes.Static |
MethodAttributes.HideBySig,
weaverTypes.Import(typeof(void)));

View File

@ -1,4 +1,3 @@
using MirrorWeaver;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -32,6 +31,29 @@ namespace Mirror.Weaver
// multi threaded logging.
public Logger Log;
// remote actions now support overloads,
// -> but IL2CPP doesnt like it when two generated methods
// -> have the same signature,
// -> so, append the signature to the generated method name,
// -> to create a unique name
// Example:
// RpcTeleport(Vector3 position) -> InvokeUserCode_RpcTeleport__Vector3()
// RpcTeleport(Vector3 position, Quaternion rotation) -> InvokeUserCode_RpcTeleport__Vector3Quaternion()
// fixes https://github.com/vis2k/Mirror/issues/3060
public static string GenerateMethodName(string initialPrefix, MethodDefinition md)
{
initialPrefix += md.Name;
for (int i = 0; i < md.Parameters.Count; ++i)
{
// with __ so it's more obvious that this is the parameter suffix.
// otherwise RpcTest(int) => RpcTestInt(int) which is not obvious.
initialPrefix += $"__{md.Parameters[i].ParameterType.Name}";
}
return initialPrefix;
}
public Weaver(Logger Log)
{
this.Log = Log;
@ -171,7 +193,7 @@ namespace Mirror.Weaver
Stopwatch rwstopwatch = Stopwatch.StartNew();
// Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages
modified = ReaderWriterProcessor.Process(CurrentAssembly, resolver, Log, writers, readers, ref WeavingFailed);
QSBReaderWriterProcessor.Process(CurrentAssembly, writers, readers, ref WeavingFailed);
MirrorWeaver.QSBReaderWriterProcessor.Process(CurrentAssembly, writers, readers, ref WeavingFailed);
rwstopwatch.Stop();
Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds");

View File

@ -19,7 +19,6 @@ namespace Mirror.Weaver
public MethodReference RemoteCallDelegateConstructor;
public MethodReference NetworkServerGetActive;
public MethodReference NetworkServerGetLocalClientActive;
public MethodReference NetworkClientGetActive;
// custom attribute types
@ -28,19 +27,17 @@ namespace Mirror.Weaver
// array segment
public MethodReference ArraySegmentConstructorReference;
// Action<T,T> for SyncVar Hooks
public MethodReference ActionT_T;
// syncvar
public MethodReference generatedSyncVarSetter;
public MethodReference generatedSyncVarSetter_GameObject;
public MethodReference generatedSyncVarSetter_NetworkIdentity;
public MethodReference generatedSyncVarSetter_NetworkBehaviour_T;
public MethodReference syncVarEqualReference;
public MethodReference syncVarNetworkIdentityEqualReference;
public MethodReference syncVarGameObjectEqualReference;
public MethodReference setSyncVarReference;
public MethodReference setSyncVarHookGuard;
public MethodReference getSyncVarHookGuard;
public MethodReference setSyncVarGameObjectReference;
public MethodReference getSyncVarGameObjectReference;
public MethodReference setSyncVarNetworkIdentityReference;
public MethodReference getSyncVarNetworkIdentityReference;
public MethodReference syncVarNetworkBehaviourEqualReference;
public MethodReference setSyncVarNetworkBehaviourReference;
public MethodReference getSyncVarNetworkBehaviourReference;
public MethodReference registerCommandReference;
public MethodReference registerRpcReference;
@ -72,9 +69,11 @@ namespace Mirror.Weaver
TypeReference ArraySegmentType = Import(typeof(ArraySegment<>));
ArraySegmentConstructorReference = Resolvers.ResolveMethod(ArraySegmentType, assembly, Log, ".ctor", ref WeavingFailed);
TypeReference ActionType = Import(typeof(Action<,>));
ActionT_T = Resolvers.ResolveMethod(ActionType, assembly, Log, ".ctor", ref WeavingFailed);
TypeReference NetworkServerType = Import(typeof(NetworkServer));
NetworkServerGetActive = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_active", ref WeavingFailed);
NetworkServerGetLocalClientActive = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_localClientActive", ref WeavingFailed);
TypeReference NetworkClientType = Import(typeof(NetworkClient));
NetworkClientGetActive = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_active", ref WeavingFailed);
@ -84,7 +83,7 @@ namespace Mirror.Weaver
TypeReference NetworkBehaviourType = Import<NetworkBehaviour>();
TypeReference RemoteProcedureCallsType = Import(typeof(RemoteCalls.RemoteProcedureCalls));
TypeReference ScriptableObjectType = Import<UnityEngine.ScriptableObject>();
TypeReference ScriptableObjectType = Import<ScriptableObject>();
ScriptableObjectCreateInstanceMethod = Resolvers.ResolveMethod(
ScriptableObjectType, assembly, Log,
@ -98,19 +97,15 @@ namespace Mirror.Weaver
NetworkClientConnectionReference = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_connection", ref WeavingFailed);
syncVarEqualReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SyncVarEqual", ref WeavingFailed);
syncVarNetworkIdentityEqualReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SyncVarNetworkIdentityEqual", ref WeavingFailed);
syncVarGameObjectEqualReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SyncVarGameObjectEqual", ref WeavingFailed);
setSyncVarReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SetSyncVar", ref WeavingFailed);
setSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SetSyncVarHookGuard", ref WeavingFailed);
getSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarHookGuard", ref WeavingFailed);
generatedSyncVarSetter = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter", ref WeavingFailed);
generatedSyncVarSetter_GameObject = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_GameObject", ref WeavingFailed);
generatedSyncVarSetter_NetworkIdentity = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_NetworkIdentity", ref WeavingFailed);
generatedSyncVarSetter_NetworkBehaviour_T = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_NetworkBehaviour", ref WeavingFailed);
syncVarEqualReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SyncVarEqual", ref WeavingFailed);
setSyncVarGameObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SetSyncVarGameObject", ref WeavingFailed);
getSyncVarGameObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarGameObject", ref WeavingFailed);
setSyncVarNetworkIdentityReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SetSyncVarNetworkIdentity", ref WeavingFailed);
getSyncVarNetworkIdentityReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkIdentity", ref WeavingFailed);
syncVarNetworkBehaviourEqualReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SyncVarNetworkBehaviourEqual", ref WeavingFailed);
setSyncVarNetworkBehaviourReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SetSyncVarNetworkBehaviour", ref WeavingFailed);
getSyncVarNetworkBehaviourReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkBehaviour", ref WeavingFailed);
registerCommandReference = Resolvers.ResolveMethod(RemoteProcedureCallsType, assembly, Log, "RegisterCommand", ref WeavingFailed);

View File

@ -1,7 +1,6 @@
using QSB.Anglerfish.WorldObjects;
using QSB.AuthoritySync;
using QSB.Syncs.Unsectored.Rigidbodies;
using QSB.Utility;
using QSB.WorldSync;
using System.Collections.Generic;
using UnityEngine;
@ -54,6 +53,8 @@ namespace QSB.Anglerfish.TransformSync
protected override void Uninit()
{
base.Uninit();
if (QSBCore.IsHost)
{
netIdentity.UnregisterAuthQueue();
@ -61,8 +62,6 @@ namespace QSB.Anglerfish.TransformSync
AttachedRigidbody.OnUnsuspendOWRigidbody -= OnUnsuspend;
AttachedRigidbody.OnSuspendOWRigidbody -= OnSuspend;
base.Uninit();
}
private void OnUnsuspend(OWRigidbody suspendedBody) => netIdentity.SendAuthQueueMessage(AuthQueueAction.Add);

View File

@ -1,48 +0,0 @@
ManifestFileVersion: 0
CRC: 2158942079
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: d7c4b4eca299ae0206b1a6bfb13a7ba5
TypeTreeHash:
serializedVersion: 2
Hash: 0b6dcb0adf46bff667535938056e8d8d
HashAppended: 0
ClassTypes:
- Class: 1
Script: {instanceID: 0}
- Class: 21
Script: {instanceID: 0}
- Class: 28
Script: {instanceID: 0}
- Class: 48
Script: {instanceID: 0}
- Class: 114
Script: {fileID: 1015169618, guid: 7f3cc24903ed9434188d184e6d0fcc8f, type: 3}
- Class: 114
Script: {fileID: 602583937, guid: 7f3cc24903ed9434188d184e6d0fcc8f, type: 3}
- Class: 114
Script: {fileID: 1980459831, guid: 106784ef860579a438677482e738fed4, type: 3}
- Class: 114
Script: {fileID: 1741964061, guid: 106784ef860579a438677482e738fed4, type: 3}
- Class: 114
Script: {fileID: -765806418, guid: 106784ef860579a438677482e738fed4, type: 3}
- Class: 114
Script: {fileID: 708705254, guid: 106784ef860579a438677482e738fed4, type: 3}
- Class: 115
Script: {instanceID: 0}
- Class: 128
Script: {instanceID: 0}
- Class: 213
Script: {instanceID: 0}
- Class: 222
Script: {instanceID: 0}
- Class: 223
Script: {instanceID: 0}
- Class: 224
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/Prefabs/DialogueBubble.prefab
- Assets/GameAssets/Texture2D/UI_DialogueBox_d.png
Dependencies: []

View File

@ -1,32 +0,0 @@
ManifestFileVersion: 0
CRC: 1531115438
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 69af2ff9e30a3a4e0f059dc00ea13d16
TypeTreeHash:
serializedVersion: 2
Hash: ae2cf77de671e115b4e55d2b65767202
HashAppended: 0
ClassTypes:
- Class: 1
Script: {instanceID: 0}
- Class: 4
Script: {instanceID: 0}
- Class: 21
Script: {instanceID: 0}
- Class: 23
Script: {instanceID: 0}
- Class: 33
Script: {instanceID: 0}
- Class: 43
Script: {instanceID: 0}
- Class: 48
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/Prefabs/Cube.prefab
- Assets/Prefabs/Capsule.prefab
- Assets/Materials/DebugVis.mat
- Assets/Prefabs/Sphere.prefab
Dependencies: []

BIN
QSB/AssetBundles/empty Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,68 +0,0 @@
ManifestFileVersion: 0
CRC: 443713126
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 7d0ca7d72c1b77d3f455afb9deb14138
TypeTreeHash:
serializedVersion: 2
Hash: a1e72967751de663a1cbd29bd1e98be5
HashAppended: 0
ClassTypes:
- Class: 21
Script: {instanceID: 0}
- Class: 28
Script: {instanceID: 0}
- Class: 43
Script: {instanceID: 0}
- Class: 48
Script: {instanceID: 0}
- Class: 74
Script: {instanceID: 0}
- Class: 90
Script: {instanceID: 0}
- Class: 91
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_ao.png
- Assets/GameAssets/AnimationClip/Riebeck_Playing.anim
- Assets/GameAssets/Avatar/Traveller_HEA_Chert_ANIM_Chatter_ChipperAvatar.asset
- Assets/GameAssets/AnimationClip/Chert_Drum_Panicked.anim
- Assets/GameAssets/Material/Traveller_HEA_Riebeck_mat.mat
- Assets/GameAssets/AnimatorController/Traveller_Chert.controller
- Assets/GameAssets/AnimationClip/Chert_Chatter_Chipper.anim
- Assets/GameAssets/AnimationClip/Chert_Drum_Chipper.anim
- Assets/GameAssets/Mesh/NewDrum_polySurface2.asset
- Assets/GameAssets/AnimationClip/Playing_banjo.anim
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_n.png
- Assets/GameAssets/Avatar/Traveller_HEA_Riebeck_ANIM_TalkingAvatar.asset
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_n.png
- Assets/GameAssets/AnimationClip/Chert_Chatter_Nervous.anim
- Assets/GameAssets/Mesh/Chert_DrumStick_Geo1.asset
- Assets/GameAssets/Material/Structure_HEA_VillageMetal_mat.mat
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_d.png
- Assets/GameAssets/Material/Structure_HEA_VillageCabin_mat.mat
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_d.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_n.png
- Assets/GameAssets/AnimationClip/Playing_to_idle.anim
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_n.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_s.png
- Assets/GameAssets/AnimationClip/Chert_Chatter_Panicked.anim
- Assets/GameAssets/Material/Traveller_HEA_Riebeck_Banjo_mat.mat
- Assets/GameAssets/AnimationClip/Chert_Dream.anim
- Assets/GameAssets/AnimationClip/Riebeck_Talking.anim
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_d.png
- Assets/GameAssets/AnimationClip/Riebeck_DreamIdle.anim
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_ao.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Chert_s.png
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_n.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_d.png
- Assets/GameAssets/AnimatorController/Traveller_Riebeck.controller
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_s.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_ao.png
- Assets/GameAssets/Texture2D/Structure_HEA_VillageMetal_d.png
- Assets/GameAssets/Texture2D/Traveller_HEA_Riebeck_Banjo_s.png
- Assets/GameAssets/Material/Traveller_HEA_Chert_mat.mat
- Assets/GameAssets/Texture2D/Structure_HEA_VillageCabin_s.png
Dependencies: []

View File

@ -1,17 +0,0 @@
ManifestFileVersion: 0
CRC: 3102539871
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: a82172ddab4ffc78bd7c16996c5f9328
TypeTreeHash:
serializedVersion: 2
Hash: 5ad585dd02dfb5016c0dad519eab8f49
HashAppended: 0
ClassTypes:
- Class: 49
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/TextAssets/GalaxyMap.txt
Dependencies: []

View File

@ -4,15 +4,9 @@ using QSB.EchoesOfTheEye.SlideProjectors.WorldObjects;
using QSB.Messaging;
using QSB.Patches;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QSB.EchoesOfTheEye.SlideProjectors
namespace QSB.EchoesOfTheEye.SlideProjectors.Patches
{
internal class ProjectorPatches : QSBPatch
{
@ -20,34 +14,26 @@ namespace QSB.EchoesOfTheEye.SlideProjectors
[HarmonyPostfix]
[HarmonyPatch(typeof(SlideProjector), nameof(SlideProjector.OnPressInteract))]
public static void Interact(SlideProjector __instance)
{
var worldObject = QSBWorldSync.GetWorldObject<QSBSlideProjector>(__instance);
worldObject.SendMessage(new ProjectorAuthorityMessage(QSBPlayerManager.LocalPlayerId));
}
public static void Interact(SlideProjector __instance) =>
__instance.GetWorldObject<QSBSlideProjector>()
.SendMessage(new ProjectorAuthorityMessage(QSBPlayerManager.LocalPlayerId));
[HarmonyPostfix]
[HarmonyPatch(typeof(SlideProjector), nameof(SlideProjector.CancelInteraction))]
public static void CancelInteract(SlideProjector __instance)
{
var worldObject = QSBWorldSync.GetWorldObject<QSBSlideProjector>(__instance);
worldObject.SendMessage(new ProjectorAuthorityMessage(0u));
}
public static void CancelInteract(SlideProjector __instance) =>
__instance.GetWorldObject<QSBSlideProjector>()
.SendMessage(new ProjectorAuthorityMessage(0));
[HarmonyPostfix]
[HarmonyPatch(typeof(SlideProjector), nameof(SlideProjector.NextSlide))]
public static void NextSlide(SlideProjector __instance)
{
var worldObject = QSBWorldSync.GetWorldObject<QSBSlideProjector>(__instance);
worldObject.SendMessage(new NextSlideMessage());
}
public static void NextSlide(SlideProjector __instance) =>
__instance.GetWorldObject<QSBSlideProjector>()
.SendMessage(new NextSlideMessage());
[HarmonyPostfix]
[HarmonyPatch(typeof(SlideProjector), nameof(SlideProjector.PreviousSlide))]
public static void PreviousSlide(SlideProjector __instance)
{
var worldObject = QSBWorldSync.GetWorldObject<QSBSlideProjector>(__instance);
worldObject.SendMessage(new PreviousSlideMessage());
}
public static void PreviousSlide(SlideProjector __instance) =>
__instance.GetWorldObject<QSBSlideProjector>()
.SendMessage(new PreviousSlideMessage());
}
}

View File

@ -34,7 +34,7 @@ namespace QSB.EchoesOfTheEye.SlideProjectors.WorldObjects
{
if (AttachedObject._oneShotSource != null)
{
AttachedObject._oneShotSource.PlayOneShot(global::AudioType.Projector_Next, 1f);
AttachedObject._oneShotSource.PlayOneShot(AudioType.Projector_Next);
}
if (AttachedObject.IsProjectorFullyLit())
@ -62,7 +62,7 @@ namespace QSB.EchoesOfTheEye.SlideProjectors.WorldObjects
{
if (AttachedObject._oneShotSource != null)
{
AttachedObject._oneShotSource.PlayOneShot(global::AudioType.Projector_Prev, 1f);
AttachedObject._oneShotSource.PlayOneShot(AudioType.Projector_Prev);
}
if (AttachedObject.IsProjectorFullyLit())

View File

@ -56,6 +56,8 @@ namespace QSB.JellyfishSync.TransformSync
protected override void Uninit()
{
base.Uninit();
if (QSBCore.IsHost)
{
netIdentity.UnregisterAuthQueue();
@ -63,8 +65,6 @@ namespace QSB.JellyfishSync.TransformSync
AttachedRigidbody.OnUnsuspendOWRigidbody -= OnUnsuspend;
AttachedRigidbody.OnSuspendOWRigidbody -= OnSuspend;
base.Uninit();
}
private void OnUnsuspend(OWRigidbody suspendedBody) => netIdentity.SendAuthQueueMessage(AuthQueueAction.Add);

View File

@ -57,24 +57,16 @@ namespace QSB.OrbSync.TransformSync
protected override void Uninit()
{
base.Uninit();
if (QSBCore.IsHost)
{
netIdentity.UnregisterAuthQueue();
}
// this is null sometimes on here, but not on other similar transforms syncs (like anglers)
// idk why, but whatever
if (AttachedTransform)
{
var body = AttachedTransform.GetAttachedOWRigidbody();
if (body)
{
body.OnUnsuspendOWRigidbody -= OnUnsuspend;
body.OnSuspendOWRigidbody -= OnSuspend;
}
}
base.Uninit();
var body = AttachedTransform.GetAttachedOWRigidbody();
body.OnUnsuspendOWRigidbody -= OnUnsuspend;
body.OnSuspendOWRigidbody -= OnSuspend;
}
private void OnUnsuspend(OWRigidbody suspendedBody) => netIdentity.SendAuthQueueMessage(AuthQueueAction.Add);

View File

@ -1,16 +1,10 @@
using OWML.Common;
using QSB.Audio;
using QSB.Messaging;
using QSB.Player.Messages;
using QSB.PlayerBodySetup.Local;
using QSB.PlayerBodySetup.Remote;
using QSB.RoastingSync;
using QSB.SectorSync;
using QSB.Syncs.Sectored.Transforms;
using QSB.Tools;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
using UnityEngine;
namespace QSB.Player.TransformSync

View File

@ -9,49 +9,22 @@ namespace QSB.PlayerBodySetup.Remote
{
public static class FixMaterialsInAllChildren
{
private static List<MaterialDefinition> _materialDefinitions = new();
private static readonly List<(string MaterialName, Material ReplacementMaterial)> _materialDefinitions = new();
static void ReplaceMaterial(Renderer renderer, int index, Material mat)
private static void ReplaceMaterial(Renderer renderer, int index, Material mat)
{
var mats = renderer.materials;
mats[index] = mat;
renderer.materials = mats;
}
static void CheckReplaceMaterials(Renderer renderer, string materialName, Material replacementMaterial)
private static void ReplaceMaterials(Renderer renderer, string materialName, Material replacementMaterial)
{
for (var i = 0; i < renderer.materials.Length; i++)
{
if (renderer.materials[i].name.Trim() == $"{materialName} (Instance)")
{
ReplaceMaterial(renderer, i, replacementMaterial);
continue;
}
}
}
public static void ReplaceMaterials(Transform rootObject)
{
DebugLog.DebugWrite($"Replace materials on children of {rootObject.name}");
if (_materialDefinitions.Count == 0)
{
try
{
GenerateMaterialDefinitions();
}
catch (Exception ex)
{
DebugLog.ToConsole($"Exception when generating material definitions. {ex}", OWML.Common.MessageType.Error);
return;
}
}
foreach (var renderer in rootObject.GetComponentsInChildren<Renderer>(true))
{
foreach (var def in _materialDefinitions)
{
CheckReplaceMaterials(renderer, def.MaterialName, def.ReplacementMaterial);
}
}
}
@ -70,7 +43,14 @@ namespace QSB.PlayerBodySetup.Remote
foreach (var name in matNameList)
{
var matchingMaterial = allMaterials.FirstOrDefault(x => x.name == name);
DebugLog.DebugWrite(name);
var matchingMaterial = allMaterials.Where(x => x.name == name).ToArray();
foreach (var item in matchingMaterial)
{
DebugLog.DebugWrite($"- {item.name}");
}
if (matchingMaterial == default)
{
@ -78,7 +58,23 @@ namespace QSB.PlayerBodySetup.Remote
return;
}
_materialDefinitions.Add(new(name, matchingMaterial));
_materialDefinitions.Add(new(name, matchingMaterial[0]));
}
}
public static void ReplaceMaterials(Transform rootObject)
{
if (_materialDefinitions.Count == 0)
{
GenerateMaterialDefinitions();
}
foreach (var renderer in rootObject.GetComponentsInChildren<Renderer>(true))
{
foreach (var (materialName, replacementMaterial) in _materialDefinitions)
{
ReplaceMaterials(renderer, materialName, replacementMaterial);
}
}
}
}

View File

@ -1,16 +0,0 @@
using UnityEngine;
namespace QSB.PlayerBodySetup.Remote
{
public struct MaterialDefinition
{
public MaterialDefinition(string materialName, Material replacementMaterial)
{
MaterialName = materialName;
ReplacementMaterial = replacementMaterial;
}
public string MaterialName { get; private set; }
public Material ReplacementMaterial { get; private set; }
}
}

View File

@ -27,7 +27,7 @@ namespace QSB.PlayerBodySetup.Remote
// Variable naming convention is broken here to reflect OW unity project (with REMOTE_ prefixed) for readability
var REMOTE_Player_Body = UnityEngine.Object.Instantiate(QSBCore.NetworkAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/REMOTE_Player_Body.prefab"));
var REMOTE_Player_Body = Object.Instantiate(QSBCore.NetworkAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/REMOTE_Player_Body.prefab"));
REMOTE_Player_Body.transform.localPosition = Vector3.zero;
REMOTE_Player_Body.transform.localScale = Vector3.one;
REMOTE_Player_Body.transform.localRotation = Quaternion.identity;

View File

@ -6,14 +6,14 @@
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<ProjectGuid>{1F00090A-C697-4C55-B401-192F3CFB9DC2}</ProjectGuid>
<OutputPath Condition="Exists($(OwmlDir))">$(OwmlDir)\Mods\QSB</OutputPath>
<NoWarn>1998</NoWarn>
<NoWarn>CS1998;CS0649</NoWarn>
</PropertyGroup>
<Target Name="weave qsb" BeforeTargets="PostBuildEvent">
<Exec Command="&quot;$(SolutionDir)\MirrorWeaver\bin\$(Configuration)\MirrorWeaver&quot; &quot;$(OutputPath)\QSB.dll&quot; &quot;$(SolutionDir)\UnityEngine&quot;" />
</Target>
<PropertyGroup>
<PostBuildEvent Condition="Exists($(UnityAssetsDir)) and Exists($(GameDir)) and Exists($(OwmlDir))">
copy /y "$(OutputPath)" "$(UnityAssetsDir)"
copy /y "$(OutputPath)\*.dll" "$(UnityAssetsDir)"
copy /y "$(GameDir)\OuterWilds_Data\Managed\Assembly-CSharp-firstpass.dll" "$(UnityAssetsDir)"
copy /y "$(GameDir)\OuterWilds_Data\Managed\Unity.InputSystem.dll" "$(UnityAssetsDir)"
copy /y "$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UI.dll" "$(UnityAssetsDir)"
@ -22,35 +22,18 @@
copy /y "$(OwmlDir)\Autofac.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Newtonsoft.Json.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\0Harmony.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\MonoMod.Utils.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\MonoMod.RuntimeDetour.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Mono.Cecil.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Mono.Cecil.Mdb.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Mono.Cecil.Pdb.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Mono.Cecil.Rocks.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Common.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.Assets.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.Events.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.Menus.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.Input.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModHelper.Interaction.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Utils.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Common.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Logging.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.ModLoader.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Patcher.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.GameFinder.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.Abstractions.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\MonoMod.*.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\Mono.Cecil*.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\OWML.*.dll" "$(UnityAssetsDir)"
copy /y "$(OwmlDir)\NAudio-Unity.dll" "$(UnityAssetsDir)"
</PostBuildEvent>
</PropertyGroup>
<ItemGroup>
<None Include="default-config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="manifest.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
@ -70,7 +53,7 @@
</ItemGroup>
<ItemGroup>
<None Update="debugsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -37,7 +37,7 @@ namespace QSB
{
public static IModHelper Helper { get; private set; }
public static string DefaultServerIP;
public static AssetBundle NetworkAssetBundle { get; internal set; }
public static AssetBundle NetworkAssetBundle { get; private set; }
public static AssetBundle InstrumentAssetBundle { get; private set; }
public static AssetBundle ConversationAssetBundle { get; private set; }
public static AssetBundle DebugAssetBundle { get; private set; }

View File

@ -40,10 +40,9 @@ namespace QSB
public GameObject AnglerPrefab { get; private set; }
public GameObject JellyfishPrefab { get; private set; }
public GameObject OccasionalPrefab { get; private set; }
public string PlayerName { get; private set; }
private string PlayerName { get; set; }
private const int MaxConnections = 128;
private const int MaxBufferedPackets = 64;
private GameObject _probePrefab;
private bool _everConnected;
@ -132,14 +131,14 @@ namespace QSB
/// see https://docs.unity3d.com/Manual/AssetBundles-Native.html.
private static GameObject MakeNewNetworkObject(int assetId, string name, Type transformSyncType)
{
QSBCore.NetworkAssetBundle.Unload(false);
QSBCore.NetworkAssetBundle = QSBCore.Helper.Assets.LoadBundle("AssetBundles/network");
var bundle = QSBCore.Helper.Assets.LoadBundle("AssetBundles/empty");
var template = bundle.LoadAsset<GameObject>("Assets/Prefabs/Empty.prefab");
bundle.Unload(false);
var template = QSBCore.NetworkAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/NetworkObject.prefab");
DebugLog.DebugWrite($"MakeNewNetworkObject - prefab id {template.GetInstanceID()} "
+ $"for {assetId} {name} {transformSyncType.Name}");
template.name = name;
template.GetRequiredComponent<NetworkIdentity>().SetValue("m_AssetId", assetId.ToGuid().ToString("N"));
template.AddComponent<NetworkIdentity>().SetValue("m_AssetId", assetId.ToGuid().ToString("N"));
template.AddComponent(transformSyncType);
return template;
}

View File

@ -134,7 +134,7 @@ namespace QSB.QuantumSync
public static void UpdateFromDebugSetting()
{
if (QSBCore.DebugSettings.ShowQuantumVisibilityObjects)
if (QSBCore.DebugSettings.DrawQuantumVisibilityObjects)
{
if (_debugSphere == null)
{

View File

@ -47,12 +47,6 @@ namespace QSB.Syncs.Sectored.Rigidbodies
_relativeAngularVelocity = reader.ReadVector3();
}
protected override void Uninit()
{
base.Uninit();
AttachedRigidbody = null;
}
protected override void GetFromAttached()
{
GetFromSector();

View File

@ -164,16 +164,7 @@ namespace QSB.Syncs
protected virtual void Init()
{
try
{
AttachedTransform = InitAttachedTransform();
}
catch (Exception ex)
{
DebugLog.ToConsole($"Exception when Init-ing {this} : {ex}", MessageType.Error);
return;
}
AttachedTransform = InitAttachedTransform();
IsInitialized = true;
}
@ -184,8 +175,6 @@ namespace QSB.Syncs
Destroy(AttachedTransform.gameObject);
}
AttachedTransform = null;
ReferenceTransform = null;
IsInitialized = false;
IsValid = false;
}
@ -308,7 +297,7 @@ namespace QSB.Syncs
private void OnGUI()
{
if (!QSBCore.DebugSettings.ShowDebugLabels
if (!QSBCore.DebugSettings.DrawLabels
|| Event.current.type != EventType.Repaint
|| !IsValid
|| !ReferenceTransform)

View File

@ -47,12 +47,6 @@ namespace QSB.Syncs.Unsectored.Rigidbodies
_relativeAngularVelocity = reader.ReadVector3();
}
protected override void Uninit()
{
base.Uninit();
AttachedRigidbody = null;
}
protected override void GetFromAttached()
{
transform.position = ReferenceTransform.ToRelPos(AttachedRigidbody.GetPosition());

View File

@ -251,7 +251,7 @@ namespace QSB.Utility
private static void DrawWorldObjectLabels()
{
if (!QSBCore.DebugSettings.ShowDebugLabels)
if (!QSBCore.DebugSettings.DrawLabels)
{
return;
}

View File

@ -9,7 +9,7 @@ namespace QSB.Utility
{
public static void ToConsole(string message, MessageType type = MessageType.Message)
{
if (NetworkClient.localPlayer != null && QSBCore.DebugSettings.PlayerIdInLogs)
if (QSBCore.DebugSettings.PlayerIdInLogs && NetworkClient.localPlayer)
{
message = $"[{NetworkClient.localPlayer.netId}] " + message;
}

View File

@ -5,16 +5,16 @@ namespace QSB.Utility
public class DebugSettings
{
[JsonProperty("useKcpTransport")]
public bool UseKcpTransport { get; set; }
public bool UseKcpTransport;
[JsonProperty("overrideAppId")]
public int OverrideAppId { get; set; } = -1;
public int OverrideAppId = -1;
[JsonProperty("dumpWorldObjects")]
public bool DumpWorldObjects { get; set; }
public bool DumpWorldObjects;
[JsonProperty("debugMode")]
public bool DebugMode { get; set; }
public bool DebugMode;
[JsonProperty("drawGui")]
private bool _drawGui;
@ -24,13 +24,13 @@ namespace QSB.Utility
private bool _drawLines;
public bool DrawLines => DebugMode && _drawLines;
[JsonProperty("showQuantumVisibilityObjects")]
private bool _showQuantumVisibilityObjects;
public bool ShowQuantumVisibilityObjects => DebugMode && _showQuantumVisibilityObjects;
[JsonProperty("drawLabels")]
private bool _drawLabels;
public bool DrawLabels => DebugMode && _drawLabels;
[JsonProperty("showDebugLabels")]
private bool _showDebugLabels;
public bool ShowDebugLabels => DebugMode && _showDebugLabels;
[JsonProperty("drawQuantumVisibilityObjects")]
private bool _drawQuantumVisibilityObjects;
public bool DrawQuantumVisibilityObjects => DebugMode && _drawQuantumVisibilityObjects;
[JsonProperty("avoidTimeSync")]
private bool _avoidTimeSync;

View File

@ -1,12 +1,12 @@
{
"useKcpTransport": true,
"overrideAppId": -1,
"dumpWorldObjects": false,
"debugMode": true,
"drawGui": true,
"drawLines": true,
"dumpWorldObjects": false,
"showQuantumVisibilityObjects": false,
"showDebugLabels": false,
"drawLabels": false,
"drawQuantumVisibilityObjects": false,
"avoidTimeSync": false,
"skipTitleScreen": true,
"greySkybox": false,

View File

@ -4,7 +4,7 @@
</PropertyGroup>
<ItemGroup>
<None Update="SteamAPI\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>