mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: adding option to receive NetworkConnectionToClient in Comand (#1970)
* moving exists check to its own function * moving order and adding whitespace * adding SenderConnection Attribute * adding weaver tests for SenderConnection Attribute * tests for sender connection * updating valid method to work with sender connection * using RemoteCallType in read write calls * adding sender connection to CallCmd * updating CmdDelegate * adding NetworkConnection to invokeFunction * updating old tests * removing SenderConnectionAttribute * typo * adding version 14 defines
This commit is contained in:
parent
822b04155d
commit
55736eba5e
@ -27,7 +27,8 @@ public static void AddDefineSymbols()
|
||||
"MIRROR_10_0_OR_NEWER",
|
||||
"MIRROR_11_0_OR_NEWER",
|
||||
"MIRROR_12_0_OR_NEWER",
|
||||
"MIRROR_13_0_OR_NEWER"
|
||||
"MIRROR_13_0_OR_NEWER",
|
||||
"MIRROR_14_0_OR_NEWER"
|
||||
};
|
||||
|
||||
// only touch PlayerSettings if we actually modified it.
|
||||
|
@ -7,6 +7,11 @@ namespace Mirror.Weaver
|
||||
public static class Extensions
|
||||
{
|
||||
public static bool IsDerivedFrom(this TypeDefinition td, TypeReference baseClass)
|
||||
{
|
||||
return IsDerivedFrom(td, baseClass.FullName);
|
||||
}
|
||||
|
||||
public static bool IsDerivedFrom(this TypeDefinition td, string baseClassFullName)
|
||||
{
|
||||
if (!td.IsClass)
|
||||
return false;
|
||||
@ -24,7 +29,7 @@ public static bool IsDerivedFrom(this TypeDefinition td, TypeReference baseClass
|
||||
parentName = parentName.Substring(0, index);
|
||||
}
|
||||
|
||||
if (parentName == baseClass.FullName)
|
||||
if (parentName == baseClassFullName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public static MethodDefinition ProcessCommandCall(TypeDefinition td, MethodDefin
|
||||
NetworkBehaviourProcessor.WriteCreateWriter(worker);
|
||||
|
||||
// write all the arguments that the user passed to the Cmd call
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, false))
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, RemoteCallType.Command))
|
||||
return null;
|
||||
|
||||
string cmdName = md.Name;
|
||||
@ -87,7 +87,7 @@ public static MethodDefinition ProcessCommandCall(TypeDefinition td, MethodDefin
|
||||
|
||||
/*
|
||||
// generates code like:
|
||||
protected static void InvokeCmdCmdThrust(NetworkBehaviour obj, NetworkReader reader)
|
||||
protected static void InvokeCmdCmdThrust(NetworkBehaviour obj, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
if (!NetworkServer.active)
|
||||
{
|
||||
@ -111,9 +111,11 @@ public static MethodDefinition ProcessCommandInvoke(TypeDefinition td, MethodDef
|
||||
worker.Append(worker.Create(OpCodes.Ldarg_0));
|
||||
worker.Append(worker.Create(OpCodes.Castclass, td));
|
||||
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(method, worker, false))
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(method, worker, RemoteCallType.Command))
|
||||
return null;
|
||||
|
||||
AddSenderConnection(method, worker);
|
||||
|
||||
// invoke actual command function
|
||||
worker.Append(worker.Create(OpCodes.Callvirt, cmdCallFunc));
|
||||
worker.Append(worker.Create(OpCodes.Ret));
|
||||
@ -124,6 +126,19 @@ public static MethodDefinition ProcessCommandInvoke(TypeDefinition td, MethodDef
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static void AddSenderConnection(MethodDefinition method, ILProcessor worker)
|
||||
{
|
||||
foreach (ParameterDefinition param in method.Parameters)
|
||||
{
|
||||
if (NetworkBehaviourProcessor.IsSenderConnection(param, RemoteCallType.Command))
|
||||
{
|
||||
// NetworkConnection is 3nd arg (arg0 is "obj" not "this" because method is static)
|
||||
// exmaple: static void InvokeCmdCmdSendCommand(NetworkBehaviour obj, NetworkReader reader, NetworkConnection connection)
|
||||
worker.Append(worker.Create(OpCodes.Ldarg_2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ProcessMethodsValidateCommand(MethodDefinition md)
|
||||
{
|
||||
if (!md.Name.StartsWith("Cmd"))
|
||||
|
@ -9,8 +9,10 @@ public enum RemoteCallType
|
||||
Command,
|
||||
ClientRpc,
|
||||
TargetRpc,
|
||||
SyncEvent
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// processes SyncVars, Cmds, Rpcs, etc. of NetworkBehaviours
|
||||
/// </summary>
|
||||
@ -134,7 +136,7 @@ public static void WriteRecycleWriter(ILProcessor worker)
|
||||
worker.Append(worker.Create(OpCodes.Call, Weaver.RecycleWriterReference));
|
||||
}
|
||||
|
||||
public static bool WriteArguments(ILProcessor worker, MethodDefinition method, bool skipFirst)
|
||||
public static bool WriteArguments(ILProcessor worker, MethodDefinition method, RemoteCallType callType)
|
||||
{
|
||||
// write each argument
|
||||
// example result
|
||||
@ -143,6 +145,9 @@ public static bool WriteArguments(ILProcessor worker, MethodDefinition method, b
|
||||
writer.WriteNetworkIdentity(someTarget);
|
||||
*/
|
||||
|
||||
bool skipFirst = (callType == RemoteCallType.TargetRpc
|
||||
&& TargetRpcProcessor.HasNetworkConnectionParameter(method));
|
||||
|
||||
// arg of calling function, arg 0 is "this" so start counting at 1
|
||||
int argNum = 1;
|
||||
foreach (ParameterDefinition param in method.Parameters)
|
||||
@ -154,6 +159,12 @@ public static bool WriteArguments(ILProcessor worker, MethodDefinition method, b
|
||||
argNum += 1;
|
||||
continue;
|
||||
}
|
||||
// skip SenderConnection in Command
|
||||
if (IsSenderConnection(param, callType))
|
||||
{
|
||||
argNum += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
MethodReference writeFunc = Writers.GetWriteFunc(param.ParameterType);
|
||||
if (writeFunc == null)
|
||||
@ -781,7 +792,7 @@ void GenerateDeSerialization()
|
||||
netBehaviourSubclass.Methods.Add(serialize);
|
||||
}
|
||||
|
||||
public static bool ReadArguments(MethodDefinition method, ILProcessor worker, bool skipFirst)
|
||||
public static bool ReadArguments(MethodDefinition method, ILProcessor worker, RemoteCallType callType)
|
||||
{
|
||||
// read each argument
|
||||
// example result
|
||||
@ -789,6 +800,9 @@ public static bool ReadArguments(MethodDefinition method, ILProcessor worker, bo
|
||||
CallCmdDoSomething(reader.ReadPackedInt32(), reader.ReadNetworkIdentity());
|
||||
*/
|
||||
|
||||
bool skipFirst = (callType == RemoteCallType.TargetRpc
|
||||
&& TargetRpcProcessor.HasNetworkConnectionParameter(method));
|
||||
|
||||
// arg of calling function, arg 0 is "this" so start counting at 1
|
||||
int argNum = 1;
|
||||
foreach (ParameterDefinition param in method.Parameters)
|
||||
@ -800,6 +814,12 @@ public static bool ReadArguments(MethodDefinition method, ILProcessor worker, bo
|
||||
argNum += 1;
|
||||
continue;
|
||||
}
|
||||
// skip SenderConnection in Command
|
||||
if (IsSenderConnection(param, callType))
|
||||
{
|
||||
argNum += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
MethodReference readFunc = Readers.GetReadFunc(param.ParameterType);
|
||||
@ -830,6 +850,8 @@ public static void AddInvokeParameters(ICollection<ParameterDefinition> collecti
|
||||
{
|
||||
collection.Add(new ParameterDefinition("obj", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(Weaver.NetworkBehaviourType)));
|
||||
collection.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||
// senderConnection is only used for commands but NetworkBehaviour.CmdDelegate is used for all remote calls
|
||||
collection.Add(new ParameterDefinition("senderConnection", ParameterAttributes.None, Weaver.CurrentAssembly.MainModule.ImportReference(Weaver.NetworkConnectionType)));
|
||||
}
|
||||
|
||||
public static bool ProcessMethodsValidateFunction(MethodReference md)
|
||||
@ -871,6 +893,7 @@ public static bool ProcessMethodsValidateParameters(MethodReference method, Remo
|
||||
static bool ValidateParameter(MethodReference method, ParameterDefinition param, RemoteCallType callType, bool firstParam)
|
||||
{
|
||||
bool isNetworkConnection = param.ParameterType.FullName == Weaver.NetworkConnectionType.FullName;
|
||||
bool isSenderConnection = IsSenderConnection(param, callType);
|
||||
|
||||
if (param.IsOut)
|
||||
{
|
||||
@ -879,15 +902,22 @@ static bool ValidateParameter(MethodReference method, ParameterDefinition param,
|
||||
}
|
||||
|
||||
|
||||
// TargetRPC is an exception to this rule and can have a NetworkConnection as first parameter
|
||||
if (isNetworkConnection && !(callType == RemoteCallType.TargetRpc && firstParam))
|
||||
// if not SenderConnection And not TargetRpc NetworkConnection first param
|
||||
if (!isSenderConnection && isNetworkConnection && !(callType == RemoteCallType.TargetRpc && firstParam))
|
||||
{
|
||||
Weaver.Error($"{method.Name} has invalid parameter {param}. Cannot pass NeworkConnections", method);
|
||||
if (callType == RemoteCallType.Command)
|
||||
{
|
||||
Weaver.Error($"{method.Name} has invalid parameter {param}, Cannot pass NeworkConnections. Instead use 'NetworkConnectionToClient conn = null' to get the sender's connection on the server", method);
|
||||
}
|
||||
else
|
||||
{
|
||||
Weaver.Error($"{method.Name} has invalid parameter {param}. Cannot pass NeworkConnections", method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// sender connection can be optional
|
||||
if (param.IsOptional)
|
||||
if (param.IsOptional && !isSenderConnection)
|
||||
{
|
||||
Weaver.Error($"{method.Name} cannot have optional parameters", method);
|
||||
return false;
|
||||
@ -896,6 +926,21 @@ static bool ValidateParameter(MethodReference method, ParameterDefinition param,
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsSenderConnection(ParameterDefinition param, RemoteCallType callType)
|
||||
{
|
||||
if (callType != RemoteCallType.Command)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeReference type = param.ParameterType;
|
||||
|
||||
const string ConnectionToClient = "Mirror.NetworkConnectionToClient";
|
||||
bool isConnectionToClient = type.FullName == ConnectionToClient || type.Resolve().IsDerivedFrom(ConnectionToClient);
|
||||
|
||||
return isConnectionToClient;
|
||||
}
|
||||
|
||||
void ProcessMethods()
|
||||
{
|
||||
HashSet<string> names = new HashSet<string>();
|
||||
|
@ -26,7 +26,7 @@ public static MethodDefinition ProcessRpcInvoke(TypeDefinition td, MethodDefinit
|
||||
worker.Append(worker.Create(OpCodes.Ldarg_0));
|
||||
worker.Append(worker.Create(OpCodes.Castclass, td));
|
||||
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(md, worker, false))
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(md, worker, RemoteCallType.ClientRpc))
|
||||
return null;
|
||||
|
||||
// invoke actual command function
|
||||
@ -77,7 +77,7 @@ public static MethodDefinition ProcessRpcCall(TypeDefinition td, MethodDefinitio
|
||||
NetworkBehaviourProcessor.WriteCreateWriter(worker);
|
||||
|
||||
// write all the arguments that the user passed to the Rpc call
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, false))
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, RemoteCallType.ClientRpc))
|
||||
return null;
|
||||
|
||||
string rpcName = md.Name;
|
||||
|
@ -53,7 +53,7 @@ public static MethodDefinition ProcessEventInvoke(TypeDefinition td, EventDefini
|
||||
|
||||
// read the event arguments
|
||||
MethodReference invoke = Resolvers.ResolveMethod(eventField.FieldType, Weaver.CurrentAssembly, "Invoke");
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(invoke.Resolve(), worker, false))
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(invoke.Resolve(), worker, RemoteCallType.SyncEvent))
|
||||
return null;
|
||||
|
||||
// invoke actual event delegate function
|
||||
@ -87,7 +87,7 @@ public static MethodDefinition ProcessEventCall(TypeDefinition td, EventDefiniti
|
||||
NetworkBehaviourProcessor.WriteCreateWriter(worker);
|
||||
|
||||
// write all the arguments that the user passed to the syncevent
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, invoke.Resolve(), false))
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, invoke.Resolve(), RemoteCallType.SyncEvent))
|
||||
return null;
|
||||
|
||||
// invoke interal send and return
|
||||
|
@ -34,15 +34,15 @@ public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodD
|
||||
worker.Append(worker.Create(OpCodes.Castclass, td));
|
||||
|
||||
// NetworkConnection parameter is optional
|
||||
bool hasNetworkConnection = HasNetworkConnectionParameter(md);
|
||||
if (hasNetworkConnection)
|
||||
if (HasNetworkConnectionParameter(md))
|
||||
{
|
||||
// if call has NetworkConnection write clients connection as first arg
|
||||
//ClientScene.readyconnection
|
||||
worker.Append(worker.Create(OpCodes.Call, Weaver.ReadyConnectionReference));
|
||||
}
|
||||
|
||||
// process reader parameters and skip first one if first one is NetworkConnection
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(md, worker, hasNetworkConnection))
|
||||
if (!NetworkBehaviourProcessor.ReadArguments(md, worker, RemoteCallType.TargetRpc))
|
||||
return null;
|
||||
|
||||
// invoke actual command function
|
||||
@ -97,12 +97,9 @@ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDef
|
||||
|
||||
NetworkBehaviourProcessor.WriteCreateWriter(worker);
|
||||
|
||||
// NetworkConnection parameter is optional
|
||||
bool hasNetworkConnection = HasNetworkConnectionParameter(md);
|
||||
|
||||
// write all the arguments that the user passed to the TargetRpc call
|
||||
// (skip first one if first one is NetworkConnection)
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, hasNetworkConnection))
|
||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, md, RemoteCallType.TargetRpc))
|
||||
return null;
|
||||
|
||||
string rpcName = md.Name;
|
||||
|
@ -361,7 +361,7 @@ public virtual bool InvokeSyncEvent(int eventHash, NetworkReader reader)
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <param name="reader"></param>
|
||||
public delegate void CmdDelegate(NetworkBehaviour obj, NetworkReader reader);
|
||||
public delegate void CmdDelegate(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient senderConnection);
|
||||
|
||||
protected class Invoker
|
||||
{
|
||||
@ -471,11 +471,12 @@ static bool GetInvokerForHash(int cmdHash, MirrorInvokeType invokeType, out Invo
|
||||
}
|
||||
|
||||
// InvokeCmd/Rpc/SyncEventDelegate can all use the same function here
|
||||
internal bool InvokeHandlerDelegate(int cmdHash, MirrorInvokeType invokeType, NetworkReader reader)
|
||||
internal bool InvokeHandlerDelegate(int cmdHash, MirrorInvokeType invokeType, NetworkReader reader, NetworkConnectionToClient senderConnection = null)
|
||||
{
|
||||
if (GetInvokerForHash(cmdHash, invokeType, out Invoker invoker) && invoker.invokeClass.IsInstanceOfType(this))
|
||||
{
|
||||
invoker.invokeFunction(this, reader);
|
||||
invoker.invokeFunction(this, reader, senderConnection);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -983,7 +983,7 @@ internal void OnDeserializeAllSafely(NetworkReader reader, bool initialState)
|
||||
}
|
||||
|
||||
// helper function to handle SyncEvent/Command/Rpc
|
||||
void HandleRemoteCall(int componentIndex, int functionHash, MirrorInvokeType invokeType, NetworkReader reader)
|
||||
void HandleRemoteCall(int componentIndex, int functionHash, MirrorInvokeType invokeType, NetworkReader reader, NetworkConnectionToClient senderConnection = null)
|
||||
{
|
||||
if (gameObject == null)
|
||||
{
|
||||
@ -995,7 +995,7 @@ void HandleRemoteCall(int componentIndex, int functionHash, MirrorInvokeType inv
|
||||
if (0 <= componentIndex && componentIndex < NetworkBehaviours.Length)
|
||||
{
|
||||
NetworkBehaviour invokeComponent = NetworkBehaviours[componentIndex];
|
||||
if (!invokeComponent.InvokeHandlerDelegate(functionHash, invokeType, reader))
|
||||
if (!invokeComponent.InvokeHandlerDelegate(functionHash, invokeType, reader, senderConnection))
|
||||
{
|
||||
logger.LogError("Found no receiver for incoming " + invokeType + " [" + functionHash + "] on " + gameObject + ", the server and client should have the same NetworkBehaviour instances [netId=" + netId + "].");
|
||||
}
|
||||
@ -1013,9 +1013,9 @@ internal void HandleSyncEvent(int componentIndex, int eventHash, NetworkReader r
|
||||
}
|
||||
|
||||
// happens on server
|
||||
internal void HandleCommand(int componentIndex, int cmdHash, NetworkReader reader)
|
||||
internal void HandleCommand(int componentIndex, int cmdHash, NetworkReader reader, NetworkConnectionToClient senderConnection)
|
||||
{
|
||||
HandleRemoteCall(componentIndex, cmdHash, MirrorInvokeType.Command, reader);
|
||||
HandleRemoteCall(componentIndex, cmdHash, MirrorInvokeType.Command, reader, senderConnection);
|
||||
}
|
||||
|
||||
// happens on server
|
||||
|
@ -1008,7 +1008,7 @@ static void OnCommandMessage(NetworkConnection conn, CommandMessage msg)
|
||||
if (logger.LogEnabled()) logger.Log("OnCommandMessage for netId=" + msg.netId + " conn=" + conn);
|
||||
|
||||
using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
|
||||
identity.HandleCommand(msg.componentIndex, msg.functionHash, networkReader);
|
||||
identity.HandleCommand(msg.componentIndex, msg.functionHash, networkReader, conn as NetworkConnectionToClient);
|
||||
}
|
||||
|
||||
internal static void SpawnObject(GameObject obj, NetworkConnection ownerConnection)
|
||||
|
@ -27,6 +27,28 @@ public void CmdSendInt(int someInt)
|
||||
}
|
||||
}
|
||||
|
||||
class SenderConnectionBehaviour : NetworkBehaviour
|
||||
{
|
||||
public event Action<int, NetworkConnection> onSendInt;
|
||||
|
||||
[Command]
|
||||
public void CmdSendInt(int someInt, NetworkConnectionToClient conn = null)
|
||||
{
|
||||
onSendInt?.Invoke(someInt, conn);
|
||||
}
|
||||
}
|
||||
|
||||
class SenderConnectionIgnoreAuthorityBehaviour : NetworkBehaviour
|
||||
{
|
||||
public event Action<int, NetworkConnection> onSendInt;
|
||||
|
||||
[Command(ignoreAuthority = true)]
|
||||
public void CmdSendInt(int someInt, NetworkConnectionToClient conn = null)
|
||||
{
|
||||
onSendInt?.Invoke(someInt, conn);
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandTest : RemoteTestBase
|
||||
{
|
||||
[Test]
|
||||
@ -101,5 +123,48 @@ public void CommandIsSentWithoutAuthorityWhenIgnoringAuthority()
|
||||
ProcessMessages();
|
||||
Assert.That(callCount, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SenderConnectionIsSetWhenCommandIsRecieved()
|
||||
{
|
||||
SenderConnectionBehaviour hostBehaviour = CreateHostObject<SenderConnectionBehaviour>(true);
|
||||
|
||||
const int someInt = 20;
|
||||
NetworkConnectionToClient connectionToClient = NetworkServer.connections[0];
|
||||
Debug.Assert(connectionToClient != null, $"connectionToClient was null, This means that the test is broken and will give the wrong results");
|
||||
|
||||
|
||||
int callCount = 0;
|
||||
hostBehaviour.onSendInt += (incomingInt, incomingConn) =>
|
||||
{
|
||||
callCount++;
|
||||
Assert.That(incomingInt, Is.EqualTo(someInt));
|
||||
Assert.That(incomingConn, Is.EqualTo(connectionToClient));
|
||||
};
|
||||
hostBehaviour.CmdSendInt(someInt);
|
||||
ProcessMessages();
|
||||
Assert.That(callCount, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SenderConnectionIsSetWhenCommandIsRecievedWithIgnoreAuthority()
|
||||
{
|
||||
SenderConnectionIgnoreAuthorityBehaviour hostBehaviour = CreateHostObject<SenderConnectionIgnoreAuthorityBehaviour>(false);
|
||||
|
||||
const int someInt = 20;
|
||||
NetworkConnectionToClient connectionToClient = NetworkServer.connections[0];
|
||||
Debug.Assert(connectionToClient != null, $"connectionToClient was null, This means that the test is broken and will give the wrong results");
|
||||
|
||||
int callCount = 0;
|
||||
hostBehaviour.onSendInt += (incomingInt, incomingConn) =>
|
||||
{
|
||||
callCount++;
|
||||
Assert.That(incomingInt, Is.EqualTo(someInt));
|
||||
Assert.That(incomingConn, Is.EqualTo(connectionToClient));
|
||||
};
|
||||
hostBehaviour.CmdSendInt(someInt);
|
||||
ProcessMessages();
|
||||
Assert.That(callCount, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class NetworkBehaviourSendCommandInternalComponent : NetworkBehaviour
|
||||
|
||||
// weaver generates this from [Command]
|
||||
// but for tests we need to add it manually
|
||||
public static void CommandGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void CommandGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((NetworkBehaviourSendCommandInternalComponent)comp).called;
|
||||
}
|
||||
@ -50,7 +50,7 @@ public class NetworkBehaviourSendRPCInternalComponent : NetworkBehaviour
|
||||
|
||||
// weaver generates this from [ClientRpc]
|
||||
// but for tests we need to add it manually
|
||||
public static void RPCGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void RPCGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((NetworkBehaviourSendRPCInternalComponent)comp).called;
|
||||
}
|
||||
@ -70,7 +70,7 @@ public class NetworkBehaviourSendTargetRPCInternalComponent : NetworkBehaviour
|
||||
|
||||
// weaver generates this from [TargetRpc]
|
||||
// but for tests we need to add it manually
|
||||
public static void TargetRPCGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void TargetRPCGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((NetworkBehaviourSendTargetRPCInternalComponent)comp).called;
|
||||
}
|
||||
@ -90,7 +90,7 @@ public class NetworkBehaviourSendEventInternalComponent : NetworkBehaviour
|
||||
|
||||
// weaver generates this from [SyncEvent]
|
||||
// but for tests we need to add it manually
|
||||
public static void EventGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void EventGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((NetworkBehaviourSendEventInternalComponent)comp).called;
|
||||
}
|
||||
@ -105,8 +105,8 @@ public void CallSendEventInternal()
|
||||
// we need to inherit from networkbehaviour to test protected functions
|
||||
public class NetworkBehaviourDelegateComponent : NetworkBehaviour
|
||||
{
|
||||
public static void Delegate(NetworkBehaviour comp, NetworkReader reader) { }
|
||||
public static void Delegate2(NetworkBehaviour comp, NetworkReader reader) { }
|
||||
public static void Delegate(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection) { }
|
||||
public static void Delegate2(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection) { }
|
||||
}
|
||||
|
||||
// we need to inherit from networkbehaviour to test protected functions
|
||||
|
@ -1292,7 +1292,9 @@ public void HandleCommand()
|
||||
{
|
||||
// add component
|
||||
CommandTestNetworkBehaviour comp0 = gameObject.AddComponent<CommandTestNetworkBehaviour>();
|
||||
NetworkConnectionToClient connection = new NetworkConnectionToClient(1);
|
||||
Assert.That(comp0.called, Is.EqualTo(0));
|
||||
Assert.That(comp0.senderConnectionInCall, Is.Null);
|
||||
|
||||
// register the command delegate, otherwise it's not found
|
||||
NetworkBehaviour.RegisterCommandDelegate(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated), CommandTestNetworkBehaviour.CommandGenerated, false);
|
||||
@ -1304,20 +1306,22 @@ public void HandleCommand()
|
||||
// call HandleCommand and check if the command was called in the component
|
||||
int functionHash = NetworkBehaviour.GetMethodHash(typeof(CommandTestNetworkBehaviour), nameof(CommandTestNetworkBehaviour.CommandGenerated));
|
||||
NetworkReader payload = new NetworkReader(new byte[0]);
|
||||
identity.HandleCommand(0, functionHash, payload);
|
||||
identity.HandleCommand(0, functionHash, payload, connection);
|
||||
Assert.That(comp0.called, Is.EqualTo(1));
|
||||
Assert.That(comp0.senderConnectionInCall, Is.EqualTo(connection));
|
||||
|
||||
|
||||
// try wrong component index. command shouldn't be called again.
|
||||
// warning is expected
|
||||
LogAssert.ignoreFailingMessages = true;
|
||||
identity.HandleCommand(1, functionHash, payload);
|
||||
identity.HandleCommand(1, functionHash, payload, connection);
|
||||
LogAssert.ignoreFailingMessages = false;
|
||||
Assert.That(comp0.called, Is.EqualTo(1));
|
||||
|
||||
// try wrong function hash. command shouldn't be called again.
|
||||
// warning is expected
|
||||
LogAssert.ignoreFailingMessages = true;
|
||||
identity.HandleCommand(0, functionHash + 1, payload);
|
||||
identity.HandleCommand(0, functionHash + 1, payload, connection);
|
||||
LogAssert.ignoreFailingMessages = false;
|
||||
Assert.That(comp0.called, Is.EqualTo(1));
|
||||
|
||||
|
@ -11,11 +11,13 @@ public class CommandTestNetworkBehaviour : NetworkBehaviour
|
||||
{
|
||||
// counter to make sure that it's called exactly once
|
||||
public int called;
|
||||
public NetworkConnection senderConnectionInCall;
|
||||
// weaver generates this from [Command]
|
||||
// but for tests we need to add it manually
|
||||
public static void CommandGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void CommandGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((CommandTestNetworkBehaviour)comp).called;
|
||||
((CommandTestNetworkBehaviour)comp).senderConnectionInCall = senderConnection;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +27,7 @@ public class RpcTestNetworkBehaviour : NetworkBehaviour
|
||||
public int called;
|
||||
// weaver generates this from [Rpc]
|
||||
// but for tests we need to add it manually
|
||||
public static void RpcGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void RpcGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((RpcTestNetworkBehaviour)comp).called;
|
||||
}
|
||||
@ -37,7 +39,7 @@ public class SyncEventTestNetworkBehaviour : NetworkBehaviour
|
||||
public int called;
|
||||
// weaver generates this from [SyncEvent]
|
||||
// but for tests we need to add it manually
|
||||
public static void SyncEventGenerated(NetworkBehaviour comp, NetworkReader reader)
|
||||
public static void SyncEventGenerated(NetworkBehaviour comp, NetworkReader reader, NetworkConnection senderConnection)
|
||||
{
|
||||
++((SyncEventTestNetworkBehaviour)comp).called;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ protected T CreateHostObject<T>(bool spawnWithAuthority) where T : NetworkBehavi
|
||||
if (spawnWithAuthority)
|
||||
{
|
||||
NetworkServer.Spawn(gameObject, NetworkServer.localConnection);
|
||||
Debug.Assert(behaviour.connectionToClient != null, $"Behaviour did not have connection to client, This means that the test is broken and will give the wrong results");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -94,11 +94,15 @@
|
||||
<Compile Include="WeaverCommandTests~\CommandCantBeStatic.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandStartsWithCmd.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandThatIgnoresAuthority.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandThatIgnoresAuthorityWithSenderConnection.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandValid.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandWithArguments.cs" />
|
||||
<Compile Include="WeaverCommandTests~\OverrideAbstractCommand.cs" />
|
||||
<Compile Include="WeaverCommandTests~\OverrideVirtualCommand.cs" />
|
||||
<Compile Include="WeaverCommandTests~\VirtualCommand.cs" />
|
||||
<Compile Include="WeaverCommandTests~\CommandWithSenderConnectionAndOtherArgs.cs" />
|
||||
<Compile Include="WeaverCommandTests~\ErrorForNetworkConnectionThatIsNotSenderConnection.cs" />
|
||||
<Compile Include="WeaverCommandTests~\ErrorForOptionalNetworkConnectionThatIsNotSenderConnection.cs" />
|
||||
<Compile Include="WeaverGeneralTests~\RecursionCount.cs" />
|
||||
<Compile Include="WeaverGeneralTests~\TestingScriptableObjectArraySerialization.cs" />
|
||||
<Compile Include="WeaverMessageTests~\MessageMemberGeneric.cs" />
|
||||
|
@ -34,6 +34,30 @@ public void CommandWithArguments()
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CommandThatIgnoresAuthorityWithSenderConnection()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CommandWithSenderConnectionAndOtherArgs()
|
||||
{
|
||||
Assert.That(weaverErrors, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ErrorForOptionalNetworkConnectionThatIsNotSenderConnection()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("CmdFunction has invalid parameter connection, Cannot pass NeworkConnections. Instead use 'NetworkConnectionToClient conn = null' to get the sender's connection on the server (at System.Void WeaverCommandTests.ErrorForOptionalNetworkConnectionThatIsNotSenderConnection.ErrorForOptionalNetworkConnectionThatIsNotSenderConnection::CmdFunction(Mirror.NetworkConnection))"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ErrorForNetworkConnectionThatIsNotSenderConnection()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("CmdFunction has invalid parameter connection, Cannot pass NeworkConnections. Instead use 'NetworkConnectionToClient conn = null' to get the sender's connection on the server (at System.Void WeaverCommandTests.ErrorForNetworkConnectionThatIsNotSenderConnection.ErrorForNetworkConnectionThatIsNotSenderConnection::CmdFunction(Mirror.NetworkConnection))"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VirtualCommand()
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Mirror;
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverCommandTests.CommandThatIgnoresAuthority
|
||||
{
|
||||
|
@ -0,0 +1,13 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverCommandTests.CommandThatIgnoresAuthorityWithSenderConnection
|
||||
{
|
||||
class CommandThatIgnoresAuthorityWithSenderConnection : NetworkBehaviour
|
||||
{
|
||||
[Command(ignoreAuthority = true)]
|
||||
void CmdFunction(NetworkConnectionToClient connection = null)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverCommandTests.CommandWithSenderConnectionAndOtherArgs
|
||||
{
|
||||
class CommandWithSenderConnectionAndOtherArgs : NetworkBehaviour
|
||||
{
|
||||
[Command(ignoreAuthority = true)]
|
||||
void CmdFunction(int someNumber, NetworkIdentity someTarget, NetworkConnectionToClient connection = null)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using Mirror;
|
||||
|
||||
|
||||
namespace WeaverCommandTests.ErrorForNetworkConnectionThatIsNotSenderConnection
|
||||
{
|
||||
class ErrorForNetworkConnectionThatIsNotSenderConnection : NetworkBehaviour
|
||||
{
|
||||
[Command(ignoreAuthority = true)]
|
||||
void CmdFunction(NetworkConnection connection)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using Mirror;
|
||||
|
||||
namespace WeaverCommandTests.ErrorForOptionalNetworkConnectionThatIsNotSenderConnection
|
||||
{
|
||||
class ErrorForOptionalNetworkConnectionThatIsNotSenderConnection : NetworkBehaviour
|
||||
{
|
||||
[Command(ignoreAuthority = true)]
|
||||
void CmdFunction(NetworkConnection connection = null)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
}
|
||||
}
|
@ -212,7 +212,7 @@ public void NetworkBehaviourCmdParamComponent()
|
||||
[Test]
|
||||
public void NetworkBehaviourCmdParamNetworkConnection()
|
||||
{
|
||||
Assert.That(weaverErrors, Contains.Item("CmdCantHaveParamOptional has invalid parameter monkeyCon. Cannot pass NeworkConnections (at System.Void WeaverNetworkBehaviourTests.NetworkBehaviourCmdParamNetworkConnection.NetworkBehaviourCmdParamNetworkConnection::CmdCantHaveParamOptional(Mirror.NetworkConnection))"));
|
||||
Assert.That(weaverErrors, Contains.Item("CmdCantHaveParamOptional has invalid parameter monkeyCon, Cannot pass NeworkConnections. Instead use 'NetworkConnectionToClient conn = null' to get the sender's connection on the server (at System.Void WeaverNetworkBehaviourTests.NetworkBehaviourCmdParamNetworkConnection.NetworkBehaviourCmdParamNetworkConnection::CmdCantHaveParamOptional(Mirror.NetworkConnection))"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -495,7 +495,7 @@ PlayerSettings:
|
||||
webGLLinkerTarget: 1
|
||||
webGLThreadsSupport: 0
|
||||
scriptingDefineSymbols:
|
||||
1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER
|
||||
1: MIRROR;MIRROR_1726_OR_NEWER;MIRROR_3_0_OR_NEWER;MIRROR_3_12_OR_NEWER;MIRROR_4_0_OR_NEWER;MIRROR_5_0_OR_NEWER;MIRROR_6_0_OR_NEWER;MIRROR_7_0_OR_NEWER;MIRROR_8_0_OR_NEWER;MIRROR_9_0_OR_NEWER;MIRROR_10_0_OR_NEWER;MIRROR_11_0_OR_NEWER;MIRROR_12_0_OR_NEWER;MIRROR_13_0_OR_NEWER;MIRROR_14_0_OR_NEWER
|
||||
platformArchitecture: {}
|
||||
scriptingBackend: {}
|
||||
il2cppCompilerConfiguration: {}
|
||||
|
Loading…
Reference in New Issue
Block a user