diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
new file mode 100644
index 00000000..027192c6
--- /dev/null
+++ b/.github/workflows/build.yaml
@@ -0,0 +1,34 @@
+name: Build
+
+on:
+ push:
+ branches: [dev]
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ build:
+ if: (github.event_name == 'pull_request' && github.event.pull_request.merged != 'true') || github.event_name == 'push'
+ runs-on: windows-latest
+ steps:
+
+ # Replace / with _ in ref name so that it can be used in a filename
+ - uses: mad9000/actions-find-and-replace-string@2
+ id: sanitizeRef
+ with:
+ source: ${{ github.ref_name }}
+ find: '/'
+ replace: '_'
+ # Get short-sha so that it can be used in a filename
+ - uses: benjlevesque/short-sha@v1.2
+ id: short-sha
+
+ - uses: actions/checkout@v2
+ - uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: "5.0.x"
+ - run: dotnet build -c Release
+ - uses: actions/upload-artifact@v2
+ with:
+ name: QSB-${{ steps.sanitizeRef.outputs.value }}-${{ steps.short-sha.outputs.sha }}
+ path: .\QSB\Bin\Release
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f8963d8c..8a1664ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+.idea
+
# User-specific files
*.rsuser
*.suo
@@ -365,3 +367,7 @@ IgnoreInGithub/
OWML.Config.json
WeavedFiles/QSB.dll
WeavedFiles/QSB.dll.mdb
+qsb-unityproject
+
+# User specific locations
+DevEnv.targets
diff --git a/AssetBundles/conversation b/AssetBundles/conversation
deleted file mode 100644
index 05538ff9..00000000
Binary files a/AssetBundles/conversation and /dev/null differ
diff --git a/AssetBundles/debug b/AssetBundles/debug
deleted file mode 100644
index 71c1eeac..00000000
Binary files a/AssetBundles/debug and /dev/null differ
diff --git a/AssetBundles/debug.manifest b/AssetBundles/debug.manifest
deleted file mode 100644
index 494f867b..00000000
--- a/AssetBundles/debug.manifest
+++ /dev/null
@@ -1,49 +0,0 @@
-ManifestFileVersion: 0
-CRC: 3095198160
-Hashes:
- AssetFileHash:
- serializedVersion: 2
- Hash: 44badca86c2222e5cc39a8497439be0c
- TypeTreeHash:
- serializedVersion: 2
- Hash: b2ece8ae09df261ff59d764d08696641
-HashAppended: 0
-ClassTypes:
-- Class: 1
- Script: {instanceID: 0}
-- Class: 4
- Script: {instanceID: 0}
-- Class: 21
- Script: {instanceID: 0}
-- Class: 23
- Script: {instanceID: 0}
-- Class: 28
- Script: {instanceID: 0}
-- Class: 33
- Script: {instanceID: 0}
-- Class: 43
- Script: {instanceID: 0}
-- Class: 48
- Script: {instanceID: 0}
-- Class: 114
- Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
-- Class: 114
- Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
-- Class: 115
- Script: {instanceID: 0}
-- Class: 128
- Script: {instanceID: 0}
-- Class: 222
- Script: {instanceID: 0}
-- Class: 223
- Script: {instanceID: 0}
-- Class: 224
- Script: {instanceID: 0}
-SerializeReferenceClassIdentifiers: []
-Assets:
-- Assets/Cube.prefab
-- Assets/Capsule.prefab
-- Assets/DebugVis.mat
-- Assets/LogCanvas.prefab
-- Assets/Sphere.prefab
-Dependencies: []
diff --git a/AssetBundles/instruments b/AssetBundles/instruments
deleted file mode 100644
index 0a4958b0..00000000
Binary files a/AssetBundles/instruments and /dev/null differ
diff --git a/AssetBundles/instruments.manifest b/AssetBundles/instruments.manifest
deleted file mode 100644
index c13bb169..00000000
--- a/AssetBundles/instruments.manifest
+++ /dev/null
@@ -1,34 +0,0 @@
-ManifestFileVersion: 0
-CRC: 2593345828
-Hashes:
- AssetFileHash:
- serializedVersion: 2
- Hash: d97fbc9cde41b6514223a2f68ba96af8
- TypeTreeHash:
- serializedVersion: 2
- Hash: ff0e1233df027a80b5add90668c49830
-HashAppended: 0
-ClassTypes:
-- Class: 43
- Script: {instanceID: 0}
-- Class: 74
- Script: {instanceID: 0}
-- Class: 91
- Script: {instanceID: 0}
-Assets:
-- Assets/Riebeck/Idle_to_playing.anim
-- Assets/Chert/Chert_Drum_Panicked.anim
-- Assets/Riebeck/Traveller_Riebeck.controller
-- Assets/Chert/Traveller_Chert.controller
-- Assets/Chert/Chert_Drum_Chipper.anim
-- Assets/Riebeck/Riebeck_DreamIdle.anim
-- Assets/Chert/Chert_Chatter_Chipper.anim
-- Assets/Riebeck/Riebeck_Playing.anim
-- Assets/Chert/Chert_Chatter_Panicked.anim
-- Assets/Chert/Chert_Chatter_Nervous.anim
-- Assets/Chert/hourglasstwinsmeshescharacters2.asset
-- Assets/Riebeck/Playing_banjo.anim
-- Assets/Riebeck/Playing_to_idle.anim
-- Assets/Chert/Chert_Dream.anim
-- Assets/Riebeck/Riebeck_Talking.anim
-Dependencies: []
diff --git a/AssetBundles/network b/AssetBundles/network
deleted file mode 100644
index b5f3712f..00000000
Binary files a/AssetBundles/network and /dev/null differ
diff --git a/AssetBundles/network.manifest b/AssetBundles/network.manifest
deleted file mode 100644
index a4d9d43c..00000000
--- a/AssetBundles/network.manifest
+++ /dev/null
@@ -1,30 +0,0 @@
-ManifestFileVersion: 0
-CRC: 1991351671
-Hashes:
- AssetFileHash:
- serializedVersion: 2
- Hash: e0f93ad04981fd266a4300b0be721792
- TypeTreeHash:
- serializedVersion: 2
- Hash: 6968c5d2bbef57a79632abd61ea01bb3
-HashAppended: 0
-ClassTypes:
-- Class: 1
- Script: {instanceID: 0}
-- Class: 4
- Script: {instanceID: 0}
-- Class: 114
- Script: {fileID: 372142912, guid: 93b08009869340045a8e7321508b6355, type: 3}
-- Class: 114
- Script: {fileID: -1768714887, guid: 93b08009869340045a8e7321508b6355, type: 3}
-- Class: 114
- Script: {fileID: -1267208747, guid: 93b08009869340045a8e7321508b6355, type: 3}
-- Class: 115
- Script: {instanceID: 0}
-SerializeReferenceClassIdentifiers: []
-Assets:
-- Assets/NetworkProbe.prefab
-- Assets/NETWORK_Player_Body.prefab
-- Assets/NetworkOrb.prefab
-- Assets/NetworkShip.prefab
-Dependencies: []
diff --git a/DevEnv.targets.example b/DevEnv.targets.example
new file mode 100644
index 00000000..76f604d8
--- /dev/null
+++ b/DevEnv.targets.example
@@ -0,0 +1,8 @@
+
+
+
+ C:\Program Files\Epic Games\OuterWilds
+ $(AppData)\OuterWildsModManager\OWML
+ $(SolutionDir)\qsb-unityproject\Assets
+
+
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 00000000..8165de0a
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,33 @@
+
+
+
+
+ $(MSBuildThisFileDirectory)DevEnv.targets
+
+
+
+
+ net48
+ true
+ 9
+ false
+ false
+ false
+ bin\$(Configuration)\QSB
+ $(OwmlDir)\Mods\QSB
+ en-GB
+ Henry Pointer, Aleksander Waage, Ricardo Lopes
+ Copyright © Henry Pointer, Aleksander Waage, Ricardo Lopes 2020-2021
+
+
+
+ C:\Program Files\Epic Games\OuterWilds
+ $(AppData)\OuterWildsModManager\OWML
+ $(SolutionDir)\qsb-unityproject\Assets
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/QNetWeaver/Helpers.cs b/QNetWeaver/Helpers.cs
deleted file mode 100644
index aed3161d..00000000
--- a/QNetWeaver/Helpers.cs
+++ /dev/null
@@ -1,236 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-using Mono.Cecil.Mdb;
-using Mono.Cecil.Pdb;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-
-namespace QNetWeaver
-{
- internal class Helpers
- {
- public static string UnityEngineDLLDirectoryName()
- {
- var directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
- return (directoryName == null) ? null : directoryName.Replace("file:\\", "");
- }
-
- public static ISymbolReaderProvider GetSymbolReaderProvider(string inputFile)
- {
- var text = inputFile.Substring(0, inputFile.Length - 4);
- ISymbolReaderProvider result;
- if (File.Exists(text + ".pdb"))
- {
- Console.WriteLine("Symbols will be read from " + text + ".pdb");
- result = new PdbReaderProvider();
- }
- else if (File.Exists(text + ".dll.mdb"))
- {
- Console.WriteLine("Symbols will be read from " + text + ".dll.mdb");
- result = new MdbReaderProvider();
- }
- else
- {
- Console.WriteLine("No symbols for " + inputFile);
- result = null;
- }
-
- return result;
- }
-
- public static bool InheritsFromSyncList(TypeReference typeRef)
- {
- try
- {
- if (typeRef.IsValueType)
- {
- return false;
- }
-
- foreach (var typeReference in ResolveInheritanceHierarchy(typeRef))
- {
- if (typeReference.IsGenericInstance)
- {
- var typeDefinition = typeReference.Resolve();
- if (typeDefinition.HasGenericParameters && typeDefinition.FullName == Weaver.SyncListType.FullName)
- {
- return true;
- }
- }
- }
- }
- catch
- {
- }
-
- return false;
- }
-
- public static IEnumerable ResolveInheritanceHierarchy(TypeReference type)
- {
- if (type.IsValueType)
- {
- yield return type;
- yield return Weaver.valueTypeType;
- yield return Weaver.objectType;
- yield break;
- }
-
- while (type != null && type.FullName != Weaver.objectType.FullName)
- {
- yield return type;
- try
- {
- var typeDefinition = type.Resolve();
- if (typeDefinition == null)
- {
- break;
- }
-
- type = typeDefinition.BaseType;
- }
- catch
- {
- break;
- }
- }
-
- yield return Weaver.objectType;
- yield break;
- }
-
- public static string DestinationFileFor(string outputDir, string assemblyPath)
- {
- var fileName = Path.GetFileName(assemblyPath);
- return Path.Combine(outputDir, fileName);
- }
-
- public static string PrettyPrintType(TypeReference type)
- {
- string result;
- if (type.IsGenericInstance)
- {
- var genericInstanceType = (GenericInstanceType)type;
- var text = genericInstanceType.Name.Substring(0, genericInstanceType.Name.Length - 2);
- var text2 = "<";
- var text3 = ", ";
- IEnumerable genericArguments = genericInstanceType.GenericArguments;
- result = text + text2 + string.Join(text3, Enumerable.ToArray(Enumerable.Select(genericArguments, new Func(PrettyPrintType)))) + ">";
- }
- else if (type.HasGenericParameters)
- {
- result = type.Name.Substring(0, type.Name.Length - 2) + "<" + string.Join(", ", Enumerable.ToArray(Enumerable.Select(type.GenericParameters, (GenericParameter x) => x.Name))) + ">";
- }
- else
- {
- result = type.Name;
- }
-
- return result;
- }
-
- public static ReaderParameters ReaderParameters(string assemblyPath, IEnumerable extraPaths, IAssemblyResolver assemblyResolver, string unityEngineDLLPath, string unityUNetDLLPath)
- {
- var readerParameters = new ReaderParameters();
- if (assemblyResolver == null)
- {
- assemblyResolver = new DefaultAssemblyResolver();
- }
-
- var addSearchDirectoryHelper = new Helpers.AddSearchDirectoryHelper(assemblyResolver);
- addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(assemblyPath));
- addSearchDirectoryHelper.AddSearchDirectory(UnityEngineDLLDirectoryName());
- addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(unityEngineDLLPath));
- addSearchDirectoryHelper.AddSearchDirectory(Path.GetDirectoryName(unityUNetDLLPath));
- if (extraPaths != null)
- {
- foreach (var directory in extraPaths)
- {
- addSearchDirectoryHelper.AddSearchDirectory(directory);
- }
- }
-
- readerParameters.AssemblyResolver = assemblyResolver;
- readerParameters.SymbolReaderProvider = GetSymbolReaderProvider(assemblyPath);
- return readerParameters;
- }
-
- public static WriterParameters GetWriterParameters(ReaderParameters readParams)
- {
- var writerParameters = new WriterParameters();
- if (readParams.SymbolReaderProvider is PdbReaderProvider)
- {
- writerParameters.SymbolWriterProvider = new PdbWriterProvider();
- }
- else if (readParams.SymbolReaderProvider is MdbReaderProvider)
- {
- writerParameters.SymbolWriterProvider = new MdbWriterProvider();
- }
-
- return writerParameters;
- }
-
- public static TypeReference MakeGenericType(TypeReference self, params TypeReference[] arguments)
- {
- if (self.GenericParameters.Count != arguments.Length)
- {
- throw new ArgumentException();
- }
-
- var genericInstanceType = new GenericInstanceType(self);
- foreach (var item in arguments)
- {
- genericInstanceType.GenericArguments.Add(item);
- }
-
- return genericInstanceType;
- }
-
- public static MethodReference MakeHostInstanceGeneric(MethodReference self, params TypeReference[] arguments)
- {
- var methodReference = new MethodReference(self.Name, self.ReturnType, MakeGenericType(self.DeclaringType, arguments))
- {
- HasThis = self.HasThis,
- ExplicitThis = self.ExplicitThis,
- CallingConvention = self.CallingConvention
- };
- foreach (var parameterDefinition in self.Parameters)
- {
- methodReference.Parameters.Add(new ParameterDefinition(parameterDefinition.ParameterType));
- }
-
- foreach (var genericParameter in self.GenericParameters)
- {
- methodReference.GenericParameters.Add(new GenericParameter(genericParameter.Name, methodReference));
- }
-
- return methodReference;
- }
-
- private class AddSearchDirectoryHelper
- {
- public AddSearchDirectoryHelper(IAssemblyResolver assemblyResolver)
- {
- var method = assemblyResolver.GetType().GetMethod("AddSearchDirectory", (BindingFlags)20, null, new Type[]
- {
- typeof(string)
- }, null);
- if (method == null)
- {
- throw new Exception("Assembly resolver doesn't implement AddSearchDirectory method.");
- }
-
- _addSearchDirectory = (Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate)Delegate.CreateDelegate(typeof(Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate), assemblyResolver, method);
- }
-
- public void AddSearchDirectory(string directory) => _addSearchDirectory(directory);
-
- private readonly Helpers.AddSearchDirectoryHelper.AddSearchDirectoryDelegate _addSearchDirectory;
-
- private delegate void AddSearchDirectoryDelegate(string directory);
- }
- }
-}
diff --git a/QNetWeaver/Log.cs b/QNetWeaver/Log.cs
deleted file mode 100644
index 7e358fae..00000000
--- a/QNetWeaver/Log.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace QNetWeaver
-{
- public static class Log
- {
- public static void Warning(string msg)
- {
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine($"WARN : {msg}");
- Console.ResetColor();
- }
-
- public static void Error(string msg)
- {
- Console.ForegroundColor = ConsoleColor.DarkRed;
- Console.WriteLine($"ERR : {msg}");
- Console.ResetColor();
- }
- }
-}
diff --git a/QNetWeaver/MessageClassProcessor.cs b/QNetWeaver/MessageClassProcessor.cs
deleted file mode 100644
index 9e4ffe7e..00000000
--- a/QNetWeaver/MessageClassProcessor.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-
-namespace QNetWeaver
-{
- internal class MessageClassProcessor
- {
- public MessageClassProcessor(TypeDefinition td)
- {
- Weaver.DLog(td, "MessageClassProcessor for " + td.Name, new object[0]);
- m_td = td;
- }
-
- public void Process()
- {
- Weaver.DLog(m_td, "MessageClassProcessor Start", new object[0]);
- Weaver.ResetRecursionCount();
- GenerateSerialization();
- if (!Weaver.fail)
- {
- GenerateDeSerialization();
- Weaver.DLog(m_td, "MessageClassProcessor Done", new object[0]);
- }
- }
-
- private void GenerateSerialization()
- {
- Weaver.DLog(m_td, " MessageClass GenerateSerialization", new object[0]);
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == "Serialize")
- {
- Weaver.DLog(m_td, " Abort - is Serialize", new object[0]);
- return;
- }
- }
-
- if (m_td.Fields.Count != 0)
- {
- foreach (var fieldDefinition in m_td.Fields)
- {
- if (fieldDefinition.FieldType.FullName == m_td.FullName)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new string[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " [",
- fieldDefinition.FullName,
- "]. [MessageBase] member cannot be self referencing."
- }));
- return;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("Serialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- foreach (var fieldDefinition2 in m_td.Fields)
- {
- if (!fieldDefinition2.IsStatic && !fieldDefinition2.IsPrivate && !fieldDefinition2.IsSpecialName)
- {
- if (fieldDefinition2.FieldType.Resolve().HasGenericParameters)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " [",
- fieldDefinition2.FieldType,
- "/",
- fieldDefinition2.FieldType.FullName,
- "]. [MessageBase] member cannot have generic parameters."
- }));
- return;
- }
-
- if (fieldDefinition2.FieldType.Resolve().IsInterface)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " [",
- fieldDefinition2.FieldType,
- "/",
- fieldDefinition2.FieldType.FullName,
- "]. [MessageBase] member cannot be an interface."
- }));
- return;
- }
-
- var writeFunc = Weaver.GetWriteFunc(fieldDefinition2.FieldType);
- if (writeFunc == null)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition2.FieldType,
- "/",
- fieldDefinition2.FieldType.FullName,
- "]. [MessageBase] member variables must be basic types."
- }));
- return;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
- }
-
- private void GenerateDeSerialization()
- {
- Weaver.DLog(m_td, " GenerateDeserialization", new object[0]);
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == "Deserialize")
- {
- return;
- }
- }
-
- if (m_td.Fields.Count != 0)
- {
- var methodDefinition2 = new MethodDefinition("Deserialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- foreach (var fieldDefinition in m_td.Fields)
- {
- if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
- {
- var readFunc = Weaver.GetReadFunc(fieldDefinition.FieldType);
- if (readFunc == null)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateDeSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition.FieldType,
- "]. [SyncVar] member variables must be basic types."
- }));
- return;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition));
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
- }
-
- private TypeDefinition m_td;
- }
-}
diff --git a/QNetWeaver/MonoBehaviourProcessor.cs b/QNetWeaver/MonoBehaviourProcessor.cs
deleted file mode 100644
index f974afe9..00000000
--- a/QNetWeaver/MonoBehaviourProcessor.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using Mono.Cecil;
-
-namespace QNetWeaver
-{
- internal class MonoBehaviourProcessor
- {
- public MonoBehaviourProcessor(TypeDefinition td) => m_td = td;
-
- public void Process()
- {
- ProcessSyncVars();
- ProcessMethods();
- }
-
- private void ProcessSyncVars()
- {
- foreach (var fieldDefinition in m_td.Fields)
- {
- foreach (var customAttribute in fieldDefinition.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.SyncVarType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses [SyncVar] ",
- fieldDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
- }
-
- if (Helpers.InheritsFromSyncList(fieldDefinition.FieldType))
- {
- Log.Error(string.Format("Script {0} defines field {1} with type {2}, but it's not a NetworkBehaviour", m_td.FullName, fieldDefinition.Name, Helpers.PrettyPrintType(fieldDefinition.FieldType)));
- Weaver.fail = true;
- }
- }
- }
-
- private void ProcessMethods()
- {
- foreach (var methodDefinition in m_td.Methods)
- {
- foreach (var customAttribute in methodDefinition.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.CommandType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses [Command] ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
-
- if (customAttribute.AttributeType.FullName == Weaver.ClientRpcType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses [ClientRpc] ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
-
- if (customAttribute.AttributeType.FullName == Weaver.TargetRpcType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses [TargetRpc] ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
-
- var text = customAttribute.Constructor.DeclaringType.ToString();
- if (text == "UnityEngine.Networking.ServerAttribute")
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses the attribute [Server] on the method ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
- else if (text == "UnityEngine.Networking.ServerCallbackAttribute")
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses the attribute [ServerCallback] on the method ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
- else if (text == "UnityEngine.Networking.ClientAttribute")
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses the attribute [Client] on the method ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
- else if (text == "UnityEngine.Networking.ClientCallbackAttribute")
- {
- Log.Error(string.Concat(new string[]
- {
- "Script ",
- m_td.FullName,
- " uses the attribute [ClientCallback] on the method ",
- methodDefinition.Name,
- " but is not a NetworkBehaviour."
- }));
- Weaver.fail = true;
- }
- }
- }
- }
-
- private TypeDefinition m_td;
- }
-}
diff --git a/QNetWeaver/NetworkBehaviourProcessor.cs b/QNetWeaver/NetworkBehaviourProcessor.cs
deleted file mode 100644
index 7f4eb714..00000000
--- a/QNetWeaver/NetworkBehaviourProcessor.cs
+++ /dev/null
@@ -1,2237 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace QNetWeaver
-{
- internal class NetworkBehaviourProcessor
- {
- public NetworkBehaviourProcessor(TypeDefinition td)
- {
- Weaver.DLog(td, "NetworkBehaviourProcessor", new object[0]);
- m_td = td;
- }
-
- public void Process()
- {
- if (m_td.HasGenericParameters)
- {
- Weaver.fail = true;
- Log.Error("NetworkBehaviour " + m_td.Name + " cannot have generic parameters");
- }
- else
- {
- Weaver.DLog(m_td, "Process Start", new object[0]);
- ProcessVersion();
- ProcessSyncVars();
- Weaver.ResetRecursionCount();
- ProcessMethods();
- ProcessEvents();
- if (!Weaver.fail)
- {
- GenerateNetworkSettings();
- GenerateConstants();
- Weaver.ResetRecursionCount();
- GenerateSerialization();
- if (!Weaver.fail)
- {
- GenerateDeSerialization();
- GeneratePreStartClient();
- Weaver.DLog(m_td, "Process Done", new object[0]);
- }
- }
- }
- }
-
- private static void WriteClientActiveCheck(ILProcessor worker, string mdName, Instruction label, string errString)
- {
- worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkClientGetActive));
- worker.Append(worker.Create(OpCodes.Brtrue, label));
- worker.Append(worker.Create(OpCodes.Ldstr, errString + " " + mdName + " called on server."));
- worker.Append(worker.Create(OpCodes.Call, Weaver.logErrorReference));
- worker.Append(worker.Create(OpCodes.Ret));
- worker.Append(label);
- }
-
- private static void WriteServerActiveCheck(ILProcessor worker, string mdName, Instruction label, string errString)
- {
- worker.Append(worker.Create(OpCodes.Call, Weaver.NetworkServerGetActive));
- worker.Append(worker.Create(OpCodes.Brtrue, label));
- worker.Append(worker.Create(OpCodes.Ldstr, errString + " " + mdName + " called on client."));
- worker.Append(worker.Create(OpCodes.Call, Weaver.logErrorReference));
- worker.Append(worker.Create(OpCodes.Ret));
- worker.Append(label);
- }
-
- private static void WriteSetupLocals(ILProcessor worker)
- {
- worker.Body.InitLocals = true;
- worker.Body.Variables.Add(new VariableDefinition(Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
- }
-
- private static void WriteCreateWriter(ILProcessor worker)
- {
- worker.Append(worker.Create(OpCodes.Newobj, Weaver.NetworkWriterCtor));
- worker.Append(worker.Create(OpCodes.Stloc_0));
- worker.Append(worker.Create(OpCodes.Ldloc_0));
- }
-
- private static void WriteMessageSize(ILProcessor worker)
- {
- worker.Append(worker.Create(OpCodes.Ldc_I4_0));
- worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
- }
-
- private static void WriteMessageId(ILProcessor worker, int msgId)
- {
- worker.Append(worker.Create(OpCodes.Ldloc_0));
- worker.Append(worker.Create(OpCodes.Ldc_I4, msgId));
- worker.Append(worker.Create(OpCodes.Conv_U2));
- worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
- }
-
- private static bool WriteArguments(ILProcessor worker, MethodDefinition md, string errString, bool skipFirst)
- {
- short num = 1;
- foreach (var parameterDefinition in md.Parameters)
- {
- if (num == 1 && skipFirst)
- {
- num += 1;
- }
- else
- {
- var writeFunc = Weaver.GetWriteFunc(parameterDefinition.ParameterType);
- if (writeFunc == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "WriteArguments for ",
- md.Name,
- " type ",
- parameterDefinition.ParameterType,
- " not supported"
- }));
- Weaver.fail = true;
- return false;
- }
-
- worker.Append(worker.Create(OpCodes.Ldloc_0));
- worker.Append(worker.Create(OpCodes.Ldarg, num));
- worker.Append(worker.Create(OpCodes.Call, writeFunc));
- num += 1;
- }
- }
-
- return true;
- }
-
- private void ProcessVersion()
- {
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == "UNetVersion")
- {
- return;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("UNetVersion", MethodAttributes.Private, Weaver.voidType);
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
-
- private void GenerateConstants()
- {
- if (m_Cmds.Count != 0 || m_Rpcs.Count != 0 || m_TargetRpcs.Count != 0 || m_Events.Count != 0 || m_SyncLists.Count != 0)
- {
- Weaver.DLog(m_td, " GenerateConstants ", new object[0]);
- MethodDefinition cctorMethodDef = null;
-
- var flag = false;
- foreach (var methodDef in m_td.Methods)
- {
- if (methodDef.Name == ".cctor")
- {
- cctorMethodDef = methodDef;
- flag = true;
- }
- }
-
- if (cctorMethodDef != null)
- {
- if (cctorMethodDef.Body.Instructions.Count != 0)
- {
- var returnInstruction = cctorMethodDef.Body.Instructions[cctorMethodDef.Body.Instructions.Count - 1];
- if (!(returnInstruction.OpCode == OpCodes.Ret))
- {
- Log.Error("No .cctor for " + m_td.Name);
- Weaver.fail = true;
- return;
- }
-
- cctorMethodDef.Body.Instructions.RemoveAt(cctorMethodDef.Body.Instructions.Count - 1);
- }
- }
- else
- {
- Weaver.DLog(m_td, " No. cctor found, making... ", new object[0]);
- cctorMethodDef = new MethodDefinition(".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, Weaver.voidType);
- }
-
- MethodDefinition ctorMethodDef = null;
- foreach (var methodDef in m_td.Methods)
- {
- if (methodDef.Name == ".ctor")
- {
- ctorMethodDef = methodDef;
- var returnInstruction = ctorMethodDef.Body.Instructions[ctorMethodDef.Body.Instructions.Count - 1];
- if (returnInstruction.OpCode == OpCodes.Ret)
- {
- Weaver.DLog(m_td, " Found .ctor ", new object[0]);
- ctorMethodDef.Body.Instructions.RemoveAt(ctorMethodDef.Body.Instructions.Count - 1);
- break;
- }
-
- Weaver.fail = true;
- Log.Error("No .ctor for " + m_td.Name);
- return;
- }
- }
-
- if (ctorMethodDef == null)
- {
- Weaver.fail = true;
- Log.Error("No .ctor for " + m_td.Name);
- }
- else
- {
- var ilprocessor = ctorMethodDef.Body.GetILProcessor();
- var ilprocessor2 = cctorMethodDef.Body.GetILProcessor();
-
- var commandIndex = 0;
- foreach (var commandDef in m_Cmds)
- {
- Weaver.DLog(m_td, $" Found command {commandDef.Name}", new object[0]);
- var field = Weaver.ResolveField(m_td, "kCmd" + commandDef.Name);
- Weaver.DLog(m_td, $" got field", new object[0]);
- var hashCode = GetHashCode(m_td.Name + ":Cmd:" + commandDef.Name);
- Weaver.DLog(m_td, $" got hashcode", new object[0]);
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, hashCode));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Stsfld, field));
-
- GenerateCommandDelegate(ilprocessor2, Weaver.registerCommandDelegateReference, m_CmdInvocationFuncs[commandIndex], field);
- commandIndex++;
- }
-
- var rpcIndex = 0;
- foreach (var rpcDef in m_Rpcs)
- {
- var field2 = Weaver.ResolveField(m_td, "kRpc" + rpcDef.Name);
- var hashCode2 = GetHashCode(m_td.Name + ":Rpc:" + rpcDef.Name);
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, hashCode2));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Stsfld, field2));
- GenerateCommandDelegate(ilprocessor2, Weaver.registerRpcDelegateReference, m_RpcInvocationFuncs[rpcIndex], field2);
- rpcIndex++;
- }
-
- var targetRpcIndex = 0;
- foreach (var targetRpcDef in m_TargetRpcs)
- {
- var field3 = Weaver.ResolveField(m_td, "kTargetRpc" + targetRpcDef.Name);
- var hashCode3 = GetHashCode(m_td.Name + ":TargetRpc:" + targetRpcDef.Name);
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, hashCode3));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Stsfld, field3));
- GenerateCommandDelegate(ilprocessor2, Weaver.registerRpcDelegateReference, m_TargetRpcInvocationFuncs[targetRpcIndex], field3);
- targetRpcIndex++;
- }
-
- var eventIndex = 0;
- foreach (var eventDef in m_Events)
- {
- var field4 = Weaver.ResolveField(m_td, "kEvent" + eventDef.Name);
- var hashCode4 = GetHashCode(m_td.Name + ":Event:" + eventDef.Name);
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, hashCode4));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Stsfld, field4));
- GenerateCommandDelegate(ilprocessor2, Weaver.registerEventDelegateReference, m_EventInvocationFuncs[eventIndex], field4);
- eventIndex++;
- }
-
- var syncListIndex = 0;
- foreach (var syncListDef in m_SyncLists)
- {
- var field5 = Weaver.ResolveField(m_td, "kList" + syncListDef.Name);
- var hashCode5 = GetHashCode(m_td.Name + ":List:" + syncListDef.Name);
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, hashCode5));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Stsfld, field5));
- GenerateSyncListInstanceInitializer(ilprocessor, syncListDef);
- GenerateCommandDelegate(ilprocessor2, Weaver.registerSyncListDelegateReference, m_SyncListInvocationFuncs[syncListIndex], field5);
- syncListIndex++;
- }
-
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldstr, m_td.Name));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ldc_I4, m_QosChannel));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Call, Weaver.RegisterBehaviourReference));
- ilprocessor2.Append(ilprocessor2.Create(OpCodes.Ret));
- if (!flag)
- {
- m_td.Methods.Add(cctorMethodDef);
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Attributes = (m_td.Attributes & ~TypeAttributes.BeforeFieldInit);
- if (m_SyncLists.Count != 0)
- {
- MethodDefinition methodDefinition8 = null;
- var flag2 = false;
- foreach (var methodDefinition9 in m_td.Methods)
- {
- if (methodDefinition9.Name == "Awake")
- {
- methodDefinition8 = methodDefinition9;
- flag2 = true;
- }
- }
-
- if (methodDefinition8 != null)
- {
- if (methodDefinition8.Body.Instructions.Count != 0)
- {
- var instruction3 = methodDefinition8.Body.Instructions[methodDefinition8.Body.Instructions.Count - 1];
- if (!(instruction3.OpCode == OpCodes.Ret))
- {
- Log.Error("No awake for " + m_td.Name);
- Weaver.fail = true;
- return;
- }
-
- methodDefinition8.Body.Instructions.RemoveAt(methodDefinition8.Body.Instructions.Count - 1);
- }
- }
- else
- {
- methodDefinition8 = new MethodDefinition("Awake", MethodAttributes.Private, Weaver.voidType);
- }
-
- var ilprocessor3 = methodDefinition8.Body.GetILProcessor();
- if (!flag2)
- {
- CheckForCustomBaseClassAwakeMethod(ilprocessor3);
- }
-
- var num6 = 0;
- foreach (var fd in m_SyncLists)
- {
- GenerateSyncListInitializer(ilprocessor3, fd, num6);
- num6++;
- }
-
- ilprocessor3.Append(ilprocessor3.Create(OpCodes.Ret));
- if (!flag2)
- {
- m_td.Methods.Add(methodDefinition8);
- }
- }
- }
- }
- }
-
- private void CheckForCustomBaseClassAwakeMethod(ILProcessor awakeWorker)
- {
- var baseType = m_td.BaseType;
- while (baseType.FullName != Weaver.NetworkBehaviourType.FullName)
- {
- var methodDefinition = Enumerable.FirstOrDefault(baseType.Resolve().Methods, (MethodDefinition x) => x.Name == "Awake" && !x.HasParameters);
- if (methodDefinition != null)
- {
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Call, methodDefinition));
- break;
- }
-
- baseType = baseType.Resolve().BaseType;
- }
- }
-
- private void GenerateSyncListInstanceInitializer(ILProcessor ctorWorker, FieldDefinition fd)
- {
- foreach (var instruction in ctorWorker.Body.Instructions)
- {
- if (instruction.OpCode.Code == Code.Stfld)
- {
- var fieldDefinition = (FieldDefinition)instruction.Operand;
- if (fieldDefinition.DeclaringType == fd.DeclaringType && fieldDefinition.Name == fd.Name)
- {
- return;
- }
- }
- }
-
- var method = Weaver.scriptDef.MainModule.ImportReference(Enumerable.First(fd.FieldType.Resolve().Methods, (MethodDefinition x) => x.Name == ".ctor" && !x.HasParameters));
- ctorWorker.Append(ctorWorker.Create(OpCodes.Ldarg_0));
- ctorWorker.Append(ctorWorker.Create(OpCodes.Newobj, method));
- ctorWorker.Append(ctorWorker.Create(OpCodes.Stfld, fd));
- }
-
- private void GenerateCommandDelegate(ILProcessor awakeWorker, MethodReference registerMethod, MethodDefinition func, FieldReference field)
- {
- Weaver.DLog(m_td, " GenerateCommandDelegate ", new object[0]);
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldtoken, m_td));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldsfld, field));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldnull));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldftn, func));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Newobj, Weaver.CmdDelegateConstructor));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Call, registerMethod));
- }
-
- private void GenerateSyncListInitializer(ILProcessor awakeWorker, FieldReference fd, int index)
- {
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldfld, fd));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
- awakeWorker.Append(awakeWorker.Create(OpCodes.Ldsfld, m_SyncListStaticFields[index]));
- var genericInstanceType = (GenericInstanceType)fd.FieldType.Resolve().BaseType;
- genericInstanceType = (GenericInstanceType)Weaver.scriptDef.MainModule.ImportReference(genericInstanceType);
- var typeReference = genericInstanceType.GenericArguments[0];
- var method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListInitBehaviourReference, new TypeReference[]
- {
- typeReference
- });
- awakeWorker.Append(awakeWorker.Create(OpCodes.Callvirt, method));
- Weaver.scriptDef.MainModule.ImportReference(method);
- }
-
- private void GenerateSerialization()
- {
- Weaver.DLog(m_td, " NetworkBehaviour GenerateSerialization", new object[0]);
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == "OnSerialize")
- {
- Weaver.DLog(m_td, " Abort - is OnSerialize", new object[0]);
- return;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("OnSerialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.boolType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
- methodDefinition2.Parameters.Add(new ParameterDefinition("forceAll", ParameterAttributes.None, Weaver.boolType));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- methodDefinition2.Body.InitLocals = true;
- var item = new VariableDefinition(Weaver.boolType);
- methodDefinition2.Body.Variables.Add(item);
- var flag = false;
-
- if (m_td.BaseType.FullName != Weaver.NetworkBehaviourType.FullName)
- {
- var methodReference = Weaver.ResolveMethod(m_td.BaseType, "OnSerialize");
- if (methodReference != null)
- {
- var item2 = new VariableDefinition(Weaver.boolType);
- methodDefinition2.Body.Variables.Add(item2);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, methodReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- flag = true;
- }
- }
-
- if (m_SyncVars.Count == 0)
- {
- Weaver.DLog(m_td, " No syncvars", new object[0]);
- if (flag)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Or));
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
- else
- {
- Weaver.DLog(m_td, " Syncvars exist", new object[0]);
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction));
- foreach (var fieldDefinition in m_SyncVars)
- {
- Weaver.DLog(m_td, $" For {fieldDefinition.Name}", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition));
- var writeFunc = Weaver.GetWriteFunc(fieldDefinition.FieldType);
- if (writeFunc == null)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition.FieldType,
- "]. UNet [SyncVar] member variables must be basic types."
- }));
- return;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
- }
-
- Weaver.DLog(m_td, $" Finish foreach 1", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- var num = Weaver.GetSyncVarStart(m_td.BaseType.FullName);
- foreach (var fieldDefinition2 in m_SyncVars)
- {
- Weaver.DLog(m_td, $" For {fieldDefinition2.Name}", new object[0]);
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- Weaver.DLog(m_td, $" Got instruction2", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- Weaver.DLog(m_td, $" call dirtbits reference", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.NetworkBehaviourDirtyBitsReference));
- Weaver.DLog(m_td, $" finish call dirtbits reference", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, 1 << num));
- ilprocessor.Append(ilprocessor.Create(OpCodes.And));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction2));
- Weaver.DLog(m_td, $" writing dirtycheck", new object[0]);
- WriteDirtyCheck(ilprocessor, true);
- Weaver.DLog(m_td, $" done writing dirtycheck", new object[0]);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition2));
- Weaver.DLog(m_td, $" Getting writeFunc2", new object[0]);
- var writeFunc2 = Weaver.GetWriteFunc(fieldDefinition2.FieldType);
- Weaver.DLog(m_td, $" Got writeFunc2", new object[0]);
- if (writeFunc2 == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition2.FieldType,
- "]. UNet [SyncVar] member variables must be basic types."
- }));
- Weaver.fail = true;
- return;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc2));
- ilprocessor.Append(instruction2);
- num++;
- }
-
- Weaver.DLog(m_td, $" Finish foreach 2", new object[0]);
- WriteDirtyCheck(ilprocessor, false);
- if (Weaver.generateLogErrors)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, "Injected Serialize " + m_td.Name));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.logErrorReference));
- }
-
- if (flag)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Or));
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- Weaver.DLog(m_td, $" Finish", new object[0]);
- }
-
- Weaver.DLog(m_td, $" Finish", new object[0]);
- }
-
- private static void WriteDirtyCheck(ILProcessor serWorker, bool reset)
- {
- var instruction = serWorker.Create(OpCodes.Nop);
- serWorker.Append(serWorker.Create(OpCodes.Ldloc_0));
- serWorker.Append(serWorker.Create(OpCodes.Brtrue, instruction));
- serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
- serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
- serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkBehaviourDirtyBitsReference));
- serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
- if (reset)
- {
- serWorker.Append(serWorker.Create(OpCodes.Ldc_I4_1));
- serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
- }
-
- serWorker.Append(instruction);
- }
-
- private static int GetChannelId(FieldDefinition field)
- {
- var result = 0;
- foreach (var customAttribute in field.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.SyncVarType.FullName)
- {
- foreach (var customAttributeNamedArgument in customAttribute.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- result = (int)customAttributeNamedArgument.Argument.Value;
- break;
- }
- }
- }
- }
-
- return result;
- }
-
- private bool CheckForHookFunction(FieldDefinition syncVar, out MethodDefinition foundMethod)
- {
- foundMethod = null;
- foreach (var customAttribute in syncVar.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.SyncVarType.FullName)
- {
- foreach (var customAttributeNamedArgument in customAttribute.Fields)
- {
- if (customAttributeNamedArgument.Name == "hook")
- {
- var text = customAttributeNamedArgument.Argument.Value as string;
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == text)
- {
- if (methodDefinition.Parameters.Count != 1)
- {
- Log.Error("SyncVar Hook function " + text + " must have one argument " + m_td.Name);
- Weaver.fail = true;
- return false;
- }
-
- if (methodDefinition.Parameters[0].ParameterType != syncVar.FieldType)
- {
- Log.Error("SyncVar Hook function " + text + " has wrong type signature for " + m_td.Name);
- Weaver.fail = true;
- return false;
- }
-
- foundMethod = methodDefinition;
- return true;
- }
- }
-
- Log.Error("SyncVar Hook function " + text + " not found for " + m_td.Name);
- Weaver.fail = true;
- return false;
- }
- }
- }
- }
-
- return true;
- }
-
- private void GenerateNetworkChannelSetting(int channel)
- {
- var methodDefinition = new MethodDefinition("GetNetworkChannel", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.int32Type);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, channel));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition);
- }
-
- private void GenerateNetworkIntervalSetting(float interval)
- {
- var methodDefinition = new MethodDefinition("GetNetworkSendInterval", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.singleType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_R4, interval));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition);
- }
-
- private void GenerateNetworkSettings()
- {
- foreach (var customAttribute in m_td.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.NetworkSettingsType.FullName)
- {
- foreach (var customAttributeNamedArgument in customAttribute.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- if ((int)customAttributeNamedArgument.Argument.Value == 0)
- {
- continue;
- }
-
- if (HasMethod("GetNetworkChannel"))
- {
- Log.Error("GetNetworkChannel, is already implemented, please make sure you either use NetworkSettings or GetNetworkChannel");
- Weaver.fail = true;
- return;
- }
-
- m_QosChannel = (int)customAttributeNamedArgument.Argument.Value;
- GenerateNetworkChannelSetting(m_QosChannel);
- }
-
- if (customAttributeNamedArgument.Name == "sendInterval")
- {
- if (Math.Abs((float)customAttributeNamedArgument.Argument.Value - 0.1f) > 1E-05f)
- {
- if (HasMethod("GetNetworkSendInterval"))
- {
- Log.Error("GetNetworkSendInterval, is already implemented, please make sure you either use NetworkSettings or GetNetworkSendInterval");
- Weaver.fail = true;
- return;
- }
-
- GenerateNetworkIntervalSetting((float)customAttributeNamedArgument.Argument.Value);
- }
- }
- }
- }
- }
- }
-
- private void GeneratePreStartClient()
- {
- m_NetIdFieldCounter = 0;
- MethodDefinition methodDefinition = null;
- ILProcessor ilprocessor = null;
- foreach (var methodDefinition2 in m_td.Methods)
- {
- if (methodDefinition2.Name == "PreStartClient")
- {
- return;
- }
- }
-
- foreach (var fieldDefinition in m_SyncVars)
- {
- if (fieldDefinition.FieldType.FullName == Weaver.gameObjectType.FullName)
- {
- if (methodDefinition == null)
- {
- methodDefinition = new MethodDefinition("PreStartClient", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
- ilprocessor = methodDefinition.Body.GetILProcessor();
- }
-
- var field = m_SyncVarNetIds[m_NetIdFieldCounter];
- m_NetIdFieldCounter++;
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldflda, field));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.NetworkInstanceIsEmpty));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brtrue, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, field));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.FindLocalObjectReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition));
- ilprocessor.Append(instruction);
- }
- }
-
- if (methodDefinition != null)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition);
- }
- }
-
- private void GenerateDeSerialization()
- {
- Weaver.DLog(m_td, " GenerateDeSerialization", new object[0]);
- m_NetIdFieldCounter = 0;
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == "OnDeserialize")
- {
- return;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("OnDeserialize", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
- methodDefinition2.Parameters.Add(new ParameterDefinition("initialState", ParameterAttributes.None, Weaver.boolType));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- if (m_td.BaseType.FullName != Weaver.NetworkBehaviourType.FullName)
- {
- var methodReference = Weaver.ResolveMethod(m_td.BaseType, "OnDeserialize");
- if (methodReference != null)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, methodReference));
- }
- }
-
- if (m_SyncVars.Count == 0)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
- else
- {
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction));
- foreach (var fieldDefinition in m_SyncVars)
- {
- var readByReferenceFunc = Weaver.GetReadByReferenceFunc(fieldDefinition.FieldType);
- if (readByReferenceFunc != null)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readByReferenceFunc));
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- if (fieldDefinition.FieldType.FullName == Weaver.gameObjectType.FullName)
- {
- var field = m_SyncVarNetIds[m_NetIdFieldCounter];
- m_NetIdFieldCounter++;
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadNetworkInstanceId));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, field));
- }
- else
- {
- var readFunc = Weaver.GetReadFunc(fieldDefinition.FieldType);
- if (readFunc == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "GenerateDeSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition.FieldType,
- "]. UNet [SyncVar] member variables must be basic types."
- }));
- Weaver.fail = true;
- return;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition));
- }
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- methodDefinition2.Body.InitLocals = true;
- var item = new VariableDefinition(Weaver.int32Type);
- methodDefinition2.Body.Variables.Add(item);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked32));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- var num = Weaver.GetSyncVarStart(m_td.BaseType.FullName);
- foreach (var fieldDefinition2 in m_SyncVars)
- {
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, 1 << num));
- ilprocessor.Append(ilprocessor.Create(OpCodes.And));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction2));
- var readByReferenceFunc2 = Weaver.GetReadByReferenceFunc(fieldDefinition2.FieldType);
- if (readByReferenceFunc2 != null)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readByReferenceFunc2));
- }
- else
- {
- var readFunc2 = Weaver.GetReadFunc(fieldDefinition2.FieldType);
- if (readFunc2 == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "GenerateDeSerialization for ",
- m_td.Name,
- " unknown type [",
- fieldDefinition2.FieldType,
- "]. UNet [SyncVar] member variables must be basic types."
- }));
- Weaver.fail = true;
- return;
- }
-
- if (!CheckForHookFunction(fieldDefinition2, out var methodDefinition3))
- {
- return;
- }
-
- if (methodDefinition3 == null)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition2));
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, methodDefinition3));
- }
- }
-
- ilprocessor.Append(instruction2);
- num++;
- }
-
- if (Weaver.generateLogErrors)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, "Injected Deserialize " + m_td.Name));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.logErrorReference));
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_td.Methods.Add(methodDefinition2);
- }
- }
-
- private bool ProcessNetworkReaderParameters(MethodDefinition md, ILProcessor worker, bool skipFirst)
- {
- var num = 0;
- foreach (var parameterDefinition in md.Parameters)
- {
- if (num++ != 0 || !skipFirst)
- {
- var readFunc = Weaver.GetReadFunc(parameterDefinition.ParameterType);
- if (readFunc == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "ProcessNetworkReaderParameters for ",
- m_td.Name,
- ":",
- md.Name,
- " type ",
- parameterDefinition.ParameterType,
- " not supported"
- }));
- Weaver.fail = true;
- return false;
- }
-
- worker.Append(worker.Create(OpCodes.Ldarg_1));
- worker.Append(worker.Create(OpCodes.Call, readFunc));
- if (parameterDefinition.ParameterType.FullName == Weaver.singleType.FullName)
- {
- worker.Append(worker.Create(OpCodes.Conv_R4));
- }
- else if (parameterDefinition.ParameterType.FullName == Weaver.doubleType.FullName)
- {
- worker.Append(worker.Create(OpCodes.Conv_R8));
- }
- }
- }
-
- return true;
- }
-
- private MethodDefinition ProcessCommandInvoke(MethodDefinition md)
- {
- var methodDefinition = new MethodDefinition("InvokeCmd" + md.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteServerActiveCheck(ilprocessor, md.Name, label, "Command");
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, m_td));
- MethodDefinition result;
- if (!ProcessNetworkReaderParameters(md, ilprocessor, false))
- {
- result = null;
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, md));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- AddInvokeParameters(methodDefinition.Parameters);
- result = methodDefinition;
- }
-
- return result;
- }
-
- private static void AddInvokeParameters(ICollection collection)
- {
- collection.Add(new ParameterDefinition("obj", ParameterAttributes.None, Weaver.NetworkBehaviourType2));
- collection.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
- }
-
- private MethodDefinition ProcessCommandCall(MethodDefinition md, CustomAttribute ca)
- {
- var methodDefinition = new MethodDefinition("Call" + md.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig, Weaver.voidType);
- foreach (var parameterDefinition in md.Parameters)
- {
- methodDefinition.Parameters.Add(new ParameterDefinition(parameterDefinition.Name, ParameterAttributes.None, parameterDefinition.ParameterType));
- }
-
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteSetupLocals(ilprocessor);
- if (Weaver.generateLogErrors)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, "Call Command function " + md.Name));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.logErrorReference));
- }
-
- WriteClientActiveCheck(ilprocessor, md.Name, label, "Command function");
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.UBehaviourIsServer));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- for (var i = 0; i < md.Parameters.Count; i++)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg, i + 1));
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, md));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- WriteCreateWriter(ilprocessor);
- WriteMessageSize(ilprocessor);
- WriteMessageId(ilprocessor, 5);
- var fieldDefinition = new FieldDefinition("kCmd" + md.Name, FieldAttributes.Private | FieldAttributes.Static, Weaver.int32Type);
- m_td.Fields.Add(fieldDefinition);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldsfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.getComponentReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
- var writeFunc = Weaver.GetWriteFunc(Weaver.NetworkInstanceIdType);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, writeFunc));
- MethodDefinition result;
- if (!WriteArguments(ilprocessor, md, "Command", false))
- {
- result = null;
- }
- else
- {
- var value = 0;
- foreach (var customAttributeNamedArgument in ca.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- value = (int)customAttributeNamedArgument.Argument.Value;
- }
- }
-
- var text = md.Name;
- var num = text.IndexOf("InvokeCmd");
- if (num > -1)
- {
- text = text.Substring("InvokeCmd".Length);
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, value));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, text));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.sendCommandInternal));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private MethodDefinition ProcessTargetRpcInvoke(MethodDefinition md)
- {
- var methodDefinition = new MethodDefinition("InvokeRpc" + md.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteClientActiveCheck(ilprocessor, md.Name, label, "TargetRPC");
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, m_td));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.ReadyConnectionReference));
- MethodDefinition result;
- if (!ProcessNetworkReaderParameters(md, ilprocessor, true))
- {
- result = null;
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, md));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- AddInvokeParameters(methodDefinition.Parameters);
- result = methodDefinition;
- }
-
- return result;
- }
-
- private MethodDefinition ProcessRpcInvoke(MethodDefinition md)
- {
- var methodDefinition = new MethodDefinition("InvokeRpc" + md.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteClientActiveCheck(ilprocessor, md.Name, label, "RPC");
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, m_td));
- MethodDefinition result;
- if (!ProcessNetworkReaderParameters(md, ilprocessor, false))
- {
- result = null;
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, md));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- AddInvokeParameters(methodDefinition.Parameters);
- result = methodDefinition;
- }
-
- return result;
- }
-
- private MethodDefinition ProcessTargetRpcCall(MethodDefinition md, CustomAttribute ca)
- {
- var methodDefinition = new MethodDefinition("Call" + md.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig, Weaver.voidType);
- foreach (var parameterDefinition in md.Parameters)
- {
- methodDefinition.Parameters.Add(new ParameterDefinition(parameterDefinition.Name, ParameterAttributes.None, parameterDefinition.ParameterType));
- }
-
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteSetupLocals(ilprocessor);
- WriteServerActiveCheck(ilprocessor, md.Name, label, "TargetRPC Function");
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Isinst, Weaver.ULocalConnectionToServerType));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, string.Format("TargetRPC Function {0} called on connection to server", md.Name)));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.logErrorReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- WriteCreateWriter(ilprocessor);
- WriteMessageSize(ilprocessor);
- WriteMessageId(ilprocessor, 2);
- var fieldDefinition = new FieldDefinition("kTargetRpc" + md.Name, FieldAttributes.Private | FieldAttributes.Static, Weaver.int32Type);
- m_td.Fields.Add(fieldDefinition);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldsfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.getComponentReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteNetworkInstanceId));
- MethodDefinition result;
- if (!WriteArguments(ilprocessor, md, "TargetRPC", true))
- {
- result = null;
- }
- else
- {
- var value = 0;
- foreach (var customAttributeNamedArgument in ca.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- value = (int)customAttributeNamedArgument.Argument.Value;
- }
- }
-
- var text = md.Name;
- var num = text.IndexOf("InvokeTargetRpc");
- if (num > -1)
- {
- text = text.Substring("InvokeTargetRpc".Length);
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, value));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, text));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.sendTargetRpcInternal));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private MethodDefinition ProcessRpcCall(MethodDefinition md, CustomAttribute ca)
- {
- var methodDefinition = new MethodDefinition("Call" + md.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig, Weaver.voidType);
- foreach (var parameterDefinition in md.Parameters)
- {
- methodDefinition.Parameters.Add(new ParameterDefinition(parameterDefinition.Name, ParameterAttributes.None, parameterDefinition.ParameterType));
- }
-
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteSetupLocals(ilprocessor);
- WriteServerActiveCheck(ilprocessor, md.Name, label, "RPC Function");
- WriteCreateWriter(ilprocessor);
- WriteMessageSize(ilprocessor);
- WriteMessageId(ilprocessor, 2);
- var fieldDefinition = new FieldDefinition("kRpc" + md.Name, FieldAttributes.Private | FieldAttributes.Static, Weaver.int32Type);
- m_td.Fields.Add(fieldDefinition);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldsfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.getComponentReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteNetworkInstanceId));
- MethodDefinition result;
- if (!WriteArguments(ilprocessor, md, "RPC", false))
- {
- result = null;
- }
- else
- {
- var value = 0;
- foreach (var customAttributeNamedArgument in ca.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- value = (int)customAttributeNamedArgument.Argument.Value;
- }
- }
-
- var text = md.Name;
- var num = text.IndexOf("InvokeRpc");
- if (num > -1)
- {
- text = text.Substring("InvokeRpc".Length);
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, value));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, text));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.sendRpcInternal));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private bool ProcessMethodsValidateFunction(MethodReference md, CustomAttribute ca, string actionType)
- {
- bool result;
- if (md.ReturnType.FullName == Weaver.IEnumeratorType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot be a coroutine"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.ReturnType.FullName != Weaver.voidType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] must have a void return type."
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.HasGenericParameters)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot have generic parameters"
- }));
- Weaver.fail = true;
- result = false;
- }
- else
- {
- result = true;
- }
-
- return result;
- }
-
- private bool ProcessMethodsValidateParameters(MethodReference md, CustomAttribute ca, string actionType)
- {
- var i = 0;
- while (i < md.Parameters.Count)
- {
- var parameterDefinition = md.Parameters[i];
- bool result;
- if (parameterDefinition.IsOut)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot have out parameters"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (parameterDefinition.IsOptional)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- "function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot have optional parameters"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (parameterDefinition.ParameterType.Resolve().IsAbstract)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot have abstract parameters"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (parameterDefinition.ParameterType.IsByReference)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot have ref parameters"
- }));
- Weaver.fail = true;
- result = false;
- }
- else
- {
- if (!(parameterDefinition.ParameterType.FullName == Weaver.NetworkConnectionType.FullName) || (ca.AttributeType.FullName == Weaver.TargetRpcType.FullName && i == 0))
- {
- if (Weaver.IsDerivedFrom(parameterDefinition.ParameterType.Resolve(), Weaver.ComponentType))
- {
- if (parameterDefinition.ParameterType.FullName != Weaver.NetworkIdentityType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " function [",
- m_td.FullName,
- ":",
- md.Name,
- "] parameter [",
- parameterDefinition.Name,
- "] is of the type [",
- parameterDefinition.ParameterType.Name,
- "] which is a Component. You cannot pass a Component to a remote call. Try passing data from within the component."
- }));
- Weaver.fail = true;
- return false;
- }
- }
-
- i++;
- continue;
- }
-
- Log.Error(string.Concat(new string[]
- {
- actionType,
- " [",
- m_td.FullName,
- ":",
- md.Name,
- "] cannot use a NetworkConnection as a parameter. To access a player object's connection on the server use connectionToClient"
- }));
- Log.Error("Name: " + ca.AttributeType.FullName + " parameter: " + md.Parameters[0].ParameterType.FullName);
- Weaver.fail = true;
- result = false;
- }
-
- return result;
- }
-
- return true;
- }
-
- private bool ProcessMethodsValidateCommand(MethodDefinition md, CustomAttribute ca)
- {
- bool result;
- if (md.Name.Length > 2 && md.Name.Substring(0, 3) != "Cmd")
- {
- Log.Error(string.Concat(new string[]
- {
- "Command function [",
- m_td.FullName,
- ":",
- md.Name,
- "] doesnt have 'Cmd' prefix"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.IsStatic)
- {
- Log.Error(string.Concat(new string[]
- {
- "Command function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cant be a static method"
- }));
- Weaver.fail = true;
- result = false;
- }
- else
- {
- result = (ProcessMethodsValidateFunction(md, ca, "Command") && ProcessMethodsValidateParameters(md, ca, "Command"));
- }
-
- return result;
- }
-
- private bool ProcessMethodsValidateTargetRpc(MethodDefinition md, CustomAttribute ca)
- {
- var length = "Target".Length;
- bool result;
- if (md.Name.Length > length && md.Name.Substring(0, length) != "Target")
- {
- Log.Error(string.Concat(new string[]
- {
- "Target Rpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] doesnt have 'Target' prefix"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.IsStatic)
- {
- Log.Error(string.Concat(new string[]
- {
- "TargetRpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cant be a static method"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (!ProcessMethodsValidateFunction(md, ca, "Target Rpc"))
- {
- result = false;
- }
- else if (md.Parameters.Count < 1)
- {
- Log.Error(string.Concat(new string[]
- {
- "Target Rpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] must have a NetworkConnection as the first parameter"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.Parameters[0].ParameterType.FullName != Weaver.NetworkConnectionType.FullName)
- {
- Log.Error(string.Concat(new string[]
- {
- "Target Rpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] first parameter must be a NetworkConnection"
- }));
- Weaver.fail = true;
- result = false;
- }
- else
- {
- result = ProcessMethodsValidateParameters(md, ca, "Target Rpc");
- }
-
- return result;
- }
-
- private bool ProcessMethodsValidateRpc(MethodDefinition md, CustomAttribute ca)
- {
- bool result;
- if (md.Name.Length > 2 && md.Name.Substring(0, 3) != "Rpc")
- {
- Log.Error(string.Concat(new string[]
- {
- "Rpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] doesnt have 'Rpc' prefix"
- }));
- Weaver.fail = true;
- result = false;
- }
- else if (md.IsStatic)
- {
- Log.Error(string.Concat(new string[]
- {
- "ClientRpc function [",
- m_td.FullName,
- ":",
- md.Name,
- "] cant be a static method"
- }));
- Weaver.fail = true;
- result = false;
- }
- else
- {
- result = (ProcessMethodsValidateFunction(md, ca, "Rpc") && ProcessMethodsValidateParameters(md, ca, "Rpc"));
- }
-
- return result;
- }
-
- private void ProcessMethods()
- {
- var hashSet = new HashSet();
- foreach (var methodDefinition in m_td.Methods)
- {
- Weaver.ResetRecursionCount();
- foreach (var customAttribute in methodDefinition.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.CommandType.FullName)
- {
- if (!ProcessMethodsValidateCommand(methodDefinition, customAttribute))
- {
- return;
- }
-
- if (hashSet.Contains(methodDefinition.Name))
- {
- Log.Error(string.Concat(new string[]
- {
- "Duplicate Command name [",
- m_td.FullName,
- ":",
- methodDefinition.Name,
- "]"
- }));
- Weaver.fail = true;
- return;
- }
-
- hashSet.Add(methodDefinition.Name);
- m_Cmds.Add(methodDefinition);
- var methodDefinition2 = ProcessCommandInvoke(methodDefinition);
- if (methodDefinition2 != null)
- {
- m_CmdInvocationFuncs.Add(methodDefinition2);
- }
-
- var methodDefinition3 = ProcessCommandCall(methodDefinition, customAttribute);
- if (methodDefinition3 != null)
- {
- m_CmdCallFuncs.Add(methodDefinition3);
- Weaver.lists.replacedMethods.Add(methodDefinition);
- Weaver.lists.replacementMethods.Add(methodDefinition3);
- }
-
- break;
- }
- else if (customAttribute.AttributeType.FullName == Weaver.TargetRpcType.FullName)
- {
- if (!ProcessMethodsValidateTargetRpc(methodDefinition, customAttribute))
- {
- return;
- }
-
- if (hashSet.Contains(methodDefinition.Name))
- {
- Log.Error(string.Concat(new string[]
- {
- "Duplicate Target Rpc name [",
- m_td.FullName,
- ":",
- methodDefinition.Name,
- "]"
- }));
- Weaver.fail = true;
- return;
- }
-
- hashSet.Add(methodDefinition.Name);
- m_TargetRpcs.Add(methodDefinition);
- var methodDefinition4 = ProcessTargetRpcInvoke(methodDefinition);
- if (methodDefinition4 != null)
- {
- m_TargetRpcInvocationFuncs.Add(methodDefinition4);
- }
-
- var methodDefinition5 = ProcessTargetRpcCall(methodDefinition, customAttribute);
- if (methodDefinition5 != null)
- {
- m_TargetRpcCallFuncs.Add(methodDefinition5);
- Weaver.lists.replacedMethods.Add(methodDefinition);
- Weaver.lists.replacementMethods.Add(methodDefinition5);
- }
-
- break;
- }
- else if (customAttribute.AttributeType.FullName == Weaver.ClientRpcType.FullName)
- {
- if (!ProcessMethodsValidateRpc(methodDefinition, customAttribute))
- {
- return;
- }
-
- if (hashSet.Contains(methodDefinition.Name))
- {
- Log.Error(string.Concat(new string[]
- {
- "Duplicate ClientRpc name [",
- m_td.FullName,
- ":",
- methodDefinition.Name,
- "]"
- }));
- Weaver.fail = true;
- return;
- }
-
- hashSet.Add(methodDefinition.Name);
- m_Rpcs.Add(methodDefinition);
- var methodDefinition6 = ProcessRpcInvoke(methodDefinition);
- if (methodDefinition6 != null)
- {
- m_RpcInvocationFuncs.Add(methodDefinition6);
- }
-
- var methodDefinition7 = ProcessRpcCall(methodDefinition, customAttribute);
- if (methodDefinition7 != null)
- {
- m_RpcCallFuncs.Add(methodDefinition7);
- Weaver.lists.replacedMethods.Add(methodDefinition);
- Weaver.lists.replacementMethods.Add(methodDefinition7);
- }
-
- break;
- }
- }
- }
-
- foreach (var item in m_CmdInvocationFuncs)
- {
- m_td.Methods.Add(item);
- }
-
- foreach (var item2 in m_CmdCallFuncs)
- {
- m_td.Methods.Add(item2);
- }
-
- foreach (var item3 in m_RpcInvocationFuncs)
- {
- m_td.Methods.Add(item3);
- }
-
- foreach (var item4 in m_TargetRpcInvocationFuncs)
- {
- m_td.Methods.Add(item4);
- }
-
- foreach (var item5 in m_RpcCallFuncs)
- {
- m_td.Methods.Add(item5);
- }
-
- foreach (var item6 in m_TargetRpcCallFuncs)
- {
- m_td.Methods.Add(item6);
- }
- }
-
- private MethodDefinition ProcessEventInvoke(EventDefinition ed)
- {
- FieldDefinition fieldDefinition = null;
- foreach (var fieldDefinition2 in m_td.Fields)
- {
- if (fieldDefinition2.FullName == ed.FullName)
- {
- fieldDefinition = fieldDefinition2;
- break;
- }
- }
-
- MethodDefinition result;
- if (fieldDefinition == null)
- {
- Weaver.DLog(m_td, "ERROR: no event field?!", new object[0]);
- Weaver.fail = true;
- result = null;
- }
- else
- {
- var methodDefinition = new MethodDefinition("InvokeSyncEvent" + ed.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- var instruction = ilprocessor.Create(OpCodes.Nop);
- WriteClientActiveCheck(ilprocessor, ed.Name, label, "Event");
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, m_td));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brtrue, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, m_td));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition));
- var methodReference = Weaver.ResolveMethod(fieldDefinition.FieldType, "Invoke");
- if (!ProcessNetworkReaderParameters(methodReference.Resolve(), ilprocessor, false))
- {
- result = null;
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, methodReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- AddInvokeParameters(methodDefinition.Parameters);
- result = methodDefinition;
- }
- }
-
- return result;
- }
-
- private MethodDefinition ProcessEventCall(EventDefinition ed, CustomAttribute ca)
- {
- var methodReference = Weaver.ResolveMethod(ed.EventType, "Invoke");
- var methodDefinition = new MethodDefinition("Call" + ed.Name, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig, Weaver.voidType);
- foreach (var parameterDefinition in methodReference.Parameters)
- {
- methodDefinition.Parameters.Add(new ParameterDefinition(parameterDefinition.Name, ParameterAttributes.None, parameterDefinition.ParameterType));
- }
-
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteSetupLocals(ilprocessor);
- WriteServerActiveCheck(ilprocessor, ed.Name, label, "Event");
- WriteCreateWriter(ilprocessor);
- WriteMessageSize(ilprocessor);
- WriteMessageId(ilprocessor, 7);
- var fieldDefinition = new FieldDefinition("kEvent" + ed.Name, FieldAttributes.Private | FieldAttributes.Static, Weaver.int32Type);
- m_td.Fields.Add(fieldDefinition);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldsfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.getComponentReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteNetworkInstanceId));
- MethodDefinition result;
- if (!WriteArguments(ilprocessor, methodReference.Resolve(), "SyncEvent", false))
- {
- result = null;
- }
- else
- {
- var value = 0;
- foreach (var customAttributeNamedArgument in ca.Fields)
- {
- if (customAttributeNamedArgument.Name == "channel")
- {
- value = (int)customAttributeNamedArgument.Argument.Value;
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, value));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldstr, ed.Name));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.sendEventInternal));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private void ProcessEvents()
- {
- foreach (var eventDefinition in m_td.Events)
- {
- foreach (var customAttribute in eventDefinition.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.SyncEventType.FullName)
- {
- if (eventDefinition.Name.Length > 4 && eventDefinition.Name.Substring(0, 5) != "Event")
- {
- Log.Error(string.Concat(new string[]
- {
- "Event [",
- m_td.FullName,
- ":",
- eventDefinition.FullName,
- "] doesnt have 'Event' prefix"
- }));
- Weaver.fail = true;
- return;
- }
-
- if (eventDefinition.EventType.Resolve().HasGenericParameters)
- {
- Log.Error(string.Concat(new string[]
- {
- "Event [",
- m_td.FullName,
- ":",
- eventDefinition.FullName,
- "] cannot have generic parameters"
- }));
- Weaver.fail = true;
- return;
- }
-
- m_Events.Add(eventDefinition);
- var methodDefinition = ProcessEventInvoke(eventDefinition);
- if (methodDefinition == null)
- {
- return;
- }
-
- m_td.Methods.Add(methodDefinition);
- m_EventInvocationFuncs.Add(methodDefinition);
- Weaver.DLog(m_td, "ProcessEvent " + eventDefinition, new object[0]);
- var methodDefinition2 = ProcessEventCall(eventDefinition, customAttribute);
- m_td.Methods.Add(methodDefinition2);
- Weaver.lists.replacedEvents.Add(eventDefinition);
- Weaver.lists.replacementEvents.Add(methodDefinition2);
- Weaver.DLog(m_td, " Event: " + eventDefinition.Name, new object[0]);
- break;
- }
- }
- }
- }
-
- private static MethodDefinition ProcessSyncVarGet(FieldDefinition fd, string originalName)
- {
- var methodDefinition = new MethodDefinition("get_Network" + originalName, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName, fd.FieldType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fd));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- methodDefinition.Body.Variables.Add(new VariableDefinition(fd.FieldType));
- methodDefinition.Body.InitLocals = true;
- methodDefinition.SemanticsAttributes = MethodSemanticsAttributes.Getter;
- return methodDefinition;
- }
-
- private MethodDefinition ProcessSyncVarSet(FieldDefinition fd, string originalName, int dirtyBit, FieldDefinition netFieldId)
- {
- var methodDefinition = new MethodDefinition("set_Network" + originalName, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
-
- var noOperatorInstruction = ilprocessor.Create(OpCodes.Nop);
- var returnInstruction = ilprocessor.Create(OpCodes.Ret);
-
- CheckForHookFunction(fd, out var methodDefinition2);
- if (methodDefinition2 != null)
- {
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.NetworkServerGetLocalClientActive));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse, noOperatorInstruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.getSyncVarHookGuard));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brtrue, noOperatorInstruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.setSyncVarHookGuard));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, methodDefinition2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.setSyncVarHookGuard));
- ilprocessor.Append(noOperatorInstruction);
- }
-
- if (fd.FieldType.FullName == Weaver.gameObjectType.FullName)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldflda, netFieldId));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.setSyncVarGameObjectReference));
- }
- else
- {
- var genericInstanceMethod = new GenericInstanceMethod(Weaver.setSyncVarReference);
- genericInstanceMethod.GenericArguments.Add(fd.FieldType);
-
- var index11 = ilprocessor.Create(OpCodes.Ldarg_0);
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.UBehaviourIsServer));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse_S, index11));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldflda, fd));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, dirtyBit));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, genericInstanceMethod));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Pop));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(index11);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldflda, fd));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4, dirtyBit));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, genericInstanceMethod));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brfalse_S, returnInstruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, Weaver.NetworkBehaviourClientSendUpdateVars));
- }
-
- ilprocessor.Append(returnInstruction);
- methodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.In, fd.FieldType));
- methodDefinition.SemanticsAttributes = MethodSemanticsAttributes.Setter;
- return methodDefinition;
- }
-
- private void ProcessSyncVar(FieldDefinition fd, int dirtyBit)
- {
- var name = fd.Name;
- Weaver.lists.replacedFields.Add(fd);
- Weaver.DLog(m_td, $"Found SyncVar {fd.Name} of type {fd.FieldType}", new object[0]);
- FieldDefinition fieldDefinition = null;
- if (fd.FieldType.FullName == Weaver.gameObjectType.FullName)
- {
- fieldDefinition = new FieldDefinition("___" + fd.Name + "NetId", FieldAttributes.Private, Weaver.NetworkInstanceIdType);
- m_SyncVarNetIds.Add(fieldDefinition);
- Weaver.lists.netIdFields.Add(fieldDefinition);
- }
-
- var methodDefinition = ProcessSyncVarGet(fd, name);
- var methodDefinition2 = ProcessSyncVarSet(fd, name, dirtyBit, fieldDefinition);
- var item = new PropertyDefinition("Network" + name, PropertyAttributes.None, fd.FieldType)
- {
- GetMethod = methodDefinition,
- SetMethod = methodDefinition2
- };
- m_td.Methods.Add(methodDefinition);
- m_td.Methods.Add(methodDefinition2);
- m_td.Properties.Add(item);
- Weaver.lists.replacementProperties.Add(methodDefinition2);
- }
-
- private static MethodDefinition ProcessSyncListInvoke(FieldDefinition fd)
- {
- var methodDefinition = new MethodDefinition("InvokeSyncList" + fd.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var label = ilprocessor.Create(OpCodes.Nop);
- WriteClientActiveCheck(ilprocessor, fd.Name, label, "SyncList");
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Castclass, fd.DeclaringType));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fd));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- var genericInstanceType = (GenericInstanceType)fd.FieldType.Resolve().BaseType;
- genericInstanceType = (GenericInstanceType)Weaver.scriptDef.MainModule.ImportReference(genericInstanceType);
- var typeReference = genericInstanceType.GenericArguments[0];
- var method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListInitHandleMsg, new TypeReference[]
- {
- typeReference
- });
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- AddInvokeParameters(methodDefinition.Parameters);
- return methodDefinition;
- }
-
- private FieldDefinition ProcessSyncList(FieldDefinition fd, int dirtyBit)
- {
- var methodDefinition = ProcessSyncListInvoke(fd);
- m_SyncListInvocationFuncs.Add(methodDefinition);
- return new FieldDefinition("kList" + fd.Name, FieldAttributes.Private | FieldAttributes.Static, Weaver.int32Type);
- }
-
- private void ProcessSyncVars()
- {
- var num = 0;
- var num2 = Weaver.GetSyncVarStart(m_td.BaseType.FullName);
- m_SyncVarNetIds.Clear();
- var list = new List();
- foreach (var fieldDefinition in m_td.Fields)
- {
- foreach (var customAttribute in fieldDefinition.CustomAttributes)
- {
- if (customAttribute.AttributeType.FullName == Weaver.SyncVarType.FullName)
- {
- var typeDefinition = fieldDefinition.FieldType.Resolve();
- if (Weaver.IsDerivedFrom(typeDefinition, Weaver.NetworkBehaviourType))
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot be derived from NetworkBehaviour.");
- Weaver.fail = true;
- return;
- }
-
- if (Weaver.IsDerivedFrom(typeDefinition, Weaver.ScriptableObjectType))
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot be derived from ScriptableObject.");
- Weaver.fail = true;
- return;
- }
-
- if ((ushort)(fieldDefinition.Attributes & FieldAttributes.Static) != 0)
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot be static.");
- Weaver.fail = true;
- return;
- }
-
- if (typeDefinition.HasGenericParameters)
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot have generic parameters.");
- Weaver.fail = true;
- return;
- }
-
- if (typeDefinition.IsInterface)
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot be an interface.");
- Weaver.fail = true;
- return;
- }
-
- var name = typeDefinition.Module.Name;
- if (name != Weaver.scriptDef.MainModule.Name && name != Weaver.UnityAssemblyDefinition.MainModule.Name && name != Weaver.QNetAssemblyDefinition.MainModule.Name && name != Weaver.corLib.Name && name != "System.Runtime.dll")
- {
- Log.Error($"SyncVar [{fieldDefinition.FullName}] is from an inaccessible module! : [{name}]");
- Weaver.fail = true;
- return;
- }
-
- if (fieldDefinition.FieldType.IsArray)
- {
- Log.Error("SyncVar [" + fieldDefinition.FullName + "] cannot be an array. Use a SyncList instead.");
- Weaver.fail = true;
- return;
- }
-
- if (Helpers.InheritsFromSyncList(fieldDefinition.FieldType))
- {
- Log.Warning(string.Format("Script class [{0}] has [SyncVar] attribute on SyncList field {1}, SyncLists should not be marked with SyncVar.", m_td.FullName, fieldDefinition.Name));
- break;
- }
-
- m_SyncVars.Add(fieldDefinition);
- ProcessSyncVar(fieldDefinition, 1 << num2);
- num2++;
- num++;
- if (num2 == 32)
- {
- Log.Error(string.Concat(new object[]
- {
- "Script class [",
- m_td.FullName,
- "] has too many SyncVars (",
- 32,
- "). (This could include base classes)"
- }));
- Weaver.fail = true;
- return;
- }
-
- break;
- }
- }
-
- if (fieldDefinition.FieldType.FullName.Contains("UnityEngine.Networking.SyncListStruct"))
- {
- Log.Error("SyncListStruct member variable [" + fieldDefinition.FullName + "] must use a dervied class, like \"class MySyncList : SyncListStruct {}\".");
- Weaver.fail = true;
- return;
- }
-
- if (Weaver.IsDerivedFrom(fieldDefinition.FieldType.Resolve(), Weaver.SyncListType))
- {
- if (fieldDefinition.IsStatic)
- {
- Log.Error(string.Concat(new string[]
- {
- "SyncList [",
- m_td.FullName,
- ":",
- fieldDefinition.FullName,
- "] cannot be a static"
- }));
- Weaver.fail = true;
- return;
- }
-
- m_SyncVars.Add(fieldDefinition);
- m_SyncLists.Add(fieldDefinition);
- list.Add(ProcessSyncList(fieldDefinition, 1 << num2));
- num2++;
- num++;
- if (num2 == 32)
- {
- Log.Error(string.Concat(new object[]
- {
- "Script class [",
- m_td.FullName,
- "] has too many SyncVars (",
- 32,
- "). (This could include base classes)"
- }));
- Weaver.fail = true;
- return;
- }
- }
- }
-
- foreach (var fieldDefinition2 in list)
- {
- m_td.Fields.Add(fieldDefinition2);
- m_SyncListStaticFields.Add(fieldDefinition2);
- }
-
- foreach (var item in m_SyncVarNetIds)
- {
- m_td.Fields.Add(item);
- }
-
- foreach (var item2 in m_SyncListInvocationFuncs)
- {
- m_td.Methods.Add(item2);
- }
-
- Weaver.SetNumSyncVars(m_td.FullName, num);
- }
-
- private static int GetHashCode(string s)
- {
- var assembly = typeof(Unity.UNetWeaver.Program).Assembly;
- var networkProcessorType = assembly.GetType("Unity.UNetWeaver.NetworkBehaviourProcessor");
- var methodInfo = networkProcessorType.GetMethod("GetHashCode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
- return (int)methodInfo.Invoke(null, new object[] { s });
- }
-
- private bool HasMethod(string name)
- {
- foreach (var methodDefinition in m_td.Methods)
- {
- if (methodDefinition.Name == name)
- {
- return true;
- }
- }
-
- return false;
- }
-
- private List m_SyncVars = new List();
-
- private List m_SyncLists = new List();
-
- private List m_SyncVarNetIds = new List();
-
- private List m_Cmds = new List();
-
- private List m_Rpcs = new List();
-
- private List m_TargetRpcs = new List();
-
- private List m_Events = new List();
-
- private List m_SyncListStaticFields = new List();
-
- private List m_CmdInvocationFuncs = new List();
-
- private List m_SyncListInvocationFuncs = new List();
-
- private List m_RpcInvocationFuncs = new List();
-
- private List m_TargetRpcInvocationFuncs = new List();
-
- private List m_EventInvocationFuncs = new List();
-
- private List m_CmdCallFuncs = new List();
-
- private List m_RpcCallFuncs = new List();
-
- private List m_TargetRpcCallFuncs = new List();
-
- private const int k_SyncVarLimit = 32;
-
- private int m_QosChannel;
-
- private TypeDefinition m_td;
-
- private int m_NetIdFieldCounter;
-
- private const string k_CmdPrefix = "InvokeCmd";
-
- private const string k_RpcPrefix = "InvokeRpc";
-
- private const string k_TargetRpcPrefix = "InvokeTargetRpc";
- }
-}
diff --git a/QNetWeaver/Program.cs b/QNetWeaver/Program.cs
deleted file mode 100644
index 8891e550..00000000
--- a/QNetWeaver/Program.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.IO;
-
-namespace QNetWeaver
-{
- public class Program
- {
- private static void Main(string[] args)
- {
- Console.WriteLine("Start weaving process.");
-
- if (args.Length == 0)
- {
- Log.Error("No args supplied!");
- }
-
- var unityEngine = args[0];
- var qnetDLL = args[1];
- var unetDLL = args[2];
- var outputDirectory = args[3];
- var assembly = args[4];
-
- CheckDLLPath(unityEngine);
- CheckDLLPath(qnetDLL);
- CheckDLLPath(unetDLL);
- CheckOutputDirectory(outputDirectory);
- CheckAssemblyPath(assembly);
- Weaver.WeaveAssemblies(assembly, null, null, outputDirectory, unityEngine, qnetDLL, unetDLL);
- }
-
- private static void CheckDLLPath(string path)
- {
- Console.WriteLine($"Check dll {path} ...");
- if (!File.Exists(path))
- {
- throw new Exception("dll could not be located at " + path + "!");
- }
-
- Console.WriteLine($"Path OK!");
- }
-
- private static void CheckAssemblyPath(string assemblyPath)
- {
- Console.WriteLine($"Check assembly path {assemblyPath} ...");
- if (!File.Exists(assemblyPath))
- {
- throw new Exception("Assembly " + assemblyPath + " does not exist!");
- }
-
- Console.WriteLine($"Assembly Path OK!");
- }
-
- private static void CheckOutputDirectory(string outputDir)
- {
- Console.WriteLine($"Check output path {outputDir} ...");
- if (!Directory.Exists(outputDir))
- {
- Directory.CreateDirectory(outputDir);
- }
-
- Console.WriteLine($"Output Path OK!");
- }
- }
-}
diff --git a/QNetWeaver/Properties/AssemblyInfo.cs b/QNetWeaver/Properties/AssemblyInfo.cs
deleted file mode 100644
index ad8f0317..00000000
--- a/QNetWeaver/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("QNetWeaver")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("QNetWeaver")]
-[assembly: AssemblyCopyright("Copyright © 2021")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("e23551f3-c095-4f50-8bf7-85bb2661859b")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/QNetWeaver/QNetWeaver.csproj b/QNetWeaver/QNetWeaver.csproj
deleted file mode 100644
index be1b5de5..00000000
--- a/QNetWeaver/QNetWeaver.csproj
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {E23551F3-C095-4F50-8BF7-85BB2661859B}
- Exe
- QNetWeaver
- QNetWeaver
- v3.5
- 512
- true
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- true
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- true
-
-
- 9.0
-
-
-
-
-
-
-
-
-
- ..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.dll
-
-
- ..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.Mdb.dll
-
-
- ..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.Pdb.dll
-
-
- ..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.UNetWeaver.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/QNetWeaver/SyncListStructProcessor.cs b/QNetWeaver/SyncListStructProcessor.cs
deleted file mode 100644
index 30bc3d4b..00000000
--- a/QNetWeaver/SyncListStructProcessor.cs
+++ /dev/null
@@ -1,309 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-
-namespace QNetWeaver
-{
- internal class SyncListStructProcessor
- {
- public SyncListStructProcessor(TypeDefinition typeDef)
- {
- Weaver.DLog(typeDef, "SyncListStructProcessor for " + typeDef.Name, new object[0]);
- m_TypeDef = typeDef;
- }
-
- public void Process()
- {
- var genericInstanceType = (GenericInstanceType)m_TypeDef.BaseType;
- if (genericInstanceType.GenericArguments.Count == 0)
- {
- Weaver.fail = true;
- Log.Error("SyncListStructProcessor no generic args");
- }
- else
- {
- m_ItemType = Weaver.scriptDef.MainModule.ImportReference(genericInstanceType.GenericArguments[0]);
- Weaver.DLog(m_TypeDef, "SyncListStructProcessor Start item:" + m_ItemType.FullName, new object[0]);
- Weaver.ResetRecursionCount();
- var methodReference = GenerateSerialization();
- if (!Weaver.fail)
- {
- var methodReference2 = GenerateDeserialization();
- if (methodReference2 != null && methodReference != null)
- {
- GenerateReadFunc(methodReference2);
- GenerateWriteFunc(methodReference);
- Weaver.DLog(m_TypeDef, "SyncListStructProcessor Done", new object[0]);
- }
- }
- }
- }
-
- private void GenerateReadFunc(MethodReference readItemFunc)
- {
- var text = "_ReadStruct" + m_TypeDef.Name + "_";
- if (m_TypeDef.DeclaringType != null)
- {
- text += m_TypeDef.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
- methodDefinition.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, m_TypeDef));
- methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
- methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
- methodDefinition.Body.InitLocals = true;
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkReadUInt16));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- var method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListClear, new TypeReference[]
- {
- m_ItemType
- });
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction));
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(instruction2);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, readItemFunc));
- var self = Weaver.ResolveMethod(Weaver.SyncListStructType, "AddInternal");
- var method2 = Helpers.MakeHostInstanceGeneric(self, new TypeReference[]
- {
- m_ItemType
- });
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- Weaver.RegisterReadByReferenceFunc(m_TypeDef.FullName, methodDefinition);
- }
-
- private void GenerateWriteFunc(MethodReference writeItemFunc)
- {
- var text = "_WriteStruct" + m_TypeDef.GetElementType().Name + "_";
- if (m_TypeDef.DeclaringType != null)
- {
- text += m_TypeDef.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
- methodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(m_TypeDef)));
- methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
- methodDefinition.Body.Variables.Add(new VariableDefinition(Weaver.uint16Type));
- methodDefinition.Body.InitLocals = true;
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- var self = Weaver.ResolveMethod(Weaver.SyncListStructType, "get_Count");
- var method = Helpers.MakeHostInstanceGeneric(self, new TypeReference[]
- {
- m_ItemType
- });
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, Weaver.NetworkWriteUInt16));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction));
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(instruction2);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- var self2 = Weaver.ResolveMethod(Weaver.SyncListStructType, "GetItem");
- var method2 = Helpers.MakeHostInstanceGeneric(self2, new TypeReference[]
- {
- m_ItemType
- });
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, method2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Callvirt, writeItemFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- Weaver.RegisterWriteFunc(m_TypeDef.FullName, methodDefinition);
- }
-
- private MethodReference GenerateSerialization()
- {
- Weaver.DLog(m_TypeDef, " SyncListStruct GenerateSerialization", new object[0]);
- foreach (var methodDefinition in m_TypeDef.Methods)
- {
- if (methodDefinition.Name == "SerializeItem")
- {
- Weaver.DLog(m_TypeDef, " Abort - is SerializeItem", new object[0]);
- return methodDefinition;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("SerializeItem", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType)));
- methodDefinition2.Parameters.Add(new ParameterDefinition("item", ParameterAttributes.None, m_ItemType));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- MethodReference result;
- if (m_ItemType.IsGenericInstance)
- {
- Weaver.fail = true;
- Log.Error("GenerateSerialization for " + Helpers.PrettyPrintType(m_ItemType) + " failed. Struct passed into SyncListStruct can't have generic parameters");
- result = null;
- }
- else
- {
- foreach (var fieldDefinition in m_ItemType.Resolve().Fields)
- {
- if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
- {
- var fieldReference = Weaver.scriptDef.MainModule.ImportReference(fieldDefinition);
- var typeDefinition = fieldReference.FieldType.Resolve();
- if (typeDefinition.HasGenericParameters)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_TypeDef.Name,
- " [",
- typeDefinition,
- "/",
- typeDefinition.FullName,
- "]. UNet [MessageBase] member cannot have generic parameters."
- }));
- return null;
- }
-
- if (typeDefinition.IsInterface)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_TypeDef.Name,
- " [",
- typeDefinition,
- "/",
- typeDefinition.FullName,
- "]. UNet [MessageBase] member cannot be an interface."
- }));
- return null;
- }
-
- var writeFunc = Weaver.GetWriteFunc(fieldDefinition.FieldType);
- if (writeFunc == null)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateSerialization for ",
- m_TypeDef.Name,
- " unknown type [",
- typeDefinition,
- "/",
- typeDefinition.FullName,
- "]. UNet [MessageBase] member variables must be basic types."
- }));
- return null;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldReference));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_TypeDef.Methods.Add(methodDefinition2);
- result = methodDefinition2;
- }
-
- return result;
- }
-
- private MethodReference GenerateDeserialization()
- {
- Weaver.DLog(m_TypeDef, " GenerateDeserialization", new object[0]);
- foreach (var methodDefinition in m_TypeDef.Methods)
- {
- if (methodDefinition.Name == "DeserializeItem")
- {
- return methodDefinition;
- }
- }
-
- var methodDefinition2 = new MethodDefinition("DeserializeItem", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig, m_ItemType);
- methodDefinition2.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
- var ilprocessor = methodDefinition2.Body.GetILProcessor();
- ilprocessor.Body.InitLocals = true;
- ilprocessor.Body.Variables.Add(new VariableDefinition(m_ItemType));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, m_ItemType));
- foreach (var fieldDefinition in m_ItemType.Resolve().Fields)
- {
- if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate && !fieldDefinition.IsSpecialName)
- {
- var fieldReference = Weaver.scriptDef.MainModule.ImportReference(fieldDefinition);
- var typeDefinition = fieldReference.FieldType.Resolve();
- var readFunc = Weaver.GetReadFunc(fieldDefinition.FieldType);
- if (readFunc == null)
- {
- Weaver.fail = true;
- Log.Error(string.Concat(new object[]
- {
- "GenerateDeserialization for ",
- m_TypeDef.Name,
- " unknown type [",
- typeDefinition,
- "]. UNet [SyncVar] member variables must be basic types."
- }));
- return null;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldReference));
- }
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- m_TypeDef.Methods.Add(methodDefinition2);
- return methodDefinition2;
- }
-
- private TypeDefinition m_TypeDef;
-
- private TypeReference m_ItemType;
- }
-}
diff --git a/QNetWeaver/Weaver.cs b/QNetWeaver/Weaver.cs
deleted file mode 100644
index 8f3ee305..00000000
--- a/QNetWeaver/Weaver.cs
+++ /dev/null
@@ -1,2038 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-using Mono.Cecil.Mdb;
-using Mono.Cecil.Pdb;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-
-namespace QNetWeaver
-{
- internal class Weaver
- {
- public static void ResetRecursionCount() => s_RecursionCount = 0;
-
- public static bool CanBeResolved(TypeReference parent)
- {
- while (parent != null)
- {
- bool result;
- if (parent.Scope.Name == "Windows")
- {
- result = false;
- }
- else
- {
- if (!(parent.Scope.Name == "mscorlib"))
- {
- try
- {
- parent = parent.Resolve().BaseType;
- }
- catch
- {
- return false;
- }
-
- continue;
- }
-
- var typeDefinition = parent.Resolve();
- result = (typeDefinition != null);
- }
-
- return result;
- }
-
- return true;
- }
-
- public static bool IsArrayType(TypeReference variable) => (!variable.IsArray || !((ArrayType)variable).ElementType.IsArray) && (!variable.IsArray || ((ArrayType)variable).Rank <= 1);
-
- public static void DLog(TypeDefinition td, string fmt, params object[] args)
- {
- if (m_DebugFlag)
- {
- Console.WriteLine("[" + td.Name + "] " + string.Format(fmt, args));
- }
- }
-
- public static int GetSyncVarStart(string className)
- {
- int result;
- if (lists.numSyncVars.ContainsKey(className))
- {
- var num = lists.numSyncVars[className];
- result = num;
- }
- else
- {
- result = 0;
- }
-
- return result;
- }
-
- public static void SetNumSyncVars(string className, int num) => lists.numSyncVars[className] = num;
-
- public static MethodReference GetWriteFunc(TypeReference variable)
- {
- MethodReference result;
- if (s_RecursionCount++ > 128)
- {
- Log.Error("GetWriteFunc recursion depth exceeded for " + variable.Name + ". Check for self-referencing member variables.");
- fail = true;
- result = null;
- }
- else
- {
- if (lists.writeFuncs.ContainsKey(variable.FullName))
- {
- var methodReference = lists.writeFuncs[variable.FullName];
- if (methodReference.Parameters[0].ParameterType.IsArray == variable.IsArray)
- {
- return methodReference;
- }
- }
-
- if (variable.IsByReference)
- {
- Log.Error("GetWriteFunc variable.IsByReference error.");
- result = null;
- }
- else
- {
- MethodDefinition methodDefinition;
- if (variable.IsArray)
- {
- var elementType = variable.GetElementType();
- var writeFunc = GetWriteFunc(elementType);
- if (writeFunc == null)
- {
- return null;
- }
-
- methodDefinition = GenerateArrayWriteFunc(variable, writeFunc);
- }
- else
- {
- if (variable.Resolve().IsEnum)
- {
- return NetworkWriterWriteInt32;
- }
-
- methodDefinition = GenerateWriterFunction(variable);
- }
-
- if (methodDefinition == null)
- {
- result = null;
- }
- else
- {
- RegisterWriteFunc(variable.FullName, methodDefinition);
- result = methodDefinition;
- }
- }
- }
-
- return result;
- }
-
- public static void RegisterWriteFunc(string name, MethodDefinition newWriterFunc)
- {
- lists.writeFuncs[name] = newWriterFunc;
- lists.generatedWriteFunctions.Add(newWriterFunc);
- ConfirmGeneratedCodeClass(scriptDef.MainModule);
- lists.generateContainerClass.Methods.Add(newWriterFunc);
- }
-
- public static MethodReference GetReadByReferenceFunc(TypeReference variable)
- {
- MethodReference result;
- if (lists.readByReferenceFuncs.ContainsKey(variable.FullName))
- {
- result = lists.readByReferenceFuncs[variable.FullName];
- }
- else
- {
- result = null;
- }
-
- return result;
- }
-
- public static MethodReference GetReadFunc(TypeReference variable)
- {
- if (lists.readFuncs.ContainsKey(variable.FullName))
- {
- var methodReference = lists.readFuncs[variable.FullName];
- if (methodReference.ReturnType.IsArray == variable.IsArray)
- {
- return methodReference;
- }
- }
-
- var typeDefinition = variable.Resolve();
- MethodReference result;
- if (typeDefinition == null)
- {
- Log.Error("GetReadFunc unsupported type " + variable.FullName);
- result = null;
- }
- else if (variable.IsByReference)
- {
- Log.Error("GetReadFunc variable.IsByReference error.");
- result = null;
- }
- else
- {
- MethodDefinition methodDefinition;
- if (variable.IsArray)
- {
- var elementType = variable.GetElementType();
- var readFunc = GetReadFunc(elementType);
- if (readFunc == null)
- {
- return null;
- }
-
- methodDefinition = GenerateArrayReadFunc(variable, readFunc);
- }
- else
- {
- if (typeDefinition.IsEnum)
- {
- return NetworkReaderReadInt32;
- }
-
- methodDefinition = GenerateReadFunction(variable);
- }
-
- if (methodDefinition == null)
- {
- Log.Error("GetReadFunc unable to generate function for:" + variable.FullName);
- result = null;
- }
- else
- {
- RegisterReadFunc(variable.FullName, methodDefinition);
- result = methodDefinition;
- }
- }
-
- return result;
- }
-
- public static void RegisterReadByReferenceFunc(string name, MethodDefinition newReaderFunc)
- {
- lists.readByReferenceFuncs[name] = newReaderFunc;
- lists.generatedReadFunctions.Add(newReaderFunc);
- ConfirmGeneratedCodeClass(scriptDef.MainModule);
- lists.generateContainerClass.Methods.Add(newReaderFunc);
- }
-
- public static void RegisterReadFunc(string name, MethodDefinition newReaderFunc)
- {
- lists.readFuncs[name] = newReaderFunc;
- lists.generatedReadFunctions.Add(newReaderFunc);
- ConfirmGeneratedCodeClass(scriptDef.MainModule);
- lists.generateContainerClass.Methods.Add(newReaderFunc);
- }
-
- private static MethodDefinition GenerateArrayReadFunc(TypeReference variable, MethodReference elementReadFunc)
- {
- MethodDefinition result;
- if (!IsArrayType(variable))
- {
- Log.Error(variable.FullName + " is an unsupported array type. Jagged and multidimensional arrays are not supported");
- result = null;
- }
- else
- {
- var text = "_ReadArray" + variable.GetElementType().Name + "_";
- if (variable.DeclaringType != null)
- {
- text += variable.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, variable);
- methodDefinition.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, scriptDef.MainModule.ImportReference(NetworkReaderType)));
- methodDefinition.Body.Variables.Add(new VariableDefinition(int32Type));
- methodDefinition.Body.Variables.Add(new VariableDefinition(variable));
- methodDefinition.Body.Variables.Add(new VariableDefinition(int32Type));
- methodDefinition.Body.InitLocals = true;
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, NetworkReadUInt16));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brtrue, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Newarr, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Newarr, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_2));
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction2));
- var instruction3 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(instruction3);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldelema, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, elementReadFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stobj, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_2));
- ilprocessor.Append(instruction2);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction3));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private static MethodDefinition GenerateArrayWriteFunc(TypeReference variable, MethodReference elementWriteFunc)
- {
- MethodDefinition result;
- if (!IsArrayType(variable))
- {
- Log.Error(variable.FullName + " is an unsupported array type. Jagged and multidimensional arrays are not supported");
- result = null;
- }
- else
- {
- var text = "_WriteArray" + variable.GetElementType().Name + "_";
- if (variable.DeclaringType != null)
- {
- text += variable.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, voidType);
- methodDefinition.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, scriptDef.MainModule.ImportReference(NetworkWriterType)));
- methodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, scriptDef.MainModule.ImportReference(variable)));
- methodDefinition.Body.Variables.Add(new VariableDefinition(uint16Type));
- methodDefinition.Body.Variables.Add(new VariableDefinition(uint16Type));
- methodDefinition.Body.InitLocals = true;
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var instruction = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Brtrue, instruction));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, NetworkWriteUInt16));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- ilprocessor.Append(instruction);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldlen));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_I4));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, NetworkWriteUInt16));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- var instruction2 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Br, instruction2));
- var instruction3 = ilprocessor.Create(OpCodes.Nop);
- ilprocessor.Append(instruction3);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldelema, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldobj, variable.GetElementType()));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, elementWriteFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldc_I4_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Add));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_U2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_1));
- ilprocessor.Append(instruction2);
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldlen));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Conv_I4));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Blt, instruction3));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private static MethodDefinition GenerateWriterFunction(TypeReference variable)
- {
- MethodDefinition result;
- if (!IsValidTypeToGenerate(variable.Resolve()))
- {
- result = null;
- }
- else
- {
- var text = "_Write" + variable.Name + "_";
- if (variable.DeclaringType != null)
- {
- text += variable.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, voidType);
- methodDefinition.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, scriptDef.MainModule.ImportReference(NetworkWriterType)));
- methodDefinition.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, scriptDef.MainModule.ImportReference(variable)));
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- var num = 0U;
- foreach (var fieldDefinition in variable.Resolve().Fields)
- {
- if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate)
- {
- if (fieldDefinition.FieldType.Resolve().HasGenericParameters)
- {
- fail = true;
- Log.Error(string.Concat(new object[]
- {
- "WriteReadFunc for ",
- fieldDefinition.Name,
- " [",
- fieldDefinition.FieldType,
- "/",
- fieldDefinition.FieldType.FullName,
- "]. Cannot have generic parameters."
- }));
- return null;
- }
-
- if (fieldDefinition.FieldType.Resolve().IsInterface)
- {
- fail = true;
- Log.Error(string.Concat(new object[]
- {
- "WriteReadFunc for ",
- fieldDefinition.Name,
- " [",
- fieldDefinition.FieldType,
- "/",
- fieldDefinition.FieldType.FullName,
- "]. Cannot be an interface."
- }));
- return null;
- }
-
- var writeFunc = GetWriteFunc(fieldDefinition.FieldType);
- if (writeFunc == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "WriteReadFunc for ",
- fieldDefinition.Name,
- " type ",
- fieldDefinition.FieldType,
- " no supported"
- }));
- fail = true;
- return null;
- }
-
- num += 1U;
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_1));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldfld, fieldDefinition));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, writeFunc));
- }
- }
-
- if (num == 0U)
- {
- Log.Warning("The class / struct " + variable.Name + " has no public or non-static fields to serialize");
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private static MethodDefinition GenerateReadFunction(TypeReference variable)
- {
- MethodDefinition result;
- if (!IsValidTypeToGenerate(variable.Resolve()))
- {
- result = null;
- }
- else
- {
- var text = "_Read" + variable.Name + "_";
- if (variable.DeclaringType != null)
- {
- text += variable.DeclaringType.Name;
- }
- else
- {
- text += "None";
- }
-
- var methodDefinition = new MethodDefinition(text, MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, variable);
- methodDefinition.Body.Variables.Add(new VariableDefinition(variable));
- methodDefinition.Body.InitLocals = true;
- methodDefinition.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, scriptDef.MainModule.ImportReference(NetworkReaderType)));
- var ilprocessor = methodDefinition.Body.GetILProcessor();
- if (variable.IsValueType)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Initobj, variable));
- }
- else
- {
- var methodDefinition2 = ResolveDefaultPublicCtor(variable);
- if (methodDefinition2 == null)
- {
- Log.Error("The class " + variable.Name + " has no default constructor or it's private, aborting.");
- return null;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Newobj, methodDefinition2));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stloc_0));
- }
-
- var num = 0U;
- foreach (var fieldDefinition in variable.Resolve().Fields)
- {
- if (!fieldDefinition.IsStatic && !fieldDefinition.IsPrivate)
- {
- if (variable.IsValueType)
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloca, 0));
- }
- else
- {
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc, 0));
- }
-
- var readFunc = GetReadFunc(fieldDefinition.FieldType);
- if (readFunc == null)
- {
- Log.Error(string.Concat(new object[]
- {
- "GetReadFunc for ",
- fieldDefinition.Name,
- " type ",
- fieldDefinition.FieldType,
- " no supported"
- }));
- fail = true;
- return null;
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldarg_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Call, readFunc));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Stfld, fieldDefinition));
- num += 1U;
- }
- }
-
- if (num == 0U)
- {
- Log.Warning("The class / struct " + variable.Name + " has no public or non-static fields to serialize");
- }
-
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ldloc_0));
- ilprocessor.Append(ilprocessor.Create(OpCodes.Ret));
- result = methodDefinition;
- }
-
- return result;
- }
-
- private static Instruction GetEventLoadInstruction(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md, int iCount, FieldReference foundEventField)
- {
- while (iCount > 0)
- {
- iCount--;
- var instruction = md.Body.Instructions[iCount];
- if (instruction.OpCode == OpCodes.Ldfld)
- {
- if (instruction.Operand == foundEventField)
- {
- DLog(td, " " + instruction.Operand, new object[0]);
- return instruction;
- }
- }
- }
-
- return null;
- }
-
- private static void ProcessInstructionMethod(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md, Instruction instr, MethodReference opMethodRef, int iCount)
- {
- if (opMethodRef.Name == "Invoke")
- {
- var flag = false;
- while (iCount > 0 && !flag)
- {
- iCount--;
- var instruction = md.Body.Instructions[iCount];
- if (instruction.OpCode == OpCodes.Ldfld)
- {
- var fieldReference = instruction.Operand as FieldReference;
- for (var i = 0; i < lists.replacedEvents.Count; i++)
- {
- var eventDefinition = lists.replacedEvents[i];
- if (eventDefinition.Name == fieldReference.Name)
- {
- instr.Operand = lists.replacementEvents[i];
- instruction.OpCode = OpCodes.Nop;
- flag = true;
- break;
- }
- }
- }
- }
- }
- else if (lists.replacementMethodNames.Contains(opMethodRef.FullName))
- {
- for (var j = 0; j < lists.replacedMethods.Count; j++)
- {
- var methodDefinition = lists.replacedMethods[j];
- if (opMethodRef.FullName == methodDefinition.FullName)
- {
- instr.Operand = lists.replacementMethods[j];
- break;
- }
- }
- }
- }
-
- private static void ConfirmGeneratedCodeClass(ModuleDefinition moduleDef)
- {
- if (lists.generateContainerClass == null)
- {
- lists.generateContainerClass = new TypeDefinition("Unity", "GeneratedNetworkCode", TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.BeforeFieldInit, objectType);
- var methodDefinition = new MethodDefinition(".ctor", MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, voidType);
- methodDefinition.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
- methodDefinition.Body.Instructions.Add(Instruction.Create(OpCodes.Call, ResolveMethod(objectType, ".ctor")));
- methodDefinition.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
- lists.generateContainerClass.Methods.Add(methodDefinition);
- }
- }
-
- private static void ProcessInstructionField(TypeDefinition td, MethodDefinition md, Instruction i, FieldDefinition opField)
- {
- if (!(md.Name == ".ctor") && !(md.Name == "OnDeserialize"))
- {
- for (var j = 0; j < lists.replacedFields.Count; j++)
- {
- var fieldDefinition = lists.replacedFields[j];
- if (opField == fieldDefinition)
- {
- i.OpCode = OpCodes.Call;
- i.Operand = lists.replacementProperties[j];
- break;
- }
- }
- }
- }
-
- private static void ProcessInstruction(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md, Instruction i, int iCount)
- {
- if (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Callvirt)
- {
- var methodReference = i.Operand as MethodReference;
- if (methodReference != null)
- {
- ProcessInstructionMethod(moduleDef, td, md, i, methodReference, iCount);
- }
- }
-
- if (i.OpCode == OpCodes.Stfld)
- {
- var fieldDefinition = i.Operand as FieldDefinition;
- if (fieldDefinition != null)
- {
- ProcessInstructionField(td, md, i, fieldDefinition);
- }
- }
- }
-
- private static void InjectGuardParameters(MethodDefinition md, ILProcessor worker, Instruction top)
- {
- var num = (!md.Resolve().IsStatic) ? 1 : 0;
- for (var i = 0; i < md.Parameters.Count; i++)
- {
- var parameterDefinition = md.Parameters[i];
- if (parameterDefinition.IsOut)
- {
- var elementType = parameterDefinition.ParameterType.GetElementType();
- if (elementType.IsPrimitive)
- {
- worker.InsertBefore(top, worker.Create(OpCodes.Ldarg, i + num));
- worker.InsertBefore(top, worker.Create(OpCodes.Ldc_I4_0));
- worker.InsertBefore(top, worker.Create(OpCodes.Stind_I4));
- }
- else
- {
- md.Body.Variables.Add(new VariableDefinition(elementType));
- md.Body.InitLocals = true;
- worker.InsertBefore(top, worker.Create(OpCodes.Ldarg, i + num));
- worker.InsertBefore(top, worker.Create(OpCodes.Ldloca_S, (byte)(md.Body.Variables.Count - 1)));
- worker.InsertBefore(top, worker.Create(OpCodes.Initobj, elementType));
- worker.InsertBefore(top, worker.Create(OpCodes.Ldloc, md.Body.Variables.Count - 1));
- worker.InsertBefore(top, worker.Create(OpCodes.Stobj, elementType));
- }
- }
- }
- }
-
- private static void InjectGuardReturnValue(MethodDefinition md, ILProcessor worker, Instruction top)
- {
- if (md.ReturnType.FullName != voidType.FullName)
- {
- if (md.ReturnType.IsPrimitive)
- {
- worker.InsertBefore(top, worker.Create(OpCodes.Ldc_I4_0));
- }
- else
- {
- md.Body.Variables.Add(new VariableDefinition(md.ReturnType));
- md.Body.InitLocals = true;
- worker.InsertBefore(top, worker.Create(OpCodes.Ldloca_S, (byte)(md.Body.Variables.Count - 1)));
- worker.InsertBefore(top, worker.Create(OpCodes.Initobj, md.ReturnType));
- worker.InsertBefore(top, worker.Create(OpCodes.Ldloc, md.Body.Variables.Count - 1));
- }
- }
- }
-
- private static void InjectServerGuard(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md, bool logWarning)
- {
- if (!IsNetworkBehaviour(td))
- {
- Log.Error("[Server] guard on non-NetworkBehaviour script at [" + md.FullName + "]");
- }
- else
- {
- var ilprocessor = md.Body.GetILProcessor();
- var instruction = md.Body.Instructions[0];
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Call, NetworkServerGetActive));
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Brtrue, instruction));
- if (logWarning)
- {
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Ldstr, "[Server] function '" + md.FullName + "' called on client"));
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Call, logWarningReference));
- }
-
- InjectGuardParameters(md, ilprocessor, instruction);
- InjectGuardReturnValue(md, ilprocessor, instruction);
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Ret));
- }
- }
-
- private static void InjectClientGuard(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md, bool logWarning)
- {
- if (!IsNetworkBehaviour(td))
- {
- Log.Error("[Client] guard on non-NetworkBehaviour script at [" + md.FullName + "]");
- }
- else
- {
- var ilprocessor = md.Body.GetILProcessor();
- var instruction = md.Body.Instructions[0];
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Call, NetworkClientGetActive));
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Brtrue, instruction));
- if (logWarning)
- {
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Ldstr, "[Client] function '" + md.FullName + "' called on server"));
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Call, logWarningReference));
- }
-
- InjectGuardParameters(md, ilprocessor, instruction);
- InjectGuardReturnValue(md, ilprocessor, instruction);
- ilprocessor.InsertBefore(instruction, ilprocessor.Create(OpCodes.Ret));
- }
- }
-
- private static void ProcessSiteMethod(ModuleDefinition moduleDef, TypeDefinition td, MethodDefinition md)
- {
- if (!(md.Name == ".cctor") && !(md.Name == "OnUnserializeVars"))
- {
- var text = md.Name.Substring(0, Math.Min(md.Name.Length, 4));
- if (!(text == "UNet"))
- {
- text = md.Name.Substring(0, Math.Min(md.Name.Length, 7));
- if (!(text == "CallCmd"))
- {
- text = md.Name.Substring(0, Math.Min(md.Name.Length, 9));
- if (!(text == "InvokeCmd") && !(text == "InvokeRpc") && !(text == "InvokeSyn"))
- {
- if (md.Body != null && md.Body.Instructions != null)
- {
- foreach (var customAttribute in md.CustomAttributes)
- {
- if (customAttribute.Constructor.DeclaringType.ToString() == "UnityEngine.Networking.ServerAttribute")
- {
- InjectServerGuard(moduleDef, td, md, true);
- }
- else if (customAttribute.Constructor.DeclaringType.ToString() == "UnityEngine.Networking.ServerCallbackAttribute")
- {
- InjectServerGuard(moduleDef, td, md, false);
- }
- else if (customAttribute.Constructor.DeclaringType.ToString() == "UnityEngine.Networking.ClientAttribute")
- {
- InjectClientGuard(moduleDef, td, md, true);
- }
- else if (customAttribute.Constructor.DeclaringType.ToString() == "UnityEngine.Networking.ClientCallbackAttribute")
- {
- InjectClientGuard(moduleDef, td, md, false);
- }
- }
-
- var num = 0;
- foreach (var i in md.Body.Instructions)
- {
- ProcessInstruction(moduleDef, td, md, i, num);
- num++;
- }
- }
- }
- }
- }
- }
- }
-
- private static void ProcessSiteClass(ModuleDefinition moduleDef, TypeDefinition td)
- {
- foreach (var md in td.Methods)
- {
- ProcessSiteMethod(moduleDef, td, md);
- }
-
- foreach (var td2 in td.NestedTypes)
- {
- ProcessSiteClass(moduleDef, td2);
- }
- }
-
- private static void ProcessSitesModule(ModuleDefinition moduleDef)
- {
- var now = DateTime.Now;
- foreach (var typeDefinition in moduleDef.Types)
- {
- if (typeDefinition.IsClass)
- {
- ProcessSiteClass(moduleDef, typeDefinition);
- }
- }
-
- if (lists.generateContainerClass != null)
- {
- moduleDef.Types.Add(lists.generateContainerClass);
- scriptDef.MainModule.ImportReference(lists.generateContainerClass);
- foreach (var method in lists.generatedReadFunctions)
- {
- scriptDef.MainModule.ImportReference(method);
- }
-
- foreach (var method2 in lists.generatedWriteFunctions)
- {
- scriptDef.MainModule.ImportReference(method2);
- }
- }
-
- Console.WriteLine(string.Concat(new object[]
- {
- " ProcessSitesModule ",
- moduleDef.Name,
- " elapsed time:",
- DateTime.Now - now
- }));
- }
-
- private static void ProcessPropertySites() => ProcessSitesModule(scriptDef.MainModule);
-
- private static bool ProcessMessageType(TypeDefinition td)
- {
- var messageClassProcessor = new MessageClassProcessor(td);
- messageClassProcessor.Process();
- return true;
- }
-
- private static bool ProcessSyncListStructType(TypeDefinition td)
- {
- var syncListStructProcessor = new SyncListStructProcessor(td);
- syncListStructProcessor.Process();
- return true;
- }
-
- private static void ProcessMonoBehaviourType(TypeDefinition td)
- {
- var monoBehaviourProcessor = new MonoBehaviourProcessor(td);
- monoBehaviourProcessor.Process();
- }
-
- private static bool ProcessNetworkBehaviourType(TypeDefinition td)
- {
- foreach (var methodDefinition in td.Resolve().Methods)
- {
- if (methodDefinition.Name == "UNetVersion")
- {
- DLog(td, " Already processed", new object[0]);
- return false;
- }
- }
-
- DLog(td, "Found NetworkBehaviour " + td.FullName, new object[0]);
- var networkBehaviourProcessor = new NetworkBehaviourProcessor(td);
- networkBehaviourProcessor.Process();
- return true;
- }
-
- public static MethodReference ResolveMethod(TypeReference t, string name)
- {
- MethodReference result;
- if (t == null)
- {
- Log.Error("Type missing for " + name);
- fail = true;
- result = null;
- }
- else
- {
- foreach (var methodDefinition in t.Resolve().Methods)
- {
- if (methodDefinition.Name == name)
- {
- return scriptDef.MainModule.ImportReference(methodDefinition);
- }
- }
-
- Log.Error($"ResolveMethod failed - Couldn't find {name} in {t.Name}");
- foreach (var methodDefinition2 in t.Resolve().Methods)
- {
- Log.Error("- has method " + methodDefinition2.Name);
- }
-
- fail = true;
- result = null;
- }
-
- return result;
- }
-
- private static MethodReference ResolveMethodWithArg(TypeReference t, string name, TypeReference argType)
- {
- foreach (var methodDefinition in t.Resolve().Methods)
- {
- if (methodDefinition.Name == name)
- {
- if (methodDefinition.Parameters.Count == 1)
- {
- if (methodDefinition.Parameters[0].ParameterType.FullName == argType.FullName)
- {
- return scriptDef.MainModule.ImportReference(methodDefinition);
- }
- }
- }
- }
-
- Log.Error(string.Concat(new object[]
- {
- "ResolveMethodWithArg failed ",
- t.Name,
- "::",
- name,
- " ",
- argType
- }));
- fail = true;
- return null;
- }
-
- private static MethodDefinition ResolveDefaultPublicCtor(TypeReference variable)
- {
- foreach (var methodDefinition in variable.Resolve().Methods)
- {
- if (methodDefinition.Name == ".ctor" && methodDefinition.Resolve().IsPublic && methodDefinition.Parameters.Count == 0)
- {
- return methodDefinition;
- }
- }
-
- return null;
- }
-
- private static GenericInstanceMethod ResolveMethodGeneric(TypeReference t, string name, TypeReference genericType)
- {
- foreach (var methodDefinition in t.Resolve().Methods)
- {
- if (methodDefinition.Name == name)
- {
- if (methodDefinition.Parameters.Count == 0)
- {
- if (methodDefinition.GenericParameters.Count == 1)
- {
- var method = scriptDef.MainModule.ImportReference(methodDefinition);
- var genericInstanceMethod = new GenericInstanceMethod(method);
- genericInstanceMethod.GenericArguments.Add(genericType);
- if (genericInstanceMethod.GenericArguments[0].FullName == genericType.FullName)
- {
- return genericInstanceMethod;
- }
- }
- }
- }
- }
-
- Log.Error(string.Concat(new object[]
- {
- "ResolveMethodGeneric failed ",
- t.Name,
- "::",
- name,
- " ",
- genericType
- }));
- fail = true;
- return null;
- }
-
- public static FieldReference ResolveField(TypeReference t, string name)
- {
- foreach (var fieldDefinition in t.Resolve().Fields)
- {
- if (fieldDefinition.Name == name)
- {
- return scriptDef.MainModule.ImportReference(fieldDefinition);
- }
- }
-
- return null;
- }
-
- public static MethodReference ResolveProperty(TypeReference t, string name)
- {
- foreach (var propertyDefinition in t.Resolve().Properties)
- {
- if (propertyDefinition.Name == name)
- {
- return scriptDef.MainModule.ImportReference(propertyDefinition.GetMethod);
- }
- }
-
- Log.Error($"ResolveProperty failed - Couldn't find {name} in {t.Name}");
- return null;
- }
-
- private static void SetupUnityTypes()
- {
- vector2Type = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Vector2");
- if (vector2Type == null)
- {
- Log.Error("Vector2Type is null!");
- }
-
- vector3Type = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Vector3");
- vector4Type = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Vector4");
- colorType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Color");
- color32Type = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Color32");
- quaternionType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Quaternion");
- rectType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Rect");
- planeType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Plane");
- rayType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Ray");
- matrixType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Matrix4x4");
- gameObjectType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.GameObject");
- if (gameObjectType == null)
- {
- Log.Error("GameObjectType is null!");
- }
-
- transformType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Transform");
- unityObjectType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Object");
-
- hashType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkHash128");
-
- NetworkClientType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkClient");
- NetworkServerType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkServer");
- NetworkCRCType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkCRC");
-
- SyncVarType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncVarAttribute");
-
- CommandType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.CommandAttribute");
-
- ClientRpcType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.ClientRpcAttribute");
-
- TargetRpcType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.TargetRpcAttribute");
-
- SyncEventType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncEventAttribute");
-
- SyncListType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncList`1");
-
- NetworkSettingsType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkSettingsAttribute");
-
- SyncListFloatType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListFloat");
-
- SyncListIntType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListInt");
-
- SyncListUIntType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListUInt");
-
- SyncListBoolType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListBool");
-
- SyncListStringType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListString");
-
- }
-
- private static void SetupCorLib()
- {
- var name = AssemblyNameReference.Parse("mscorlib");
- var parameters = new ReaderParameters
- {
- AssemblyResolver = scriptDef.MainModule.AssemblyResolver
- };
- corLib = scriptDef.MainModule.AssemblyResolver.Resolve(name, parameters).MainModule;
- }
-
- private static TypeReference ImportCorLibType(string fullName)
- {
- var type = corLib.GetType(fullName) ?? Enumerable.First(corLib.ExportedTypes, (ExportedType t) => t.FullName == fullName).Resolve();
- return scriptDef.MainModule.ImportReference(type);
- }
-
- private static void SetupTargetTypes()
- {
- SetupCorLib();
- voidType = ImportCorLibType("System.Void");
- singleType = ImportCorLibType("System.Single");
- doubleType = ImportCorLibType("System.Double");
- decimalType = ImportCorLibType("System.Decimal");
- boolType = ImportCorLibType("System.Boolean");
- stringType = ImportCorLibType("System.String");
- int64Type = ImportCorLibType("System.Int64");
- uint64Type = ImportCorLibType("System.UInt64");
- int32Type = ImportCorLibType("System.Int32");
- uint32Type = ImportCorLibType("System.UInt32");
- int16Type = ImportCorLibType("System.Int16");
- uint16Type = ImportCorLibType("System.UInt16");
- byteType = ImportCorLibType("System.Byte");
- sbyteType = ImportCorLibType("System.SByte");
- charType = ImportCorLibType("System.Char");
- objectType = ImportCorLibType("System.Object");
- valueTypeType = ImportCorLibType("System.ValueType");
- typeType = ImportCorLibType("System.Type");
- IEnumeratorType = ImportCorLibType("System.Collections.IEnumerator");
- MemoryStreamType = ImportCorLibType("System.IO.MemoryStream");
-
- NetworkReaderType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.Transport.QNetworkReader");
-
- NetworkReaderDef = NetworkReaderType.Resolve();
- NetworkReaderCtor = ResolveMethod(NetworkReaderDef, ".ctor");
-
- NetworkWriterType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.Transport.QNetworkWriter");
-
- NetworkWriterDef = NetworkWriterType.Resolve();
- NetworkWriterCtor = ResolveMethod(NetworkWriterDef, ".ctor");
- MemoryStreamCtor = ResolveMethod(MemoryStreamType, ".ctor");
-
- NetworkInstanceIdType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkInstanceId");
- NetworkSceneIdType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkSceneId");
- NetworkInstanceIdType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkInstanceId");
- NetworkSceneIdType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.NetworkSceneId");
-
- NetworkServerGetActive = ResolveMethod(NetworkServerType, "get_active");
- NetworkServerGetLocalClientActive = ResolveMethod(NetworkServerType, "get_localClientActive");
- NetworkClientGetActive = ResolveMethod(NetworkClientType, "get_active");
- NetworkReaderReadInt32 = ResolveMethod(NetworkReaderType, "ReadInt32");
- NetworkWriterWriteInt32 = ResolveMethodWithArg(NetworkWriterType, "Write", int32Type);
- NetworkWriterWriteInt16 = ResolveMethodWithArg(NetworkWriterType, "Write", int16Type);
- NetworkReaderReadPacked32 = ResolveMethod(NetworkReaderType, "ReadPackedUInt32");
- NetworkReaderReadPacked64 = ResolveMethod(NetworkReaderType, "ReadPackedUInt64");
- NetworkReaderReadByte = ResolveMethod(NetworkReaderType, "ReadByte");
- NetworkWriterWritePacked32 = ResolveMethod(NetworkWriterType, "WritePackedUInt32");
- NetworkWriterWritePacked64 = ResolveMethod(NetworkWriterType, "WritePackedUInt64");
- NetworkWriterWriteNetworkInstanceId = ResolveMethodWithArg(NetworkWriterType, "Write", NetworkInstanceIdType);
- NetworkWriterWriteNetworkSceneId = ResolveMethodWithArg(NetworkWriterType, "Write", NetworkSceneIdType);
- NetworkWriterStartMessage = ResolveMethod(NetworkWriterType, "StartMessage");
- NetworkWriterFinishMessage = ResolveMethod(NetworkWriterType, "FinishMessage");
- NetworkReaderReadNetworkInstanceId = ResolveMethod(NetworkReaderType, "ReadNetworkId");
- NetworkReaderReadNetworkSceneId = ResolveMethod(NetworkReaderType, "ReadSceneId");
- NetworkInstanceIsEmpty = ResolveMethod(NetworkInstanceIdType, "IsEmpty");
- NetworkReadUInt16 = ResolveMethod(NetworkReaderType, "ReadUInt16");
- NetworkWriteUInt16 = ResolveMethodWithArg(NetworkWriterType, "Write", uint16Type);
-
- CmdDelegateReference = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkBehaviour/CmdDelegate");
-
- CmdDelegateConstructor = ResolveMethod(CmdDelegateReference, ".ctor");
- Console.WriteLine("gameobject");
- scriptDef.MainModule.ImportReference(gameObjectType);
- Console.WriteLine("transform");
- scriptDef.MainModule.ImportReference(transformType);
-
- TypeReference type = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.Components.QNetworkIdentity");
-
- Console.WriteLine("type");
- NetworkIdentityType = scriptDef.MainModule.ImportReference(type);
- Console.WriteLine("networkinstanceidtype");
- NetworkInstanceIdType = scriptDef.MainModule.ImportReference(NetworkInstanceIdType);
- SyncListFloatReadType = ResolveMethod(SyncListFloatType, "ReadReference");
- SyncListIntReadType = ResolveMethod(SyncListIntType, "ReadReference");
- SyncListUIntReadType = ResolveMethod(SyncListUIntType, "ReadReference");
- SyncListBoolReadType = ResolveMethod(SyncListBoolType, "ReadReference");
- SyncListStringReadType = ResolveMethod(SyncListStringType, "ReadReference");
- SyncListFloatWriteType = ResolveMethod(SyncListFloatType, "WriteInstance");
- SyncListIntWriteType = ResolveMethod(SyncListIntType, "WriteInstance");
- SyncListUIntWriteType = ResolveMethod(SyncListUIntType, "WriteInstance");
- SyncListBoolWriteType = ResolveMethod(SyncListBoolType, "WriteInstance");
- SyncListStringWriteType = ResolveMethod(SyncListStringType, "WriteInstance");
-
- NetworkBehaviourType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkBehaviour");
-
- Console.WriteLine("networkbehaviourtype");
- NetworkBehaviourType2 = scriptDef.MainModule.ImportReference(NetworkBehaviourType);
-
- NetworkConnectionType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkConnection");
-
- MonoBehaviourType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.MonoBehaviour");
- ScriptableObjectType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.ScriptableObject");
-
- NetworkConnectionType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QNetworkConnection");
-
- NetworkConnectionType = scriptDef.MainModule.ImportReference(NetworkConnectionType);
-
- ULocalConnectionToServerType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QULocalConnectionToServer");
-
- ULocalConnectionToServerType = scriptDef.MainModule.ImportReference(ULocalConnectionToServerType);
-
- ULocalConnectionToClientType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QULocalConnectionToClient");
-
- ULocalConnectionToClientType = scriptDef.MainModule.ImportReference(ULocalConnectionToClientType);
-
- MessageBaseType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.Messages.QMessageBase");
- SyncListStructType = UNetAssemblyDefinition.MainModule.GetType("UnityEngine.Networking.SyncListStruct`1");
-
- NetworkBehaviourDirtyBitsReference = ResolveProperty(NetworkBehaviourType, "SyncVarDirtyBits");
- NetworkBehaviourOnSerialize = ResolveMethod(NetworkBehaviourType, "OnSerialize");
- NetworkBehaviourClearAllDirtyBits = ResolveMethod(NetworkBehaviourType, "ClearAllDirtyBits");
- NetworkBehaviourGetNetworkChannel = ResolveMethod(NetworkBehaviourType, "GetNetworkChannel");
- NetworkBehaviourClientSendUpdateVars = ResolveMethod(NetworkBehaviourType, "ClientSendUpdateVars");
- NetworkConnectionSendWriter = ResolveMethod(NetworkConnectionType, "SendWriter");
- ComponentType = UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Component");
-
- ClientSceneType = QNetAssemblyDefinition.MainModule.GetType("QuantumUNET.QClientScene");
-
- FindLocalObjectReference = ResolveMethod(ClientSceneType, "FindLocalObject");
- RegisterBehaviourReference = ResolveMethod(NetworkCRCType, "RegisterBehaviour");
- ReadyConnectionReference = ResolveMethod(ClientSceneType, "get_readyConnection");
- getComponentReference = ResolveMethodGeneric(ComponentType, "GetComponent", NetworkIdentityType);
- getUNetIdReference = ResolveMethod(type, "get_NetId");
- gameObjectInequality = ResolveMethod(unityObjectType, "op_Inequality");
- UBehaviourIsServer = ResolveMethod(NetworkBehaviourType, "get_IsServer");
- getPlayerIdReference = ResolveMethod(NetworkBehaviourType, "get_PlayerControllerId");
- setSyncVarReference = ResolveMethod(NetworkBehaviourType, "SetSyncVar");
- setSyncVarHookGuard = ResolveMethod(NetworkBehaviourType, "set_SyncVarHookGuard");
- getSyncVarHookGuard = ResolveMethod(NetworkBehaviourType, "get_SyncVarHookGuard");
- setSyncVarGameObjectReference = ResolveMethod(NetworkBehaviourType, "SetSyncVarGameObject");
- registerCommandDelegateReference = ResolveMethod(NetworkBehaviourType, "RegisterCommandDelegate");
- registerRpcDelegateReference = ResolveMethod(NetworkBehaviourType, "RegisterRpcDelegate");
- registerEventDelegateReference = ResolveMethod(NetworkBehaviourType, "RegisterEventDelegate");
- registerSyncListDelegateReference = ResolveMethod(NetworkBehaviourType, "RegisterSyncListDelegate");
- getTypeReference = ResolveMethod(objectType, "GetType");
- getTypeFromHandleReference = ResolveMethod(typeType, "GetTypeFromHandle");
- logErrorReference = ResolveMethod(UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Debug"), "LogError");
- logWarningReference = ResolveMethod(UnityAssemblyDefinition.MainModule.GetType("UnityEngine.Debug"), "LogWarning");
- sendCommandInternal = ResolveMethod(NetworkBehaviourType, "SendCommandInternal");
- sendRpcInternal = ResolveMethod(NetworkBehaviourType, "SendRPCInternal");
- sendTargetRpcInternal = ResolveMethod(NetworkBehaviourType, "SendTargetRPCInternal");
- sendEventInternal = ResolveMethod(NetworkBehaviourType, "SendEventInternal");
- Console.WriteLine("synclisttype");
- SyncListType = scriptDef.MainModule.ImportReference(SyncListType);
- SyncListInitBehaviourReference = ResolveMethod(SyncListType, "InitializeBehaviour");
- SyncListInitHandleMsg = ResolveMethod(SyncListType, "HandleMsg");
- SyncListClear = ResolveMethod(SyncListType, "Clear");
- }
-
- private static void SetupReadFunctions()
- {
- var weaverLists = lists;
- var dictionary = new Dictionary
- {
- { singleType.FullName, ResolveMethod(NetworkReaderType, "ReadSingle") },
- { doubleType.FullName, ResolveMethod(NetworkReaderType, "ReadDouble") },
- { boolType.FullName, ResolveMethod(NetworkReaderType, "ReadBoolean") },
- { stringType.FullName, ResolveMethod(NetworkReaderType, "ReadString") },
- { int64Type.FullName, NetworkReaderReadPacked64 },
- { uint64Type.FullName, NetworkReaderReadPacked64 },
- { int32Type.FullName, NetworkReaderReadPacked32 },
- { uint32Type.FullName, NetworkReaderReadPacked32 },
- { int16Type.FullName, NetworkReaderReadPacked32 },
- { uint16Type.FullName, NetworkReaderReadPacked32 },
- { byteType.FullName, NetworkReaderReadPacked32 },
- { sbyteType.FullName, NetworkReaderReadPacked32 },
- { charType.FullName, NetworkReaderReadPacked32 },
- { decimalType.FullName, ResolveMethod(NetworkReaderType, "ReadDecimal") },
- { vector2Type.FullName, ResolveMethod(NetworkReaderType, "ReadVector2") },
- { vector3Type.FullName, ResolveMethod(NetworkReaderType, "ReadVector3") },
- { vector4Type.FullName, ResolveMethod(NetworkReaderType, "ReadVector4") },
- { colorType.FullName, ResolveMethod(NetworkReaderType, "ReadColor") },
- { color32Type.FullName, ResolveMethod(NetworkReaderType, "ReadColor32") },
- { quaternionType.FullName, ResolveMethod(NetworkReaderType, "ReadQuaternion") },
- { rectType.FullName, ResolveMethod(NetworkReaderType, "ReadRect") },
- { planeType.FullName, ResolveMethod(NetworkReaderType, "ReadPlane") },
- { rayType.FullName, ResolveMethod(NetworkReaderType, "ReadRay") },
- { matrixType.FullName, ResolveMethod(NetworkReaderType, "ReadMatrix4x4") },
- { hashType.FullName, ResolveMethod(NetworkReaderType, "ReadNetworkHash128") },
- { gameObjectType.FullName, ResolveMethod(NetworkReaderType, "ReadGameObject") },
- { NetworkIdentityType.FullName, ResolveMethod(NetworkReaderType, "ReadNetworkIdentity") },
- { NetworkInstanceIdType.FullName, NetworkReaderReadNetworkInstanceId },
- { NetworkSceneIdType.FullName, NetworkReaderReadNetworkSceneId },
- { transformType.FullName, ResolveMethod(NetworkReaderType, "ReadTransform") },
- { "System.Byte[]", ResolveMethod(NetworkReaderType, "ReadBytesAndSize") }
- };
- weaverLists.readFuncs = dictionary;
- var weaverLists2 = lists;
- dictionary = new Dictionary
- {
- { SyncListFloatType.FullName, SyncListFloatReadType },
- { SyncListIntType.FullName, SyncListIntReadType },
- { SyncListUIntType.FullName, SyncListUIntReadType },
- { SyncListBoolType.FullName, SyncListBoolReadType },
- { SyncListStringType.FullName, SyncListStringReadType }
- };
- weaverLists2.readByReferenceFuncs = dictionary;
- }
-
- private static void SetupWriteFunctions()
- {
- var weaverLists = lists;
- var dictionary = new Dictionary
- {
- { singleType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", singleType) },
- { doubleType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", doubleType) },
- { boolType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", boolType) },
- { stringType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", stringType) },
- { int64Type.FullName, NetworkWriterWritePacked64 },
- { uint64Type.FullName, NetworkWriterWritePacked64 },
- { int32Type.FullName, NetworkWriterWritePacked32 },
- { uint32Type.FullName, NetworkWriterWritePacked32 },
- { int16Type.FullName, NetworkWriterWritePacked32 },
- { uint16Type.FullName, NetworkWriterWritePacked32 },
- { byteType.FullName, NetworkWriterWritePacked32 },
- { sbyteType.FullName, NetworkWriterWritePacked32 },
- { charType.FullName, NetworkWriterWritePacked32 },
- { decimalType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", decimalType) },
- { vector2Type.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", vector2Type) },
- { vector3Type.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", vector3Type) },
- { vector4Type.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", vector4Type) },
- { colorType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", colorType) },
- { color32Type.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", color32Type) },
- { quaternionType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", quaternionType) },
- { rectType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", rectType) },
- { planeType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", planeType) },
- { rayType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", rayType) },
- { matrixType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", matrixType) },
- { hashType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", hashType) },
- { gameObjectType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", gameObjectType) },
- { NetworkIdentityType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", NetworkIdentityType) },
- { NetworkInstanceIdType.FullName, NetworkWriterWriteNetworkInstanceId },
- { NetworkSceneIdType.FullName, NetworkWriterWriteNetworkSceneId },
- { transformType.FullName, ResolveMethodWithArg(NetworkWriterType, "Write", transformType) },
- { "System.Byte[]", ResolveMethod(NetworkWriterType, "WriteBytesFull") },
- { SyncListFloatType.FullName, SyncListFloatWriteType },
- { SyncListIntType.FullName, SyncListIntWriteType },
- { SyncListUIntType.FullName, SyncListUIntWriteType },
- { SyncListBoolType.FullName, SyncListBoolWriteType },
- { SyncListStringType.FullName, SyncListStringWriteType }
- };
- weaverLists.writeFuncs = dictionary;
- }
-
- private static bool IsNetworkBehaviour(TypeDefinition td)
- {
- bool result;
- if (!td.IsClass)
- {
- result = false;
- }
- else
- {
- var baseType = td.BaseType;
- while (baseType != null)
- {
- if (baseType.FullName == NetworkBehaviourType.FullName)
- {
- return true;
- }
-
- try
- {
- baseType = baseType.Resolve().BaseType;
- }
- catch (AssemblyResolutionException)
- {
- break;
- }
- }
-
- result = false;
- }
-
- return result;
- }
-
- public static bool IsDerivedFrom(TypeDefinition td, TypeReference baseClass)
- {
- bool result;
- if (!td.IsClass)
- {
- result = false;
- }
- else
- {
- var baseType = td.BaseType;
- while (baseType != null)
- {
- var text = baseType.FullName;
- var num = text.IndexOf('<');
- if (num != -1)
- {
- text = text.Substring(0, num);
- }
-
- if (text == baseClass.FullName)
- {
- return true;
- }
-
- try
- {
- baseType = baseType.Resolve().BaseType;
- }
- catch (AssemblyResolutionException)
- {
- break;
- }
- }
-
- result = false;
- }
-
- return result;
- }
-
- public static bool IsValidTypeToGenerate(TypeDefinition variable)
- {
- var name = scriptDef.MainModule.Name;
- bool result;
- if (variable.Module.Name != name)
- {
- Log.Error(string.Concat(new string[]
- {
- "parameter [",
- variable.Name,
- "] is of the type [",
- variable.FullName,
- "] is not a valid type, please make sure to use a valid type."
- }));
- fail = true;
- fail = true;
- result = false;
- }
- else
- {
- result = true;
- }
-
- return result;
- }
-
- private static void CheckMonoBehaviour(TypeDefinition td)
- {
- if (IsDerivedFrom(td, MonoBehaviourType))
- {
- ProcessMonoBehaviourType(td);
- }
- }
-
- private static bool CheckNetworkBehaviour(TypeDefinition td)
- {
- bool result;
- if (!td.IsClass)
- {
- result = false;
- }
- else if (!IsNetworkBehaviour(td))
- {
- CheckMonoBehaviour(td);
- result = false;
- }
- else
- {
- var list = new List();
- var typeDefinition = td;
- while (typeDefinition != null)
- {
- if (typeDefinition.FullName == NetworkBehaviourType.FullName)
- {
- break;
- }
-
- try
- {
- list.Insert(0, typeDefinition);
- typeDefinition = typeDefinition.BaseType.Resolve();
- }
- catch (AssemblyResolutionException)
- {
- break;
- }
- }
-
- var flag = false;
- foreach (var td2 in list)
- {
- flag |= ProcessNetworkBehaviourType(td2);
- }
-
- result = flag;
- }
-
- return result;
- }
-
- private static bool CheckMessageBase(TypeDefinition td)
- {
- bool result;
- if (!td.IsClass)
- {
- result = false;
- }
- else
- {
- var flag = false;
- var baseType = td.BaseType;
- while (baseType != null)
- {
- if (baseType.FullName == MessageBaseType.FullName)
- {
- flag |= ProcessMessageType(td);
- break;
- }
-
- try
- {
- baseType = baseType.Resolve().BaseType;
- }
- catch (AssemblyResolutionException)
- {
- break;
- }
- }
-
- foreach (var td2 in td.NestedTypes)
- {
- flag |= CheckMessageBase(td2);
- }
-
- result = flag;
- }
-
- return result;
- }
-
- private static bool CheckSyncListStruct(TypeDefinition td)
- {
- bool result;
- if (!td.IsClass)
- {
- result = false;
- }
- else
- {
- var flag = false;
- var baseType = td.BaseType;
- while (baseType != null)
- {
- if (baseType.FullName.Contains("SyncListStruct"))
- {
- flag |= ProcessSyncListStructType(td);
- break;
- }
-
- try
- {
- baseType = baseType.Resolve().BaseType;
- }
- catch (AssemblyResolutionException)
- {
- break;
- }
- }
-
- foreach (var td2 in td.NestedTypes)
- {
- flag |= CheckSyncListStruct(td2);
- }
-
- result = flag;
- }
-
- return result;
- }
-
- private static bool Weave(string assName, IEnumerable dependencies, IAssemblyResolver assemblyResolver, string unityEngineDLLPath, string unityUNetDLLPath, string outputDir)
- {
- var readerParameters = Helpers.ReaderParameters(assName, dependencies, assemblyResolver, unityEngineDLLPath, unityUNetDLLPath);
- scriptDef = AssemblyDefinition.ReadAssembly(assName, readerParameters);
- SetupTargetTypes();
- SetupReadFunctions();
- SetupWriteFunctions();
- var mainModule = scriptDef.MainModule;
- Console.WriteLine("Script Module: {0}", mainModule.Name);
- var flag = false;
- for (var i = 0; i < 2; i++)
- {
- var stopwatch = Stopwatch.StartNew();
- foreach (var typeDefinition in mainModule.Types)
- {
- if (typeDefinition.IsClass && CanBeResolved(typeDefinition.BaseType))
- {
- try
- {
- if (i == 0)
- {
- flag |= CheckSyncListStruct(typeDefinition);
- }
- else
- {
- flag |= CheckNetworkBehaviour(typeDefinition);
- flag |= CheckMessageBase(typeDefinition);
- }
- }
- catch (Exception ex)
- {
- if (scriptDef.MainModule.SymbolReader != null)
- {
- scriptDef.MainModule.SymbolReader.Dispose();
- }
-
- fail = true;
- throw ex;
- }
- }
-
- if (fail)
- {
- if (scriptDef.MainModule.SymbolReader != null)
- {
- scriptDef.MainModule.SymbolReader.Dispose();
- }
-
- return false;
- }
- }
-
- stopwatch.Stop();
- Console.WriteLine(string.Concat(new object[]
- {
- "Pass: ",
- i,
- " took ",
- stopwatch.ElapsedMilliseconds,
- " milliseconds"
- }));
- }
-
- if (flag)
- {
- foreach (var methodDefinition in lists.replacedMethods)
- {
- lists.replacementMethodNames.Add(methodDefinition.FullName);
- }
-
- try
- {
- ProcessPropertySites();
- }
- catch (Exception ex2)
- {
- Log.Error("ProcessPropertySites exception: " + ex2);
- if (scriptDef.MainModule.SymbolReader != null)
- {
- scriptDef.MainModule.SymbolReader.Dispose();
- }
-
- return false;
- }
-
- if (fail)
- {
- if (scriptDef.MainModule.SymbolReader != null)
- {
- scriptDef.MainModule.SymbolReader.Dispose();
- }
-
- return false;
- }
-
- var fileName = Helpers.DestinationFileFor(outputDir, assName);
- var writerParameters = Helpers.GetWriterParameters(readerParameters);
- if (writerParameters.SymbolWriterProvider is PdbWriterProvider)
- {
- writerParameters.SymbolWriterProvider = new MdbWriterProvider();
- var text = Path.ChangeExtension(assName, ".pdb");
- File.Delete(text);
- }
-
- scriptDef.Write(fileName, writerParameters);
- }
-
- if (scriptDef.MainModule.SymbolReader != null)
- {
- scriptDef.MainModule.SymbolReader.Dispose();
- }
-
- return true;
- }
-
- public static bool WeaveAssemblies(string assembly, IEnumerable dependencies, IAssemblyResolver assemblyResolver, string outputDir, string unityEngineDLLPath, string unityQNetDLLPath, string unityUNetDLLPath)
- {
- fail = false;
- lists = new WeaverLists();
- Console.WriteLine($"load unity engine from {unityEngineDLLPath}");
- UnityAssemblyDefinition = AssemblyDefinition.ReadAssembly(unityEngineDLLPath);
- Console.WriteLine($"load qnet from {unityQNetDLLPath}");
- QNetAssemblyDefinition = AssemblyDefinition.ReadAssembly(unityQNetDLLPath);
- Console.WriteLine($"load unet from {unityUNetDLLPath}");
- UNetAssemblyDefinition = AssemblyDefinition.ReadAssembly(unityUNetDLLPath);
- SetupUnityTypes();
- try
- {
- if (!Weave(assembly, dependencies, assemblyResolver, unityEngineDLLPath, unityQNetDLLPath, outputDir))
- {
- return false;
- }
- }
- catch (Exception ex)
- {
- Log.Error("Exception :" + ex);
- return false;
- }
-
- corLib = null;
- return true;
- }
-
- public static TypeReference NetworkBehaviourType;
-
- public static TypeReference NetworkBehaviourType2;
-
- public static TypeReference MonoBehaviourType;
-
- public static TypeReference ScriptableObjectType;
-
- public static TypeReference NetworkConnectionType;
-
- public static TypeReference ULocalConnectionToServerType;
-
- public static TypeReference ULocalConnectionToClientType;
-
- public static TypeReference MessageBaseType;
-
- public static TypeReference SyncListStructType;
-
- public static MethodReference NetworkBehaviourDirtyBitsReference;
-
- public static MethodReference NetworkBehaviourOnSerialize;
-
- public static MethodReference NetworkBehaviourClearAllDirtyBits;
-
- public static MethodReference NetworkBehaviourGetNetworkChannel;
-
- public static MethodReference NetworkConnectionSendWriter;
-
- public static MethodReference NetworkBehaviourClientSendUpdateVars;
-
- public static TypeReference NetworkClientType;
-
- public static TypeReference NetworkServerType;
-
- public static TypeReference NetworkCRCType;
-
- public static TypeReference NetworkReaderType;
-
- public static TypeDefinition NetworkReaderDef;
-
- public static TypeReference NetworkWriterType;
-
- public static TypeDefinition NetworkWriterDef;
-
- public static MethodReference NetworkWriterCtor;
-
- public static MethodReference NetworkReaderCtor;
-
- public static TypeReference MemoryStreamType;
-
- public static MethodReference MemoryStreamCtor;
-
- public static MethodReference getComponentReference;
-
- public static MethodReference getUNetIdReference;
-
- public static MethodReference getPlayerIdReference;
-
- public static TypeReference NetworkIdentityType;
-
- public static TypeReference NetworkInstanceIdType;
-
- public static TypeReference NetworkSceneIdType;
-
- public static TypeReference IEnumeratorType;
-
- public static TypeReference ClientSceneType;
-
- public static MethodReference FindLocalObjectReference;
-
- public static MethodReference RegisterBehaviourReference;
-
- public static MethodReference ReadyConnectionReference;
-
- public static TypeReference ComponentType;
-
- public static TypeReference CmdDelegateReference;
-
- public static MethodReference CmdDelegateConstructor;
-
- public static MethodReference NetworkReaderReadInt32;
-
- public static MethodReference NetworkWriterWriteInt32;
-
- public static MethodReference NetworkWriterWriteInt16;
-
- public static MethodReference NetworkServerGetActive;
-
- public static MethodReference NetworkServerGetLocalClientActive;
-
- public static MethodReference NetworkClientGetActive;
-
- public static MethodReference UBehaviourIsServer;
-
- public static MethodReference NetworkReaderReadPacked32;
-
- public static MethodReference NetworkReaderReadPacked64;
-
- public static MethodReference NetworkReaderReadByte;
-
- public static MethodReference NetworkWriterWritePacked32;
-
- public static MethodReference NetworkWriterWritePacked64;
-
- public static MethodReference NetworkWriterWriteNetworkInstanceId;
-
- public static MethodReference NetworkWriterWriteNetworkSceneId;
-
- public static MethodReference NetworkWriterStartMessage;
-
- public static MethodReference NetworkWriterFinishMessage;
-
- public static MethodReference NetworkReaderReadNetworkInstanceId;
-
- public static MethodReference NetworkReaderReadNetworkSceneId;
-
- public static MethodReference NetworkInstanceIsEmpty;
-
- public static MethodReference NetworkReadUInt16;
-
- public static MethodReference NetworkWriteUInt16;
-
- public static TypeReference SyncVarType;
-
- public static TypeReference CommandType;
-
- public static TypeReference ClientRpcType;
-
- public static TypeReference TargetRpcType;
-
- public static TypeReference SyncEventType;
-
- public static TypeReference SyncListType;
-
- public static MethodReference SyncListInitBehaviourReference;
-
- public static MethodReference SyncListInitHandleMsg;
-
- public static MethodReference SyncListClear;
-
- public static TypeReference NetworkSettingsType;
-
- public static TypeReference SyncListFloatType;
-
- public static TypeReference SyncListIntType;
-
- public static TypeReference SyncListUIntType;
-
- public static TypeReference SyncListBoolType;
-
- public static TypeReference SyncListStringType;
-
- public static MethodReference SyncListFloatReadType;
-
- public static MethodReference SyncListIntReadType;
-
- public static MethodReference SyncListUIntReadType;
-
- public static MethodReference SyncListStringReadType;
-
- public static MethodReference SyncListBoolReadType;
-
- public static MethodReference SyncListFloatWriteType;
-
- public static MethodReference SyncListIntWriteType;
-
- public static MethodReference SyncListUIntWriteType;
-
- public static MethodReference SyncListBoolWriteType;
-
- public static MethodReference SyncListStringWriteType;
-
- public static TypeReference voidType;
-
- public static TypeReference singleType;
-
- public static TypeReference doubleType;
-
- public static TypeReference decimalType;
-
- public static TypeReference boolType;
-
- public static TypeReference stringType;
-
- public static TypeReference int64Type;
-
- public static TypeReference uint64Type;
-
- public static TypeReference int32Type;
-
- public static TypeReference uint32Type;
-
- public static TypeReference int16Type;
-
- public static TypeReference uint16Type;
-
- public static TypeReference byteType;
-
- public static TypeReference sbyteType;
-
- public static TypeReference charType;
-
- public static TypeReference objectType;
-
- public static TypeReference valueTypeType;
-
- public static TypeReference vector2Type;
-
- public static TypeReference vector3Type;
-
- public static TypeReference vector4Type;
-
- public static TypeReference colorType;
-
- public static TypeReference color32Type;
-
- public static TypeReference quaternionType;
-
- public static TypeReference rectType;
-
- public static TypeReference rayType;
-
- public static TypeReference planeType;
-
- public static TypeReference matrixType;
-
- public static TypeReference hashType;
-
- public static TypeReference typeType;
-
- public static TypeReference gameObjectType;
-
- public static TypeReference transformType;
-
- public static TypeReference unityObjectType;
-
- public static MethodReference gameObjectInequality;
-
- public static MethodReference setSyncVarReference;
-
- public static MethodReference setSyncVarHookGuard;
-
- public static MethodReference getSyncVarHookGuard;
-
- public static MethodReference setSyncVarGameObjectReference;
-
- public static MethodReference registerCommandDelegateReference;
-
- public static MethodReference registerRpcDelegateReference;
-
- public static MethodReference registerEventDelegateReference;
-
- public static MethodReference registerSyncListDelegateReference;
-
- public static MethodReference getTypeReference;
-
- public static MethodReference getTypeFromHandleReference;
-
- public static MethodReference logErrorReference;
-
- public static MethodReference logWarningReference;
-
- public static MethodReference sendCommandInternal;
-
- public static MethodReference sendRpcInternal;
-
- public static MethodReference sendTargetRpcInternal;
-
- public static MethodReference sendEventInternal;
-
- public static WeaverLists lists;
-
- public static AssemblyDefinition scriptDef;
-
- public static ModuleDefinition corLib;
-
- public static AssemblyDefinition UnityAssemblyDefinition;
-
- public static AssemblyDefinition QNetAssemblyDefinition;
-
- public static AssemblyDefinition UNetAssemblyDefinition;
-
- private static bool m_DebugFlag = true;
-
- public static bool fail;
-
- public static bool generateLogErrors = false;
-
- private const int MaxRecursionCount = 128;
-
- private static int s_RecursionCount;
- }
-}
diff --git a/QNetWeaver/WeaverLists.cs b/QNetWeaver/WeaverLists.cs
deleted file mode 100644
index e8a96c60..00000000
--- a/QNetWeaver/WeaverLists.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using Mono.Cecil;
-using System.Collections.Generic;
-
-namespace QNetWeaver
-{
- internal class WeaverLists
- {
- public List replacedFields = new List();
-
- public List replacementProperties = new List();
-
- public List netIdFields = new List();
-
- public List replacedMethods = new List();
-
- public List replacementMethods = new List();
-
- public HashSet replacementMethodNames = new HashSet();
-
- public List replacedEvents = new List();
-
- public List replacementEvents = new List();
-
- public Dictionary readFuncs;
-
- public Dictionary readByReferenceFuncs;
-
- public Dictionary writeFuncs;
-
- public List generatedReadFunctions = new List();
-
- public List generatedWriteFunctions = new List();
-
- public TypeDefinition generateContainerClass;
-
- public Dictionary numSyncVars = new Dictionary();
- }
-}
diff --git a/QSB.sln b/QSB.sln
index b7e39c4d..15709d10 100644
--- a/QSB.sln
+++ b/QSB.sln
@@ -1,22 +1,18 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29613.14
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSB", "QSB\QSB.csproj", "{1F00090A-C697-4C55-B401-192F3CFB9DC2}"
- ProjectSection(ProjectDependencies) = postProject
- {E23551F3-C095-4F50-8BF7-85BB2661859B} = {E23551F3-C095-4F50-8BF7-85BB2661859B}
- EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuantumUNET", "QuantumUNET\QuantumUNET.csproj", "{C8C53004-1508-4F86-A419-4292C188DC2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSBTests", "QSBTests\QSBTests.csproj", "{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QNetWeaver", "QNetWeaver\QNetWeaver.csproj", "{E23551F3-C095-4F50-8BF7-85BB2661859B}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2569F98D-F671-42AA-82DE-505B05CDCEF2}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
+ Directory.Build.targets = Directory.Build.targets
LICENSE = LICENSE
README.md = README.md
EndProjectSection
@@ -39,10 +35,6 @@ Global
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Release|Any CPU.Build.0 = Release|Any CPU
- {E23551F3-C095-4F50-8BF7-85BB2661859B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E23551F3-C095-4F50-8BF7-85BB2661859B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E23551F3-C095-4F50-8BF7-85BB2661859B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E23551F3-C095-4F50-8BF7-85BB2661859B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/QSB/Anglerfish/AnglerManager.cs b/QSB/Anglerfish/AnglerManager.cs
new file mode 100644
index 00000000..09ea3945
--- /dev/null
+++ b/QSB/Anglerfish/AnglerManager.cs
@@ -0,0 +1,11 @@
+using QSB.Anglerfish.WorldObjects;
+using QSB.WorldSync;
+
+namespace QSB.Anglerfish
+{
+ public class AnglerManager : WorldObjectManager
+ {
+ protected override void RebuildWorldObjects(OWScene scene)
+ => QSBWorldSync.Init();
+ }
+}
diff --git a/QSB/Anglerfish/Events/AnglerChangeStateEvent.cs b/QSB/Anglerfish/Events/AnglerChangeStateEvent.cs
new file mode 100644
index 00000000..efd0dcfa
--- /dev/null
+++ b/QSB/Anglerfish/Events/AnglerChangeStateEvent.cs
@@ -0,0 +1,82 @@
+using QSB.Anglerfish.WorldObjects;
+using QSB.Events;
+using QSB.Player;
+using QSB.WorldSync;
+using UnityEngine;
+using EventType = QSB.Events.EventType;
+
+namespace QSB.Anglerfish.Events
+{
+ public class AnglerChangeStateEvent : QSBEvent
+ {
+ public override EventType Type => EventType.AnglerChangeState;
+
+ public override void SetupListener()
+ => GlobalMessenger.AddListener(EventNames.QSBAnglerChangeState, Handler);
+
+ public override void CloseListener()
+ => GlobalMessenger.RemoveListener(EventNames.QSBAnglerChangeState, Handler);
+
+ private void Handler(QSBAngler qsbAngler) => SendEvent(CreateMessage(qsbAngler));
+
+ private AnglerChangeStateMessage CreateMessage(QSBAngler qsbAngler) => new()
+ {
+ ObjectId = qsbAngler.ObjectId,
+ EnumValue = qsbAngler.AttachedObject._currentState,
+ TargetId = TargetToId(qsbAngler.TargetTransform),
+ LocalDisturbancePos = qsbAngler.AttachedObject._localDisturbancePos
+ };
+
+ public override void OnReceiveLocal(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
+ public override void OnReceiveRemote(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
+
+ private static void OnReceive(bool isHost, AnglerChangeStateMessage message)
+ {
+ if (!QSBCore.WorldObjectsReady)
+ {
+ return;
+ }
+
+ var qsbAngler = QSBWorldSync.GetWorldFromId(message.ObjectId);
+
+ if (isHost)
+ {
+ qsbAngler.TransferAuthority(message.FromId);
+ }
+
+ qsbAngler.TargetTransform = IdToTarget(message.TargetId);
+ qsbAngler.AttachedObject._localDisturbancePos = message.LocalDisturbancePos;
+ qsbAngler.AttachedObject.ChangeState(message.EnumValue);
+ }
+
+ private static uint TargetToId(Transform transform)
+ {
+ if (transform == null)
+ {
+ return uint.MaxValue;
+ }
+
+ if (transform == Locator.GetShipTransform())
+ {
+ return uint.MaxValue - 1;
+ }
+
+ return QSBPlayerManager.LocalPlayerId;
+ }
+
+ private static Transform IdToTarget(uint id)
+ {
+ if (id == uint.MaxValue)
+ {
+ return null;
+ }
+
+ if (id == uint.MaxValue - 1)
+ {
+ return Locator.GetShipTransform();
+ }
+
+ return QSBPlayerManager.GetPlayer(id).Body.transform;
+ }
+ }
+}
diff --git a/QSB/Anglerfish/Events/AnglerChangeStateMessage.cs b/QSB/Anglerfish/Events/AnglerChangeStateMessage.cs
new file mode 100644
index 00000000..0615153d
--- /dev/null
+++ b/QSB/Anglerfish/Events/AnglerChangeStateMessage.cs
@@ -0,0 +1,26 @@
+using QSB.WorldSync.Events;
+using QuantumUNET.Transport;
+using UnityEngine;
+
+namespace QSB.Anglerfish.Events
+{
+ public class AnglerChangeStateMessage : EnumWorldObjectMessage
+ {
+ public uint TargetId;
+ public Vector3 LocalDisturbancePos;
+
+ public override void Deserialize(QNetworkReader reader)
+ {
+ base.Deserialize(reader);
+ TargetId = reader.ReadUInt32();
+ LocalDisturbancePos = reader.ReadVector3();
+ }
+
+ public override void Serialize(QNetworkWriter writer)
+ {
+ base.Serialize(writer);
+ writer.Write(TargetId);
+ writer.Write(LocalDisturbancePos);
+ }
+ }
+}
diff --git a/QSB/Anglerfish/Patches/AnglerPatches.cs b/QSB/Anglerfish/Patches/AnglerPatches.cs
new file mode 100644
index 00000000..198f87fa
--- /dev/null
+++ b/QSB/Anglerfish/Patches/AnglerPatches.cs
@@ -0,0 +1,362 @@
+using HarmonyLib;
+using QSB.Anglerfish.WorldObjects;
+using QSB.Events;
+using QSB.Patches;
+using QSB.WorldSync;
+using System;
+using UnityEngine;
+
+namespace QSB.Anglerfish.Patches
+{
+ public class AnglerPatches : QSBPatch
+ {
+ public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.GetTargetPosition))]
+ public static bool GetTargetPosition(AnglerfishController __instance, ref Vector3 __result)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ __result = qsbAngler.TargetTransform != null
+ ? qsbAngler.TargetTransform.position
+ : __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnSectorOccupantRemoved))]
+ public static bool OnSectorOccupantRemoved(AnglerfishController __instance,
+ SectorDetector sectorDetector)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ if (!(qsbAngler.TargetTransform != null) || !(sectorDetector.GetAttachedOWRigidbody().transform == qsbAngler.TargetTransform))
+ {
+ return false;
+ }
+
+ qsbAngler.TargetTransform = null;
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateState))]
+ public static bool UpdateState(AnglerfishController __instance)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ switch (__instance._currentState)
+ {
+ case AnglerfishController.AnglerState.Investigating:
+ if ((__instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos) - __instance._anglerBody.GetPosition()).sqrMagnitude >= __instance._arrivalDistance * (double)__instance._arrivalDistance)
+ {
+ break;
+ }
+
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+
+ case AnglerfishController.AnglerState.Chasing:
+ if (qsbAngler.TargetTransform == null)
+ {
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+ }
+
+ if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude <= __instance._escapeDistance * (double)__instance._escapeDistance)
+ {
+ break;
+ }
+
+ qsbAngler.TargetTransform = null;
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+
+ case AnglerfishController.AnglerState.Consuming:
+ if (__instance._consumeComplete)
+ {
+ break;
+ }
+
+ if (qsbAngler.TargetTransform == null)
+ {
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+ }
+
+ var num = Time.time - __instance._consumeStartTime;
+ if (qsbAngler.TargetTransform.CompareTag("Player") && num > (double)__instance._consumeDeathDelay)
+ {
+ qsbAngler.TargetTransform = null;
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ __instance.ApplyDrag(1f);
+
+ Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
+ __instance._consumeComplete = true;
+ break;
+ }
+
+ if (!qsbAngler.TargetTransform.CompareTag("Ship"))
+ {
+ break;
+ }
+
+ if (num > (double)__instance._consumeShipCrushDelay)
+ {
+ qsbAngler.TargetTransform.GetComponentInChildren().TriggerSystemFailure();
+ }
+
+ if (num <= (double)__instance._consumeDeathDelay)
+ {
+ break;
+ }
+
+ if (PlayerState.IsInsideShip())
+ {
+ qsbAngler.TargetTransform = null;
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ __instance.ApplyDrag(1f);
+
+ Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
+ }
+
+ __instance._consumeComplete = true;
+ break;
+
+ case AnglerfishController.AnglerState.Stunned:
+ __instance._stunTimer -= Time.deltaTime;
+ if (__instance._stunTimer > 0.0)
+ {
+ break;
+ }
+
+ if (qsbAngler.TargetTransform != null)
+ {
+ __instance.ChangeState(AnglerfishController.AnglerState.Chasing);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+ }
+
+ __instance.ChangeState(AnglerfishController.AnglerState.Lurking);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ break;
+ }
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateMovement))]
+ public static bool UpdateMovement(AnglerfishController __instance)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ qsbAngler.FixedUpdate();
+
+ if (__instance._anglerBody.GetVelocity().sqrMagnitude > (double)Mathf.Pow(__instance._chaseSpeed * 1.5f, 2f))
+ {
+ __instance.ApplyDrag(10f);
+ }
+
+ switch (__instance._currentState)
+ {
+ case AnglerfishController.AnglerState.Lurking:
+ __instance.ApplyDrag(1f);
+ break;
+
+ case AnglerfishController.AnglerState.Investigating:
+ var targetPos = __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
+ __instance.RotateTowardsTarget(targetPos, __instance._turnSpeed, __instance._turnSpeed);
+ if (__instance._turningInPlace)
+ {
+ break;
+ }
+
+ __instance.MoveTowardsTarget(targetPos, __instance._investigateSpeed, __instance._acceleration);
+ break;
+
+ case AnglerfishController.AnglerState.Chasing:
+ var velocity = qsbAngler.TargetVelocity;
+ var normalized = velocity.normalized;
+ var from = __instance._anglerBody.GetPosition() + __instance.transform.TransformDirection(__instance._mouthOffset) - qsbAngler.TargetTransform.position;
+ var magnitude1 = velocity.magnitude;
+ var num1 = Vector3.Angle(from, normalized);
+ var a = magnitude1 * 2f;
+ var num2 = a;
+ if (num1 < 90.0)
+ {
+ var magnitude2 = (double)from.magnitude;
+ var num3 = (float)magnitude2 * Mathf.Sin(num1 * ((float)Math.PI / 180f));
+ var num4 = (float)magnitude2 * Mathf.Cos(num1 * ((float)Math.PI / 180f));
+ var magnitude3 = __instance._anglerBody.GetVelocity().magnitude;
+ var num5 = num4 / Mathf.Max(magnitude1, 0.0001f) / (num3 / Mathf.Max(magnitude3, 0.0001f));
+ if (num5 <= 1.0)
+ {
+ var t = Mathf.Clamp01(num5);
+ num2 = Mathf.Lerp(a, num4, t);
+ }
+ else
+ {
+ var num6 = Mathf.InverseLerp(1f, 4f, num5);
+ num2 = Mathf.Lerp(num4, 0.0f, num6 * num6);
+ }
+ }
+
+ __instance._targetPos = qsbAngler.TargetTransform.position + (normalized * num2);
+ __instance.RotateTowardsTarget(__instance._targetPos, __instance._turnSpeed, __instance._quickTurnSpeed);
+ if (__instance._turningInPlace)
+ {
+ break;
+ }
+
+ __instance.MoveTowardsTarget(__instance._targetPos, __instance._chaseSpeed, __instance._acceleration);
+ break;
+
+ case AnglerfishController.AnglerState.Consuming:
+ __instance.ApplyDrag(1f);
+ break;
+
+ case AnglerfishController.AnglerState.Stunned:
+ __instance.ApplyDrag(0.5f);
+ break;
+ }
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnImpact))]
+ public static bool OnImpact(AnglerfishController __instance,
+ ImpactData impact)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ var attachedOwRigidbody = impact.otherCollider.GetAttachedOWRigidbody();
+ if ((attachedOwRigidbody.CompareTag("Player") || attachedOwRigidbody.CompareTag("Ship"))
+ && __instance._currentState != AnglerfishController.AnglerState.Consuming
+ && __instance._currentState != AnglerfishController.AnglerState.Stunned)
+ {
+ qsbAngler.TargetTransform = attachedOwRigidbody.transform;
+ __instance.ChangeState(AnglerfishController.AnglerState.Chasing);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ }
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnClosestAudibleNoise))]
+ public static bool OnClosestAudibleNoise(AnglerfishController __instance,
+ NoiseMaker noiseMaker)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+ if (qsbAngler == null || qsbAngler.TransformSync == null)
+ {
+ return false;
+ }
+
+ if (__instance._currentState is AnglerfishController.AnglerState.Consuming
+ or AnglerfishController.AnglerState.Stunned)
+ {
+ return false;
+ }
+
+ if ((noiseMaker.GetNoiseOrigin() - __instance.transform.position).sqrMagnitude < __instance._pursueDistance * (double)__instance._pursueDistance)
+ {
+ if (!(qsbAngler.TargetTransform != noiseMaker.GetAttachedBody().transform))
+ {
+ return false;
+ }
+
+ qsbAngler.TargetTransform = noiseMaker.GetAttachedBody().transform;
+ if (__instance._currentState == AnglerfishController.AnglerState.Chasing)
+ {
+ return false;
+ }
+
+ __instance.ChangeState(AnglerfishController.AnglerState.Chasing);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ }
+ else
+ {
+ if (__instance._currentState is not AnglerfishController.AnglerState.Lurking
+ and not AnglerfishController.AnglerState.Investigating)
+ {
+ return false;
+ }
+
+ __instance._localDisturbancePos = __instance._brambleBody.transform.InverseTransformPoint(noiseMaker.GetNoiseOrigin());
+ if (__instance._currentState == AnglerfishController.AnglerState.Investigating)
+ {
+ return false;
+ }
+
+ __instance.ChangeState(AnglerfishController.AnglerState.Investigating);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ }
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnCaughtObject))]
+ public static bool OnCaughtObject(AnglerfishController __instance,
+ OWRigidbody caughtBody)
+ {
+ var qsbAngler = QSBWorldSync.GetWorldFromUnity(__instance);
+
+ if (__instance._currentState == AnglerfishController.AnglerState.Consuming)
+ {
+ if (qsbAngler.TargetTransform.CompareTag("Player") || !caughtBody.CompareTag("Player"))
+ {
+ return false;
+ }
+
+ Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
+ }
+ else
+ {
+ if (!caughtBody.CompareTag("Player") && !caughtBody.CompareTag("Ship"))
+ {
+ return false;
+ }
+
+ qsbAngler.TargetTransform = caughtBody.transform;
+ __instance._consumeStartTime = Time.time;
+ __instance.ChangeState(AnglerfishController.AnglerState.Consuming);
+ QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/QSB/Anglerfish/TransformSync/AnglerTransformSync.cs b/QSB/Anglerfish/TransformSync/AnglerTransformSync.cs
new file mode 100644
index 00000000..297524da
--- /dev/null
+++ b/QSB/Anglerfish/TransformSync/AnglerTransformSync.cs
@@ -0,0 +1,83 @@
+using QSB.Anglerfish.WorldObjects;
+using QSB.Syncs.Unsectored.Rigidbodies;
+using QSB.WorldSync;
+using QuantumUNET.Transport;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace QSB.Anglerfish.TransformSync
+{
+ public class AnglerTransformSync : UnsectoredRigidbodySync
+ {
+ public override bool IsReady => QSBCore.WorldObjectsReady;
+ public override bool UseInterpolation => false;
+
+ private QSBAngler _qsbAngler;
+ private static readonly List _instances = new();
+
+ protected override OWRigidbody GetRigidbody()
+ => _qsbAngler.AttachedObject._anglerBody;
+
+ public override void Start()
+ {
+ _instances.Add(this);
+ base.Start();
+ }
+
+ protected override void OnDestroy()
+ {
+ _instances.Remove(this);
+ base.OnDestroy();
+ }
+
+ public override float GetNetworkSendInterval() => 1;
+
+ protected override void Init()
+ {
+ _qsbAngler = QSBWorldSync.GetWorldFromId(_instances.IndexOf(this));
+ _qsbAngler.TransformSync = this;
+
+ base.Init();
+ SetReferenceTransform(_qsbAngler.AttachedObject._brambleBody.transform);
+ }
+
+ private bool _shouldUpdate;
+
+ public override void DeserializeTransform(QNetworkReader reader, bool initialState)
+ {
+ base.DeserializeTransform(reader, initialState);
+ _shouldUpdate = true;
+ }
+
+ protected override bool UpdateTransform()
+ {
+ if (HasAuthority)
+ {
+ return base.UpdateTransform();
+ }
+
+ if (!_shouldUpdate)
+ {
+ return false;
+ }
+
+ _shouldUpdate = false;
+ return base.UpdateTransform();
+ }
+
+ protected override void OnRenderObject()
+ {
+ base.OnRenderObject();
+
+ if (!QSBCore.WorldObjectsReady
+ || !QSBCore.ShowLinesInDebug
+ || !IsReady
+ || ReferenceTransform == null)
+ {
+ return;
+ }
+
+ Popcron.Gizmos.Line(AttachedObject.transform.position, _qsbAngler.AttachedObject.GetTargetPosition(), Color.white);
+ }
+ }
+}
diff --git a/QSB/Anglerfish/WorldObjects/QSBAngler.cs b/QSB/Anglerfish/WorldObjects/QSBAngler.cs
new file mode 100644
index 00000000..007c02c2
--- /dev/null
+++ b/QSB/Anglerfish/WorldObjects/QSBAngler.cs
@@ -0,0 +1,69 @@
+using QSB.Anglerfish.TransformSync;
+using QSB.Utility;
+using QSB.WorldSync;
+using QuantumUNET;
+using System.Linq;
+using UnityEngine;
+using Object = UnityEngine.Object;
+
+namespace QSB.Anglerfish.WorldObjects
+{
+ public class QSBAngler : WorldObject
+ {
+ public AnglerTransformSync TransformSync;
+ public Transform TargetTransform;
+ public Vector3 TargetVelocity { get; private set; }
+
+ private Vector3 _lastTargetPosition;
+
+ public override void Init(AnglerfishController attachedObject, int id)
+ {
+ ObjectId = id;
+ AttachedObject = attachedObject;
+
+ if (QSBCore.IsHost)
+ {
+ Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab).SpawnWithServerAuthority();
+ }
+ }
+
+ public override void OnRemoval()
+ {
+ if (QSBCore.IsHost)
+ {
+ QNetworkServer.Destroy(TransformSync.gameObject);
+ }
+ }
+
+ public void TransferAuthority(uint id)
+ {
+ var conn = QNetworkServer.connections.First(x => x.GetPlayerId() == id);
+ var identity = TransformSync.NetIdentity;
+
+ if (identity.ClientAuthorityOwner == conn)
+ {
+ return;
+ }
+
+ if (identity.ClientAuthorityOwner != null)
+ {
+ identity.RemoveClientAuthority(identity.ClientAuthorityOwner);
+ }
+
+ identity.AssignClientAuthority(conn);
+
+ DebugLog.DebugWrite($"angler {ObjectId} - transferred authority to {id}");
+ }
+
+ public void FixedUpdate()
+ {
+ if (TargetTransform == null)
+ {
+ return;
+ }
+
+ TargetVelocity = TargetTransform.position - _lastTargetPosition;
+ _lastTargetPosition = TargetTransform.position;
+ }
+ }
+}
diff --git a/QSB/Animation/NPC/CharacterAnimManager.cs b/QSB/Animation/NPC/CharacterAnimManager.cs
index 59a60c08..24291324 100644
--- a/QSB/Animation/NPC/CharacterAnimManager.cs
+++ b/QSB/Animation/NPC/CharacterAnimManager.cs
@@ -1,7 +1,6 @@
using QSB.Animation.NPC.WorldObjects;
using QSB.WorldSync;
using System.Linq;
-using UnityEngine;
namespace QSB.Animation.NPC
{
@@ -11,10 +10,12 @@ namespace QSB.Animation.NPC
{
QSBWorldSync.Init();
QSBWorldSync.Init();
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
//MOVE : this is the wrong place to put this... move it to Conversations?
QSBWorldSync.OldDialogueTrees.Clear();
- QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll().ToList();
+ QSBWorldSync.OldDialogueTrees = QSBWorldSync.GetUnityObjects().ToList();
}
}
}
diff --git a/QSB/Animation/NPC/Events/NpcAnimationEvent.cs b/QSB/Animation/NPC/Events/NpcAnimationEvent.cs
index 46108968..2316e2fa 100644
--- a/QSB/Animation/NPC/Events/NpcAnimationEvent.cs
+++ b/QSB/Animation/NPC/Events/NpcAnimationEvent.cs
@@ -13,7 +13,7 @@ namespace QSB.Animation.NPC.Events
private void Handler(AnimationEvent animEvent, int index) => SendEvent(CreateMessage(animEvent, index));
- private NpcAnimationMessage CreateMessage(AnimationEvent animEvent, int index) => new NpcAnimationMessage
+ private NpcAnimationMessage CreateMessage(AnimationEvent animEvent, int index) => new()
{
AboutId = LocalPlayerId,
AnimationEvent = animEvent,
diff --git a/QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs b/QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs
index fffa8883..b4427279 100644
--- a/QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs
+++ b/QSB/Animation/NPC/Patches/CharacterAnimationPatches.cs
@@ -8,7 +8,6 @@ using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using System.Linq;
-using System.Reflection;
using UnityEngine;
namespace QSB.Animation.NPC.Patches
@@ -24,7 +23,6 @@ namespace QSB.Animation.NPC.Patches
CharacterAnimController __instance,
float ___headTrackingWeight,
bool ___lookOnlyWhenTalking,
- bool ____playerInHeadZone,
bool ____inConversation,
ref float ____currentLookWeight,
ref Vector3 ____currentLookTarget,
@@ -39,7 +37,7 @@ namespace QSB.Animation.NPC.Patches
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
var player = QSBPlayerManager.GetPlayer(playerId);
- var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
PlayerInfo playerToUse = null;
if (____inConversation)
@@ -100,8 +98,8 @@ namespace QSB.Animation.NPC.Patches
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneExit))]
public static bool HeadZoneExit(CharacterAnimController __instance)
{
- var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance);
- QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance);
+ QSBEventManager.FireEvent(EventNames.QSBExitNonNomaiHeadZone, qsbObj.ObjectId);
return false;
}
@@ -109,21 +107,19 @@ namespace QSB.Animation.NPC.Patches
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneEntry))]
public static bool HeadZoneEntry(CharacterAnimController __instance)
{
- var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance);
- QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance);
+ QSBEventManager.FireEvent(EventNames.QSBEnterNonNomaiHeadZone, qsbObj.ObjectId);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(FacePlayerWhenTalking), nameof(FacePlayerWhenTalking.OnStartConversation))]
- public static bool OnStartConversation(
- FacePlayerWhenTalking __instance,
- CharacterDialogueTree ____dialogueTree)
+ public static bool OnStartConversation(FacePlayerWhenTalking __instance)
{
- var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
+ var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(__instance._dialogueTree);
if (playerId == uint.MaxValue)
{
- DebugLog.ToConsole($"Error - No player talking to {____dialogueTree.name}!", MessageType.Error);
+ DebugLog.ToConsole($"Error - No player talking to {__instance._dialogueTree.name}!", MessageType.Error);
return false;
}
@@ -134,7 +130,7 @@ namespace QSB.Animation.NPC.Patches
var angle = Vector3.Angle(__instance.transform.forward, vector2) * Mathf.Sign(Vector3.Dot(vector2, __instance.transform.right));
var axis = __instance.transform.parent.InverseTransformDirection(__instance.transform.up);
var lhs = Quaternion.AngleAxis(angle, axis);
- __instance.GetType().GetMethod("FaceLocalRotation", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { lhs * __instance.transform.localRotation });
+ __instance.FaceLocalRotation(lhs * __instance.transform.localRotation);
return false;
}
@@ -173,22 +169,18 @@ namespace QSB.Animation.NPC.Patches
[HarmonyPrefix]
[HarmonyPatch(typeof(KidRockController), nameof(KidRockController.Update))]
- public static bool UpdateReplacement(
- KidRockController __instance,
- bool ____throwingRock,
- CharacterDialogueTree ____dialogueTree,
- float ____nextThrowTime)
+ public static bool UpdateReplacement(KidRockController __instance)
{
if (!WorldObjectManager.AllReady)
{
return true;
}
- var qsbObj = QSBWorldSync.GetWorldObjects().First(x => x.GetDialogueTree() == ____dialogueTree);
+ var qsbObj = QSBWorldSync.GetWorldObjects().First(x => x.GetDialogueTree() == __instance._dialogueTree);
- if (!____throwingRock && !qsbObj.InConversation() && Time.time > ____nextThrowTime)
+ if (!__instance._throwingRock && !qsbObj.InConversation() && Time.time > __instance._nextThrowTime)
{
- __instance.GetType().GetMethod("StartRockThrow", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null);
+ __instance.StartRockThrow();
}
return false;
diff --git a/QSB/Animation/NPC/Patches/SolanumPatches.cs b/QSB/Animation/NPC/Patches/SolanumPatches.cs
new file mode 100644
index 00000000..30761ba6
--- /dev/null
+++ b/QSB/Animation/NPC/Patches/SolanumPatches.cs
@@ -0,0 +1,229 @@
+using HarmonyLib;
+using QSB.Animation.NPC.WorldObjects;
+using QSB.Events;
+using QSB.Patches;
+using QSB.Player;
+using QSB.WorldSync;
+using System.Linq;
+using UnityEngine;
+
+namespace QSB.Animation.NPC.Patches
+{
+ [HarmonyPatch]
+ public class SolanumPatches : QSBPatch
+ {
+ public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(SolanumAnimController), nameof(SolanumAnimController.LateUpdate))]
+ public static bool SolanumLateUpdateReplacement(SolanumAnimController __instance)
+ {
+ if (__instance._animatorStateEvents == null)
+ {
+ __instance._animatorStateEvents = __instance._animator.GetBehaviour();
+ __instance._animatorStateEvents.OnEnterState += __instance.OnEnterAnimatorState;
+ }
+
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance);
+ var playersInHeadZone = qsbObj.GetPlayersInHeadZone();
+
+ var targetCamera = playersInHeadZone == null || playersInHeadZone.Count == 0
+ ? __instance._playerCameraTransform
+ : QSBPlayerManager.GetClosestPlayerToWorldPoint(playersInHeadZone, __instance.transform.position).CameraBody.transform;
+
+ var targetValue = Quaternion.LookRotation(targetCamera.position - __instance._headBoneTransform.position, __instance.transform.up);
+ __instance._currentLookRotation = __instance._lookSpring.Update(__instance._currentLookRotation, targetValue, Time.deltaTime);
+
+ var position = __instance._headBoneTransform.position + (__instance._currentLookRotation * Vector3.forward);
+ __instance._localLookPosition = __instance.transform.InverseTransformPoint(position);
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnEnterWatchVolume))]
+ public static bool EnterWatchZone(NomaiConversationManager __instance)
+ {
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance._solanumAnimController);
+ QSBEventManager.FireEvent(EventNames.QSBEnterNomaiHeadZone, qsbObj.ObjectId);
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.OnExitWatchVolume))]
+ public static bool ExitWatchZone(NomaiConversationManager __instance)
+ {
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance._solanumAnimController);
+ QSBEventManager.FireEvent(EventNames.QSBExitNomaiHeadZone, qsbObj.ObjectId);
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(NomaiConversationManager), nameof(NomaiConversationManager.Update))]
+ public static bool ReplacementUpdate(NomaiConversationManager __instance)
+ {
+ var qsbObj = QSBWorldSync.GetWorldFromUnity(__instance._solanumAnimController);
+ __instance._playerInWatchVolume = qsbObj.GetPlayersInHeadZone().Any();
+
+ if (!__instance._initialized)
+ {
+ __instance.InitializeNomaiText();
+ }
+
+ //var heldItem = Locator.GetToolModeSwapper().GetItemCarryTool().GetHeldItem();
+ //var holdingConversationStone = heldItem != null && heldItem is NomaiConversationStone;
+ var holdingConversationStone = QSBPlayerManager.GetPlayerCarryItems().Any(x => x.Item2 != null && x.Item2.GetItemType() == ItemType.ConversationStone);
+
+ switch (__instance._state)
+ {
+ case NomaiConversationManager.State.WatchingSky:
+ if (__instance._playerInWatchVolume)
+ {
+ __instance._state = NomaiConversationManager.State.WatchingPlayer;
+ __instance._solanumAnimController.StartWatchingPlayer();
+ }
+
+ break;
+
+ case NomaiConversationManager.State.WatchingPlayer:
+ if (!__instance._solanumAnimController.isPerformingAction)
+ {
+ // player left watch zone
+ if (!__instance._playerInWatchVolume)
+ {
+ __instance._state = NomaiConversationManager.State.WatchingSky;
+ __instance._solanumAnimController.StopWatchingPlayer();
+ }
+ else if (__instance._dialogueComplete)
+ {
+ // create conversation stones
+ if (__instance._dialogueComplete && !__instance._conversationStonesCreated)
+ {
+ __instance._stoneCreationTimer -= Time.deltaTime;
+ if (__instance._stoneCreationTimer <= 0f)
+ {
+ __instance._state = NomaiConversationManager.State.CreatingStones;
+ __instance._solanumAnimController.PlayCreateWordStones();
+ }
+ }
+ else if (__instance._conversationStonesCreated && !__instance._cairnRaised)
+ {
+ if (!holdingConversationStone)
+ {
+ __instance._stoneGestureTimer -= Time.deltaTime;
+ if (__instance._stoneGestureTimer <= 0f)
+ {
+ __instance._solanumAnimController.PlayGestureToWordStones();
+ __instance._stoneGestureTimer = UnityEngine.Random.Range(8f, 16f);
+ }
+ }
+ // raise cairns
+ else if (__instance._solanumAnimController.IsPlayerLooking())
+ {
+ __instance._state = NomaiConversationManager.State.RaisingCairns;
+ __instance._solanumAnimController.PlayRaiseCairns();
+ __instance._cairnAnimator.SetTrigger("Raise");
+ __instance._cairnCollision.SetActivation(true);
+ }
+ }
+ else if (__instance._activeResponseText == null && __instance._hasValidSocketedStonePair)
+ {
+ __instance._activeResponseText = __instance._pendingResponseText;
+ __instance._pendingResponseText = null;
+ __instance._state = NomaiConversationManager.State.WritingResponse;
+ __instance._solanumAnimController.StartWritingMessage();
+ }
+ else if (__instance._activeResponseText != null && (!__instance._hasValidSocketedStonePair || __instance._pendingResponseText != null))
+ {
+ __instance._state = NomaiConversationManager.State.ErasingResponse;
+ __instance._solanumAnimController.StartWritingMessage();
+ }
+ else if (!holdingConversationStone)
+ {
+ if (__instance._playerWasHoldingStone)
+ {
+ __instance.ResetStoneGestureTimer();
+ }
+
+ __instance._stoneGestureTimer -= Time.deltaTime;
+ if (__instance._stoneGestureTimer < 0f)
+ {
+ __instance._solanumAnimController.PlayGestureToWordStones();
+ __instance.ResetStoneGestureTimer();
+ }
+ }
+ else
+ {
+ if (!__instance._playerWasHoldingStone)
+ {
+ __instance.ResetCairnGestureTimer();
+ }
+
+ __instance._cairnGestureTimer -= Time.deltaTime;
+ if (__instance._cairnGestureTimer < 0f)
+ {
+ __instance._solanumAnimController.PlayGestureToCairns();
+ __instance.ResetCairnGestureTimer();
+ }
+ }
+ }
+ }
+
+ break;
+
+ case NomaiConversationManager.State.CreatingStones:
+ if (!__instance._solanumAnimController.isPerformingAction)
+ {
+ __instance._state = NomaiConversationManager.State.WatchingPlayer;
+ __instance._conversationStonesCreated = true;
+ }
+
+ break;
+
+ case NomaiConversationManager.State.RaisingCairns:
+ if (!__instance._solanumAnimController.isPerformingAction)
+ {
+ __instance._state = NomaiConversationManager.State.WatchingPlayer;
+ __instance._cairnRaised = true;
+ __instance._stoneSocketATrigger.SetActivation(true);
+ __instance._stoneSocketBTrigger.SetActivation(true);
+ }
+
+ break;
+
+ case NomaiConversationManager.State.ErasingResponse:
+ if (!__instance._solanumAnimController.isStartingWrite && !__instance._activeResponseText.IsAnimationPlaying())
+ {
+ __instance._activeResponseText = null;
+ if (__instance._pendingResponseText == null)
+ {
+ __instance._state = NomaiConversationManager.State.WatchingPlayer;
+ __instance._solanumAnimController.StopWritingMessage(false);
+ }
+ else
+ {
+ __instance._activeResponseText = __instance._pendingResponseText;
+ __instance._pendingResponseText = null;
+ __instance._state = NomaiConversationManager.State.WritingResponse;
+ __instance._activeResponseText.Show();
+ }
+ }
+
+ break;
+
+ case NomaiConversationManager.State.WritingResponse:
+ if (!__instance._solanumAnimController.isStartingWrite && !__instance._activeResponseText.IsAnimationPlaying())
+ {
+ __instance._state = NomaiConversationManager.State.WatchingPlayer;
+ __instance._solanumAnimController.StopWritingMessage(true);
+ }
+
+ break;
+ }
+
+ __instance._playerWasHoldingStone = holdingConversationStone;
+
+ return false;
+ }
+ }
+}
diff --git a/QSB/Animation/NPC/Patches/TravelerControllerPatches.cs b/QSB/Animation/NPC/Patches/TravelerControllerPatches.cs
new file mode 100644
index 00000000..04a9fe85
--- /dev/null
+++ b/QSB/Animation/NPC/Patches/TravelerControllerPatches.cs
@@ -0,0 +1,164 @@
+using HarmonyLib;
+using QSB.Patches;
+using System;
+using System.Linq;
+using UnityEngine;
+
+namespace QSB.Animation.NPC.Patches
+{
+ [HarmonyPatch(typeof(TravelerController))]
+ public class TravelerControllerPatches : QSBPatch
+ {
+ public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
+
+ [HarmonyPrefix]
+ [HarmonyPatch(nameof(TravelerController.OnStartConversation))]
+ public static bool OnStartConversation(TravelerController __instance)
+ {
+ __instance._talking = true;
+
+ if (__instance is GabbroTravelerController gabbro)
+ {
+ if (gabbro._animator.enabled)
+ {
+ gabbro._animator.CrossFadeInFixedTime("Gabbro_Talking", 1.8f);
+ gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Talking", 1.8f);
+ }
+
+ Locator.GetTravelerAudioManager().StopTravelerAudio(gabbro.name);
+ }
+ else
+ {
+ if (__instance._animator != null && __instance._animator.enabled)
+ {
+ __instance._playingAnimID = __instance._animator.IsInTransition(0)
+ ? __instance._animator.GetNextAnimatorStateInfo(0).fullPathHash
+ : __instance._animator.GetCurrentAnimatorStateInfo(0).fullPathHash;
+
+ __instance._animator.SetTrigger("Talking");
+ }
+
+ Locator.GetTravelerAudioManager().StopTravelerAudio(__instance.name);
+
+ if (__instance is ChertTravelerController chert)
+ {
+ chert._moodWeight = (float)chert._mood;
+ }
+ }
+
+ return false;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(nameof(TravelerController.OnEndConversation))]
+ public static bool OnEndConversation(TravelerController __instance)
+ {
+ if (__instance is GabbroTravelerController gabbro)
+ {
+ if (gabbro._animator.enabled)
+ {
+ gabbro._animator.CrossFadeInFixedTime("Gabbro_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
+ gabbro._hammockAnimator.CrossFadeInFixedTime("GabbroHammock_Playing", gabbro._delayToRestartAudio, -1, -gabbro._delayToRestartAudio);
+ }
+
+ Locator.GetTravelerAudioManager().PlayTravelerAudio(gabbro.name, gabbro._delayToRestartAudio);
+ if (DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_REMINDER") || DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION"))
+ {
+ var conditionState = DialogueConditionManager.SharedInstance.GetConditionState("MAP_PROMPT_ATTENTION");
+ DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_REMINDER");
+ DialogueConditionManager.SharedInstance.SetConditionState("MAP_PROMPT_ATTENTION");
+ GlobalMessenger.FireEvent("TriggerMapPromptReminder", conditionState);
+ }
+ }
+ else
+ {
+ if (__instance._animator != null && __instance._animator.enabled)
+ {
+ if (__instance._delayToRestartAudio > 0f)
+ {
+ __instance._animator.CrossFadeInFixedTime(__instance._playingAnimID, __instance._delayToRestartAudio, -1, -__instance._delayToRestartAudio);
+ }
+ else
+ {
+ __instance._animator.SetTrigger("Playing");
+ }
+ }
+
+ Locator.GetTravelerAudioManager().PlayTravelerAudio(__instance.name, __instance._delayToRestartAudio);
+ }
+
+ __instance._talking = false;
+
+ return false;
+ }
+ }
+
+ internal static class TravelerAudioManagerExtensions
+ {
+ /// bad, but works great
+ private static SignalName TravelerToSignal(string name)
+ {
+ if (name.Contains("Esker"))
+ {
+ return SignalName.Traveler_Esker;
+ }
+
+ if (name.Contains("Chert"))
+ {
+ return SignalName.Traveler_Chert;
+ }
+
+ if (name.Contains("Riebeck"))
+ {
+ return SignalName.Traveler_Riebeck;
+ }
+
+ if (name.Contains("Gabbro"))
+ {
+ return SignalName.Traveler_Gabbro;
+ }
+
+ if (name.Contains("Feldspar"))
+ {
+ return SignalName.Traveler_Feldspar;
+ }
+
+ if (name.Contains("Nomai"))
+ {
+ return SignalName.Traveler_Nomai;
+ }
+
+ if (name.Contains("Prisoner"))
+ {
+ return SignalName.Traveler_Prisoner;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(name), name, null);
+ }
+
+ internal static void StopTravelerAudio(this TravelerAudioManager manager, string name)
+ {
+ var signalName = TravelerToSignal(name);
+ var audioSignal = manager._signals.First(x => x.GetName() == signalName);
+
+ audioSignal.GetOWAudioSource().FadeOut(0.5f);
+ }
+
+ internal static void PlayTravelerAudio(this TravelerAudioManager manager, string name, float audioDelay)
+ {
+ var signalName = TravelerToSignal(name);
+ var audioSignal = manager._signals.First(x => x.GetName() == signalName);
+
+ manager._playAfterDelay = false;
+ manager._playAudioTime = Time.time + audioDelay;
+ QSBCore.UnityEvents.RunWhen(() => Time.time >= manager._playAudioTime, () =>
+ {
+ if (!audioSignal.IsOnlyAudibleToScope() || audioSignal.GetOWAudioSource().isPlaying)
+ {
+ audioSignal.GetOWAudioSource().FadeIn(0.5f);
+ audioSignal.GetOWAudioSource().timeSamples = 0;
+ }
+ });
+ }
+ }
+}
diff --git a/QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs b/QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs
index 56f4b6bd..9144e966 100644
--- a/QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs
+++ b/QSB/Animation/NPC/WorldObjects/QSBCharacterAnimController.cs
@@ -1,12 +1,11 @@
-using OWML.Utils;
-using QSB.Player;
+using QSB.Player;
using System.Collections.Generic;
namespace QSB.Animation.NPC.WorldObjects
{
internal class QSBCharacterAnimController : NpcAnimController
{
- private readonly List _playersInHeadZone = new List();
+ private readonly List _playersInHeadZone = new();
public List GetPlayersInHeadZone()
=> _playersInHeadZone;
@@ -32,9 +31,9 @@ namespace QSB.Animation.NPC.WorldObjects
}
public override CharacterDialogueTree GetDialogueTree()
- => AttachedObject.GetValue("_dialogueTree");
+ => AttachedObject._dialogueTree;
public override bool InConversation()
- => AttachedObject.GetValue("_inConversation");
+ => AttachedObject._inConversation;
}
}
diff --git a/QSB/Animation/NPC/WorldObjects/QSBSolanumAnimController.cs b/QSB/Animation/NPC/WorldObjects/QSBSolanumAnimController.cs
new file mode 100644
index 00000000..3505f973
--- /dev/null
+++ b/QSB/Animation/NPC/WorldObjects/QSBSolanumAnimController.cs
@@ -0,0 +1,40 @@
+using QSB.Player;
+using QSB.WorldSync;
+using System.Collections.Generic;
+
+namespace QSB.Animation.NPC.WorldObjects
+{
+ internal class QSBSolanumAnimController : WorldObject
+ {
+ private readonly List _playersInHeadZone = new();
+
+ public override void Init(SolanumAnimController controller, int id)
+ {
+ ObjectId = id;
+ AttachedObject = controller;
+ }
+
+ public List GetPlayersInHeadZone()
+ => _playersInHeadZone;
+
+ public void AddPlayerToHeadZone(PlayerInfo player)
+ {
+ if (_playersInHeadZone.Contains(player))
+ {
+ return;
+ }
+
+ _playersInHeadZone.Add(player);
+ }
+
+ public void RemovePlayerFromHeadZone(PlayerInfo player)
+ {
+ if (!_playersInHeadZone.Contains(player))
+ {
+ return;
+ }
+
+ _playersInHeadZone.Remove(player);
+ }
+ }
+}
diff --git a/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs b/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs
new file mode 100644
index 00000000..945fbc6b
--- /dev/null
+++ b/QSB/Animation/NPC/WorldObjects/QSBSolanumController.cs
@@ -0,0 +1,11 @@
+namespace QSB.Animation.NPC.WorldObjects
+{
+ internal class QSBSolanumController : NpcAnimController
+ {
+ public override CharacterDialogueTree GetDialogueTree()
+ => AttachedObject._characterDialogueTree;
+
+ public override bool InConversation()
+ => AttachedObject._solanumAnimController._animator.GetBool("ListeningToPlayer");
+ }
+}
diff --git a/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs b/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs
index 7c8927e7..52700584 100644
--- a/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs
+++ b/QSB/Animation/NPC/WorldObjects/QSBTravelerController.cs
@@ -1,13 +1,11 @@
-using OWML.Utils;
-
-namespace QSB.Animation.NPC.WorldObjects
+namespace QSB.Animation.NPC.WorldObjects
{
internal class QSBTravelerController : NpcAnimController
{
public override CharacterDialogueTree GetDialogueTree()
- => AttachedObject.GetValue("_dialogueSystem");
+ => AttachedObject._dialogueSystem;
public override bool InConversation()
- => AttachedObject.GetValue("_talking");
+ => AttachedObject._talking;
}
}
diff --git a/QSB/Animation/Player/AnimationSync.cs b/QSB/Animation/Player/AnimationSync.cs
index 53204e38..d6ef7908 100644
--- a/QSB/Animation/Player/AnimationSync.cs
+++ b/QSB/Animation/Player/AnimationSync.cs
@@ -155,7 +155,7 @@ namespace QSB.Animation.Player
public void SetSuitState(bool state)
{
- if (!Player.PlayerStates.IsReady)
+ if (!Player.IsReady)
{
return;
}
@@ -225,7 +225,7 @@ namespace QSB.Animation.Player
InvisibleAnimator.runtimeAnimatorController = controller;
VisibleAnimator.runtimeAnimatorController = controller;
- if (type != AnimationType.PlayerSuited && type != AnimationType.PlayerUnsuited)
+ if (type is not AnimationType.PlayerSuited and not AnimationType.PlayerUnsuited)
{
VisibleAnimator.SetTrigger("Playing");
InvisibleAnimator.SetTrigger("Playing");
diff --git a/QSB/Animation/Player/AnimatorMirror.cs b/QSB/Animation/Player/AnimatorMirror.cs
index 08299aa3..b324413b 100644
--- a/QSB/Animation/Player/AnimatorMirror.cs
+++ b/QSB/Animation/Player/AnimatorMirror.cs
@@ -13,7 +13,7 @@ namespace QSB.Animation.Player
private Animator _from;
private Animator _to;
- private readonly Dictionary _floatParams = new Dictionary();
+ private readonly Dictionary _floatParams = new();
public void Init(Animator from, Animator to)
{
diff --git a/QSB/Animation/Player/CrouchSync.cs b/QSB/Animation/Player/CrouchSync.cs
index 9cf9cb66..dabcf039 100644
--- a/QSB/Animation/Player/CrouchSync.cs
+++ b/QSB/Animation/Player/CrouchSync.cs
@@ -1,4 +1,6 @@
-using QuantumUNET;
+using QSB.Utility;
+using QSB.Utility.VariableSync;
+using QuantumUNET;
using UnityEngine;
using UnityEngine.Networking;
@@ -14,13 +16,15 @@ namespace QSB.Animation.Player
private PlayerCharacterController _playerController;
private Animator _bodyAnim;
- [SyncVar]
- private float _crouchValue;
+ public FloatVariableSyncer CrouchVariableSyncer;
+ public float CrouchValue = 0f;
public void Init(PlayerCharacterController playerController, Animator bodyAnim)
{
_playerController = playerController;
_bodyAnim = bodyAnim;
+
+ CrouchVariableSyncer.Init(() => CrouchValue, val => CrouchValue = val);
}
public void Update()
@@ -42,7 +46,7 @@ namespace QSB.Animation.Player
}
var jumpChargeFraction = _playerController.GetJumpCrouchFraction();
- _crouchValue = jumpChargeFraction;
+ CrouchVariableSyncer.ValueToSync.Value = jumpChargeFraction;
}
private void SyncRemoteCrouch()
@@ -52,7 +56,7 @@ namespace QSB.Animation.Player
return;
}
- CrouchParam.Target = _crouchValue;
+ CrouchParam.Target = CrouchValue;
CrouchParam.Smooth(CrouchSmoothTime);
var jumpChargeFraction = CrouchParam.Current;
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
diff --git a/QSB/Animation/Player/Events/AnimationTriggerEvent.cs b/QSB/Animation/Player/Events/AnimationTriggerEvent.cs
index 4a99cd32..8a6709bf 100644
--- a/QSB/Animation/Player/Events/AnimationTriggerEvent.cs
+++ b/QSB/Animation/Player/Events/AnimationTriggerEvent.cs
@@ -12,7 +12,7 @@ namespace QSB.Animation.Player.Events
private void Handler(uint attachedNetId, string name) => SendEvent(CreateMessage(attachedNetId, name));
- private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new AnimationTriggerMessage
+ private AnimationTriggerMessage CreateMessage(uint attachedNetId, string name) => new()
{
AboutId = LocalPlayerId,
AttachedNetId = attachedNetId,
@@ -22,7 +22,7 @@ namespace QSB.Animation.Player.Events
public override void OnReceiveRemote(bool server, AnimationTriggerMessage message)
{
var animationSync = QSBPlayerManager.GetSyncObject(message.AttachedNetId);
- if (!QSBCore.WorldObjectsReady || animationSync != null)
+ if (!QSBCore.WorldObjectsReady || animationSync == null)
{
return;
}
diff --git a/QSB/Animation/Player/Events/ChangeAnimTypeEvent.cs b/QSB/Animation/Player/Events/ChangeAnimTypeEvent.cs
index d7ec029d..56709c2a 100644
--- a/QSB/Animation/Player/Events/ChangeAnimTypeEvent.cs
+++ b/QSB/Animation/Player/Events/ChangeAnimTypeEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.Animation.Player.Events
private void Handler(uint player, AnimationType type) => SendEvent(CreateMessage(player, type));
- private EnumMessage CreateMessage(uint player, AnimationType type) => new EnumMessage
+ private EnumMessage CreateMessage(uint player, AnimationType type) => new()
{
AboutId = player,
EnumValue = type
@@ -22,7 +22,7 @@ namespace QSB.Animation.Player.Events
public override void OnReceiveRemote(bool server, EnumMessage message)
{
- if (!QSBCore.WorldObjectsReady || !QSBPlayerManager.GetPlayer(message.AboutId).PlayerStates.IsReady)
+ if (!QSBCore.WorldObjectsReady || !QSBPlayerManager.GetPlayer(message.AboutId).IsReady)
{
return;
}
diff --git a/QSB/Animation/Player/Events/PlayerSuitEvent.cs b/QSB/Animation/Player/Events/PlayerSuitEvent.cs
index 87f2dd1f..29e5ce95 100644
--- a/QSB/Animation/Player/Events/PlayerSuitEvent.cs
+++ b/QSB/Animation/Player/Events/PlayerSuitEvent.cs
@@ -23,7 +23,7 @@ namespace QSB.Animation.Player.Events
private void HandleSuitUp() => SendEvent(CreateMessage(true));
private void HandleSuitDown() => SendEvent(CreateMessage(false));
- private ToggleMessage CreateMessage(bool value) => new ToggleMessage
+ private ToggleMessage CreateMessage(bool value) => new()
{
AboutId = LocalPlayerId,
ToggleValue = value
@@ -32,9 +32,9 @@ namespace QSB.Animation.Player.Events
public override void OnReceiveRemote(bool server, ToggleMessage message)
{
var player = QSBPlayerManager.GetPlayer(message.AboutId);
- player.PlayerStates.SuitedUp = message.ToggleValue;
+ player.SuitedUp = message.ToggleValue;
- if (!QSBCore.WorldObjectsReady || !player.PlayerStates.IsReady)
+ if (!QSBCore.WorldObjectsReady || !player.IsReady)
{
return;
}
@@ -46,7 +46,7 @@ namespace QSB.Animation.Player.Events
public override void OnReceiveLocal(bool server, ToggleMessage message)
{
- QSBPlayerManager.LocalPlayer.PlayerStates.SuitedUp = message.ToggleValue;
+ QSBPlayerManager.LocalPlayer.SuitedUp = message.ToggleValue;
var animator = QSBPlayerManager.LocalPlayer.AnimationSync;
var type = message.ToggleValue ? AnimationType.PlayerSuited : AnimationType.PlayerUnsuited;
animator.CurrentType = type;
diff --git a/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs b/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs
index 94b3d5b4..d15be2c0 100644
--- a/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs
+++ b/QSB/Animation/Player/Thrusters/JetpackAccelerationSync.cs
@@ -1,23 +1,27 @@
-using QuantumUNET;
+using QSB.Utility.VariableSync;
+using QuantumUNET;
using UnityEngine;
-using UnityEngine.Networking;
namespace QSB.Animation.Player.Thrusters
{
public class JetpackAccelerationSync : QNetworkBehaviour
{
- [SyncVar]
- private Vector3 _localAcceleration;
- [SyncVar]
- private bool _isThrusting;
+ public Vector3VariableSyncer AccelerationVariableSyncer;
+ public BoolVariableSyncer ThrustingVariableSyncer;
+ public Vector3 LocalAcceleration => AccelerationVariableSyncer.ValueToSync.Value;
+ public bool IsThrusting => ThrustingVariableSyncer.ValueToSync.Value;
+ private Vector3 _localAcceleration;
+ private bool _isThrusting;
private ThrusterModel _thrusterModel;
- public Vector3 LocalAcceleration => _localAcceleration;
- public bool IsThrusting => _isThrusting;
-
public void Init(ThrusterModel model)
- => _thrusterModel = model;
+ {
+ _thrusterModel = model;
+
+ AccelerationVariableSyncer.Init(() => _localAcceleration, val => _localAcceleration = val);
+ ThrustingVariableSyncer.Init(() => _isThrusting, val => _isThrusting = val);
+ }
public void Update()
{
@@ -31,8 +35,8 @@ namespace QSB.Animation.Player.Thrusters
{
if (_thrusterModel != null)
{
- _localAcceleration = _thrusterModel.GetLocalAcceleration();
- _isThrusting = _thrusterModel.IsTranslationalThrusterFiring();
+ AccelerationVariableSyncer.ValueToSync.Value = _thrusterModel.GetLocalAcceleration();
+ ThrustingVariableSyncer.ValueToSync.Value = _thrusterModel.IsTranslationalThrusterFiring();
}
}
}
diff --git a/QSB/Animation/Player/Thrusters/RemoteThrusterFlameController.cs b/QSB/Animation/Player/Thrusters/RemoteThrusterFlameController.cs
index cd51091e..956373f3 100644
--- a/QSB/Animation/Player/Thrusters/RemoteThrusterFlameController.cs
+++ b/QSB/Animation/Player/Thrusters/RemoteThrusterFlameController.cs
@@ -8,7 +8,7 @@ namespace QSB.Animation.Player.Thrusters
private Thruster _thruster;
private Light _light;
private AnimationCurve _scaleByThrust = AnimationCurve.Linear(0f, 0f, 1f, 1f);
- private DampedSpring _scaleSpring = new DampedSpring();
+ private DampedSpring _scaleSpring = new();
private float _belowMaxThrustScalar = 1f;
private MeshRenderer _thrusterRenderer;
private Vector3 _thrusterFilter;
@@ -82,5 +82,16 @@ namespace QSB.Animation.Player.Thrusters
}
private float GetThrustFraction() => Vector3.Dot(_attachedPlayer.JetpackAcceleration.LocalAcceleration, _thrusterFilter);
+
+ private void OnRenderObject()
+ {
+ if (!QSBCore.WorldObjectsReady || !QSBCore.ShowLinesInDebug)
+ {
+ return;
+ }
+
+ Popcron.Gizmos.Sphere(_light.transform.position, 0.05f, Color.yellow, 4);
+ Popcron.Gizmos.Line(_light.transform.position, _light.transform.parent.position, Color.yellow);
+ }
}
}
diff --git a/QSB/Animation/Player/Thrusters/ThrusterManager.cs b/QSB/Animation/Player/Thrusters/ThrusterManager.cs
index 65c4fe78..e8870a03 100644
--- a/QSB/Animation/Player/Thrusters/ThrusterManager.cs
+++ b/QSB/Animation/Player/Thrusters/ThrusterManager.cs
@@ -47,10 +47,18 @@ namespace QSB.Animation.Player.Thrusters
var gameObject = controller.gameObject;
var oldThruster = controller.GetValue("_thruster");
var oldLight = controller.GetValue("_light");
+ var localPos = oldThruster switch
+ {
+ Thruster.Up_RightThruster or Thruster.Up_LeftThruster => new Vector3(0, 0, 3),
+ Thruster.Down_RightThruster or Thruster.Down_LeftThruster => new Vector3(0, 0, 7),
+ _ => new Vector3(0, 0, 5),
+ };
+ oldLight.transform.localPosition = localPos;
+
var oldAnimCurve = controller.GetValue("_scaleByThrust");
var oldScaleSpring = controller.GetValue("_scaleSpring");
var oldScalar = controller.GetValue("_belowMaxThrustScalar");
- var oldBase = controller.GetValue("_baseLightRadius");
+ var oldBase = oldLight.range;
Object.Destroy(controller);
var newObj = gameObject.AddComponent();
newObj.InitFromOld(oldThruster, oldLight, oldAnimCurve, oldScaleSpring, oldScalar, oldBase, player);
diff --git a/QSB/AssetBundles/conversation b/QSB/AssetBundles/conversation
new file mode 100644
index 00000000..dc830635
Binary files /dev/null and b/QSB/AssetBundles/conversation differ
diff --git a/AssetBundles/conversation.manifest b/QSB/AssetBundles/conversation.manifest
similarity index 75%
rename from AssetBundles/conversation.manifest
rename to QSB/AssetBundles/conversation.manifest
index 40c3a960..5f486847 100644
--- a/AssetBundles/conversation.manifest
+++ b/QSB/AssetBundles/conversation.manifest
@@ -1,12 +1,12 @@
ManifestFileVersion: 0
-CRC: 3328595786
+CRC: 2681871399
Hashes:
AssetFileHash:
serializedVersion: 2
- Hash: b1b55f9f86f72ed72608b36f0729af6d
+ Hash: d9191ca383ce2fbef699ba7106af389e
TypeTreeHash:
serializedVersion: 2
- Hash: 50a27bfc3e679077929938a6fa57f4db
+ Hash: a0ed95779b7375b06978e51f19fbfba7
HashAppended: 0
ClassTypes:
- Class: 1
@@ -25,6 +25,10 @@ ClassTypes:
Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
- Class: 114
Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
+- Class: 114
+ Script: {fileID: 1015169618, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 602583937, guid: 27687deae413b90448366870cb0de502, type: 3}
- Class: 115
Script: {instanceID: 0}
- Class: 128
@@ -39,6 +43,6 @@ ClassTypes:
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
-- Assets/DialogueBubble.prefab
+- Assets/Prefabs/DialogueBubble.prefab
- Assets/GameAssets/Texture2D/UI_DialogueBox_d.png
Dependencies: []
diff --git a/QSB/AssetBundles/debug b/QSB/AssetBundles/debug
new file mode 100644
index 00000000..77921aed
Binary files /dev/null and b/QSB/AssetBundles/debug differ
diff --git a/QSB/AssetBundles/debug.manifest b/QSB/AssetBundles/debug.manifest
new file mode 100644
index 00000000..dafb9acb
--- /dev/null
+++ b/QSB/AssetBundles/debug.manifest
@@ -0,0 +1,32 @@
+ManifestFileVersion: 0
+CRC: 1531115438
+Hashes:
+ AssetFileHash:
+ serializedVersion: 2
+ Hash: 289361968514e20b1d351d2d2fda5b6e
+ 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: []
diff --git a/QSB/AssetBundles/instruments b/QSB/AssetBundles/instruments
new file mode 100644
index 00000000..14517dd5
Binary files /dev/null and b/QSB/AssetBundles/instruments differ
diff --git a/QSB/AssetBundles/instruments.manifest b/QSB/AssetBundles/instruments.manifest
new file mode 100644
index 00000000..10973aa7
--- /dev/null
+++ b/QSB/AssetBundles/instruments.manifest
@@ -0,0 +1,68 @@
+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: []
diff --git a/QSB/AssetBundles/network b/QSB/AssetBundles/network
new file mode 100644
index 00000000..8de1b060
Binary files /dev/null and b/QSB/AssetBundles/network differ
diff --git a/QSB/AssetBundles/network.manifest b/QSB/AssetBundles/network.manifest
new file mode 100644
index 00000000..2b01cb6a
--- /dev/null
+++ b/QSB/AssetBundles/network.manifest
@@ -0,0 +1,55 @@
+ManifestFileVersion: 0
+CRC: 1923832523
+Hashes:
+ AssetFileHash:
+ serializedVersion: 2
+ Hash: 4fc717bd6085672c7fc1dafa5359e292
+ TypeTreeHash:
+ serializedVersion: 2
+ Hash: 9036f53e57d0e71c74f56622ad045de9
+HashAppended: 0
+ClassTypes:
+- Class: 1
+ Script: {instanceID: 0}
+- Class: 4
+ Script: {instanceID: 0}
+- Class: 114
+ Script: {fileID: -1208705890, guid: 8929207a0d76fd54a8a2a820c652720f, type: 3}
+- Class: 114
+ Script: {fileID: 1142416158, guid: 8929207a0d76fd54a8a2a820c652720f, type: 3}
+- Class: 114
+ Script: {fileID: 519208029, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -790547616, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 916105004, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -1309757293, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 78926581, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -1381557116, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -1937550126, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -749020886, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -2281650, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 2036222940, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: -1164351254, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 806682216, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 114
+ Script: {fileID: 677635994, guid: 27687deae413b90448366870cb0de502, type: 3}
+- Class: 115
+ Script: {instanceID: 0}
+SerializeReferenceClassIdentifiers: []
+Assets:
+- Assets/Prefabs/NetworkProbe.prefab
+- Assets/Prefabs/NETWORK_Player_Body.prefab
+- Assets/Prefabs/NetworkOrb.prefab
+- Assets/Prefabs/NetworkAngler.prefab
+- Assets/Prefabs/NetworkShip.prefab
+Dependencies: []
diff --git a/QSB/CampfireSync/Events/CampfireStateEvent.cs b/QSB/CampfireSync/Events/CampfireStateEvent.cs
index e0bc3df8..1bfb13fa 100644
--- a/QSB/CampfireSync/Events/CampfireStateEvent.cs
+++ b/QSB/CampfireSync/Events/CampfireStateEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.CampfireSync.Events
private void Handler(int objId, Campfire.State state) => SendEvent(CreateMessage(objId, state));
- private EnumWorldObjectMessage CreateMessage(int objId, Campfire.State state) => new EnumWorldObjectMessage
+ private EnumWorldObjectMessage CreateMessage(int objId, Campfire.State state) => new()
{
AboutId = LocalPlayerId,
ObjectId = objId,
diff --git a/QSB/CampfireSync/Patches/CampfirePatches.cs b/QSB/CampfireSync/Patches/CampfirePatches.cs
index 5dc7f0e0..3a0c8bc7 100644
--- a/QSB/CampfireSync/Patches/CampfirePatches.cs
+++ b/QSB/CampfireSync/Patches/CampfirePatches.cs
@@ -15,7 +15,7 @@ namespace QSB.CampfireSync.Patches
[HarmonyPatch(typeof(Campfire), nameof(Campfire.OnPressInteract))]
public static bool LightCampfireEvent(Campfire __instance)
{
- var qsbCampfire = QSBWorldSync.GetWorldFromUnity(__instance);
+ var qsbCampfire = QSBWorldSync.GetWorldFromUnity(__instance);
if (__instance._state == Campfire.State.LIT)
{
qsbCampfire.StartRoasting();
diff --git a/QSB/ClientServerStateSync/ClientStateManager.cs b/QSB/ClientServerStateSync/ClientStateManager.cs
index 2e1d1d11..c9b88e7e 100644
--- a/QSB/ClientServerStateSync/ClientStateManager.cs
+++ b/QSB/ClientServerStateSync/ClientStateManager.cs
@@ -29,7 +29,6 @@ namespace QSB.ClientServerStateSync
return;
}
- DebugLog.DebugWrite($"CHANGE CLIENT STATE FROM {QSBPlayerManager.LocalPlayer.State} to {newState}");
QSBPlayerManager.LocalPlayer.State = newState;
OnChangeState?.Invoke(newState);
}
@@ -46,31 +45,30 @@ namespace QSB.ClientServerStateSync
switch (newScene)
{
case OWScene.TitleScreen:
- DebugLog.DebugWrite($"SERVER LOAD TITLESCREEN");
newState = ClientState.InTitleScreen;
break;
case OWScene.Credits_Fast:
- DebugLog.DebugWrite($"SERVER LOAD SHORT CREDITS");
newState = ClientState.WatchingShortCredits;
break;
case OWScene.Credits_Final:
case OWScene.PostCreditsScene:
- DebugLog.DebugWrite($"SERVER LOAD LONG CREDITS");
newState = ClientState.WatchingLongCredits;
break;
case OWScene.SolarSystem:
if (oldScene == OWScene.SolarSystem)
{
// reloading scene
- DebugLog.DebugWrite($"SERVER RELOAD SOLARSYSTEM");
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
}
else
{
// loading in from title screen
- DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
newState = ClientState.AliveInSolarSystem;
}
+
+ break;
+ case OWScene.EyeOfTheUniverse:
+ newState = ClientState.AliveInEye;
break;
default:
newState = ClientState.NotLoaded;
@@ -82,22 +80,18 @@ namespace QSB.ClientServerStateSync
switch (newScene)
{
case OWScene.TitleScreen:
- DebugLog.DebugWrite($"CLIENT LOAD TITLESCREEN");
newState = ClientState.InTitleScreen;
break;
case OWScene.Credits_Fast:
- DebugLog.DebugWrite($"CLIENT LOAD SHORT CREDITS");
newState = ClientState.WatchingShortCredits;
break;
case OWScene.Credits_Final:
case OWScene.PostCreditsScene:
- DebugLog.DebugWrite($"CLIENT LOAD LONG CREDITS");
newState = ClientState.WatchingLongCredits;
break;
case OWScene.SolarSystem:
if (serverState == ServerState.WaitingForAllPlayersToDie)
{
- DebugLog.DebugWrite($"SEVER IN DEATH PHASE - WAIT");
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
break;
}
@@ -105,13 +99,11 @@ namespace QSB.ClientServerStateSync
if (oldScene == OWScene.SolarSystem)
{
// reloading scene
- DebugLog.DebugWrite($"CLIENT RELOAD SOLARSYSTEM");
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
}
else
{
// loading in from title screen
- DebugLog.DebugWrite($"CLIENT LOAD SOLARSYSTEM");
if (serverState == ServerState.WaitingForAllPlayersToReady)
{
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
@@ -121,6 +113,10 @@ namespace QSB.ClientServerStateSync
newState = ClientState.AliveInSolarSystem;
}
}
+
+ break;
+ case OWScene.EyeOfTheUniverse:
+ newState = ClientState.WaitingForOthersToReadyInSolarSystem;
break;
default:
newState = ClientState.NotLoaded;
@@ -165,32 +161,17 @@ namespace QSB.ClientServerStateSync
private ClientState ForceGetCurrentState()
{
- DebugLog.DebugWrite($"ForceGetCurrentState");
var currentScene = LoadManager.GetCurrentScene();
- var lastScene = LoadManager.GetPreviousScene();
- switch (currentScene)
+ return currentScene switch
{
- case OWScene.TitleScreen:
- DebugLog.DebugWrite($"- TitleScreen");
- return ClientState.InTitleScreen;
- case OWScene.Credits_Fast:
- DebugLog.DebugWrite($"- Short Credits");
- return ClientState.WatchingShortCredits;
- case OWScene.Credits_Final:
- case OWScene.PostCreditsScene:
- DebugLog.DebugWrite($"- Long Credits");
- return ClientState.WatchingLongCredits;
- case OWScene.SolarSystem:
- DebugLog.DebugWrite($"- SolarSystem");
- return ClientState.AliveInSolarSystem;
- case OWScene.EyeOfTheUniverse:
- DebugLog.DebugWrite($"- Eye");
- return ClientState.AliveInEye;
- default:
- DebugLog.DebugWrite($"- Not Loaded");
- return ClientState.NotLoaded;
- }
+ OWScene.TitleScreen => ClientState.InTitleScreen,
+ OWScene.Credits_Fast => ClientState.WatchingShortCredits,
+ OWScene.Credits_Final or OWScene.PostCreditsScene => ClientState.WatchingLongCredits,
+ OWScene.SolarSystem => ClientState.AliveInSolarSystem,
+ OWScene.EyeOfTheUniverse => ClientState.AliveInEye,
+ _ => ClientState.NotLoaded,
+ };
}
}
}
diff --git a/QSB/ClientServerStateSync/Events/ClientStateEvent.cs b/QSB/ClientServerStateSync/Events/ClientStateEvent.cs
index b664a3e1..aa3b8126 100644
--- a/QSB/ClientServerStateSync/Events/ClientStateEvent.cs
+++ b/QSB/ClientServerStateSync/Events/ClientStateEvent.cs
@@ -17,7 +17,7 @@ namespace QSB.ClientServerStateSync.Events
private void Handler(ClientState state) => SendEvent(CreateMessage(state));
- private EnumMessage CreateMessage(ClientState state) => new EnumMessage
+ private EnumMessage CreateMessage(ClientState state) => new()
{
AboutId = LocalPlayerId,
EnumValue = state
diff --git a/QSB/ClientServerStateSync/Events/ServerStateEvent.cs b/QSB/ClientServerStateSync/Events/ServerStateEvent.cs
index c0cabdef..170ea063 100644
--- a/QSB/ClientServerStateSync/Events/ServerStateEvent.cs
+++ b/QSB/ClientServerStateSync/Events/ServerStateEvent.cs
@@ -15,7 +15,7 @@ namespace QSB.ClientServerStateSync.Events
private void Handler(ServerState state) => SendEvent(CreateMessage(state));
- private EnumMessage CreateMessage(ServerState state) => new EnumMessage
+ private EnumMessage CreateMessage(ServerState state) => new()
{
AboutId = LocalPlayerId,
EnumValue = state
diff --git a/QSB/ClientServerStateSync/ServerStateManager.cs b/QSB/ClientServerStateSync/ServerStateManager.cs
index 42e93e1b..173614c3 100644
--- a/QSB/ClientServerStateSync/ServerStateManager.cs
+++ b/QSB/ClientServerStateSync/ServerStateManager.cs
@@ -54,17 +54,14 @@ namespace QSB.ClientServerStateSync
case OWScene.Credits_Fast:
case OWScene.Credits_Final:
case OWScene.PostCreditsScene:
- DebugLog.DebugWrite($"SERVER LOAD CREDITS");
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.Credits);
break;
case OWScene.TitleScreen:
- DebugLog.DebugWrite($"SERVER LOAD TITLE SCREEN");
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
break;
case OWScene.SolarSystem:
- DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
if (oldScene == OWScene.SolarSystem)
{
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
@@ -77,7 +74,6 @@ namespace QSB.ClientServerStateSync
break;
case OWScene.EyeOfTheUniverse:
- DebugLog.DebugWrite($"EYE");
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
break;
@@ -98,21 +94,15 @@ namespace QSB.ClientServerStateSync
private ServerState ForceGetCurrentState()
{
- DebugLog.DebugWrite($"ForceGetCurrentState");
-
var currentScene = LoadManager.GetCurrentScene();
- var lastScene = LoadManager.GetPreviousScene();
switch (currentScene)
{
case OWScene.SolarSystem:
- DebugLog.DebugWrite($"- SolarSystem");
return ServerState.InSolarSystem;
case OWScene.EyeOfTheUniverse:
- DebugLog.DebugWrite($"- Eye");
return ServerState.InEye;
default:
- DebugLog.DebugWrite($"- Not Loaded");
return ServerState.NotLoaded;
}
}
@@ -132,12 +122,27 @@ namespace QSB.ClientServerStateSync
if (_currentState == ServerState.WaitingForAllPlayersToReady)
{
- if (QSBPlayerManager.PlayerList.All(x => x.State == ClientState.WaitingForOthersToReadyInSolarSystem)
- || QSBPlayerManager.PlayerList.All(x => x.State == ClientState.AliveInSolarSystem))
+ if (QSBPlayerManager.PlayerList.All(x
+ => x.State is ClientState.WaitingForOthersToReadyInSolarSystem
+ or ClientState.AliveInSolarSystem
+ or ClientState.AliveInEye))
{
DebugLog.DebugWrite($"All ready!!");
QSBEventManager.FireEvent(EventNames.QSBStartLoop);
- QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
+ if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
+ {
+ QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
+ }
+ else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
+ {
+ QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InEye);
+ }
+ else
+ {
+ DebugLog.ToConsole($"Error - All players were ready in non-universe scene!?", OWML.Common.MessageType.Error);
+ QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
+ }
+
_blockNextCheck = true;
}
}
diff --git a/QSB/ConversationSync/CameraFacingBillboard.cs b/QSB/ConversationSync/CameraFacingBillboard.cs
index 74b0630c..55e3ce0d 100644
--- a/QSB/ConversationSync/CameraFacingBillboard.cs
+++ b/QSB/ConversationSync/CameraFacingBillboard.cs
@@ -22,7 +22,7 @@ public class CameraFacingBillboard : MonoBehaviour
UpdateRotation();
}
- void LateUpdate()
+ private void LateUpdate()
=> UpdateRotation();
private void UpdateRotation()
diff --git a/QSB/ConversationSync/ConversationManager.cs b/QSB/ConversationSync/ConversationManager.cs
index ba18f6c3..2304d018 100644
--- a/QSB/ConversationSync/ConversationManager.cs
+++ b/QSB/ConversationSync/ConversationManager.cs
@@ -21,7 +21,7 @@ namespace QSB.ConversationSync
{
Instance = this;
- _boxPrefab = QSBCore.ConversationAssetBundle.LoadAsset("assets/dialoguebubble.prefab");
+ _boxPrefab = QSBCore.ConversationAssetBundle.LoadAsset("assets/Prefabs/dialoguebubble.prefab");
var font = (Font)Resources.Load(@"fonts\english - latin\HVD Fonts - BrandonGrotesque-Bold_Dynamic");
if (font == null)
@@ -118,9 +118,7 @@ namespace QSB.ConversationSync
newBox.transform.SetParent(parent);
newBox.transform.localPosition = new Vector3(0, vertOffset, 0);
newBox.transform.rotation = parent.rotation;
- newBox.AddComponent();
newBox.GetComponent().text = text;
- newBox.AddComponent();
newBox.SetActive(true);
return newBox;
}
diff --git a/QSB/ConversationSync/Events/ConversationEvent.cs b/QSB/ConversationSync/Events/ConversationEvent.cs
index d60a1d76..c9073432 100644
--- a/QSB/ConversationSync/Events/ConversationEvent.cs
+++ b/QSB/ConversationSync/Events/ConversationEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.ConversationSync.Events
private void Handler(uint id, string message, ConversationType type) => SendEvent(CreateMessage(id, message, type));
- private ConversationMessage CreateMessage(uint id, string message, ConversationType type) => new ConversationMessage
+ private ConversationMessage CreateMessage(uint id, string message, ConversationType type) => new()
{
AboutId = LocalPlayerId,
ObjectId = (int)id,
diff --git a/QSB/ConversationSync/Events/ConversationStartEndEvent.cs b/QSB/ConversationSync/Events/ConversationStartEndEvent.cs
index 83fbc3c1..32dc8178 100644
--- a/QSB/ConversationSync/Events/ConversationStartEndEvent.cs
+++ b/QSB/ConversationSync/Events/ConversationStartEndEvent.cs
@@ -15,7 +15,7 @@ namespace QSB.ConversationSync.Events
private void Handler(int objId, uint playerId, bool state) => SendEvent(CreateMessage(objId, playerId, state));
- private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new ConversationStartEndMessage
+ private ConversationStartEndMessage CreateMessage(int objId, uint playerId, bool state) => new()
{
AboutId = LocalPlayerId,
TreeId = objId,
diff --git a/QSB/ConversationSync/Events/DialogueConditionEvent.cs b/QSB/ConversationSync/Events/DialogueConditionEvent.cs
index c1380ff4..c97e3cf5 100644
--- a/QSB/ConversationSync/Events/DialogueConditionEvent.cs
+++ b/QSB/ConversationSync/Events/DialogueConditionEvent.cs
@@ -12,7 +12,7 @@ namespace QSB.ConversationSync.Events
private void Handler(string name, bool state) => SendEvent(CreateMessage(name, state));
- private DialogueConditionMessage CreateMessage(string name, bool state) => new DialogueConditionMessage
+ private DialogueConditionMessage CreateMessage(string name, bool state) => new()
{
AboutId = LocalPlayerId,
ConditionName = name,
diff --git a/QSB/DeathSync/Events/EndLoopEvent.cs b/QSB/DeathSync/Events/EndLoopEvent.cs
index 0208c4ea..17af3ffb 100644
--- a/QSB/DeathSync/Events/EndLoopEvent.cs
+++ b/QSB/DeathSync/Events/EndLoopEvent.cs
@@ -1,6 +1,7 @@
using QSB.ClientServerStateSync;
using QSB.Events;
using QSB.Messaging;
+using QSB.Patches;
using QSB.Utility;
namespace QSB.DeathSync.Events
@@ -14,7 +15,7 @@ namespace QSB.DeathSync.Events
private void Handler(EndLoopReason type) => SendEvent(CreateMessage(type));
- private EnumMessage CreateMessage(EndLoopReason type) => new EnumMessage
+ private EnumMessage CreateMessage(EndLoopReason type) => new()
{
AboutId = LocalPlayerId,
EnumValue = type
@@ -29,6 +30,8 @@ namespace QSB.DeathSync.Events
switch (message.EnumValue)
{
case EndLoopReason.AllPlayersDead:
+ QSBPatchManager.DoUnpatchType(QSBPatchTypes.RespawnTime);
+
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
if (QSBCore.IsHost)
{
diff --git a/QSB/DeathSync/Events/PlayerDeathEvent.cs b/QSB/DeathSync/Events/PlayerDeathEvent.cs
index 00234ade..0cf756c4 100644
--- a/QSB/DeathSync/Events/PlayerDeathEvent.cs
+++ b/QSB/DeathSync/Events/PlayerDeathEvent.cs
@@ -1,6 +1,7 @@
using QSB.ClientServerStateSync;
using QSB.Events;
using QSB.Player;
+using QSB.RespawnSync;
using QSB.Utility;
namespace QSB.DeathSync.Events
@@ -14,7 +15,7 @@ namespace QSB.DeathSync.Events
private void Handler(DeathType type) => SendEvent(CreateMessage(type));
- private PlayerDeathMessage CreateMessage(DeathType type) => new PlayerDeathMessage
+ private PlayerDeathMessage CreateMessage(DeathType type) => new()
{
AboutId = LocalPlayerId,
EnumValue = type,
diff --git a/QSB/DeathSync/Events/StartLoopEvent.cs b/QSB/DeathSync/Events/StartLoopEvent.cs
index 243f2e8a..4911070c 100644
--- a/QSB/DeathSync/Events/StartLoopEvent.cs
+++ b/QSB/DeathSync/Events/StartLoopEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.DeathSync.Events
private void Handler() => SendEvent(CreateMessage());
- private PlayerMessage CreateMessage() => new PlayerMessage
+ private PlayerMessage CreateMessage() => new()
{
AboutId = LocalPlayerId
};
@@ -25,7 +25,19 @@ namespace QSB.DeathSync.Events
public override void OnReceiveRemote(bool server, PlayerMessage message)
{
DebugLog.DebugWrite($" ~~~ LOOP START ~~~");
- QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
+ if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
+ {
+ QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
+ }
+ else if (QSBSceneManager.CurrentScene == OWScene.EyeOfTheUniverse)
+ {
+ QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInEye);
+ }
+ else
+ {
+ DebugLog.ToConsole($"Error - Got StartLoop event when not in universe!", OWML.Common.MessageType.Error);
+ QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.NotLoaded);
+ }
}
}
}
diff --git a/QSB/DeathSync/Necronomicon.cs b/QSB/DeathSync/Necronomicon.cs
index 163d878a..3cb96b36 100644
--- a/QSB/DeathSync/Necronomicon.cs
+++ b/QSB/DeathSync/Necronomicon.cs
@@ -5,14 +5,19 @@ namespace QSB.DeathSync
{
public static class Necronomicon
{
- private static readonly Dictionary Darkhold = new Dictionary
+ private static readonly Dictionary Darkhold = new()
{
- { DeathType.Default, new[] // Running out of health
+ {
+ DeathType.Default,
+ new[] // Running out of health
{
"{0} died",
"{0} was killed"
- } },
- { DeathType.Impact, new[] // Hitting the ground/wall/object
+ }
+ },
+ {
+ DeathType.Impact,
+ new[] // Hitting the ground/wall/object
{
"{0} forgot to use retro-rockets",
"{0} bonked into the ground too hard",
@@ -22,8 +27,11 @@ namespace QSB.DeathSync
"{0} was killed",
"{0} died due to impact",
"{0} impacted the ground too hard"
- } },
- { DeathType.Asphyxiation, new[] // Running out of oxygen
+ }
+ },
+ {
+ DeathType.Asphyxiation,
+ new[] // Running out of oxygen
{
"{0} forgot to breathe",
"{0} asphyxiated",
@@ -33,14 +41,20 @@ namespace QSB.DeathSync
"{0} ran out of air",
"{0} ran out of oxygen",
"{0} didn't need air anyway"
- } },
- { DeathType.Energy, new[] // Electricity, sun, etc.
+ }
+ },
+ {
+ DeathType.Energy,
+ new[] // Electricity, sun, etc.
{
"{0} was cooked",
"{0} died",
"{0} was killed"
- } },
- { DeathType.Supernova, new[] // Supernova
+ }
+ },
+ {
+ DeathType.Supernova,
+ new[] // Supernova
{
"{0} ran out of time",
"{0} burnt up",
@@ -52,8 +66,11 @@ namespace QSB.DeathSync
"{0} became cosmic marshmallow",
"{0} photosynthesized too much",
"{0} died due to the supernova"
- } },
- { DeathType.Digestion, new[] // Anglerfish
+ }
+ },
+ {
+ DeathType.Digestion,
+ new[] // Anglerfish
{
"{0} was eaten",
"{0} found a fish",
@@ -61,14 +78,21 @@ namespace QSB.DeathSync
"{0} messed with the wrong fish",
"{0} was digested",
"{0} died due to digestion"
- } },
- { DeathType.BigBang, new[] // End of the game
+ }
+ },
{
+ DeathType.BigBang,
+ new[] // End of the game
+ {
+ // TODO : maybe don't show these?
"{0} sacrificed themself for the universe",
"{0} knows the true meaning of sacrifice",
"{0} won at the cost of their life"
- } },
- { DeathType.Crushed, new[] // Crushed in sand
+ }
+ },
+ {
+ DeathType.Crushed,
+ new[] // Crushed in sand
{
"{0} went through the tunnel too slow",
"{0} didn't make it out in time",
@@ -78,18 +102,20 @@ namespace QSB.DeathSync
"{0} went swimming in the sand",
"{0} underestimated the danger of sand",
"{0} died due to being crushed"
- } },
- { DeathType.Meditation, new[] // Meditation
+ }
+ },
{
- "{0} broke QSB. this is a bug, you should never see this"
- } },
- { DeathType.TimeLoop, new[] // Escaping the supernova
+ DeathType.TimeLoop,
+ new[] // Escaping the supernova
{
"{0} ran out of time",
"{0} lost track of time",
"{0} watched the sun go kaboom"
- } },
- { DeathType.Lava, new[] // Lava
+ }
+ },
+ {
+ DeathType.Lava,
+ new[] // Lava
{
"{0} died in lava",
"{0} was melted",
@@ -99,17 +125,47 @@ namespace QSB.DeathSync
"{0} became one with the glowing gooey rock",
"{0} died due to lava",
"{0} got burnt in the lava"
- } },
- { DeathType.BlackHole, new[] // ATP core black hole
+ }
+ },
+ {
+ DeathType.BlackHole,
+ new[] // ATP core black hole
{
"{0} should visit the Ash Twin Project again",
"{0} waited inside the Ash Twin Project",
"{0} chased their memories"
- } }
+ }
+ },
+ {
+ DeathType.DreamExplosion,
+ new[] // using the prototype
+ {
+ "{0} exploded",
+ "{0} was an early adopter",
+ "{0} went kaboom",
+ "{0} was fried",
+ "{0} died due to explosion",
+ "{0} used the wrong artifact"
+ }
+ },
+ {
+ DeathType.CrushedByElevator,
+ new[] // elevator-induced pancakeness
+ {
+ "{0} was crushed",
+ "{0} was squished",
+ "{0} was crushed by an elevator",
+ "{0} stood under an elevator",
+ "{0} became a flat-hearther",
+ "{0} was squished by an elevator"
+ }
+ },
};
- public static string GetPhrase(DeathType deathType, int index) =>
- Darkhold[deathType][index];
+ public static string GetPhrase(DeathType deathType, int index)
+ => !Darkhold.ContainsKey(deathType)
+ ? Darkhold[DeathType.Default][index]
+ : Darkhold[deathType][index];
public static int GetRandomIndex(DeathType deathType)
=> new Random().Next(0, Darkhold[deathType].Length);
diff --git a/QSB/DeathSync/Patches/DeathPatches.cs b/QSB/DeathSync/Patches/DeathPatches.cs
index 28c9ddfe..9a768393 100644
--- a/QSB/DeathSync/Patches/DeathPatches.cs
+++ b/QSB/DeathSync/Patches/DeathPatches.cs
@@ -209,10 +209,7 @@ namespace QSB.DeathSync.Patches
[HarmonyPostfix]
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
- public static void DeathManager_KillPlayer_Postfix(DeathType deathType)
- {
- QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
- }
+ public static void DeathManager_KillPlayer_Postfix(DeathType deathType) => QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
[HarmonyPostfix]
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Awake))]
diff --git a/QSB/DeathSync/Patches/RespawnPatches.cs b/QSB/DeathSync/Patches/RespawnPatches.cs
deleted file mode 100644
index 00bddc16..00000000
--- a/QSB/DeathSync/Patches/RespawnPatches.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-using HarmonyLib;
-using OWML.Utils;
-using QSB.Patches;
-
-namespace QSB.DeathSync.Patches
-{
- [HarmonyPatch]
- internal class RespawnPatches : QSBPatch
- {
- public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
-
- [HarmonyPrefix]
- [HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnGainFocus))]
- public static bool PlayerRecoveryPoint_OnGainFocus(
- PlayerResources ____playerResources,
- bool ____refuelsPlayer,
- bool ____healsPlayer,
- SingleInteractionVolume ____interactVolume
- )
- {
- if (____playerResources == null)
- {
- ____playerResources = Locator.GetPlayerTransform().GetComponent();
- }
-
- var isAtFullHealth = ____playerResources.GetHealthFraction() == 1f;
- var isAtFullFuel = ____playerResources.GetFuelFraction() == 1f;
- var canBeRefueled = false;
- var canBeHealed = false;
-
- if (!isAtFullFuel && ____refuelsPlayer)
- {
- canBeRefueled = true;
- }
-
- if (!isAtFullHealth && ____healsPlayer)
- {
- canBeHealed = true;
- }
-
- var showRespawnPrompt = false;
-
- var uitextType = UITextType.None;
- if (canBeHealed && canBeRefueled)
- {
- // Heal and refuel
- uitextType = UITextType.RefillPrompt_0;
-
- ____interactVolume.SetKeyCommandVisible(true);
- }
- else if (canBeHealed)
- {
- // Heal
- uitextType = UITextType.RefillPrompt_2;
-
- ____interactVolume.SetKeyCommandVisible(true);
- }
- else if (canBeRefueled)
- {
- // Refuel
- uitextType = UITextType.RefillPrompt_4;
- ____interactVolume.SetKeyCommandVisible(true);
- }
- else if (RespawnManager.Instance.RespawnNeeded)
- {
- showRespawnPrompt = true;
- }
- else if (____refuelsPlayer && ____healsPlayer)
- {
- // Fuel and health full
- uitextType = UITextType.RefillPrompt_7;
- ____interactVolume.SetKeyCommandVisible(false);
- }
- else if (____refuelsPlayer)
- {
- // Fuel full
- uitextType = UITextType.RefillPrompt_8;
- ____interactVolume.SetKeyCommandVisible(false);
- }
- else if (____healsPlayer)
- {
- // Health full
- uitextType = UITextType.RefillPrompt_9;
- ____interactVolume.SetKeyCommandVisible(false);
- }
-
- if (showRespawnPrompt)
- {
- ____interactVolume.GetValue("_screenPrompt").SetText($" Respawn Player");
- ____interactVolume.GetValue("_noCommandIconPrompt").SetText("Respawn Player");
- }
-
- if (uitextType != UITextType.None)
- {
- ____interactVolume.ChangePrompt(uitextType);
- }
-
- return false;
- }
-
- [HarmonyPrefix]
- [HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnPressInteract))]
- public static bool PlayerRecoveryPoint_OnPressInteract(
- PlayerRecoveryPoint __instance,
- PlayerResources ____playerResources,
- ref bool ____recovering,
- bool ____refuelsPlayer,
- bool ____healsPlayer,
- PlayerAudioController ____playerAudioController,
- SingleInteractionVolume ____interactVolume
- )
- {
- var playerNeedsRefueling = ____playerResources.GetFuelFraction() != 1f;
- var playerNeedsHealing = ____playerResources.GetHealthFraction() != 1f;
- var canBeInteractedWith = false;
-
- if (playerNeedsRefueling && ____refuelsPlayer)
- {
- canBeInteractedWith = true;
- }
-
- if (playerNeedsHealing && ____healsPlayer)
- {
- canBeInteractedWith = true;
- }
-
- if (RespawnManager.Instance.RespawnNeeded)
- {
- canBeInteractedWith = true;
- }
-
- if (canBeInteractedWith)
- {
- if (RespawnManager.Instance.RespawnNeeded && !playerNeedsRefueling && !playerNeedsHealing)
- {
- RespawnManager.Instance.RespawnSomePlayer();
- return false;
- }
-
- ____playerResources.StartRefillResources(____refuelsPlayer, ____healsPlayer);
-
- if (____playerAudioController != null)
- {
- if (playerNeedsRefueling && ____refuelsPlayer)
- {
- ____playerAudioController.PlayRefuel();
- }
-
- if (playerNeedsHealing && ____healsPlayer)
- {
- ____playerAudioController.PlayMedkit();
- }
- }
-
- ____recovering = true;
- __instance.enabled = true;
- }
- else
- {
- ____interactVolume.ResetInteraction();
- }
-
- return false;
- }
- }
-}
diff --git a/QSB/DeathSync/RespawnOnDeath.cs b/QSB/DeathSync/RespawnOnDeath.cs
index df5bc325..cc1ff8a5 100644
--- a/QSB/DeathSync/RespawnOnDeath.cs
+++ b/QSB/DeathSync/RespawnOnDeath.cs
@@ -3,7 +3,9 @@ using OWML.Utils;
using QSB.Events;
using QSB.Player;
using QSB.Player.TransformSync;
+using QSB.RespawnSync;
using QSB.Utility;
+using QSB.WorldSync;
using System.Linq;
using UnityEngine;
@@ -75,7 +77,7 @@ namespace QSB.DeathSync
}
else
{
- var allAstroobjects = Resources.FindObjectsOfTypeAll().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
+ var allAstroobjects = QSBWorldSync.GetUnityObjects().Where(x => x.GetAstroObjectName() != AstroObject.Name.None && x.GetAstroObjectType() != AstroObject.Type.Satellite);
var ordered = allAstroobjects.OrderBy(x => Vector3.SqrMagnitude(x.transform.position));
DeathClosestAstroObject = ordered.First().transform;
}
@@ -138,4 +140,4 @@ namespace QSB.DeathSync
&& spawnPoint.IsShipSpawn() == false);
}
}
-}
\ No newline at end of file
+}
diff --git a/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs b/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs
new file mode 100644
index 00000000..a2fa5f5e
--- /dev/null
+++ b/QSB/EchoesOfTheEye/AirlockSync/AirlockManager.cs
@@ -0,0 +1,10 @@
+using QSB.EchoesOfTheEye.AirlockSync.WorldObjects;
+using QSB.WorldSync;
+
+namespace QSB.EchoesOfTheEye.AirlockSync
+{
+ internal class AirlockManager : WorldObjectManager
+ {
+ protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init();
+ }
+}
diff --git a/QSB/EchoesOfTheEye/AirlockSync/WorldObjects/QSBGhostAirlock.cs b/QSB/EchoesOfTheEye/AirlockSync/WorldObjects/QSBGhostAirlock.cs
new file mode 100644
index 00000000..67b73576
--- /dev/null
+++ b/QSB/EchoesOfTheEye/AirlockSync/WorldObjects/QSBGhostAirlock.cs
@@ -0,0 +1,13 @@
+using QSB.WorldSync;
+
+namespace QSB.EchoesOfTheEye.AirlockSync.WorldObjects
+{
+ internal class QSBGhostAirlock : WorldObject
+ {
+ public override void Init(GhostAirlock airlock, int id)
+ {
+ ObjectId = id;
+ AttachedObject = airlock;
+ }
+ }
+}
diff --git a/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs b/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs
new file mode 100644
index 00000000..0ffd4f8a
--- /dev/null
+++ b/QSB/EchoesOfTheEye/LightSensorSync/LightSensorManager.cs
@@ -0,0 +1,10 @@
+using QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
+using QSB.WorldSync;
+
+namespace QSB.EchoesOfTheEye.LightSensorSync
+{
+ internal class LightSensorManager : WorldObjectManager
+ {
+ protected override void RebuildWorldObjects(OWScene scene) => QSBWorldSync.Init();
+ }
+}
diff --git a/QSB/EchoesOfTheEye/LightSensorSync/Patches/LightSensorPatches.cs b/QSB/EchoesOfTheEye/LightSensorSync/Patches/LightSensorPatches.cs
new file mode 100644
index 00000000..41ec66de
--- /dev/null
+++ b/QSB/EchoesOfTheEye/LightSensorSync/Patches/LightSensorPatches.cs
@@ -0,0 +1,149 @@
+using HarmonyLib;
+using QSB.Patches;
+using QSB.Player;
+using QSB.Tools.FlashlightTool;
+using System.Linq;
+using UnityEngine;
+
+namespace QSB.EchoesOfTheEye.LightSensorSync.Patches
+{
+ [HarmonyPatch]
+ internal class LightSensorPatches : QSBPatch
+ {
+ public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(SingleLightSensor), nameof(SingleLightSensor.UpdateIllumination))]
+ public static bool UpdateIlluminationReplacement(SingleLightSensor __instance)
+ {
+ __instance._illuminated = false;
+ if (__instance._illuminatingDreamLanternList != null)
+ {
+ __instance._illuminatingDreamLanternList.Clear();
+ }
+
+ var vector = __instance.transform.TransformPoint(__instance._localSensorOffset);
+ var sensorWorldDir = Vector3.zero;
+ if (__instance._directionalSensor)
+ {
+ sensorWorldDir = __instance.transform.TransformDirection(__instance._localDirection).normalized;
+ }
+
+ if (__instance._lightSources == null)
+ {
+ return false;
+ }
+
+ for (var i = 0; i < __instance._lightSources.Count; i++)
+ {
+ var source = __instance._lightSources[i];
+
+ if ((__instance._lightSourceMask & source.GetLightSourceType()) == source.GetLightSourceType()
+ && source.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance))
+ {
+ var lightSourceType = source.GetLightSourceType();
+ switch (lightSourceType)
+ {
+ case LightSourceType.UNDEFINED:
+ {
+ var owlight = source as OWLight2;
+ var occludableLight = owlight.GetLight().shadows != LightShadows.None
+ && owlight.GetLight().shadowStrength > 0.5f;
+
+ if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
+ && !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
+ {
+ __instance._illuminated = true;
+ }
+
+ break;
+ }
+ case LightSourceType.FLASHLIGHT:
+ {
+ if (source is Flashlight && (source as Flashlight) == Locator.GetFlashlight())
+ {
+ var position = Locator.GetPlayerCamera().transform.position;
+ var to = __instance.transform.position - position;
+ if (Vector3.Angle(Locator.GetPlayerCamera().transform.forward, to) <= __instance._maxSpotHalfAngle
+ && !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
+ {
+ __instance._illuminated = true;
+ }
+ }
+ else
+ {
+ var player = QSBPlayerManager.PlayerList.First(x => x.FlashLight == (QSBFlashlight)source);
+
+ var position = player.Camera.transform.position;
+ var to = __instance.transform.position - position;
+ if (Vector3.Angle(player.Camera.transform.forward, to) <= __instance._maxSpotHalfAngle
+ && !__instance.CheckOcclusion(position, vector, sensorWorldDir, true))
+ {
+ __instance._illuminated = true;
+ }
+ }
+
+ break;
+ }
+ case LightSourceType.PROBE:
+ {
+ var probe = Locator.GetProbe();
+ if (probe != null
+ && probe.IsLaunched()
+ && !probe.IsRetrieving()
+ && probe.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
+ && !__instance.CheckOcclusion(probe.GetLightSourcePosition(), vector, sensorWorldDir, true))
+ {
+ __instance._illuminated = true;
+ }
+
+ break;
+ }
+ case LightSourceType.FLASHLIGHT | LightSourceType.PROBE:
+ case LightSourceType.FLASHLIGHT | LightSourceType.DREAM_LANTERN:
+ case LightSourceType.PROBE | LightSourceType.DREAM_LANTERN:
+ case LightSourceType.FLASHLIGHT | LightSourceType.PROBE | LightSourceType.DREAM_LANTERN:
+ break;
+ case LightSourceType.DREAM_LANTERN:
+ {
+ var dreamLanternController = __instance._lightSources[i] as DreamLanternController;
+ if (dreamLanternController.IsLit()
+ && dreamLanternController.IsFocused(__instance._lanternFocusThreshold)
+ && dreamLanternController.CheckIlluminationAtPoint(vector, __instance._sensorRadius, __instance._maxDistance)
+ && !__instance.CheckOcclusion(dreamLanternController.GetLightPosition(), vector, sensorWorldDir, true))
+ {
+ __instance._illuminatingDreamLanternList.Add(dreamLanternController);
+ __instance._illuminated = true;
+ }
+
+ break;
+ }
+ case LightSourceType.SIMPLE_LANTERN:
+ foreach (var owlight in __instance._lightSources[i].GetLights())
+ {
+ var occludableLight = owlight.GetLight().shadows != LightShadows.None
+ && owlight.GetLight().shadowStrength > 0.5f;
+ var maxDistance = Mathf.Min(__instance._maxSimpleLanternDistance, __instance._maxDistance);
+ if (owlight.CheckIlluminationAtPoint(vector, __instance._sensorRadius, maxDistance) && !__instance.CheckOcclusion(owlight.transform.position, vector, sensorWorldDir, occludableLight))
+ {
+ __instance._illuminated = true;
+ break;
+ }
+ }
+
+ break;
+ default:
+ if (lightSourceType == LightSourceType.VOLUME_ONLY)
+ {
+ __instance._illuminated = true;
+ }
+
+ break;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/QSB/EchoesOfTheEye/LightSensorSync/WorldObjects/QSBSingleLightSensor.cs b/QSB/EchoesOfTheEye/LightSensorSync/WorldObjects/QSBSingleLightSensor.cs
new file mode 100644
index 00000000..089e67d3
--- /dev/null
+++ b/QSB/EchoesOfTheEye/LightSensorSync/WorldObjects/QSBSingleLightSensor.cs
@@ -0,0 +1,13 @@
+using QSB.WorldSync;
+
+namespace QSB.EchoesOfTheEye.LightSensorSync.WorldObjects
+{
+ internal class QSBSingleLightSensor : WorldObject
+ {
+ public override void Init(SingleLightSensor sensor, int id)
+ {
+ ObjectId = id;
+ AttachedObject = sensor;
+ }
+ }
+}
diff --git a/QSB/ElevatorSync/Events/ElevatorEvent.cs b/QSB/ElevatorSync/Events/ElevatorEvent.cs
index 5328676a..84f037e4 100644
--- a/QSB/ElevatorSync/Events/ElevatorEvent.cs
+++ b/QSB/ElevatorSync/Events/ElevatorEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.ElevatorSync.Events
private void Handler(int id, bool isGoingUp) => SendEvent(CreateMessage(id, isGoingUp));
- private BoolWorldObjectMessage CreateMessage(int id, bool isGoingUp) => new BoolWorldObjectMessage
+ private BoolWorldObjectMessage CreateMessage(int id, bool isGoingUp) => new()
{
State = isGoingUp,
ObjectId = id
diff --git a/QSB/ElevatorSync/Patches/ElevatorPatches.cs b/QSB/ElevatorSync/Patches/ElevatorPatches.cs
index 2e12063a..1b218863 100644
--- a/QSB/ElevatorSync/Patches/ElevatorPatches.cs
+++ b/QSB/ElevatorSync/Patches/ElevatorPatches.cs
@@ -17,7 +17,7 @@ namespace QSB.ElevatorSync.Patches
public static void Elevator_StartLift(Elevator __instance)
{
var isGoingUp = __instance.GetValue("_goingToTheEnd");
- var id = QSBWorldSync.GetIdFromUnity(__instance);
+ var id = QSBWorldSync.GetIdFromUnity(__instance);
QSBEventManager.FireEvent(EventNames.QSBStartLift, id, isGoingUp);
}
}
diff --git a/QSB/ElevatorSync/WorldObjects/QSBElevator.cs b/QSB/ElevatorSync/WorldObjects/QSBElevator.cs
index 9358ae02..f322af7a 100644
--- a/QSB/ElevatorSync/WorldObjects/QSBElevator.cs
+++ b/QSB/ElevatorSync/WorldObjects/QSBElevator.cs
@@ -1,5 +1,4 @@
-using OWML.Utils;
-using QSB.WorldSync;
+using QSB.WorldSync;
using UnityEngine;
namespace QSB.ElevatorSync.WorldObjects
@@ -12,42 +11,65 @@ namespace QSB.ElevatorSync.WorldObjects
private SingleInteractionVolume _interactVolume;
private OWAudioSource _owAudioSourceOneShot;
private OWAudioSource _owAudioSourceLP;
+ private OWTriggerVolume _elevatorTrigger;
public override void Init(Elevator elevator, int id)
{
AttachedObject = elevator;
ObjectId = id;
- QSBCore.UnityEvents.RunWhen(() => AttachedObject.GetValue("_interactVolume") != null, InitValues);
+ QSBCore.UnityEvents.RunWhen(() => AttachedObject._interactVolume != null, InitValues);
}
private void InitValues()
{
- _startLocalPos = AttachedObject.GetValue("_startLocalPos");
- _endLocalPos = AttachedObject.GetValue("_endLocalPos");
- _interactVolume = AttachedObject.GetValue("_interactVolume");
- _owAudioSourceOneShot = AttachedObject.GetValue("_owAudioSourceOneShot");
- _owAudioSourceLP = AttachedObject.GetValue("_owAudioSourceLP");
+ _startLocalPos = AttachedObject._startLocalPos;
+ _endLocalPos = AttachedObject._endLocalPos;
+ _interactVolume = AttachedObject._interactVolume;
+ _owAudioSourceOneShot = AttachedObject._owAudioSourceOneShot;
+ _owAudioSourceLP = AttachedObject._owAudioSourceLP;
+
+ var boxShape = AttachedObject.gameObject.AddComponent();
+ boxShape.center = new Vector3(0, 1.75f, 0.25f);
+ boxShape.size = new Vector3(3, 3.5f, 3);
+
+ _elevatorTrigger = AttachedObject.gameObject.GetAddComponent();
}
public void RemoteCall(bool isGoingUp)
{
- SetDirection(isGoingUp);
- RemoteStartLift();
+ if (_elevatorTrigger.IsTrackingObject(Locator.GetPlayerDetector()))
+ {
+ SetDirection(isGoingUp);
+
+ AttachedObject._attachPoint.AttachPlayer();
+
+ if (Locator.GetPlayerSuit().IsWearingSuit(true) && Locator.GetPlayerSuit().IsTrainingSuit())
+ {
+ Locator.GetPlayerSuit().RemoveSuit(false);
+ }
+
+ RemoteStartLift();
+ }
+ else
+ {
+ SetDirection(isGoingUp);
+ RemoteStartLift();
+ }
}
private void SetDirection(bool isGoingUp)
{
- var targetPos = isGoingUp ? _endLocalPos : _startLocalPos;
- AttachedObject.SetValue("_goingToTheEnd", isGoingUp);
- AttachedObject.SetValue("_targetLocalPos", targetPos);
_interactVolume.transform.Rotate(0f, 180f, 0f);
+ var targetPos = isGoingUp ? _endLocalPos : _startLocalPos;
+ AttachedObject._targetLocalPos = targetPos;
+ AttachedObject._goingToTheEnd = isGoingUp;
}
private void RemoteStartLift()
{
AttachedObject.enabled = true;
- AttachedObject.SetValue("_initLocalPos", AttachedObject.transform.localPosition);
- AttachedObject.SetValue("_initLiftTime", Time.time);
+ AttachedObject._initLocalPos = AttachedObject.transform.localPosition;
+ AttachedObject._initLiftTime = Time.time;
_owAudioSourceOneShot.PlayOneShot(AudioType.TH_LiftActivate);
_owAudioSourceLP.FadeIn(0.5f);
_interactVolume.DisableInteraction();
diff --git a/QSB/Events/EventNames.cs b/QSB/Events/EventNames.cs
index 168d66c4..c5b946e2 100644
--- a/QSB/Events/EventNames.cs
+++ b/QSB/Events/EventNames.cs
@@ -62,8 +62,8 @@
public static string QSBCampfireState = "QSBCampfireState";
public static string QSBMarshmallowEvent = "QSBMarshmallowEvent";
public static string QSBAnimTrigger = "QSBAnimTrigger";
- public static string QSBEnterHeadZone = "QSBEnterHeadZone";
- public static string QSBExitHeadZone = "QSBExitHeadZone";
+ public static string QSBEnterNonNomaiHeadZone = "QSBEnterNonNomaiHeadZone";
+ public static string QSBExitNonNomaiHeadZone = "QSBExitNonNomaiHeadZone";
public static string QSBNpcAnimEvent = "QSBNpcAnimEvent";
public static string QSBHatchState = "QSBHatchState";
public static string QSBEnableFunnel = "QSBEnableFunnel";
@@ -87,5 +87,17 @@
public static string QSBServerState = "QSBServerState";
public static string QSBClientState = "QSBClientState";
public static string QSBDebugEvent = "QSBDebugEvent";
+ public static string QSBEnterNomaiHeadZone = "QSBEnterNomaiHeadZone";
+ public static string QSBExitNomaiHeadZone = "QSBExitNomaiHeadZone";
+ public static string QSBEnterSatelliteCamera = "QSBEnterSatelliteCamera";
+ public static string QSBExitSatelliteCamera = "QSBExitSatelliteCamera";
+ public static string QSBSatelliteSnapshot = "QSBSatelliteSnapshot";
+ public static string QSBAnglerChangeState = "QSBAnglerChangeState";
+ public static string QSBMeteorPreLaunch = "QSBMeteorPreLaunch";
+ public static string QSBMeteorLaunch = "QSBMeteorLaunch";
+ public static string QSBMeteorSpecialImpact = "QSBMeteorSpecialImpact";
+ public static string QSBFragmentDamage = "QSBFragmentDamage";
+ public static string QSBFragmentResync = "QSBFragmentResync";
+ public static string QSBLearnLaunchCodes = "QSBLearnLaunchCodes";
}
-}
\ No newline at end of file
+}
diff --git a/QSB/Events/EventType.cs b/QSB/Events/EventType.cs
index be7a01f7..119011e3 100644
--- a/QSB/Events/EventType.cs
+++ b/QSB/Events/EventType.cs
@@ -3,9 +3,13 @@
public enum EventType
{
/*
- * MISC.
+ * MISC.
*/
DebugEvent,
+ SatelliteProjector,
+ SatelliteProjectorSnapshot,
+ LaunchCodes,
+ VariableSync,
/*
* SERVER EVENTS
@@ -131,6 +135,14 @@
RetrieveProbe,
PlayerRetrieveProbe,
LaunchProbe,
- PlayerLaunchProbe
+ PlayerLaunchProbe,
+
+ AnglerChangeState,
+
+ MeteorPreLaunch,
+ MeteorLaunch,
+ MeteorSpecialImpact,
+ FragmentDamage,
+ FragmentResync
}
-}
\ No newline at end of file
+}
diff --git a/QSB/Events/IQSBEvent.cs b/QSB/Events/IQSBEvent.cs
index 63ad403b..ddac051f 100644
--- a/QSB/Events/IQSBEvent.cs
+++ b/QSB/Events/IQSBEvent.cs
@@ -2,6 +2,8 @@
{
public interface IQSBEvent
{
+ EventType Type { get; }
+
void SetupListener();
void CloseListener();
}
diff --git a/QSB/Events/QSBEvent.cs b/QSB/Events/QSBEvent.cs
index 18fe3523..f3663a30 100644
--- a/QSB/Events/QSBEvent.cs
+++ b/QSB/Events/QSBEvent.cs
@@ -1,6 +1,8 @@
using OWML.Common;
+using QSB.ClientServerStateSync;
using QSB.Messaging;
using QSB.Player;
+using QSB.Player.Events;
using QSB.Player.TransformSync;
using QSB.Utility;
using QuantumUNET.Components;
@@ -75,10 +77,24 @@ namespace QSB.Events
if (PlayerTransformSync.LocalInstance == null || PlayerTransformSync.LocalInstance.GetComponent() == null)
{
- DebugLog.ToConsole($"Warning - Tried to handle message of type <{message.GetType().Name}> before localplayer was established.", MessageType.Warning);
+ DebugLog.ToConsole($"Warning - Tried to handle message of type <{GetType().Name}> before localplayer was established.", MessageType.Warning);
return;
}
+ if (QSBPlayerManager.PlayerExists(message.FromId))
+ {
+ var player = QSBPlayerManager.GetPlayer(message.FromId);
+
+ if (!player.IsReady
+ && player.PlayerId != LocalPlayerId
+ && (player.State is ClientState.AliveInSolarSystem or ClientState.AliveInEye or ClientState.DeadInSolarSystem)
+ && (message is not PlayerInformationEvent or PlayerReadyEvent))
+ {
+ DebugLog.ToConsole($"Warning - Got message from player {message.FromId}, but they were not ready. Asking for state resync, just in case.", MessageType.Warning);
+ QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
+ }
+ }
+
try
{
if (message.FromId == QSBPlayerManager.LocalPlayerId ||
@@ -92,7 +108,7 @@ namespace QSB.Events
}
catch (Exception ex)
{
- DebugLog.ToConsole($"Error - Exception handling message {message.GetType().Name} : {ex}", MessageType.Error);
+ DebugLog.ToConsole($"Error - Exception handling message {GetType().Name} : {ex}", MessageType.Error);
}
}
}
diff --git a/QSB/Events/QSBEventManager.cs b/QSB/Events/QSBEventManager.cs
index 68029535..1ac362da 100644
--- a/QSB/Events/QSBEventManager.cs
+++ b/QSB/Events/QSBEventManager.cs
@@ -1,4 +1,5 @@
using OWML.Common;
+using QSB.Anglerfish.Events;
using QSB.Animation.NPC.Events;
using QSB.Animation.Player.Events;
using QSB.CampfireSync.Events;
@@ -6,26 +7,33 @@ using QSB.ClientServerStateSync.Events;
using QSB.ConversationSync.Events;
using QSB.DeathSync.Events;
using QSB.ElevatorSync.Events;
-using QSB.FrequencySync.Events;
using QSB.GeyserSync.Events;
using QSB.ItemSync.Events;
using QSB.LogSync.Events;
+using QSB.MeteorSync.Events;
using QSB.OrbSync.Events;
using QSB.Player.Events;
-using QSB.ProbeSync.Events;
using QSB.QuantumSync.Events;
+using QSB.RespawnSync.Events;
using QSB.RoastingSync.Events;
+using QSB.SatelliteSync.Events;
using QSB.ShipSync.Events;
using QSB.ShipSync.Events.Component;
using QSB.ShipSync.Events.Hull;
using QSB.StatueSync.Events;
using QSB.TimeSync.Events;
-using QSB.Tools.Events;
+using QSB.Tools.FlashlightTool.Events;
using QSB.Tools.ProbeLauncherTool.Events;
-using QSB.TranslationSync.Events;
+using QSB.Tools.ProbeTool.Events;
+using QSB.Tools.SignalscopeTool.Events;
+using QSB.Tools.SignalscopeTool.FrequencySync.Events;
+using QSB.Tools.TranslatorTool.Events;
+using QSB.Tools.TranslatorTool.TranslationSync.Events;
using QSB.Utility;
using QSB.Utility.Events;
using System.Collections.Generic;
+using System.Linq;
+using System.Text;
namespace QSB.Events
{
@@ -33,7 +41,7 @@ namespace QSB.Events
{
public static bool Ready { get; private set; }
- private static List _eventList = new List();
+ private static List _eventList = new();
public static void Init()
{
@@ -69,6 +77,9 @@ namespace QSB.Events
new ServerStateEvent(),
new ClientStateEvent(),
new DebugEvent(),
+ new SatelliteProjectorEvent(),
+ new SatelliteProjectorSnapshotEvent(),
+ new LaunchCodesEvent(),
// World Objects
new ElevatorEvent(),
new GeyserEvent(),
@@ -86,6 +97,12 @@ namespace QSB.Events
new MoveToCarryEvent(),
new StartStatueEvent(),
new CampfireStateEvent(),
+ new AnglerChangeStateEvent(),
+ new MeteorPreLaunchEvent(),
+ new MeteorLaunchEvent(),
+ new MeteorSpecialImpactEvent(),
+ new FragmentDamageEvent(),
+ new FragmentResyncEvent(),
// Conversation/dialogue/exploration
new ConversationEvent(),
new ConversationStartEndEvent(),
@@ -115,6 +132,26 @@ namespace QSB.Events
_eventList.ForEach(ev => ev.SetupListener());
+ var duplicates = _eventList
+ .GroupBy(qsbEvent => qsbEvent.Type)
+ .Where(group => group.Count() > 1);
+
+ if (duplicates.Count() != 0)
+ {
+ var totalSb = new StringBuilder();
+ foreach (var group in duplicates)
+ {
+ totalSb.Append($"{group.Key}\r\n");
+ foreach (var qsbEvent in group)
+ {
+ totalSb.Append($"- {qsbEvent.GetType().Name}\r\n");
+ }
+ }
+
+ DebugLog.ToConsole($"Error - These QSBEvents handle the same EventType!\r\n{totalSb}", MessageType.Error);
+ return;
+ }
+
Ready = true;
DebugLog.DebugWrite("Event Manager ready.", MessageType.Success);
@@ -203,4 +240,4 @@ namespace QSB.Events
GlobalMessenger.FireEvent(eventName, arg1, arg2, arg3, arg4, arg5, arg6);
}
}
-}
\ No newline at end of file
+}
diff --git a/QSB/GeyserSync/Events/GeyserEvent.cs b/QSB/GeyserSync/Events/GeyserEvent.cs
index 13ac1e02..d13a50c6 100644
--- a/QSB/GeyserSync/Events/GeyserEvent.cs
+++ b/QSB/GeyserSync/Events/GeyserEvent.cs
@@ -14,7 +14,7 @@ namespace QSB.GeyserSync.Events
private void Handler(int id, bool state) => SendEvent(CreateMessage(id, state));
- private BoolWorldObjectMessage CreateMessage(int id, bool state) => new BoolWorldObjectMessage
+ private BoolWorldObjectMessage CreateMessage(int id, bool state) => new()
{
AboutId = LocalPlayerId,
ObjectId = id,
diff --git a/QSB/ItemSync/Events/DropItemEvent.cs b/QSB/ItemSync/Events/DropItemEvent.cs
index f2db3153..4ecc5e00 100644
--- a/QSB/ItemSync/Events/DropItemEvent.cs
+++ b/QSB/ItemSync/Events/DropItemEvent.cs
@@ -1,5 +1,6 @@
using QSB.Events;
-using QSB.ItemSync.WorldObjects;
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
@@ -19,7 +20,7 @@ namespace QSB.ItemSync.Events
private void Handler(int objectId, Vector3 position, Vector3 normal, Sector sector)
=> SendEvent(CreateMessage(objectId, position, normal, sector));
- private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new DropItemMessage
+ private DropItemMessage CreateMessage(int objectId, Vector3 position, Vector3 normal, Sector sector) => new()
{
ObjectId = objectId,
Position = position,
@@ -31,6 +32,9 @@ namespace QSB.ItemSync.Events
{
var worldObject = QSBWorldSync.GetWorldFromId(message.ObjectId);
worldObject.DropItem(message.Position, message.Normal, message.Sector);
+
+ var player = QSBPlayerManager.GetPlayer(message.FromId);
+ player.HeldItem = worldObject;
}
}
}
diff --git a/QSB/ItemSync/Events/DropItemMessage.cs b/QSB/ItemSync/Events/DropItemMessage.cs
index 18f1c465..2771cc32 100644
--- a/QSB/ItemSync/Events/DropItemMessage.cs
+++ b/QSB/ItemSync/Events/DropItemMessage.cs
@@ -29,7 +29,7 @@ namespace QSB.ItemSync.Events
writer.Write(ObjectId);
writer.Write(Position);
writer.Write(Normal);
- var qsbSector = QSBWorldSync.GetWorldFromUnity(Sector);
+ var qsbSector = QSBWorldSync.GetWorldFromUnity(Sector);
writer.Write(qsbSector.ObjectId);
}
}
diff --git a/QSB/ItemSync/Events/MoveToCarryEvent.cs b/QSB/ItemSync/Events/MoveToCarryEvent.cs
index 450db0ca..f799c5c8 100644
--- a/QSB/ItemSync/Events/MoveToCarryEvent.cs
+++ b/QSB/ItemSync/Events/MoveToCarryEvent.cs
@@ -1,9 +1,8 @@
using QSB.Events;
-using QSB.ItemSync.WorldObjects;
+using QSB.ItemSync.WorldObjects.Items;
using QSB.Player;
using QSB.WorldSync;
using QSB.WorldSync.Events;
-using UnityEngine;
namespace QSB.ItemSync.Events
{
@@ -20,7 +19,7 @@ namespace QSB.ItemSync.Events
private void Handler(int itemId)
=> SendEvent(CreateMessage(itemId));
- private WorldObjectMessage CreateMessage(int itemid) => new WorldObjectMessage
+ private WorldObjectMessage CreateMessage(int itemid) => new()
{
AboutId = QSBPlayerManager.LocalPlayerId,
ObjectId = itemid
@@ -31,26 +30,21 @@ namespace QSB.ItemSync.Events
var player = QSBPlayerManager.GetPlayer(message.AboutId);
var itemObject = QSBWorldSync.GetWorldFromId(message.ObjectId);
var itemType = itemObject.GetItemType();
- Transform itemSocket = null;
- switch (itemType)
+
+ player.HeldItem = itemObject;
+ var itemSocket = itemType switch
{
- case ItemType.Scroll:
- itemSocket = player.ScrollSocket;
- break;
- case ItemType.SharedStone:
- itemSocket = player.SharedStoneSocket;
- break;
- case ItemType.WarpCore:
- itemSocket = ((QSBWarpCoreItem)itemObject).IsVesselCoreType()
- ? player.VesselCoreSocket
- : player.WarpCoreSocket;
- break;
- default:
- itemSocket = player.ItemSocket;
- break;
-
- }
-
+ ItemType.Scroll => player.ScrollSocket,
+ ItemType.SharedStone => player.SharedStoneSocket,
+ ItemType.WarpCore => ((QSBWarpCoreItem)itemObject).IsVesselCoreType()
+ ? player.VesselCoreSocket
+ : player.WarpCoreSocket,
+ ItemType.Lantern => player.SimpleLanternSocket,
+ ItemType.DreamLantern => player.DreamLanternSocket,
+ ItemType.SlideReel => player.SlideReelSocket,
+ ItemType.VisionTorch => player.VisionTorchSocket,
+ _ => player.ItemSocket,
+ };
itemObject.PickUpItem(itemSocket, message.AboutId);
}
}
diff --git a/QSB/ItemSync/Events/SocketItemEvent.cs b/QSB/ItemSync/Events/SocketItemEvent.cs
index 2e66f015..088ab528 100644
--- a/QSB/ItemSync/Events/SocketItemEvent.cs
+++ b/QSB/ItemSync/Events/SocketItemEvent.cs
@@ -1,5 +1,6 @@
using QSB.Events;
-using QSB.ItemSync.WorldObjects;
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
@@ -19,7 +20,7 @@ namespace QSB.ItemSync.Events
private void Handler(int socketId, int itemId, SocketEventType type)
=> SendEvent(CreateMessage(socketId, itemId, type));
- private SocketItemMessage CreateMessage(int socketId, int itemId, SocketEventType type) => new SocketItemMessage
+ private SocketItemMessage CreateMessage(int socketId, int itemId, SocketEventType type) => new()
{
AboutId = QSBPlayerManager.LocalPlayerId,
SocketId = socketId,
@@ -31,6 +32,8 @@ namespace QSB.ItemSync.Events
{
var socketWorldObject = QSBWorldSync.GetWorldFromId(message.SocketId);
var itemWorldObject = QSBWorldSync.GetWorldFromId(message.ItemId);
+ var player = QSBPlayerManager.GetPlayer(message.FromId);
+ player.HeldItem = null;
switch (message.SocketType)
{
case SocketEventType.Socket:
diff --git a/QSB/ItemSync/ItemManager.cs b/QSB/ItemSync/ItemManager.cs
index 97c304e2..55f43a26 100644
--- a/QSB/ItemSync/ItemManager.cs
+++ b/QSB/ItemSync/ItemManager.cs
@@ -1,5 +1,6 @@
using OWML.Common;
-using QSB.ItemSync.WorldObjects;
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Utility;
using QSB.WorldSync;
@@ -10,80 +11,22 @@ namespace QSB.ItemSync
protected override void RebuildWorldObjects(OWScene scene)
{
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Info);
- QSBWorldSync.Init();
+
+ // Items
QSBWorldSync.Init();
- QSBWorldSync.Init();
QSBWorldSync.Init();
- QSBWorldSync.Init();
QSBWorldSync.Init();
- QSBWorldSync.Init();
QSBWorldSync.Init();
- }
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
- public static IQSBOWItem GetObject(OWItem unityObject)
- {
- if (unityObject == null)
- {
- DebugLog.ToConsole($"Error - Trying to run GetObject (Item) with null unity object!", MessageType.Error);
- return default;
- }
-
- IQSBOWItem worldObj = null;
- if (unityObject.GetType() == typeof(ScrollItem))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((ScrollItem)unityObject);
- }
- else if (unityObject.GetType() == typeof(SharedStone))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((SharedStone)unityObject);
- }
- else if (unityObject.GetType() == typeof(WarpCoreItem))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((WarpCoreItem)unityObject);
- }
- else if (unityObject.GetType() == typeof(NomaiConversationStone))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((NomaiConversationStone)unityObject);
- }
- else
- {
- DebugLog.ToConsole($"Warning - couldn't work out type of OWItem {unityObject.name}.", MessageType.Warning);
- }
-
- return worldObj;
- }
-
- public static IQSBOWItemSocket GetObject(OWItemSocket unityObject)
- {
- if (unityObject == null)
- {
- DebugLog.ToConsole($"Error - Trying to run GetObject (Socket) with null unity object!", MessageType.Error);
- return default;
- }
-
- IQSBOWItemSocket worldObj = null;
- if (unityObject.GetType() == typeof(ScrollSocket))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((ScrollSocket)unityObject);
- }
- else if (unityObject.GetType() == typeof(SharedStoneSocket))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((SharedStoneSocket)unityObject);
- }
- else if (unityObject.GetType() == typeof(WarpCoreSocket))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((WarpCoreSocket)unityObject);
- }
- else if (unityObject.GetType() == typeof(NomaiConversationStone))
- {
- worldObj = QSBWorldSync.GetWorldFromUnity((NomaiConversationStoneSocket)unityObject);
- }
- else
- {
- DebugLog.ToConsole($"Warning - couldn't work out type of OWItemSocket {unityObject.name}.", MessageType.Warning);
- }
-
- return worldObj;
+ // Sockets
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
+ QSBWorldSync.Init();
}
}
}
diff --git a/QSB/ItemSync/Patches/ItemPatches.cs b/QSB/ItemSync/Patches/ItemPatches.cs
index d515a122..f9d6edeb 100644
--- a/QSB/ItemSync/Patches/ItemPatches.cs
+++ b/QSB/ItemSync/Patches/ItemPatches.cs
@@ -1,7 +1,10 @@
using HarmonyLib;
using OWML.Common;
using QSB.Events;
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Patches;
+using QSB.Player;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
@@ -17,7 +20,9 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.MoveItemToCarrySocket))]
public static bool ItemTool_MoveItemToCarrySocket(OWItem item)
{
- var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(item));
+ var qsbObj = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(item);
+ var itemId = QSBWorldSync.GetIdFromTypeSubset(qsbObj);
+ QSBPlayerManager.LocalPlayer.HeldItem = qsbObj;
QSBEventManager.FireEvent(EventNames.QSBMoveToCarry, itemId);
return true;
}
@@ -26,8 +31,10 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.SocketItem))]
public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket)
{
- var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
- var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
+ var qsbObj = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem);
+ var socketId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(socket));
+ var itemId = QSBWorldSync.GetIdFromTypeSubset(qsbObj);
+ QSBPlayerManager.LocalPlayer.HeldItem = null;
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, itemId, SocketEventType.Socket);
return true;
}
@@ -36,7 +43,9 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.StartUnsocketItem))]
public static bool ItemTool_StartUnsocketItem(OWItemSocket socket)
{
- var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
+ var item = (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(socket.GetSocketedItem());
+ QSBPlayerManager.LocalPlayer.HeldItem = item;
+ var socketId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(socket));
QSBEventManager.FireEvent(EventNames.QSBSocketItem, socketId, 0, SocketEventType.StartUnsocket);
return true;
}
@@ -45,7 +54,7 @@ namespace QSB.ItemSync.Patches
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.CompleteUnsocketItem))]
public static bool ItemTool_CompleteUnsocketItem(OWItem ____heldItem)
{
- var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
+ var itemId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem));
QSBEventManager.FireEvent(EventNames.QSBSocketItem, 0, itemId, SocketEventType.CompleteUnsocket);
return true;
}
@@ -70,7 +79,7 @@ namespace QSB.ItemSync.Patches
sector = sectorGroup.GetSector();
if (sector == null && sectorGroup is SectorCullGroup)
{
- SectorProxy controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
+ var controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
if (controllingProxy != null)
{
sector = controllingProxy.GetSector();
@@ -81,9 +90,10 @@ namespace QSB.ItemSync.Patches
var parent = (customDropTarget == null)
? targetRigidbody.transform
: customDropTarget.GetItemDropTargetTransform(hit.collider.gameObject);
- var objectId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
+ var objectId = QSBWorldSync.GetIdFromTypeSubset((IQSBOWItem)QSBWorldSync.GetWorldFromUnity(____heldItem));
____heldItem.DropItem(hit.point, hit.normal, parent, sector, customDropTarget);
____heldItem = null;
+ QSBPlayerManager.LocalPlayer.HeldItem = null;
Locator.GetToolModeSwapper().UnequipTool();
var parentSector = parent.GetComponentInChildren();
if (parentSector != null)
diff --git a/QSB/ItemSync/WorldObjects/IQSBOWItem.cs b/QSB/ItemSync/WorldObjects/Items/IQSBOWItem.cs
similarity index 91%
rename from QSB/ItemSync/WorldObjects/IQSBOWItem.cs
rename to QSB/ItemSync/WorldObjects/Items/IQSBOWItem.cs
index 90651be4..4fc184e0 100644
--- a/QSB/ItemSync/WorldObjects/IQSBOWItem.cs
+++ b/QSB/ItemSync/WorldObjects/Items/IQSBOWItem.cs
@@ -1,7 +1,7 @@
using QSB.WorldSync;
using UnityEngine;
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
public interface IQSBOWItem : IWorldObjectTypeSubset
{
diff --git a/QSB/ItemSync/WorldObjects/QSBNomaiConversationStone.cs b/QSB/ItemSync/WorldObjects/Items/QSBNomaiConversationStone.cs
similarity index 85%
rename from QSB/ItemSync/WorldObjects/QSBNomaiConversationStone.cs
rename to QSB/ItemSync/WorldObjects/Items/QSBNomaiConversationStone.cs
index 6230ce1a..97a2798e 100644
--- a/QSB/ItemSync/WorldObjects/QSBNomaiConversationStone.cs
+++ b/QSB/ItemSync/WorldObjects/Items/QSBNomaiConversationStone.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
internal class QSBNomaiConversationStone : QSBOWItem
{
diff --git a/QSB/ItemSync/WorldObjects/QSBOWItem.cs b/QSB/ItemSync/WorldObjects/Items/QSBOWItem.cs
similarity index 77%
rename from QSB/ItemSync/WorldObjects/QSBOWItem.cs
rename to QSB/ItemSync/WorldObjects/Items/QSBOWItem.cs
index acca3daa..9de0c8d8 100644
--- a/QSB/ItemSync/WorldObjects/QSBOWItem.cs
+++ b/QSB/ItemSync/WorldObjects/Items/QSBOWItem.cs
@@ -1,10 +1,11 @@
-using OWML.Utils;
+using QSB.ItemSync.WorldObjects.Sockets;
using QSB.Player;
using QSB.SectorSync.WorldObjects;
+using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
internal class QSBOWItem : WorldObject, IQSBOWItem
where T : OWItem
@@ -18,13 +19,25 @@ namespace QSB.ItemSync.WorldObjects
public override void Init(T attachedObject, int id)
{
+ if (attachedObject == null)
+ {
+ DebugLog.ToConsole($"Error - AttachedObject is null! Type:{GetType().Name}", OWML.Common.MessageType.Error);
+ return;
+ }
+
InitialParent = attachedObject.transform.parent;
InitialPosition = attachedObject.transform.localPosition;
InitialRotation = attachedObject.transform.localRotation;
- InitialSector = QSBWorldSync.GetWorldFromUnity(attachedObject.GetSector());
- if (InitialParent.GetComponent() != null)
+ InitialSector = QSBWorldSync.GetWorldFromUnity(attachedObject.GetSector());
+
+ if (InitialParent == null)
{
- var qsbObj = ItemManager.GetObject(InitialParent.GetComponent());
+ DebugLog.ToConsole($"Warning - InitialParent of {attachedObject.name} is null!", OWML.Common.MessageType.Warning);
+ }
+
+ if (InitialParent?.GetComponent() != null)
+ {
+ var qsbObj = (IQSBOWItemSocket)QSBWorldSync.GetWorldFromUnity(InitialParent.GetComponent());
InitialSocket = qsbObj;
}
@@ -76,10 +89,10 @@ namespace QSB.ItemSync.WorldObjects
{
AttachedObject.transform.SetParent(sector.transform);
AttachedObject.transform.localScale = Vector3.one;
- var localDropNormal = AttachedObject.GetValue("_localDropNormal");
+ var localDropNormal = AttachedObject._localDropNormal;
var lhs = Quaternion.FromToRotation(AttachedObject.transform.TransformDirection(localDropNormal), normal);
AttachedObject.transform.rotation = lhs * AttachedObject.transform.rotation;
- var localDropOffset = AttachedObject.GetValue("_localDropOffset");
+ var localDropOffset = AttachedObject._localDropOffset;
AttachedObject.transform.position = sector.transform.TransformPoint(position) + AttachedObject.transform.TransformDirection(localDropOffset);
AttachedObject.SetSector(sector);
AttachedObject.SetColliderActivation(true);
diff --git a/QSB/ItemSync/WorldObjects/QSBScrollItem.cs b/QSB/ItemSync/WorldObjects/Items/QSBScrollItem.cs
similarity index 93%
rename from QSB/ItemSync/WorldObjects/QSBScrollItem.cs
rename to QSB/ItemSync/WorldObjects/Items/QSBScrollItem.cs
index e8cc6aaf..425f980c 100644
--- a/QSB/ItemSync/WorldObjects/QSBScrollItem.cs
+++ b/QSB/ItemSync/WorldObjects/Items/QSBScrollItem.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
internal class QSBScrollItem : QSBOWItem
{
diff --git a/QSB/ItemSync/WorldObjects/QSBSharedStone.cs b/QSB/ItemSync/WorldObjects/Items/QSBSharedStone.cs
similarity index 93%
rename from QSB/ItemSync/WorldObjects/QSBSharedStone.cs
rename to QSB/ItemSync/WorldObjects/Items/QSBSharedStone.cs
index 4a0ed717..fe2830f4 100644
--- a/QSB/ItemSync/WorldObjects/QSBSharedStone.cs
+++ b/QSB/ItemSync/WorldObjects/Items/QSBSharedStone.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
internal class QSBSharedStone : QSBOWItem
{
diff --git a/QSB/ItemSync/WorldObjects/Items/QSBSimpleLanternItem.cs b/QSB/ItemSync/WorldObjects/Items/QSBSimpleLanternItem.cs
new file mode 100644
index 00000000..12bf9c7b
--- /dev/null
+++ b/QSB/ItemSync/WorldObjects/Items/QSBSimpleLanternItem.cs
@@ -0,0 +1,21 @@
+namespace QSB.ItemSync.WorldObjects.Items
+{
+ internal class QSBSimpleLanternItem : QSBOWItem
+ {
+ public override void Init(SimpleLanternItem attachedObject, int id)
+ {
+ ObjectId = id;
+ AttachedObject = attachedObject;
+ base.Init(attachedObject, id);
+ }
+
+ public override void PlaySocketAnimation()
+ => AttachedObject.PlaySocketAnimation();
+
+ public override void PlayUnsocketAnimation()
+ => AttachedObject.PlayUnsocketAnimation();
+
+ public override void OnCompleteUnsocket()
+ => AttachedObject.OnCompleteUnsocket();
+ }
+}
diff --git a/QSB/ItemSync/WorldObjects/Items/QSBSlideReelItem.cs b/QSB/ItemSync/WorldObjects/Items/QSBSlideReelItem.cs
new file mode 100644
index 00000000..41735ea0
--- /dev/null
+++ b/QSB/ItemSync/WorldObjects/Items/QSBSlideReelItem.cs
@@ -0,0 +1,21 @@
+namespace QSB.ItemSync.WorldObjects.Items
+{
+ internal class QSBSlideReelItem : QSBOWItem
+ {
+ public override void Init(SlideReelItem attachedObject, int id)
+ {
+ ObjectId = id;
+ AttachedObject = attachedObject;
+ base.Init(attachedObject, id);
+ }
+
+ public override void PlaySocketAnimation()
+ => AttachedObject.PlaySocketAnimation();
+
+ public override void PlayUnsocketAnimation()
+ => AttachedObject.PlayUnsocketAnimation();
+
+ public override void OnCompleteUnsocket()
+ => AttachedObject.OnCompleteUnsocket();
+ }
+}
diff --git a/QSB/ItemSync/WorldObjects/QSBWarpCoreItem.cs b/QSB/ItemSync/WorldObjects/Items/QSBWarpCoreItem.cs
similarity index 87%
rename from QSB/ItemSync/WorldObjects/QSBWarpCoreItem.cs
rename to QSB/ItemSync/WorldObjects/Items/QSBWarpCoreItem.cs
index 88e31da7..3be29380 100644
--- a/QSB/ItemSync/WorldObjects/QSBWarpCoreItem.cs
+++ b/QSB/ItemSync/WorldObjects/Items/QSBWarpCoreItem.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Items
{
internal class QSBWarpCoreItem : QSBOWItem
{
diff --git a/QSB/ItemSync/WorldObjects/IQSBOWItemSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/IQSBOWItemSocket.cs
similarity index 66%
rename from QSB/ItemSync/WorldObjects/IQSBOWItemSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/IQSBOWItemSocket.cs
index 8d42f9bc..a1cc6887 100644
--- a/QSB/ItemSync/WorldObjects/IQSBOWItemSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/IQSBOWItemSocket.cs
@@ -1,6 +1,7 @@
-using QSB.WorldSync;
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.WorldSync;
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
public interface IQSBOWItemSocket : IWorldObjectTypeSubset
{
diff --git a/QSB/ItemSync/WorldObjects/QSBNomaiConversationStoneSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBNomaiConversationStoneSocket.cs
similarity index 85%
rename from QSB/ItemSync/WorldObjects/QSBNomaiConversationStoneSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/QSBNomaiConversationStoneSocket.cs
index f193246b..bc48b86e 100644
--- a/QSB/ItemSync/WorldObjects/QSBNomaiConversationStoneSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBNomaiConversationStoneSocket.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
internal class QSBNomaiConversationStoneSocket : QSBOWItemSocket
{
diff --git a/QSB/ItemSync/WorldObjects/Sockets/QSBOWItemDoubleSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBOWItemDoubleSocket.cs
new file mode 100644
index 00000000..7ca06e54
--- /dev/null
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBOWItemDoubleSocket.cs
@@ -0,0 +1,27 @@
+using QSB.ItemSync.WorldObjects.Items;
+using QSB.WorldSync;
+
+namespace QSB.ItemSync.WorldObjects.Sockets
+{
+ internal class QSBOWItemDoubleSocket : WorldObject, IQSBOWItemSocket
+ where T : OWItemSocket
+ {
+ public override void Init(T attachedObject, int id) { }
+
+ public virtual bool AcceptsItem(IQSBOWItem item)
+ {
+ var itemType = item.GetItemType();
+ var acceptableType = AttachedObject._acceptableType;
+ return (itemType & acceptableType) == itemType;
+ }
+
+ public virtual bool IsSocketOccupied()
+ => AttachedObject.IsSocketOccupied();
+
+ public virtual bool PlaceIntoSocket(IQSBOWItem item)
+ => AttachedObject.PlaceIntoSocket((OWItem)(item as IWorldObject).ReturnObject());
+
+ public virtual IQSBOWItem RemoveFromSocket()
+ => (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(AttachedObject.RemoveFromSocket());
+ }
+}
diff --git a/QSB/ItemSync/WorldObjects/QSBOWItemSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBOWItemSocket.cs
similarity index 72%
rename from QSB/ItemSync/WorldObjects/QSBOWItemSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/QSBOWItemSocket.cs
index bd8321cb..545e8ca1 100644
--- a/QSB/ItemSync/WorldObjects/QSBOWItemSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBOWItemSocket.cs
@@ -1,7 +1,7 @@
-using OWML.Utils;
+using QSB.ItemSync.WorldObjects.Items;
using QSB.WorldSync;
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
internal class QSBOWItemSocket : WorldObject, IQSBOWItemSocket
where T : OWItemSocket
@@ -11,7 +11,7 @@ namespace QSB.ItemSync.WorldObjects
public virtual bool AcceptsItem(IQSBOWItem item)
{
var itemType = item.GetItemType();
- var acceptableType = AttachedObject.GetValue("_acceptableType");
+ var acceptableType = AttachedObject._acceptableType;
return (itemType & acceptableType) == itemType;
}
@@ -22,6 +22,6 @@ namespace QSB.ItemSync.WorldObjects
=> AttachedObject.PlaceIntoSocket((OWItem)(item as IWorldObject).ReturnObject());
public virtual IQSBOWItem RemoveFromSocket()
- => ItemManager.GetObject(AttachedObject.RemoveFromSocket());
+ => (IQSBOWItem)QSBWorldSync.GetWorldFromUnity(AttachedObject.RemoveFromSocket());
}
}
diff --git a/QSB/ItemSync/WorldObjects/QSBScrollSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBScrollSocket.cs
similarity index 83%
rename from QSB/ItemSync/WorldObjects/QSBScrollSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/QSBScrollSocket.cs
index bdf15f89..79755b9d 100644
--- a/QSB/ItemSync/WorldObjects/QSBScrollSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBScrollSocket.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
internal class QSBScrollSocket : QSBOWItemSocket
{
diff --git a/QSB/ItemSync/WorldObjects/QSBSharedStoneSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBSharedStoneSocket.cs
similarity index 84%
rename from QSB/ItemSync/WorldObjects/QSBSharedStoneSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/QSBSharedStoneSocket.cs
index 3c8341ce..357b3a0b 100644
--- a/QSB/ItemSync/WorldObjects/QSBSharedStoneSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBSharedStoneSocket.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
internal class QSBSharedStoneSocket : QSBOWItemSocket
{
diff --git a/QSB/ItemSync/WorldObjects/Sockets/QSBSlideProjectorSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBSlideProjectorSocket.cs
new file mode 100644
index 00000000..6d353c95
--- /dev/null
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBSlideProjectorSocket.cs
@@ -0,0 +1,12 @@
+namespace QSB.ItemSync.WorldObjects.Sockets
+{
+ internal class QSBSlideProjectorSocket : QSBOWItemDoubleSocket
+ {
+ public override void Init(SlideProjectorSocket attachedObject, int id)
+ {
+ ObjectId = id;
+ AttachedObject = attachedObject;
+ base.Init(attachedObject, id);
+ }
+ }
+}
diff --git a/QSB/ItemSync/WorldObjects/Sockets/QSBSlideReelSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBSlideReelSocket.cs
new file mode 100644
index 00000000..72ed11e3
--- /dev/null
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBSlideReelSocket.cs
@@ -0,0 +1,12 @@
+namespace QSB.ItemSync.WorldObjects.Sockets
+{
+ internal class QSBSlideReelSocket : QSBOWItemSocket
+ {
+ public override void Init(SlideReelSocket attachedObject, int id)
+ {
+ ObjectId = id;
+ AttachedObject = attachedObject;
+ base.Init(attachedObject, id);
+ }
+ }
+}
diff --git a/QSB/ItemSync/WorldObjects/QSBWarpCoreSocket.cs b/QSB/ItemSync/WorldObjects/Sockets/QSBWarpCoreSocket.cs
similarity index 83%
rename from QSB/ItemSync/WorldObjects/QSBWarpCoreSocket.cs
rename to QSB/ItemSync/WorldObjects/Sockets/QSBWarpCoreSocket.cs
index 1c55e986..5afa4e20 100644
--- a/QSB/ItemSync/WorldObjects/QSBWarpCoreSocket.cs
+++ b/QSB/ItemSync/WorldObjects/Sockets/QSBWarpCoreSocket.cs
@@ -1,4 +1,4 @@
-namespace QSB.ItemSync.WorldObjects
+namespace QSB.ItemSync.WorldObjects.Sockets
{
internal class QSBWarpCoreSocket : QSBOWItemSocket
{
diff --git a/QSB/LogSync/Events/RevealFactEvent.cs b/QSB/LogSync/Events/RevealFactEvent.cs
index 3c93efb2..2fd1c43f 100644
--- a/QSB/LogSync/Events/RevealFactEvent.cs
+++ b/QSB/LogSync/Events/RevealFactEvent.cs
@@ -12,7 +12,7 @@ namespace QSB.LogSync.Events
private void Handler(string id, bool saveGame, bool showNotification) => SendEvent(CreateMessage(id, saveGame, showNotification));
- private RevealFactMessage CreateMessage(string id, bool saveGame, bool showNotification) => new RevealFactMessage
+ private RevealFactMessage CreateMessage(string id, bool saveGame, bool showNotification) => new()
{
AboutId = LocalPlayerId,
FactId = id,
diff --git a/QSB/Menus/MenuManager.cs b/QSB/Menus/MenuManager.cs
index b2077ad5..7ac927ca 100644
--- a/QSB/Menus/MenuManager.cs
+++ b/QSB/Menus/MenuManager.cs
@@ -1,11 +1,12 @@
using QSB.Player;
+using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
namespace QSB.Menus
{
- class MenuManager : MonoBehaviour
+ internal class MenuManager : MonoBehaviour
{
public static MenuManager Instance;
@@ -27,7 +28,7 @@ namespace QSB.Menus
QSBNetworkManager.Instance.OnClientErrorThrown += OnClientError;
}
- void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)
+ private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)
{
if (isUniverse)
{
@@ -66,6 +67,7 @@ namespace QSB.Menus
pauseCommandListener.RemovePauseCommandLock();
_addedPauseLock = false;
}
+
OWTime.Unpause(OWTime.PauseType.System);
OWInput.RestorePreviousInputs();
}
@@ -91,7 +93,6 @@ namespace QSB.Menus
DisconnectButton = MenuApi.PauseMenu_MakeSimpleButton("DISCONNECT");
DisconnectButton.onClick.AddListener(Disconnect);
-
if (QSBCore.IsInMultiplayer)
{
ClientButton.SetActive(false);
@@ -134,6 +135,25 @@ namespace QSB.Menus
}
OnConnected();
+
+ if (QSBCore.SkipTitleScreen)
+ {
+ Application.runInBackground = true;
+ var titleScreenManager = FindObjectOfType();
+ var titleScreenAnimation = titleScreenManager._cameraController;
+ const float small = 1 / 1000f;
+ titleScreenAnimation._gamepadSplash = false;
+ titleScreenAnimation._introPan = false;
+ titleScreenAnimation._fadeDuration = small;
+ titleScreenAnimation.Start();
+ var titleAnimationController = titleScreenManager._gfxController;
+ titleAnimationController._logoFadeDelay = small;
+ titleAnimationController._logoFadeDuration = small;
+ titleAnimationController._echoesFadeDelay = small;
+ titleAnimationController._optionsFadeDelay = small;
+ titleAnimationController._optionsFadeDuration = small;
+ titleAnimationController._optionsFadeSpacing = small;
+ }
}
private void Disconnect()
@@ -155,7 +175,7 @@ namespace QSB.Menus
private void Connect()
{
- QSBNetworkManager.Instance.networkAddress = (PopupMenu as PopupInputMenu).GetInputText();
+ QSBNetworkManager.Instance.networkAddress = string.Concat((PopupMenu as PopupInputMenu).GetInputText().Where(c => !char.IsWhiteSpace(c)));
QSBNetworkManager.Instance.StartClient();
DisconnectButton.transform.GetChild(0).GetChild(1).GetComponent().text = "CONNECTING... (STOP)";
DisconnectButton.gameObject.SetActive(true);
@@ -174,26 +194,14 @@ namespace QSB.Menus
public void OnKicked(KickReason reason)
{
- string text;
- switch (reason)
+ var text = reason switch
{
- case KickReason.QSBVersionNotMatching:
- text = "Server refused connection as QSB version does not match.";
- break;
- case KickReason.GameVersionNotMatching:
- text = "Server refused connection as Outer Wilds version does not match.";
- break;
- case KickReason.GamePlatformNotMatching:
- text = "Server refused connection as Outer Wilds platform does not match. (Steam/Epic)";
- break;
- case KickReason.None:
- text = "Kicked from server. No reason given.";
- break;
- default:
- text = $"Kicked from server. KickReason:{reason}";
- break;
- }
-
+ KickReason.QSBVersionNotMatching => "Server refused connection as QSB version does not match.",
+ KickReason.GameVersionNotMatching => "Server refused connection as Outer Wilds version does not match.",
+ KickReason.GamePlatformNotMatching => "Server refused connection as Outer Wilds platform does not match. (Steam/Epic)",
+ KickReason.None => "Kicked from server. No reason given.",
+ _ => $"Kicked from server. KickReason:{reason}",
+ };
OpenInfoPopup(text, "OK");
DisconnectButton.gameObject.SetActive(false);
@@ -208,17 +216,11 @@ namespace QSB.Menus
return;
}
- string text;
- switch (error)
+ var text = error switch
{
- case NetworkError.Timeout:
- text = "Client disconnected with error!\r\nConnection timed out.";
- break;
- default:
- text = $"Client disconnected with error!\r\nNetworkError:{error}";
- break;
- }
-
+ NetworkError.Timeout => "Client disconnected with error!\r\nConnection timed out.",
+ _ => $"Client disconnected with error!\r\nNetworkError:{error}",
+ };
OpenInfoPopup(text, "OK");
DisconnectButton.gameObject.SetActive(false);
@@ -251,4 +253,4 @@ namespace QSB.Menus
OpenInfoPopup(text, "OK");
}
}
-}
\ No newline at end of file
+}
diff --git a/QSB/MeteorSync/Events/FragmentDamageEvent.cs b/QSB/MeteorSync/Events/FragmentDamageEvent.cs
new file mode 100644
index 00000000..4b830cbd
--- /dev/null
+++ b/QSB/MeteorSync/Events/FragmentDamageEvent.cs
@@ -0,0 +1,37 @@
+using QSB.Events;
+using QSB.MeteorSync.WorldObjects;
+using QSB.WorldSync;
+
+namespace QSB.MeteorSync.Events
+{
+ public class FragmentDamageEvent : QSBEvent
+ {
+ public override EventType Type => EventType.FragmentDamage;
+
+ public override void SetupListener()
+ => GlobalMessenger