mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
feat: Use Server Client attribute outside of NetworkBehaviour (#2150)
* adding generated test for other baseclasses * removing errors when attribute is not in networkbehaviour * temp weaver tests * updating weaver tests for monobehaviour * adding weaver tests for non-networkbehaviour * moving where serverclient attributes are processed * removing un-used code * regenerate tests
This commit is contained in:
parent
c6fa49c72a
commit
eec49fafce
@ -49,24 +49,6 @@ static void ProcessMethods(TypeDefinition td)
|
||||
{
|
||||
Weaver.Error($"TargetRpc {md.Name} must be declared inside a NetworkBehaviour", md);
|
||||
}
|
||||
|
||||
string attributeName = ca.Constructor.DeclaringType.ToString();
|
||||
|
||||
switch (attributeName)
|
||||
{
|
||||
case "Mirror.ServerAttribute":
|
||||
Weaver.Error($"Server method {md.Name} must be declared inside a NetworkBehaviour", md);
|
||||
break;
|
||||
case "Mirror.ServerCallbackAttribute":
|
||||
Weaver.Error($"ServerCallback method {md.Name} must be declared inside a NetworkBehaviour", md);
|
||||
break;
|
||||
case "Mirror.ClientAttribute":
|
||||
Weaver.Error($"Client method {md.Name} must be declared inside a NetworkBehaviour", md);
|
||||
break;
|
||||
case "Mirror.ClientCallbackAttribute":
|
||||
Weaver.Error($"ClientCallback method {md.Name} must be declared inside a NetworkBehaviour", md);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ static void ProcessSiteClass(TypeDefinition td)
|
||||
//Console.WriteLine(" ProcessSiteClass " + td);
|
||||
foreach (MethodDefinition md in td.Methods)
|
||||
{
|
||||
ProcessSiteMethod(td, md);
|
||||
ProcessSiteMethod(md);
|
||||
}
|
||||
|
||||
foreach (TypeDefinition nested in td.NestedTypes)
|
||||
@ -50,7 +50,7 @@ static void ProcessSiteClass(TypeDefinition td)
|
||||
}
|
||||
}
|
||||
|
||||
static void ProcessSiteMethod(TypeDefinition td, MethodDefinition md)
|
||||
static void ProcessSiteMethod(MethodDefinition md)
|
||||
{
|
||||
// process all references to replaced members with properties
|
||||
//Weaver.DLog(td, " ProcessSiteMethod " + md);
|
||||
@ -62,18 +62,11 @@ static void ProcessSiteMethod(TypeDefinition td, MethodDefinition md)
|
||||
|
||||
if (md.IsAbstract)
|
||||
{
|
||||
if (ServerClientAttributeProcessor.HasServerClientAttribute(md))
|
||||
{
|
||||
Weaver.Error("Server or Client Attributes can't be added to abstract method. Server and Client Attributes are not inherited so they need to be applied to the override methods instead.", md);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (md.Body != null && md.Body.Instructions != null)
|
||||
{
|
||||
// TODO move this to NetworkBehaviourProcessor
|
||||
ServerClientAttributeProcessor.ProcessMethodAttributes(td, md);
|
||||
|
||||
for (int iCount = 0; iCount < md.Body.Instructions.Count;)
|
||||
{
|
||||
Instruction instr = md.Body.Instructions[iCount];
|
||||
|
@ -8,6 +8,44 @@ namespace Mirror.Weaver
|
||||
/// </summary>
|
||||
static class ServerClientAttributeProcessor
|
||||
{
|
||||
public static bool ProcessSiteClass(TypeDefinition td)
|
||||
{
|
||||
bool modified = false;
|
||||
foreach (MethodDefinition md in td.Methods)
|
||||
{
|
||||
modified |= ProcessSiteMethod(td, md);
|
||||
}
|
||||
|
||||
foreach (TypeDefinition nested in td.NestedTypes)
|
||||
{
|
||||
modified |= ProcessSiteClass(nested);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
static bool ProcessSiteMethod(TypeDefinition td, MethodDefinition md)
|
||||
{
|
||||
if (md.Name == ".cctor" ||
|
||||
md.Name == NetworkBehaviourProcessor.ProcessedFunctionName ||
|
||||
md.Name.StartsWith(Weaver.InvokeRpcPrefix))
|
||||
return false;
|
||||
|
||||
if (md.IsAbstract)
|
||||
{
|
||||
if (HasServerClientAttribute(md))
|
||||
{
|
||||
Weaver.Error("Server or Client Attributes can't be added to abstract method. Server and Client Attributes are not inherited so they need to be applied to the override methods instead.", md);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (md.Body != null && md.Body.Instructions != null)
|
||||
{
|
||||
return ProcessMethodAttributes(td, md);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasServerClientAttribute(MethodDefinition md)
|
||||
{
|
||||
foreach (CustomAttribute attr in md.CustomAttributes)
|
||||
@ -26,37 +64,39 @@ public static bool HasServerClientAttribute(MethodDefinition md)
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ProcessMethodAttributes(TypeDefinition td, MethodDefinition md)
|
||||
public static bool ProcessMethodAttributes(TypeDefinition td, MethodDefinition md)
|
||||
{
|
||||
bool modified = false;
|
||||
foreach (CustomAttribute attr in md.CustomAttributes)
|
||||
{
|
||||
switch (attr.Constructor.DeclaringType.ToString())
|
||||
{
|
||||
case "Mirror.ServerAttribute":
|
||||
InjectServerGuard(td, md, true);
|
||||
InjectServerGuard(md, true);
|
||||
modified = true;
|
||||
break;
|
||||
case "Mirror.ServerCallbackAttribute":
|
||||
InjectServerGuard(td, md, false);
|
||||
InjectServerGuard(md, false);
|
||||
modified = true;
|
||||
break;
|
||||
case "Mirror.ClientAttribute":
|
||||
InjectClientGuard(td, md, true);
|
||||
InjectClientGuard(md, true);
|
||||
modified = true;
|
||||
break;
|
||||
case "Mirror.ClientCallbackAttribute":
|
||||
InjectClientGuard(td, md, false);
|
||||
InjectClientGuard(md, false);
|
||||
modified = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
static void InjectServerGuard(TypeDefinition td, MethodDefinition md, bool logWarning)
|
||||
static void InjectServerGuard(MethodDefinition md, bool logWarning)
|
||||
{
|
||||
if (!Weaver.IsNetworkBehaviour(td))
|
||||
{
|
||||
Weaver.Error($"Server method {md.Name} must be declared in a NetworkBehaviour", md);
|
||||
return;
|
||||
}
|
||||
ILProcessor worker = md.Body.GetILProcessor();
|
||||
Instruction top = md.Body.Instructions[0];
|
||||
|
||||
@ -72,13 +112,8 @@ static void InjectServerGuard(TypeDefinition td, MethodDefinition md, bool logWa
|
||||
worker.InsertBefore(top, worker.Create(OpCodes.Ret));
|
||||
}
|
||||
|
||||
static void InjectClientGuard(TypeDefinition td, MethodDefinition md, bool logWarning)
|
||||
static void InjectClientGuard(MethodDefinition md, bool logWarning)
|
||||
{
|
||||
if (!Weaver.IsNetworkBehaviour(td))
|
||||
{
|
||||
Weaver.Error($"Client method {md.Name} must be declared in a NetworkBehaviour", md);
|
||||
return;
|
||||
}
|
||||
ILProcessor worker = md.Body.GetILProcessor();
|
||||
Instruction top = md.Body.Instructions[0];
|
||||
|
||||
|
@ -278,6 +278,7 @@ static bool WeaveModule(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
modified |= WeaveNetworkBehavior(td);
|
||||
modified |= WeaveMessage(td);
|
||||
modified |= ServerClientAttributeProcessor.ProcessSiteClass(td);
|
||||
}
|
||||
}
|
||||
watch.Stop();
|
||||
@ -330,7 +331,7 @@ static bool Weave(string assName, AssemblyDefinition unityAssembly, AssemblyDefi
|
||||
// this must be done for ALL code, not just NetworkBehaviours
|
||||
try
|
||||
{
|
||||
PropertySiteProcessor.ProcessSitesModule(CurrentAssembly.MainModule);
|
||||
PropertySiteProcessor.ProcessSitesModule(moduleDefinition);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -89,8 +89,8 @@ static string ReturnTypeToFullName(string returnType)
|
||||
static string[] baseClassArray = new string[]
|
||||
{
|
||||
"NetworkBehaviour",
|
||||
//"MonoBehaviour",
|
||||
//"ClassWithNoConstructor" // non unity class
|
||||
"MonoBehaviour",
|
||||
"ClassWithNoConstructor" // non unity class
|
||||
};
|
||||
|
||||
const string NameSpace = BaseNameSpace + ".Attributes";
|
||||
@ -114,6 +114,8 @@ static string Classes(string baseClass, IEnumerable<string> functions, IEnumerab
|
||||
{
|
||||
string mergedFunctions = Merge(functions);
|
||||
string mergedTests = Merge(tests);
|
||||
string setupBody = SetupForBaseClass(baseClass);
|
||||
string teardownBody = TearDownForBaseClass(baseClass);
|
||||
|
||||
return $@"
|
||||
public class {AttributeBehaviourName(baseClass)} : {baseClass}
|
||||
@ -142,14 +144,13 @@ public class AttributeTest_{baseClass}
|
||||
[OneTimeSetUp]
|
||||
public void SetUp()
|
||||
{{
|
||||
go = new GameObject();
|
||||
behaviour = go.AddComponent<{AttributeBehaviourName(baseClass)}>();
|
||||
{setupBody}
|
||||
}}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void TearDown()
|
||||
{{
|
||||
UnityEngine.Object.DestroyImmediate(go);
|
||||
{teardownBody}
|
||||
NetworkClient.connectState = ConnectState.None;
|
||||
NetworkServer.active = false;
|
||||
}}
|
||||
@ -158,6 +159,50 @@ public void TearDown()
|
||||
}}";
|
||||
}
|
||||
|
||||
static string SetupForBaseClass(string baseClass)
|
||||
{
|
||||
switch (baseClass)
|
||||
{
|
||||
case "NetworkBehaviour":
|
||||
case "MonoBehaviour":
|
||||
return SetupBodyMonoBehaviour(baseClass);
|
||||
default:
|
||||
return SetupBodyClass(baseClass);
|
||||
}
|
||||
}
|
||||
|
||||
static string TearDownForBaseClass(string baseClass)
|
||||
{
|
||||
switch (baseClass)
|
||||
{
|
||||
case "NetworkBehaviour":
|
||||
case "MonoBehaviour":
|
||||
return TearDownBodyMonoBehaviour();
|
||||
default:
|
||||
return TearDownBodyClass();
|
||||
}
|
||||
}
|
||||
|
||||
static string SetupBodyMonoBehaviour(string baseClass)
|
||||
{
|
||||
return
|
||||
$@"go = new GameObject();
|
||||
behaviour = go.AddComponent<{AttributeBehaviourName(baseClass)}>();";
|
||||
}
|
||||
static string TearDownBodyMonoBehaviour()
|
||||
{
|
||||
return "UnityEngine.Object.DestroyImmediate(go);";
|
||||
}
|
||||
static string SetupBodyClass(string baseClass)
|
||||
{
|
||||
return $@"behaviour = new {AttributeBehaviourName(baseClass)}();";
|
||||
}
|
||||
static string TearDownBodyClass()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
static string AttributeBehaviourName(string baseClass)
|
||||
{
|
||||
return $"AttributeBehaviour_{baseClass}";
|
||||
@ -171,6 +216,7 @@ static string AttributeOutFunctionName(string attribute, string returnType)
|
||||
return $"{attribute}_{returnType}_out_Function";
|
||||
}
|
||||
|
||||
|
||||
static string AttributeFunction(string attribute, string returnType)
|
||||
{
|
||||
return $@"
|
||||
|
@ -100,11 +100,17 @@
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ClientAttributeOnAbstractMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ClientAttributeOnOverrideMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ClientAttributeOnVirutalMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\MonoBehaviourClient.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\MonoBehaviourServer.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\NetworkBehaviourClient.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\NetworkBehaviourServer.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\RegularClassClient.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\RegularClassServer.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ServerAttributeOnAbstractMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ServerAttributeOnOverrideMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\ServerAttributeOnVirutalMethod.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\StaticClassClient.cs" />
|
||||
<Compile Include="WeaverClientServerAttributeTests~\StaticClassServer.cs" />
|
||||
<Compile Include="WeaverCommandTests~\AbstractCommand.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandCantBeStatic.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandThatIgnoresAuthority.cs" />
|
||||
|
@ -74,6 +74,59 @@ public void ClientAttributeOnOverrideMethod()
|
||||
CheckAddedCode(networkClientGetActive, "WeaverClientServerAttributeTests.ClientAttributeOnOverrideMethod.ClientAttributeOnOverrideMethod", "ClientOnlyMethod");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StaticClassClient()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkClientGetActive = WeaverTypes.NetworkClientGetActive.ToString();
|
||||
CheckAddedCode(networkClientGetActive, "WeaverClientServerAttributeTests.StaticClassClient.StaticClassClient", "ClientOnlyMethod");
|
||||
}
|
||||
[Test]
|
||||
public void RegularClassClient()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkClientGetActive = WeaverTypes.NetworkClientGetActive.ToString();
|
||||
CheckAddedCode(networkClientGetActive, "WeaverClientServerAttributeTests.RegularClassClient.RegularClassClient", "ClientOnlyMethod");
|
||||
}
|
||||
[Test]
|
||||
public void MonoBehaviourClient()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkClientGetActive = WeaverTypes.NetworkClientGetActive.ToString();
|
||||
CheckAddedCode(networkClientGetActive, "WeaverClientServerAttributeTests.MonoBehaviourClient.MonoBehaviourClient", "ClientOnlyMethod");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StaticClassServer()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkServerGetActive = WeaverTypes.NetworkServerGetActive.ToString();
|
||||
CheckAddedCode(networkServerGetActive, "WeaverClientServerAttributeTests.StaticClassServer.StaticClassServer", "ServerOnlyMethod");
|
||||
}
|
||||
[Test]
|
||||
public void RegularClassServer()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkServerGetActive = WeaverTypes.NetworkServerGetActive.ToString();
|
||||
CheckAddedCode(networkServerGetActive, "WeaverClientServerAttributeTests.RegularClassServer.RegularClassServer", "ServerOnlyMethod");
|
||||
}
|
||||
[Test]
|
||||
public void MonoBehaviourServer()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
|
||||
string networkServerGetActive = WeaverTypes.NetworkServerGetActive.ToString();
|
||||
CheckAddedCode(networkServerGetActive, "WeaverClientServerAttributeTests.MonoBehaviourServer.MonoBehaviourServer", "ServerOnlyMethod");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks that first Instructions in MethodBody is addedString
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,11 @@
|
||||
using Mirror;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.MonoBehaviourClient
|
||||
{
|
||||
class MonoBehaviourClient : MonoBehaviour
|
||||
{
|
||||
[Client]
|
||||
void ClientOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
using Mirror;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.MonoBehaviourServer
|
||||
{
|
||||
class MonoBehaviourServer : MonoBehaviour
|
||||
{
|
||||
[Server]
|
||||
void ServerOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.RegularClassClient
|
||||
{
|
||||
class RegularClassClient
|
||||
{
|
||||
[Client]
|
||||
void ClientOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.RegularClassServer
|
||||
{
|
||||
class RegularClassServer
|
||||
{
|
||||
[Server]
|
||||
void ServerOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.StaticClassClient
|
||||
{
|
||||
static class StaticClassClient
|
||||
{
|
||||
[Client]
|
||||
static void ClientOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverClientServerAttributeTests.StaticClassServer
|
||||
{
|
||||
static class StaticClassServer
|
||||
{
|
||||
[Server]
|
||||
static void ServerOnlyMethod() { }
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Mirror.Weaver.Tests
|
||||
{
|
||||
@ -43,25 +43,25 @@ public void MonoBehaviourTargetRpc()
|
||||
[Test]
|
||||
public void MonoBehaviourServer()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("Server method ThisCantBeOutsideNetworkBehaviour must be declared inside a NetworkBehaviour (at System.Void WeaverMonoBehaviourTests.MonoBehaviourServer.MonoBehaviourServer::ThisCantBeOutsideNetworkBehaviour())"));
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MonoBehaviourServerCallback()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("ServerCallback method ThisCantBeOutsideNetworkBehaviour must be declared inside a NetworkBehaviour (at System.Void WeaverMonoBehaviourTests.MonoBehaviourServerCallback.MonoBehaviourServerCallback::ThisCantBeOutsideNetworkBehaviour())"));
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MonoBehaviourClient()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("Client method ThisCantBeOutsideNetworkBehaviour must be declared inside a NetworkBehaviour (at System.Void WeaverMonoBehaviourTests.MonoBehaviourClient.MonoBehaviourClient::ThisCantBeOutsideNetworkBehaviour())"));
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MonoBehaviourClientCallback()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("ClientCallback method ThisCantBeOutsideNetworkBehaviour must be declared inside a NetworkBehaviour (at System.Void WeaverMonoBehaviourTests.MonoBehaviourClientCallback.MonoBehaviourClientCallback::ThisCantBeOutsideNetworkBehaviour())"));
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user