mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-24 00:39:52 +00:00
merge dev into fixes
This commit is contained in:
commit
4b886951db
Binary file not shown.
@ -1,12 +1,12 @@
|
|||||||
ManifestFileVersion: 0
|
ManifestFileVersion: 0
|
||||||
CRC: 912924545
|
CRC: 1923832523
|
||||||
Hashes:
|
Hashes:
|
||||||
AssetFileHash:
|
AssetFileHash:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Hash: 01fb51db952cadf5ea7a5ff414ca5734
|
Hash: 4fc717bd6085672c7fc1dafa5359e292
|
||||||
TypeTreeHash:
|
TypeTreeHash:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Hash: 4c1d64afc7729493eb4d28f957f9246d
|
Hash: 9036f53e57d0e71c74f56622ad045de9
|
||||||
HashAppended: 0
|
HashAppended: 0
|
||||||
ClassTypes:
|
ClassTypes:
|
||||||
- Class: 1
|
- Class: 1
|
||||||
@ -37,6 +37,12 @@ ClassTypes:
|
|||||||
Script: {fileID: -2281650, guid: 27687deae413b90448366870cb0de502, type: 3}
|
Script: {fileID: -2281650, guid: 27687deae413b90448366870cb0de502, type: 3}
|
||||||
- Class: 114
|
- Class: 114
|
||||||
Script: {fileID: 2036222940, guid: 27687deae413b90448366870cb0de502, type: 3}
|
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
|
- Class: 115
|
||||||
Script: {instanceID: 0}
|
Script: {instanceID: 0}
|
||||||
SerializeReferenceClassIdentifiers: []
|
SerializeReferenceClassIdentifiers: []
|
||||||
|
@ -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<TypeReference> 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<TypeReference> genericArguments = genericInstanceType.GenericArguments;
|
|
||||||
result = text + text2 + string.Join(text3, Enumerable.ToArray<string>(Enumerable.Select<TypeReference, string>(genericArguments, new Func<TypeReference, string>(PrettyPrintType)))) + ">";
|
|
||||||
}
|
|
||||||
else if (type.HasGenericParameters)
|
|
||||||
{
|
|
||||||
result = type.Name.Substring(0, type.Name.Length - 2) + "<" + string.Join(", ", Enumerable.ToArray<string>(Enumerable.Select<GenericParameter, string>(type.GenericParameters, (GenericParameter x) => x.Name))) + ">";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = type.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ReaderParameters ReaderParameters(string assemblyPath, IEnumerable<string> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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")]
|
|
@ -1,86 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProjectGuid>{E23551F3-C095-4F50-8BF7-85BB2661859B}</ProjectGuid>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<RootNamespace>QNetWeaver</RootNamespace>
|
|
||||||
<AssemblyName>QNetWeaver</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
<FileAlignment>512</FileAlignment>
|
|
||||||
<Deterministic>true</Deterministic>
|
|
||||||
<TargetFrameworkProfile />
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
<Optimize>true</Optimize>
|
|
||||||
<OutputPath>bin\Release\</OutputPath>
|
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<LangVersion>9.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Mono.Cecil, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Mdb, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Mdb.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Pdb, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Pdb.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Cecil.Rocks, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Rocks.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="Unity.UNetWeaver, Version=1.0.7209.2424, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>lib\Unity.UNetWeaver.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="Helpers.cs" />
|
|
||||||
<Compile Include="Log.cs" />
|
|
||||||
<Compile Include="MessageClassProcessor.cs" />
|
|
||||||
<Compile Include="MonoBehaviourProcessor.cs" />
|
|
||||||
<Compile Include="NetworkBehaviourProcessor.cs" />
|
|
||||||
<Compile Include="Program.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
|
||||||
<Compile Include="SyncListStructProcessor.cs" />
|
|
||||||
<Compile Include="Weaver.cs" />
|
|
||||||
<Compile Include="WeaverLists.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="lib\Unity.UNetWeaver.dll" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="app.config" />
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
</Project>
|
|
@ -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<T> 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;
|
|
||||||
}
|
|
||||||
}
|
|
2038
QNetWeaver/Weaver.cs
2038
QNetWeaver/Weaver.cs
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
|||||||
using Mono.Cecil;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace QNetWeaver
|
|
||||||
{
|
|
||||||
internal class WeaverLists
|
|
||||||
{
|
|
||||||
public List<FieldDefinition> replacedFields = new List<FieldDefinition>();
|
|
||||||
|
|
||||||
public List<MethodDefinition> replacementProperties = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public List<FieldDefinition> netIdFields = new List<FieldDefinition>();
|
|
||||||
|
|
||||||
public List<MethodDefinition> replacedMethods = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public List<MethodDefinition> replacementMethods = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public HashSet<string> replacementMethodNames = new HashSet<string>();
|
|
||||||
|
|
||||||
public List<EventDefinition> replacedEvents = new List<EventDefinition>();
|
|
||||||
|
|
||||||
public List<MethodDefinition> replacementEvents = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public Dictionary<string, MethodReference> readFuncs;
|
|
||||||
|
|
||||||
public Dictionary<string, MethodReference> readByReferenceFuncs;
|
|
||||||
|
|
||||||
public Dictionary<string, MethodReference> writeFuncs;
|
|
||||||
|
|
||||||
public List<MethodDefinition> generatedReadFunctions = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public List<MethodDefinition> generatedWriteFunctions = new List<MethodDefinition>();
|
|
||||||
|
|
||||||
public TypeDefinition generateContainerClass;
|
|
||||||
|
|
||||||
public Dictionary<string, int> numSyncVars = new Dictionary<string, int>();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
|
|
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Mono.Cecil" version="0.11.4" targetFramework="net40" />
|
|
||||||
</packages>
|
|
13
QSB.sln
13
QSB.sln
@ -1,19 +1,14 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29613.14
|
VisualStudioVersion = 17.0.31903.59
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSB", "QSB\QSB.csproj", "{1F00090A-C697-4C55-B401-192F3CFB9DC2}"
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuantumUNET", "QuantumUNET\QuantumUNET.csproj", "{C8C53004-1508-4F86-A419-4292C188DC2A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuantumUNET", "QuantumUNET\QuantumUNET.csproj", "{C8C53004-1508-4F86-A419-4292C188DC2A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSBTests", "QSBTests\QSBTests.csproj", "{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSBTests", "QSBTests\QSBTests.csproj", "{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}"
|
||||||
EndProject
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2569F98D-F671-42AA-82DE-505B05CDCEF2}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.gitignore = .gitignore
|
.gitignore = .gitignore
|
||||||
@ -40,10 +35,6 @@ Global
|
|||||||
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{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.ActiveCfg = Release|Any CPU
|
||||||
{2FE8256C-0CB6-48F1-A4C0-5FA18A1846A3}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using QuantumUNET;
|
using QSB.Utility;
|
||||||
|
using QSB.Utility.VariableSync;
|
||||||
|
using QuantumUNET;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
@ -14,13 +16,15 @@ namespace QSB.Animation.Player
|
|||||||
private PlayerCharacterController _playerController;
|
private PlayerCharacterController _playerController;
|
||||||
private Animator _bodyAnim;
|
private Animator _bodyAnim;
|
||||||
|
|
||||||
[SyncVar]
|
public FloatVariableSyncer CrouchVariableSyncer;
|
||||||
private float _crouchValue;
|
public float CrouchValue = 0f;
|
||||||
|
|
||||||
public void Init(PlayerCharacterController playerController, Animator bodyAnim)
|
public void Init(PlayerCharacterController playerController, Animator bodyAnim)
|
||||||
{
|
{
|
||||||
_playerController = playerController;
|
_playerController = playerController;
|
||||||
_bodyAnim = bodyAnim;
|
_bodyAnim = bodyAnim;
|
||||||
|
|
||||||
|
CrouchVariableSyncer.Init(() => CrouchValue, val => CrouchValue = val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@ -42,7 +46,7 @@ namespace QSB.Animation.Player
|
|||||||
}
|
}
|
||||||
|
|
||||||
var jumpChargeFraction = _playerController.GetJumpCrouchFraction();
|
var jumpChargeFraction = _playerController.GetJumpCrouchFraction();
|
||||||
_crouchValue = jumpChargeFraction;
|
CrouchVariableSyncer.ValueToSync.Value = jumpChargeFraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SyncRemoteCrouch()
|
private void SyncRemoteCrouch()
|
||||||
@ -52,7 +56,7 @@ namespace QSB.Animation.Player
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CrouchParam.Target = _crouchValue;
|
CrouchParam.Target = CrouchValue;
|
||||||
CrouchParam.Smooth(CrouchSmoothTime);
|
CrouchParam.Smooth(CrouchSmoothTime);
|
||||||
var jumpChargeFraction = CrouchParam.Current;
|
var jumpChargeFraction = CrouchParam.Current;
|
||||||
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
|
_bodyAnim.SetLayerWeight(CrouchLayerIndex, jumpChargeFraction);
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
using QuantumUNET;
|
using QSB.Utility.VariableSync;
|
||||||
|
using QuantumUNET;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
|
||||||
|
|
||||||
namespace QSB.Animation.Player.Thrusters
|
namespace QSB.Animation.Player.Thrusters
|
||||||
{
|
{
|
||||||
public class JetpackAccelerationSync : QNetworkBehaviour
|
public class JetpackAccelerationSync : QNetworkBehaviour
|
||||||
{
|
{
|
||||||
[SyncVar]
|
public Vector3VariableSyncer AccelerationVariableSyncer;
|
||||||
private Vector3 _localAcceleration;
|
public BoolVariableSyncer ThrustingVariableSyncer;
|
||||||
[SyncVar]
|
public Vector3 LocalAcceleration => AccelerationVariableSyncer.ValueToSync.Value;
|
||||||
private bool _isThrusting;
|
public bool IsThrusting => ThrustingVariableSyncer.ValueToSync.Value;
|
||||||
|
|
||||||
|
private Vector3 _localAcceleration;
|
||||||
|
private bool _isThrusting;
|
||||||
private ThrusterModel _thrusterModel;
|
private ThrusterModel _thrusterModel;
|
||||||
|
|
||||||
public Vector3 LocalAcceleration => _localAcceleration;
|
|
||||||
public bool IsThrusting => _isThrusting;
|
|
||||||
|
|
||||||
public void Init(ThrusterModel model)
|
public void Init(ThrusterModel model)
|
||||||
=> _thrusterModel = model;
|
{
|
||||||
|
_thrusterModel = model;
|
||||||
|
|
||||||
|
AccelerationVariableSyncer.Init(() => _localAcceleration, val => _localAcceleration = val);
|
||||||
|
ThrustingVariableSyncer.Init(() => _isThrusting, val => _isThrusting = val);
|
||||||
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
@ -31,8 +35,8 @@ namespace QSB.Animation.Player.Thrusters
|
|||||||
{
|
{
|
||||||
if (_thrusterModel != null)
|
if (_thrusterModel != null)
|
||||||
{
|
{
|
||||||
_localAcceleration = _thrusterModel.GetLocalAcceleration();
|
AccelerationVariableSyncer.ValueToSync.Value = _thrusterModel.GetLocalAcceleration();
|
||||||
_isThrusting = _thrusterModel.IsTranslationalThrusterFiring();
|
ThrustingVariableSyncer.ValueToSync.Value = _thrusterModel.IsTranslationalThrusterFiring();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
SatelliteProjector,
|
SatelliteProjector,
|
||||||
SatelliteProjectorSnapshot,
|
SatelliteProjectorSnapshot,
|
||||||
LaunchCodes,
|
LaunchCodes,
|
||||||
|
VariableSync,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SERVER EVENTS
|
* SERVER EVENTS
|
||||||
|
@ -332,6 +332,11 @@
|
|||||||
<Compile Include="Utility\Events\DebugEvent.cs" />
|
<Compile Include="Utility\Events\DebugEvent.cs" />
|
||||||
<Compile Include="Utility\Events\DebugEventEnum.cs" />
|
<Compile Include="Utility\Events\DebugEventEnum.cs" />
|
||||||
<Compile Include="Utility\UIHelper.cs" />
|
<Compile Include="Utility\UIHelper.cs" />
|
||||||
|
<Compile Include="Utility\VariableSync\BaseVariableSyncer.cs" />
|
||||||
|
<Compile Include="Utility\VariableSync\BoolVariableSyncer.cs" />
|
||||||
|
<Compile Include="Utility\VariableSync\VariableReference.cs" />
|
||||||
|
<Compile Include="Utility\VariableSync\FloatVariableSyncer.cs" />
|
||||||
|
<Compile Include="Utility\VariableSync\Vector3VariableSyncer.cs" />
|
||||||
<Compile Include="Utility\ZOverride.cs" />
|
<Compile Include="Utility\ZOverride.cs" />
|
||||||
<Compile Include="Utility\Extensions.cs" />
|
<Compile Include="Utility\Extensions.cs" />
|
||||||
<Compile Include="Utility\GlobalMessenger4Args.cs" />
|
<Compile Include="Utility\GlobalMessenger4Args.cs" />
|
||||||
@ -487,23 +492,18 @@ md "$(OwmlDir)\Mods\$(ProjectName)\assets"
|
|||||||
:: delete old config file
|
:: delete old config file
|
||||||
del "$(OwmlDir)\Mods\$(ProjectName)\config.json"
|
del "$(OwmlDir)\Mods\$(ProjectName)\config.json"
|
||||||
|
|
||||||
:: copy files that dont need to be processed
|
:: copy files
|
||||||
copy /y "$(ProjectDir)\default-config.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
copy /y "$(ProjectDir)\default-config.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||||
copy /y "$(SolutionDir)\AssetBundles" "$(OwmlDir)\Mods\$(ProjectName)\assets"
|
copy /y "$(SolutionDir)\AssetBundles" "$(OwmlDir)\Mods\$(ProjectName)\assets"
|
||||||
copy /y "$(ProjectDir)\manifest.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
copy /y "$(ProjectDir)\manifest.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||||
copy /y "$(ProjectDir)\debugsettings.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
copy /y "$(ProjectDir)\debugsettings.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||||
|
copy /y "$(TargetPath)" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||||
:: process qsb.dll
|
|
||||||
"$(SolutionDir)\QNetWeaver\bin\$(Configuration)\QNetWeaver.exe" "$(GameDir)\OuterWilds_Data\Managed\UnityEngine.CoreModule.dll" "$(OwmlDir)\Mods\$(ProjectName)\QuantumUNET.dll" "$(ProjectDir)\lib\UnityEngine.Networking.dll" "$(SolutionDir)\WeavedFiles" "$(TargetPath)"
|
|
||||||
|
|
||||||
:: copy processed dll
|
|
||||||
copy /y "$(SolutionDir)\WeavedFiles\QSB.dll" "$(OwmlDir)\Mods\$(ProjectName)"
|
|
||||||
|
|
||||||
:: copy all lib files
|
:: copy all lib files
|
||||||
xcopy /y "$(ProjectDir)\lib" "$(OwmlDir)\Mods\$(ProjectName)"
|
xcopy /y "$(ProjectDir)\lib" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||||
|
|
||||||
:: copy processed dll to unity project
|
:: copy dll to unity project
|
||||||
copy /y "$(SolutionDir)\WeavedFiles\QSB.dll" $(UnityAssetsDir)
|
copy /y "$(TargetPath)" $(UnityAssetsDir)
|
||||||
:: copy quantumunet to unity project
|
:: copy quantumunet to unity project
|
||||||
copy /y "$(OwmlDir)\Mods\$(ProjectName)\QuantumUNET.dll" $(UnityAssetsDir)
|
copy /y "$(OwmlDir)\Mods\$(ProjectName)\QuantumUNET.dll" $(UnityAssetsDir)
|
||||||
:: copy game assembly to unity project
|
:: copy game assembly to unity project
|
||||||
|
114
QSB/Utility/VariableSync/BaseVariableSyncer.cs
Normal file
114
QSB/Utility/VariableSync/BaseVariableSyncer.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using QuantumUNET;
|
||||||
|
using QuantumUNET.Messages;
|
||||||
|
using QuantumUNET.Transport;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
|
namespace QSB.Utility.VariableSync
|
||||||
|
{
|
||||||
|
public abstract class BaseVariableSyncer : QNetworkBehaviour
|
||||||
|
{
|
||||||
|
private float _lastClientSendTime;
|
||||||
|
private QNetworkWriter _writer;
|
||||||
|
private int _index;
|
||||||
|
protected bool _ready;
|
||||||
|
|
||||||
|
public abstract void WriteData(QNetworkWriter writer);
|
||||||
|
public abstract void ReadData(QNetworkReader writer);
|
||||||
|
|
||||||
|
public virtual void Awake()
|
||||||
|
{
|
||||||
|
QNetworkServer.instance.m_SimpleServerSimple.RegisterHandlerSafe((short)QSB.Events.EventType.VariableSync, HandleVariable);
|
||||||
|
|
||||||
|
if (LocalPlayerAuthority)
|
||||||
|
{
|
||||||
|
_writer = new QNetworkWriter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Start()
|
||||||
|
=> _index = GetComponents<BaseVariableSyncer>().ToList().IndexOf(this);
|
||||||
|
|
||||||
|
public override bool OnSerialize(QNetworkWriter writer, bool initialState)
|
||||||
|
{
|
||||||
|
if (!initialState)
|
||||||
|
{
|
||||||
|
if (SyncVarDirtyBits == 0U)
|
||||||
|
{
|
||||||
|
writer.WritePackedUInt32(0U);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackedUInt32(1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteData(writer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDeserialize(QNetworkReader reader, bool initialState)
|
||||||
|
{
|
||||||
|
if (!IsServer || !QNetworkServer.localClientActive)
|
||||||
|
{
|
||||||
|
if (!initialState && reader.ReadPackedUInt32() == 0U)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadData(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (!IsServer || SyncVarDirtyBits != 0U || !QNetworkServer.active || !_ready)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetNetworkSendInterval() != 0f)
|
||||||
|
{
|
||||||
|
SetDirtyBit(1U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Update()
|
||||||
|
{
|
||||||
|
if (!HasAuthority || !LocalPlayerAuthority || QNetworkServer.active || !_ready)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.time - _lastClientSendTime > GetNetworkSendInterval())
|
||||||
|
{
|
||||||
|
SendVariable();
|
||||||
|
_lastClientSendTime = Time.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
private void SendVariable()
|
||||||
|
{
|
||||||
|
// TODO - this sends a message, even when the value hasnt changed! this is really bad!
|
||||||
|
if (QClientScene.readyConnection != null)
|
||||||
|
{
|
||||||
|
_writer.StartMessage((short)QSB.Events.EventType.VariableSync);
|
||||||
|
_writer.Write(NetId);
|
||||||
|
_writer.Write(_index);
|
||||||
|
WriteData(_writer);
|
||||||
|
_writer.FinishMessage();
|
||||||
|
QClientScene.readyConnection.SendWriter(_writer, GetNetworkChannel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HandleVariable(QNetworkMessage netMsg)
|
||||||
|
{
|
||||||
|
var networkInstanceId = netMsg.Reader.ReadNetworkId();
|
||||||
|
var index = netMsg.Reader.ReadInt32();
|
||||||
|
var gameObject = QNetworkServer.FindLocalObject(networkInstanceId);
|
||||||
|
var components = gameObject.GetComponents<BaseVariableSyncer>();
|
||||||
|
components[index].ReadData(netMsg.Reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
QSB/Utility/VariableSync/BoolVariableSyncer.cs
Normal file
26
QSB/Utility/VariableSync/BoolVariableSyncer.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using QuantumUNET.Transport;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace QSB.Utility.VariableSync
|
||||||
|
{
|
||||||
|
public class BoolVariableSyncer : BaseVariableSyncer
|
||||||
|
{
|
||||||
|
public VariableReference<bool> ValueToSync { get; private set; } = new();
|
||||||
|
|
||||||
|
public void Init(Func<bool> getter, Action<bool> setter)
|
||||||
|
{
|
||||||
|
ValueToSync.Getter = getter;
|
||||||
|
ValueToSync.Setter = setter;
|
||||||
|
_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDestroy()
|
||||||
|
=> _ready = false;
|
||||||
|
|
||||||
|
public override void WriteData(QNetworkWriter writer)
|
||||||
|
=> writer.Write(ValueToSync.Value);
|
||||||
|
|
||||||
|
public override void ReadData(QNetworkReader writer)
|
||||||
|
=> ValueToSync.Value = writer.ReadBoolean();
|
||||||
|
}
|
||||||
|
}
|
26
QSB/Utility/VariableSync/FloatVariableSyncer.cs
Normal file
26
QSB/Utility/VariableSync/FloatVariableSyncer.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using QuantumUNET.Transport;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace QSB.Utility.VariableSync
|
||||||
|
{
|
||||||
|
public class FloatVariableSyncer : BaseVariableSyncer
|
||||||
|
{
|
||||||
|
public VariableReference<float> ValueToSync { get; private set; } = new();
|
||||||
|
|
||||||
|
public void Init(Func<float> getter, Action<float> setter)
|
||||||
|
{
|
||||||
|
ValueToSync.Getter = getter;
|
||||||
|
ValueToSync.Setter = setter;
|
||||||
|
_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDestroy()
|
||||||
|
=> _ready = false;
|
||||||
|
|
||||||
|
public override void WriteData(QNetworkWriter writer)
|
||||||
|
=> writer.Write(ValueToSync.Value);
|
||||||
|
|
||||||
|
public override void ReadData(QNetworkReader writer)
|
||||||
|
=> ValueToSync.Value = writer.ReadSingle();
|
||||||
|
}
|
||||||
|
}
|
45
QSB/Utility/VariableSync/VariableReference.cs
Normal file
45
QSB/Utility/VariableSync/VariableReference.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using QSB.Player;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace QSB.Utility.VariableSync
|
||||||
|
{
|
||||||
|
public class VariableReference<T>
|
||||||
|
{
|
||||||
|
public Func<T> Getter;
|
||||||
|
public Action<T> Setter;
|
||||||
|
|
||||||
|
public T Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Getter != null)
|
||||||
|
{
|
||||||
|
return Getter();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (QSBPlayerManager.LocalPlayer.IsReady)
|
||||||
|
{
|
||||||
|
DebugLog.ToConsole($"Warning - Getter is null!", OWML.Common.MessageType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Setter != null)
|
||||||
|
{
|
||||||
|
Setter(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (QSBPlayerManager.LocalPlayer.IsReady)
|
||||||
|
{
|
||||||
|
DebugLog.ToConsole($"Warning - Setter is null!", OWML.Common.MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
QSB/Utility/VariableSync/Vector3VariableSyncer.cs
Normal file
27
QSB/Utility/VariableSync/Vector3VariableSyncer.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using QuantumUNET.Transport;
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace QSB.Utility.VariableSync
|
||||||
|
{
|
||||||
|
public class Vector3VariableSyncer : BaseVariableSyncer
|
||||||
|
{
|
||||||
|
public VariableReference<Vector3> ValueToSync { get; private set; } = new();
|
||||||
|
|
||||||
|
public void Init(Func<Vector3> getter, Action<Vector3> setter)
|
||||||
|
{
|
||||||
|
ValueToSync.Getter = getter;
|
||||||
|
ValueToSync.Setter = setter;
|
||||||
|
_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDestroy()
|
||||||
|
=> _ready = false;
|
||||||
|
|
||||||
|
public override void WriteData(QNetworkWriter writer)
|
||||||
|
=> writer.Write(ValueToSync.Value);
|
||||||
|
|
||||||
|
public override void ReadData(QNetworkReader writer)
|
||||||
|
=> ValueToSync.Value = writer.ReadVector3();
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ namespace QuantumUNET
|
|||||||
|
|
||||||
public static bool dontListen { get; set; }
|
public static bool dontListen { get; set; }
|
||||||
|
|
||||||
internal static QNetworkServer instance
|
public static QNetworkServer instance
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -1348,7 +1348,7 @@ namespace QuantumUNET
|
|||||||
|
|
||||||
private readonly HashSet<int> m_ExternalConnections;
|
private readonly HashSet<int> m_ExternalConnections;
|
||||||
|
|
||||||
private readonly ServerSimpleWrapper m_SimpleServerSimple;
|
public readonly ServerSimpleWrapper m_SimpleServerSimple;
|
||||||
|
|
||||||
private float m_MaxDelay = 0.1f;
|
private float m_MaxDelay = 0.1f;
|
||||||
|
|
||||||
@ -1362,7 +1362,7 @@ namespace QuantumUNET
|
|||||||
|
|
||||||
private static readonly QRemovePlayerMessage s_RemovePlayerMessage = new();
|
private static readonly QRemovePlayerMessage s_RemovePlayerMessage = new();
|
||||||
|
|
||||||
private class ServerSimpleWrapper : QNetworkServerSimple
|
public class ServerSimpleWrapper : QNetworkServerSimple
|
||||||
{
|
{
|
||||||
public ServerSimpleWrapper(QNetworkServer server) => m_Server = server;
|
public ServerSimpleWrapper(QNetworkServer server) => m_Server = server;
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ namespace QuantumUNET
|
|||||||
serverHostId = -1;
|
serverHostId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RegisterHandlerSafe(short msgType, QNetworkMessageDelegate handler)
|
public void RegisterHandlerSafe(short msgType, QNetworkMessageDelegate handler)
|
||||||
=> m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
|
=> m_MessageHandlers.RegisterHandlerSafe(msgType, handler);
|
||||||
|
|
||||||
public void RegisterHandler(short msgType, QNetworkMessageDelegate handler)
|
public void RegisterHandler(short msgType, QNetworkMessageDelegate handler)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user