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); }
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 }); }
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; }
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); } }
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()); }
/// <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())); }
internal static void Postfix(ConfigFile __instance, BepInPlugin ownerMetadata) { CachedConfigFile cached = new(__instance, ownerMetadata); ConfigFiles.Add(cached); ConfigFileCreated?.Invoke(cached); }
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); }
/// <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); }
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); }
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 }
/// <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; }
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); }
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>()); }
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()); }
/// <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(); } }
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); }
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); }
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; }
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; } } }
/// <summary> /// ctor automatically getting the SourceMod /// </summary> internal CustomEntity() { SourceMod = BepInExUtils.GetSourceModMetadata(); }
/// <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; }
/// <summary> /// ctor with manual assigned SourceMod /// </summary> /// <param name="sourceMod">Metadata of the mod adding this entity</param> internal CustomEntity(BepInPlugin sourceMod) { SourceMod = sourceMod; }