Пример #1
0
        public void ApplyCommonChanges(ModuleDefinition mod, string tag = "Relink")
        {
            if (DestroyPublicKeyTokens.Contains(mod.Assembly.Name.Name))
            {
                Log($"[{tag}] Destroying public key token for module {mod.Assembly.Name.Name}");
                mod.Assembly.Name.PublicKeyToken = new byte[0];
            }

            Log($"[{tag}] Updating dependencies");
            for (int i = 0; i < mod.AssemblyReferences.Count; i++)
            {
                AssemblyNameReference dep = mod.AssemblyReferences[i];

                // Main mapping mass.
                foreach (XnaToFnaMapping mapping in Mappings)
                {
                    if (mapping.Sources.Contains(dep.Name) &&
                        // Check if the target module has been found and cached
                        Modder.DependencyCache.ContainsKey(mapping.Target))
                    {
                        // Check if module already depends on the remap
                        if (mod.AssemblyReferences.Any(existingDep => existingDep.Name == mapping.Target))
                        {
                            // If so, just remove the dependency.
                            mod.AssemblyReferences.RemoveAt(i);
                            i--;
                            goto NextDep;
                        }
                        Log($"[{tag}] Replacing dependency {dep.Name} -> {mapping.Target}");
                        // Replace the dependency.
                        mod.AssemblyReferences[i] = Modder.DependencyCache[mapping.Target].Assembly.Name;
                        // Only check until first match found.
                        goto NextDep;
                    }
                }

                // Didn't remap; Check for RemoveDeps
                if (RemoveDeps.Contains(dep.Name))
                {
                    // Remove any unwanted (f.e. mixed) dependencies.
                    Log($"[{tag}] Removing unwanted dependency {dep.Name}");
                    mod.AssemblyReferences.RemoveAt(i);
                    i--;
                    goto NextDep;
                }

                // Didn't remove

                // Check for DestroyPublicKeyTokens
                if (DestroyPublicKeyTokens.Contains(dep.Name))
                {
                    Log($"[{tag}] Destroying public key token for dependency {dep.Name}");
                    dep.PublicKeyToken = new byte[0];
                }

                // Check for ModulesToStub (formerly managed references)
                if (ModulesToStub.Any(stub => stub.Assembly.Name.Name == dep.Name))
                {
                    // Fix stubbed dependencies.
                    Log($"[{tag}] Fixing stubbed dependency {dep.Name}");
                    dep.IsWindowsRuntime = false;
                    dep.HasPublicKey     = false;
                }

                // Check for .NET compact (X360) version
                if (dep.Version == DotNetX360Version)
                {
                    // Replace public key token.
                    dep.PublicKeyToken = DotNetFrameworkKeyToken;
                    // Technically .NET 2(?), but let's just bump the version.
                    dep.Version = DotNetFramework4Version;
                }

NextDep:
                continue;
            }
            if (AddAssemblyReference && !mod.AssemblyReferences.Any(dep => dep.Name == ThisAssemblyName))
            {
                // Add XnaToFna as dependency
                Log($"[{tag}] Adding dependency XnaToFna");
                mod.AssemblyReferences.Add(Modder.DependencyCache[ThisAssemblyName].Assembly.Name);
            }

            if (mod.Runtime < TargetRuntime.Net_4_0)
            {
                // XNA 3.0 / 3.1 and X360 games depend on a .NET Framework pre-4.0
                mod.Runtime = TargetRuntime.Net_4_0;
                // TODO: What about the System.*.dll dependencies?
            }

            Log($"[{tag}] Updating module attributes");
            mod.Attributes &= ~ModuleAttributes.StrongNameSigned;
            if (PreferredPlatform != ILPlatform.Keep)
            {
                // "Clear" to AnyCPU.
                mod.Architecture = TargetArchitecture.I386;
                mod.Attributes  &= ~ModuleAttributes.Required32Bit & ~ModuleAttributes.Preferred32Bit;

                switch (PreferredPlatform)
                {
                case ILPlatform.x86:
                    mod.Architecture = TargetArchitecture.I386;
                    mod.Attributes  |= ModuleAttributes.Required32Bit;
                    break;

                case ILPlatform.x64:
                    mod.Architecture = TargetArchitecture.AMD64;
                    break;

                case ILPlatform.x86Pref:
                    mod.Architecture = TargetArchitecture.I386;
                    mod.Attributes  |= ModuleAttributes.Preferred32Bit;
                    break;
                }
            }

            bool mixed = (mod.Attributes & ModuleAttributes.ILOnly) != ModuleAttributes.ILOnly;

            if (ModulesToStub.Count != 0 || mixed)
            {
                Log($"[{tag}] Making assembly unsafe");
                mod.Attributes |= ModuleAttributes.ILOnly;
                for (int i = 0; i < mod.Assembly.CustomAttributes.Count; i++)
                {
                    CustomAttribute attrib = mod.Assembly.CustomAttributes[i];
                    if (attrib.AttributeType.FullName == "System.CLSCompliantAttribute")
                    {
                        mod.Assembly.CustomAttributes.RemoveAt(i);
                        i--;
                    }
                }
                if (!mod.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Security.UnverifiableCodeAttribute"))
                {
                    mod.AddAttribute(mod.ImportReference(m_UnverifiableCodeAttribute_ctor));
                }
            }

            // MonoMod needs to relink some types (f.e. XnaToFnaHelper) via FindType, which requires a dependency map.
            Log($"[{tag}] Mapping dependencies for MonoMod");
            Modder.MapDependencies(mod);
        }