コード例 #1
0
        public static void ResolveSyncListFields()
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var type in assembly.GetTypes())
                {
                    if (!typeof(NetworkBehaviour).IsAssignableFrom(type))
                    {
                        continue;
                    }

                    // execute the static constructor instead of parsing its instructions
                    System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);

                    foreach (var method in AccessTools.GetDeclaredMethods(type))
                    {
                        if (!method.Name.StartsWith("InvokeSyncList"))
                        {
                            continue;
                        }

                        var methodParams = method.GetParameters();
                        if (methodParams.Length != 2 ||
                            methodParams[0].ParameterType.FullName != "EvoS.Framework.Network.Unity.NetworkBehaviour" ||
                            methodParams[1].ParameterType.FullName != "EvoS.Framework.Network.Unity.NetworkReader")
                        {
                            continue;
                        }

                        var methodDelegate = (NetworkBehaviour.CmdDelegate)Delegate.CreateDelegate(
                            typeof(NetworkBehaviour.CmdDelegate), method);

                        var instructions = AnalysisUtils.GetMethodInstructions(method);
                        var hash         = 0;
                        foreach (var instruction in instructions)
                        {
                            if (instruction.opcode != OpCodes.Ldfld)
                            {
                                continue;
                            }

                            hash = NetworkBehaviour.GetHashByDelegate(methodDelegate);
                            SyncListLookup.Add(hash, (FieldInfo)instruction.operand);
                            break;
                        }

                        if (hash != 0)
                        {
                            continue;
                        }

                        Log.Print(LogType.Warning, $"No SyncList found in {method.FullDescription()}");
                    }
                }
            }
        }