fishnet installed

This commit is contained in:
2023-05-31 11:32:21 -04:00
parent 47b25269f1
commit a001fe1b04
1291 changed files with 126631 additions and 1 deletions

View File

@ -0,0 +1,68 @@
using FishNet.CodeGenerating.Helping;
using FishNet.Object.Helping;
using MonoFN.Cecil;
using System.Collections.Generic;
namespace FishNet.CodeGenerating.Processing.Rpc
{
internal static class AttributeDataExtensions
{
/// <summary>
/// Returns RpcTypes in datas.
/// </summary>
public static List<RpcType> GetRpcTypes(this List<AttributeData> datas)
{
//RpcTypes for originalMd.
List<RpcType> rpcTypes = new List<RpcType>();
foreach (AttributeData ad in datas)
rpcTypes.Add(ad.RpcType);
return rpcTypes;
}
/// <summary>
/// Gets CustomAttribute for rpcType
/// </summary>
public static CustomAttribute GetAttribute(this List<AttributeData> datas, CodegenSession session, RpcType rpcType)
{
for (int i = 0; i < datas.Count; i++)
{
if (datas[i].RpcType == rpcType)
return datas[i].Attribute;
}
session.LogError($"RpcType {rpcType} not found in datas.");
return null;
}
/// <summary>
/// Returns RpcType as flag through combining datas.
/// </summary>
/// <param name="datas"></param>
/// <returns></returns>
public static RpcType GetCombinedRpcType(this List<AttributeData> datas)
{
RpcType result = RpcType.None;
for (int i = 0; i < datas.Count; i++)
result |= datas[i].RpcType;
return result;
}
}
internal class AttributeData
{
public readonly CustomAttribute Attribute;
public readonly RpcType RpcType;
public AttributeData(CustomAttribute attribute, RpcType rpcType)
{
Attribute = attribute;
RpcType = rpcType;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91f84e00db3d1ad448fb6a760afb6927
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,166 @@
using FishNet.CodeGenerating.Helping;
using FishNet.CodeGenerating.Helping.Extension;
using FishNet.Connection;
using FishNet.Object.Helping;
using MonoFN.Cecil;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace FishNet.CodeGenerating.Processing.Rpc
{
internal class Attributes : CodegenBase
{
/// <summary>
/// Returns if methodDef has any Rpc attribute.
/// </summary>
public bool HasRpcAttributes(MethodDefinition methodDef)
{
foreach (CustomAttribute customAttribute in methodDef.CustomAttributes)
{
RpcType rt = base.Session.GetClass<AttributeHelper>().GetRpcAttributeType(customAttribute);
if (rt != RpcType.None)
return true;
}
//Fall through, nothing found.
return false;
}
/// <summary>
/// Returns a collection of RpcAttribute for methodDef.
/// </summary>
public List<AttributeData> GetRpcAttributes(MethodDefinition methodDef)
{
List<AttributeData> results = new List<AttributeData>();
string asyncAttributeFullName = typeof(AsyncStateMachineAttribute).FullName;
bool isAsync = false;
foreach (CustomAttribute customAttribute in methodDef.CustomAttributes)
{
RpcType rt = base.Session.GetClass<AttributeHelper>().GetRpcAttributeType(customAttribute);
if (rt != RpcType.None)
{
results.Add(new AttributeData(customAttribute, rt));
}
//Not a rpc attribute.
else
{
//Check if async.
if (customAttribute.Is(asyncAttributeFullName))
isAsync = true;
}
}
//Nothing found, exit early.
if (results.Count == 0)
{
return results;
}
//If has at least one RPC attrivbute and is an async method.
else if (isAsync)
{
base.Session.LogError($"{methodDef.Name} is an async RPC. This feature is not currently supported. You may instead run an async method from this RPC.");
return new List<AttributeData>();
}
//If more than one attribute make sure the combination is allowed.
else if (results.Count >= 2)
{
RpcType allRpcTypes = results.GetCombinedRpcType();
if (allRpcTypes != (RpcType.Observers | RpcType.Target))
{
base.Session.LogError($"{methodDef.Name} contains multiple RPC attributes. Only ObserversRpc and TargetRpc attributes may be combined.");
return new List<AttributeData>();
}
}
//Next validate that the method is setup properly for each rpcType.
foreach (AttributeData ad in results)
{
//If not valid then return empty list.
if (!IsRpcMethodValid(methodDef, ad.RpcType))
return new List<AttributeData>();
}
return results;
}
/// <summary>
/// Returns if a RpcMethod can be serialized and has a proper signature.
/// </summary>
private bool IsRpcMethodValid(MethodDefinition methodDef, RpcType rpcType)
{
//Static method.
if (methodDef.IsStatic)
{
base.Session.LogError($"{methodDef.Name} RPC method cannot be static.");
return false;
}
//Is generic type.
else if (methodDef.HasGenericParameters)
{
base.Session.LogError($"{methodDef.Name} RPC method cannot contain generic parameters.");
return false;
}
//Abstract method.
else if (methodDef.IsAbstract)
{
base.Session.LogError($"{methodDef.Name} RPC method cannot be abstract.");
return false;
}
//Non void return.
else if (methodDef.ReturnType != methodDef.Module.TypeSystem.Void)
{
base.Session.LogError($"{methodDef.Name} RPC method must return void.");
return false;
}
//Misc failing conditions.
else
{
//Check for async attribute.
foreach (CustomAttribute ca in methodDef.CustomAttributes)
{
}
}
//TargetRpc but missing correct parameters.
if (rpcType == RpcType.Target)
{
if (methodDef.Parameters.Count == 0 || !methodDef.Parameters[0].Is(typeof(NetworkConnection)))
{
base.Session.LogError($"Target RPC {methodDef.Name} must have a NetworkConnection as the first parameter.");
return false;
}
}
//Make sure all parameters can be serialized.
for (int i = 0; i < methodDef.Parameters.Count; i++)
{
ParameterDefinition parameterDef = methodDef.Parameters[i];
//If NetworkConnection, TargetRpc, and first parameter.
if ((i == 0) && (rpcType == RpcType.Target) && parameterDef.Is(typeof(NetworkConnection)))
continue;
if (parameterDef.ParameterType.IsGenericParameter)
{
base.Session.LogError($"RPC method{methodDef.Name} contains a generic parameter. This is currently not supported.");
return false;
}
//Can be serialized/deserialized.
bool canSerialize = base.GetClass<GeneralHelper>().HasSerializerAndDeserializer(parameterDef.ParameterType, true);
if (!canSerialize)
{
base.Session.LogError($"RPC method {methodDef.Name} parameter type {parameterDef.ParameterType.FullName} does not support serialization. Use a supported type or create a custom serializer.");
return false;
}
}
//Fall through, success.
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 974ebf09757267941a86f92e5072258c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,58 @@
using FishNet.Object.Helping;
using MonoFN.Cecil;
using System.Collections.Generic;
namespace FishNet.CodeGenerating.Processing.Rpc
{
internal class CreatedRpc
{
public MethodDefinition OriginalMethodDef;
public uint MethodHash;
public AttributeData AttributeData;
public MethodDefinition WriterMethodDef;
public MethodDefinition ReaderMethodDef;
public MethodDefinition LogicMethodDef;
public MethodDefinition RedirectMethodDef;
public bool RunLocally;
public RpcType RpcType => AttributeData.RpcType;
public CustomAttribute Attribute => AttributeData.Attribute;
public TypeDefinition TypeDef => OriginalMethodDef.DeclaringType;
public ModuleDefinition Module => OriginalMethodDef.Module;
}
internal static class CreatedRpcExtensions
{
/// <summary>
/// Returns CreatedRpc for rpcType.
/// </summary>
/// <returns></returns>
public static CreatedRpc GetCreatedRpc(this List<CreatedRpc> lst, RpcType rpcType)
{
for (int i = 0; i < lst.Count; i++)
{
if (lst[i].RpcType == rpcType)
return lst[i];
}
//Fall through.
return null;
}
/// <summary>
/// Returns combined RpcType for all entries.
/// </summary>
/// <returns></returns>
public static RpcType GetCombinedRpcType(this List<CreatedRpc> lst)
{
RpcType result = RpcType.None;
for (int i = 0; i < lst.Count; i++)
result |= lst[i].RpcType;
return result;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c2176b6bfcc49934d8f36fba3df74d0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d4adb5891ee44f4397cd07ac2df0ce0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: