This is the code block I use to fake a Reload button click to achieve a full plugin reload (the same as if you click on Reload in the UI of the plugin).
The code still contains full debug info, which can be removed.
C#:
protected void removePlugin(string selectedPlugin, string function)
{
//This function serves to either remove or reload a certain plugin. The string selectedPlugin should contain the plugin creator and plugin name (e.g. RunRudolf.ControlCenter), the string function can be either "Reload" or "Remove".
SuperController.LogError("2. " + function + selectedPlugin + " plugin");
Atom atom = containingAtom;
if (atom == null) return;
var pluginManager = atom.GetStorableByID("PluginManager") as MVRPluginManager;
if (pluginManager == null) return;
Transform panelRoot = pluginManager.UITransform;
if (panelRoot == null) return;
foreach (Transform pluginPanel in panelRoot)
{
Text[] allTexts = pluginPanel.GetComponentsInChildren<Text>(true);
Button[] buttons = pluginPanel.GetComponentsInChildren<Button>(true);
//1. Count the number of plugin#? text entries (e.g. "plugin#1")
List<Text> pluginTexts = new List<Text>();
Regex pattern1 = new Regex(@"^plugin#\d+$");
foreach (var txt in allTexts)
{
if (!string.IsNullOrEmpty(txt.text) && pattern1.IsMatch(txt.text))
{
pluginTexts.Add(txt);
}
}
SuperController.LogError(function + ": " + pluginTexts.Count + " plugin#? gefunden.");
//DEBUG
StringBuilder sb = new StringBuilder();
foreach (Text tx in pluginTexts)
{
sb.AppendLine(tx.text);
}
string result1 = sb.ToString();
SuperController.LogError(result1);
//2. Count the number of plugin#?_? text entries (e.g. "plugin#1_RunRudolf.ControlCenter")
List<Text> pluginTexts2 = new List<Text>();
Regex pattern2 = new Regex(@"^plugin#\d+_.+$");
foreach (var txt in allTexts)
{
if (!string.IsNullOrEmpty(txt.text) && pattern2.IsMatch(txt.text))
{
pluginTexts2.Add(txt);
}
}
SuperController.LogError(function + ": " + pluginTexts2.Count + " plugin#?_? gefunden.");
//DEBUG
StringBuilder sb2 = new StringBuilder();
foreach (Text tx in pluginTexts2)
{
sb2.AppendLine(tx.text);
}
string result2 = sb2.ToString();
SuperController.LogError(result2);
//3. Determine position of selectedPlugin
string escapedPlugin = Regex.Escape(selectedPlugin);
Regex pattern3 = new Regex($@"^plugin#\d+_{escapedPlugin}$");
for (int i = 0; i < pluginTexts2.Count; i++)
{
if (pattern3.IsMatch(pluginTexts2[i].text))
{
int position1 = i + 1;
SuperController.LogError(function + ": " + "'" + selectedPlugin + "' gefunden an Position " + position1 + " von " + pluginTexts2.Count);
//4. Determine plugin#? at position i+1 (index i)
string text = pluginTexts2[i].text;
SuperController.LogError(function + ": " + text);
if (text.Contains("_"))
{
string[] parts = text.Split('_');
if (parts.Length > 1)
{
string pluginId = parts[0];
SuperController.LogError(function + ": " + "PluginID von " + selectedPlugin + ": " + pluginId);
//5. Compare selectedPlugin to plugin#? from list in 1
int index = pluginTexts.FindIndex(t => t.text == pluginId);
if (index >= 0)
{
int position2 = index + 1;
SuperController.LogError(function + ": " + pluginId + " gefunden an Position: " + position2);
//6. Count number of Reload/Remove buttons
List<Button> reloadButtons = new List<Button>();
foreach (var btn in buttons)
{
string btnText = btn.GetComponentInChildren<Text>()?.text;
if (btnText == function)
{
reloadButtons.Add(btn);
}
}
SuperController.LogError(function + ": " + reloadButtons.Count + " " + function + " Buttons gefunden.");
//7. Execute Button at correct position
//Reload buttons for plugins are positioned in the UI starting from index 0, Remove buttons for plugins start at index 1 (first is atom remove)
if (function == "Reload")
{
position2 = position2 - 1;
}
reloadButtons[position2].onClick.Invoke();
SuperController.LogError(function + ": " + function + " Button for " + selectedPlugin + " clicked at index: " + position2);
return;
}
}
}
}
}
}
}
You can call this function by either using
removePlugin("Stopper.AlternativeFuta", "
Reload"); or removePlugin("Stopper.AlternativeFuta", "
Remove");
Replace the text "Stopper.AlternativeFuta" with your plugin URL, e.g. RunRudolf.ControlCenter. You can also use a variable there of course.
And attached you find the hierarchy of the VaM plugin UI, in order to understand why I did all this. You can search there for "plugin#", "Reload" or "Remove" to find the relevant entries.