示例#1
0
        public ConfigSettingEntry(ConfigEntryBase entry, BepInPlugin meta, ConfigFile configFile)
        {
            Entry = entry;

            DispName    = entry.Definition.Key;
            Category    = entry.Definition.Section;
            Description = entry.Description?.Description;

            var converter = TomlTypeConverter.GetConverter(entry.SettingType);

            if (converter != null)
            {
                ObjToStr = o => converter.ConvertToString(o, entry.SettingType);
                StrToObj = s => converter.ConvertToObject(s, entry.SettingType);
            }

            var values = entry.Description?.AcceptableValues;

            if (values != null)
            {
                GetAcceptableValues(values);
            }

            DefaultValue = entry.DefaultValue;

            SetFromAttributes(entry.Description?.Tags, meta, configFile);
        }
示例#2
0
        public static PluginInfo ToPluginInfo(TypeDefinition type)
        {
            if (type.IsInterface || type.IsAbstract)
            {
                return(null);
            }

            try
            {
                if (!type.IsSubtypeOf(typeof(BaseUnityPlugin)))
                {
                    return(null);
                }
            }
            catch (AssemblyResolutionException)
            {
                // Can happen if this type inherits a type from an assembly that can't be found. Safe to assume it's not a plugin.
                return(null);
            }

            var metadata = BepInPlugin.FromCecilType(type);

            // Perform checks that will prevent the plugin from being loaded in ALL cases
            if (metadata == null)
            {
                Logger.LogWarning($"Skipping over type [{type.FullName}] as no metadata attribute is specified");
                return(null);
            }

            if (string.IsNullOrEmpty(metadata.GUID) || !allowedGuidRegex.IsMatch(metadata.GUID))
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its GUID [{metadata.GUID}] is of an illegal format.");
                return(null);
            }

            if (metadata.Version == null)
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its version is invalid.");
                return(null);
            }

            if (metadata.Name == null)
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its name is null.");
                return(null);
            }

            var filters           = BepInProcess.FromCecilType(type);
            var dependencies      = BepInDependency.FromCecilType(type);
            var incompatibilities = BepInIncompatibility.FromCecilType(type);

            return(new PluginInfo
            {
                Metadata = metadata,
                Processes = filters,
                Dependencies = dependencies,
                Incompatibilities = incompatibilities,
                TypeName = type.FullName
            });
        }
示例#3
0
            new List <KeyValuePair <long, string> >(); // avoid leaking memory

        /// <summary>
        ///     Internal constructor only, CustomRPCs are instantiated via <see cref="NetworkManager"/>
        /// </summary>
        /// <param name="sourceMod">Reference to the <see cref="BepInPlugin"/> which created this RPC.</param>
        /// <param name="name"></param>
        /// <param name="serverReceive"></param>
        /// <param name="clientReceive"></param>
        internal CustomRPC(BepInPlugin sourceMod, string name, NetworkManager.CoroutineHandler serverReceive,
                           NetworkManager.CoroutineHandler clientReceive) : base(sourceMod)
        {
            Name            = name;
            OnServerReceive = serverReceive;
            OnClientReceive = clientReceive;
        }
示例#4
0
 public static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
 {
     try
     {
         parentLogger.LogInfo("On Scene Loaded" + scene.name);
         UnityEngine.Debug.Log("Loading Scene: " + scene.name);
         if (scene.name == "UI")
         {
             TextMeshProUGUI betaText = GetUITextByName("BETA");
             if (betaText)
             {
                 betaText.text = "INJECTED BUILD - unstable mods";
             }
         }
         else
         {
             TextMeshProUGUI modListText = GetUITextByName("TextMeshPro Text");
             if (modListText)
             {
                 BepInPlugin bepInPlugin = (BepInPlugin)Attribute.GetCustomAttribute(ModdingUtils.parentPlugin.GetType(), typeof(BepInPlugin));
                 if (modListText.text.EndsWith("</size>"))
                 {
                     modListText.text += "\n\nMods Currently Installed:\n";
                 }
                 modListText.text += "\n" + bepInPlugin.Name + " - " + bepInPlugin.Version;
             }
         }
     }
     catch (Exception ex)
     {
         parentLogger.LogFatal(ex);
     }
 }
示例#5
0
        private void CacheIcon(GameObject target, BepInPlugin plugin, Sprite rendered)
        {
            string version = GetVersion(plugin);

            Directory.CreateDirectory(Utils.Paths.IconCachePath);
            File.WriteAllBytes(GetCachePath(target.name, version), rendered.texture.EncodeToPNG());
        }
示例#6
0
        /// <summary>
        ///     Add a custom prefab to the manager with known source mod metadata. Don't fix references.
        /// </summary>
        /// <param name="prefab">Prefab to add</param>
        /// <param name="sourceMod">Metadata of the mod adding this prefab</param>
        /// <returns>true if the custom prefab was added to the manager.</returns>
        internal bool AddPrefab(GameObject prefab, BepInPlugin sourceMod)
        {
            CustomPrefab customPrefab = new CustomPrefab(prefab, sourceMod);

            AddPrefab(customPrefab);
            return(Prefabs.ContainsKey(prefab.name.GetStableHashCode()));
        }
示例#7
0
        internal static void Postfix(ConfigFile __instance, BepInPlugin ownerMetadata)
        {
            CachedConfigFile cached = new(__instance, ownerMetadata);

            ConfigFiles.Add(cached);

            ConfigFileCreated?.Invoke(cached);
        }
示例#8
0
        public ModDetails(BepInPlugin attribute, string dllFileFullPath)
        {
            GUID    = attribute.GUID;
            modName = attribute.Name;
            version = attribute.Version.ToString();
            this.dllFileFullPath = dllFileFullPath;
            int ix = dllFileFullPath.LastIndexOf("\\") + 1;

            dllFileName = dllFileFullPath.Substring(ix, dllFileFullPath.Length - ix);
        }
示例#9
0
        /// <summary>
        ///     Get the <see cref="CustomRPC"/> for a given mod.
        /// </summary>
        /// <param name="sourceMod">Reference to the <see cref="BepInPlugin"/> which added this entity</param>
        /// <param name="name">Unique name for your RPC</param>
        /// <param name="serverReceive">Delegate which gets called on client instances when packages are received</param>
        /// <param name="clientReceive">Delegate which gets called on server instances when packages are received</param>
        /// <returns>Existing or newly created <see cref="CustomRPC"/>.</returns>
        internal CustomRPC AddRPC(BepInPlugin sourceMod, string name, CoroutineHandler serverReceive, CoroutineHandler clientReceive)
        {
            var ret = RPCs.FirstOrDefault(x => x.SourceMod == sourceMod && x.Name == name);

            if (ret != null)
            {
                return(ret);
            }

            ret = new CustomRPC(sourceMod, name, serverReceive, clientReceive);
            RPCs.Add(ret);
            return(ret);
        }
示例#10
0
 private static bool MetadataHelperGetMetadataPrefix(object plugin, ref BepInPlugin __result)
 {
     if (plugin is QModPlugin)
     {
         var pluginInfo = Chainloader.PluginInfos.Values.LastOrDefault(x => QModPluginInfos.Values.Contains(x) && !InitialisedQModPlugins.Contains(x));
         if (pluginInfo is PluginInfo)
         {
             InitialisedQModPlugins.Add(pluginInfo);
             __result = pluginInfo.Metadata;
             return(false);
         }
     }
     return(true);
 }
示例#11
0
        private string GetVersion(BepInPlugin plugin)
        {
            string version;

            if (plugin != null)
            {
                version = plugin.Name + "-" + plugin.Version;
            }
            else
            {
                version = Version.GetVersionString();
            }

            return(version.Replace("/", "_")); // some mods add a '/' to the version name
        }
示例#12
0
        /// <summary>
        ///     todo from property that checks canread canwrite
        ///     from method that shows a button?
        ///     change to inheritance? or isbutton and ignore set argument
        /// </summary>
        public void SetFromAttributes(MemberInfo settingProp, BepInPlugin pluginInfo)
        {
            PluginInfo = pluginInfo;

            var attribs = settingProp.GetCustomAttributes(false);

            DispName         = attribs.OfType <DisplayNameAttribute>().FirstOrDefault()?.DisplayName;
            Category         = attribs.OfType <CategoryAttribute>().FirstOrDefault()?.Category;
            Description      = attribs.OfType <DescriptionAttribute>().FirstOrDefault()?.Description;
            DefaultValue     = attribs.OfType <DefaultValueAttribute>().FirstOrDefault()?.Value;
            AcceptableValues = attribs.OfType <AcceptableValueBaseAttribute>().FirstOrDefault();

            ReadOnly  = attribs.OfType <ReadOnlyAttribute>().FirstOrDefault()?.IsReadOnly;
            Browsable = attribs.OfType <BrowsableAttribute>().FirstOrDefault()?.Browsable;
        }
示例#13
0
        public static PluginInfo ToPluginInfo(TypeDefinition type)
        {
            if (type.IsInterface || type.IsAbstract || !type.IsSubtypeOf(typeof(BaseUnityPlugin)))
            {
                return(null);
            }

            var metadata = BepInPlugin.FromCecilType(type);

            // Perform checks that will prevent the plugin from being loaded in ALL cases
            if (metadata == null)
            {
                Logger.LogWarning($"Skipping over type [{type.FullName}] as no metadata attribute is specified");
                return(null);
            }

            if (string.IsNullOrEmpty(metadata.GUID) || !allowedGuidRegex.IsMatch(metadata.GUID))
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its GUID [{metadata.GUID}] is of an illegal format.");
                return(null);
            }

            if (metadata.Version == null)
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its version is invalid.");
                return(null);
            }

            if (metadata.Name == null)
            {
                Logger.LogWarning($"Skipping type [{type.FullName}] because its name is null.");
                return(null);
            }

            var filters      = BepInProcess.FromCecilType(type);
            var dependencies = BepInDependency.FromCecilType(type);

            return(new PluginInfo
            {
                Metadata = metadata,
                Processes = filters,
                Dependencies = dependencies,
                TypeName = type.FullName
            });
        }
        /// <summary>
        ///     Get the CustomLocalization for a given mod.
        ///     Creates a new <see cref="CustomLocalization"/> if no localization was added before.
        /// </summary>
        /// <returns>Existing or newly created <see cref="CustomLocalization"/>.</returns>
        internal CustomLocalization GetLocalization(BepInPlugin sourceMod)
        {
            var ret = Localizations.FirstOrDefault(ctx => ctx.SourceMod == sourceMod);

            if (ret != null)
            {
                return(ret);
            }

            if (sourceMod == Main.Instance.Info.Metadata)
            {
                return(JotunnLocalization);
            }

            ret = new CustomLocalization(sourceMod);
            Localizations.Add(ret);
            return(ret);
        }
示例#15
0
        private static IEnumerable <SettingEntryBase> GetBepInExConfig()
        {
            var coreConfigProp = typeof(ConfigFile).GetProperty("CoreConfig", BindingFlags.Static | BindingFlags.NonPublic);

            if (coreConfigProp == null)
            {
                throw new ArgumentNullException(nameof(coreConfigProp));
            }

            var coreConfig = (ConfigFile)coreConfigProp.GetValue(null, null);
            var bepinMeta  = new BepInPlugin("BepInEx", "BepInEx", typeof(BepInEx.Bootstrap.Chainloader).Assembly.GetName().Version.ToString());

            return(coreConfig.GetConfigEntries()
                   .Select(x => new ConfigSettingEntry(x, null)
            {
                IsAdvanced = true, PluginInfo = bepinMeta
            })
                   .Cast <SettingEntryBase>());
        }
示例#16
0
    void ICacheable.Load(BinaryReader br)
    {
        TypeName = br.ReadString();
        Location = br.ReadString();

        Metadata = new BepInPlugin(br.ReadString(), br.ReadString(), br.ReadString());

        var processListCount = br.ReadInt32();
        var processList      = new List <BepInProcess>(processListCount);

        for (var i = 0; i < processListCount; i++)
        {
            processList.Add(new BepInProcess(br.ReadString()));
        }
        Processes = processList;

        var depCount = br.ReadInt32();
        var depList  = new List <BepInDependency>(depCount);

        for (var i = 0; i < depCount; i++)
        {
            var dep = new BepInDependency("");
            ((ICacheable)dep).Load(br);
            depList.Add(dep);
        }

        Dependencies = depList;

        var incCount = br.ReadInt32();
        var incList  = new List <BepInIncompatibility>(incCount);

        for (var i = 0; i < incCount; i++)
        {
            var inc = new BepInIncompatibility("");
            ((ICacheable)inc).Load(br);
            incList.Add(inc);
        }

        Incompatibilities = incList;

        TargettedBepInExVersion = new Version(br.ReadString());
    }
示例#17
0
    /// <summary>
    ///     Create a new config file at the specified config path.
    /// </summary>
    /// <param name="configPath">Full path to a file that contains settings. The file will be created as needed.</param>
    /// <param name="saveOnInit">If the config file/directory doesn't exist, create it immediately.</param>
    /// <param name="ownerMetadata">Information about the plugin that owns this setting file.</param>
    public ConfigFile(string configPath, bool saveOnInit, BepInPlugin ownerMetadata)
    {
        _ownerMetadata = ownerMetadata;

        if (configPath == null)
        {
            throw new ArgumentNullException(nameof(configPath));
        }
        configPath     = Path.GetFullPath(configPath);
        ConfigFilePath = configPath;

        if (File.Exists(ConfigFilePath))
        {
            Reload();
        }
        else if (saveOnInit)
        {
            Save();
        }
    }
示例#18
0
        private bool ContainsIconCache(GameObject target, BepInPlugin plugin, out Sprite sprite)
        {
            string version = GetVersion(plugin);
            string path    = GetCachePath(target.name, version);
            bool   exists  = File.Exists(path);

            if (!exists)
            {
                sprite = null;
                return(false);
            }

            byte[]    bytesPNG = File.ReadAllBytes(path);
            Texture2D texture  = new Texture2D(1, 1);

            texture.LoadImage(bytesPNG);

            sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one / 2f);
            return(true);
        }
示例#19
0
 void OnSceneLoaded(Scene scene, LoadSceneMode mode)
 {
     UnityEngine.Debug.Log("Loading Scene: " + scene.name);
     TextMeshProUGUI[] texts = FindObjectsOfType <TextMeshProUGUI>();
     for (int i = 0; i < texts.Length; i++)
     {
         if (scene.name == "UI" && texts[i].name == "BETA")
         {
             texts[i].text = "INJECTED BUILD - unstable mods";
         }
         if (scene.name == "Login" && texts[i].name == "TextMeshPro Text")
         {
             BepInPlugin bepInPlugin = (BepInPlugin)Attribute.GetCustomAttribute(this.GetType(), typeof(BepInPlugin));
             if (texts[i].text.EndsWith("</size>"))
             {
                 texts[i].text += "\n\nMods Currently Installed:\n";
             }
             texts[i].text += "\n" + bepInPlugin.Name + " - " + bepInPlugin.Version;
         }
     }
 }
        internal static ModInfo GetModInfo(this Assembly assembly)
        {
            ModInfo modInfo = default;

            Type[] types = assembly.GetExportedTypes();

            foreach (var item in types)
            {
                BepInPlugin bepInPlugin = item.GetCustomAttribute <BepInPlugin>();

                if (bepInPlugin == null)
                {
                    continue;
                }

                modInfo.ModGuid = bepInPlugin.GUID;
                modInfo.ModName = bepInPlugin.Name;
            }

            return(modInfo);
        }
示例#21
0
        public void Load(BinaryReader br)
        {
            TypeName = br.ReadString();

            Metadata = new BepInPlugin(br.ReadString(), br.ReadString(), br.ReadString());

            var processListCount = br.ReadInt32();
            var processList      = new List <BepInProcess>(processListCount);

            for (int i = 0; i < processListCount; i++)
            {
                processList.Add(new BepInProcess(br.ReadString()));
            }
            Processes = processList;

            var depCount = br.ReadInt32();
            var depList  = new List <BepInDependency>(depCount);

            for (int i = 0; i < depCount; i++)
            {
                depList.Add(new BepInDependency(br.ReadString(), (BepInDependency.DependencyFlags)br.ReadInt32()));
            }
            Dependencies = depList;
        }
示例#22
0
        internal void SetFromAttributes(object[] attribs, BepInPlugin metadata, ConfigFile configFile)
        {
            //PluginInstance = pluginInstance;
            //PluginInfo = pluginInstance?.Info.Metadata;

            if (metadata != null)
            {
                ConfigFileName = metadata.Name;
                ConfigFileGUID = metadata.GUID;
            }
            else
            {
                ConfigFileName = Path.GetFileNameWithoutExtension(configFile.ConfigFilePath);
                ConfigFileGUID = string.Empty;
            }

            if (attribs == null || attribs.Length == 0)
            {
                return;
            }

            foreach (var attrib in attribs)
            {
                switch (attrib)
                {
                case null: break;

                    // Obsolete attributes from bepin4 -----------------------
#pragma warning disable 618 // Disable obsolete warning
                case DisplayNameAttribute da:
                    DispName = da.DisplayName;
                    break;

                case CategoryAttribute ca:
                    Category = ca.Category;
                    break;

                case DescriptionAttribute de:
                    Description = de.Description;
                    break;

                case DefaultValueAttribute def:
                    DefaultValue = def.Value;
                    break;

                case ReadOnlyAttribute ro:
                    ReadOnly = ro.IsReadOnly;
                    break;

                case BrowsableAttribute bro:
                    Browsable = bro.Browsable;
                    break;
#pragma warning restore 618

                // Obsolete attributes from early bepin5 -----------------------
                case Action <SettingEntryBase> newCustomDraw:
                    CustomDrawer = _ => newCustomDraw(this);
                    break;

                case string str:
                    switch (str)
                    {
                    case "ReadOnly": ReadOnly = true; break;

                    case "Browsable": Browsable = true; break;

                    case "Unbrowsable":
                    case "Hidden": Browsable = false; break;

                    case "Advanced": IsAdvanced = true; break;
                    }
                    break;

                // Copy attributes from a specially formatted object, currently recommended
                default:
                    var attrType = attrib.GetType();
                    if (attrType.Name == "ConfigurationManagerAttributes")
                    {
                        var otherFields = attrType.GetFields(BindingFlags.Instance | BindingFlags.Public);
                        foreach (var propertyPair in _myProperties.Join(otherFields, my => my.Name, other => other.Name, (my, other) => new { my, other }))
                        {
                            try
                            {
                                var val = propertyPair.other.GetValue(attrib);
                                if (val != null)
                                {
                                    propertyPair.my.SetValue(this, val, null);
                                }
                            }
                            catch (Exception ex)
                            {
                                ConfigurationManager.Logger.LogWarning($"Failed to copy value {propertyPair.my.Name} from provided tag object {attrType.FullName} - " + ex.Message);
                            }
                        }
                        break;
                    }
                    return;
                }
            }
        }
示例#23
0
 /// <summary>
 ///     ctor automatically getting the SourceMod
 /// </summary>
 internal CustomEntity()
 {
     SourceMod = BepInExUtils.GetSourceModMetadata();
 }
示例#24
0
 /// <summary>
 ///     Internal ctor with provided <see cref="BepInPlugin"/> metadata.<br />
 ///     Does not fix references.
 /// </summary>
 /// <param name="prefab">Prefab added</param>
 /// <param name="sourceMod">Metadata of the mod adding this prefab</param>
 internal CustomPrefab(GameObject prefab, BepInPlugin sourceMod) : base(sourceMod)
 {
     Prefab = prefab;
 }
示例#25
0
 /// <summary>
 ///     ctor with manual assigned SourceMod
 /// </summary>
 /// <param name="sourceMod">Metadata of the mod adding this entity</param>
 internal CustomEntity(BepInPlugin sourceMod)
 {
     SourceMod = sourceMod;
 }