Fix PluginManager.Unload erroring on mono.

This commit is contained in:
UnknownShadow200 2016-07-29 10:05:33 +10:00
parent 23b0d3fcc9
commit 49a7a1ab03
6 changed files with 235 additions and 236 deletions

View File

@ -539,20 +539,20 @@
<Compile Include="Player\Undo\UndoFile.cs" /> <Compile Include="Player\Undo\UndoFile.cs" />
<Compile Include="Player\Undo\UndoFileBin.cs" /> <Compile Include="Player\Undo\UndoFileBin.cs" />
<Compile Include="Player\Undo\UndoFileText.cs" /> <Compile Include="Player\Undo\UndoFileText.cs" />
<Compile Include="Plugins\Enums.cs" /> <Compile Include="Plugins\Events\Enums.cs" />
<Compile Include="Plugins\Events\GroupEvents.cs" /> <Compile Include="Plugins\Events\GroupEvents.cs" />
<Compile Include="Plugins\Events\IPluginEvent.cs" />
<Compile Include="Plugins\Events\LevelEvents.cs" /> <Compile Include="Plugins\Events\LevelEvents.cs" />
<Compile Include="Plugins\Events\PlayerEvents.cs" /> <Compile Include="Plugins\Events\PlayerEvents.cs" />
<Compile Include="Plugins\Events\ServerEvents.cs" /> <Compile Include="Plugins\Events\ServerEvents.cs" />
<Compile Include="Plugins\IPluginEvent.cs" />
<Compile Include="Plugins\Manager\Plugin.Events.cs" />
<Compile Include="Plugins\Manager\PluginManager.cs" />
<Compile Include="Plugins\Manager\Plugin.cs" />
<Compile Include="Network\NetUtils.cs" /> <Compile Include="Network\NetUtils.cs" />
<Compile Include="Network\Opcode.cs" /> <Compile Include="Network\Opcode.cs" />
<Compile Include="Network\Player.Networking.cs" /> <Compile Include="Network\Player.Networking.cs" />
<Compile Include="Player\Alias.cs" /> <Compile Include="Player\Alias.cs" />
<Compile Include="API\API.cs" /> <Compile Include="API\API.cs" />
<Compile Include="Plugins\Plugin.cs" />
<Compile Include="Plugins\Plugin.Events.cs" />
<Compile Include="Plugins\PluginManager.cs" />
<Compile Include="Scripting\Scripting.cs" /> <Compile Include="Scripting\Scripting.cs" />
<Compile Include="Player\Ban.cs" /> <Compile Include="Player\Ban.cs" />
<Compile Include="Levels\BlockDefinitions.cs" /> <Compile Include="Levels\BlockDefinitions.cs" />
@ -706,7 +706,6 @@
<Folder Include="Player\Undo" /> <Folder Include="Player\Undo" />
<Folder Include="Plugins" /> <Folder Include="Plugins" />
<Folder Include="Plugins\Events" /> <Folder Include="Plugins\Events" />
<Folder Include="Plugins\Manager" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -1,85 +1,85 @@
/* /*
Copyright 2011 MCForge Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace MCGalaxy { namespace MCGalaxy {
// NOTE: You must use a different delegate type for each subclass // NOTE: You must use a different delegate type for each subclass
// This is because the static events are unique to each generic instantiation, not each subclass. // This is because the static events are unique to each generic instantiation, not each subclass.
public class IPluginEvent<IMethod> { public class IPluginEvent<IMethod> {
protected internal static List<IPluginEvent<IMethod>> handlers = new List<IPluginEvent<IMethod>>(); protected internal static List<IPluginEvent<IMethod>> handlers = new List<IPluginEvent<IMethod>>();
protected internal Plugin plugin; protected internal Plugin plugin;
protected internal IMethod method; protected internal IMethod method;
protected internal Priority priority; protected internal Priority priority;
internal IPluginEvent(IMethod method, Priority priority, Plugin plugin) { internal IPluginEvent(IMethod method, Priority priority, Plugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.priority = priority; this.priority = priority;
this.method = method; this.method = method;
} }
/// <summary> Register this event </summary> /// <summary> Register this event </summary>
/// <param name="method">This is the delegate that will get called when this event occurs</param> /// <param name="method">This is the delegate that will get called when this event occurs</param>
/// <param name="priority">The priority (imporantce) of this call</param> /// <param name="priority">The priority (imporantce) of this call</param>
/// <param name="plugin">The plugin object that is registering the event</param> /// <param name="plugin">The plugin object that is registering the event</param>
/// <param name="bypass">Register more than one of the same event</param> /// <param name="bypass">Register more than one of the same event</param>
public static void Register(IMethod method, Priority priority, Plugin plugin, bool bypass = false) { public static void Register(IMethod method, Priority priority, Plugin plugin, bool bypass = false) {
if (Find(plugin) != null && !bypass) if (Find(plugin) != null && !bypass)
throw new ArgumentException("The user tried to register 2 of the same event!"); throw new ArgumentException("The user tried to register 2 of the same event!");
handlers.Add(new IPluginEvent<IMethod>(method, priority, plugin)); handlers.Add(new IPluginEvent<IMethod>(method, priority, plugin));
Organize(); Organize();
} }
/// <summary> UnRegister this event </summary> /// <summary> UnRegister this event </summary>
/// <param name="plugin">The plugin object that has this event registered</param> /// <param name="plugin">The plugin object that has this event registered</param>
public static void UnRegister(Plugin plugin) { public static void UnRegister(Plugin plugin) {
if (Find(plugin) == null) if (Find(plugin) == null)
throw new ArgumentException("This plugin doesnt have this event registered!"); throw new ArgumentException("This plugin doesnt have this event registered!");
else else
handlers.Remove(Find(plugin)); handlers.Remove(Find(plugin));
} }
public static IPluginEvent<IMethod> Find(Plugin plugin) { public static IPluginEvent<IMethod> Find(Plugin plugin) {
foreach (var p in handlers) { foreach (var p in handlers) {
if (p.plugin == plugin) return p; if (p.plugin == plugin) return p;
} }
return null; return null;
} }
protected static void Organize() { protected static void Organize() {
handlers.Sort((a, b) => b.priority.CompareTo(a.priority)); handlers.Sort((a, b) => b.priority.CompareTo(a.priority));
} }
protected static void CallImpl(Action<IMethod> action) { protected static void CallImpl(Action<IMethod> action) {
try { try {
foreach (var pl in handlers) { foreach (var pl in handlers) {
try { try {
action(pl.method); action(pl.method);
} catch (Exception ex) { } catch (Exception ex) {
Server.s.Log("Plugin " + pl.plugin.name + " errored when calling " + typeof(IMethod).Name + " event"); Server.s.Log("Plugin " + pl.plugin.name + " errored when calling " + typeof(IMethod).Name + " event");
Server.ErrorLog(ex); Server.ErrorLog(ex);
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
Server.s.Log("Error when calling " + typeof(IMethod).Name + " event"); Server.s.Log("Error when calling " + typeof(IMethod).Name + " event");
Server.ErrorLog(ex); Server.ErrorLog(ex);
} }
} }
} }
} }

View File

@ -1,145 +1,145 @@
/* /*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy) Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
namespace MCGalaxy { namespace MCGalaxy {
/// <summary> This class provides for more advanced modification to MCGalaxy </summary> /// <summary> This class provides for more advanced modification to MCGalaxy </summary>
public abstract partial class Plugin { public abstract partial class Plugin {
/// <summary> List of all plugins. </summary> /// <summary> List of all plugins. </summary>
public static List<Plugin> all = new List<Plugin>(); public static List<Plugin> all = new List<Plugin>();
/// <summary> Look to see if a plugin is loaded </summary> /// <summary> Look to see if a plugin is loaded </summary>
/// <param name="name">The name of the plugin</param> /// <param name="name">The name of the plugin</param>
/// <returns>Returns the plugin (returns null if non is found)</returns> /// <returns>Returns the plugin (returns null if non is found)</returns>
public static Plugin Find(string name) { public static Plugin Find(string name) {
List<Plugin> tempList = new List<Plugin>(); List<Plugin> tempList = new List<Plugin>();
tempList.AddRange(all); tempList.AddRange(all);
Plugin match = null; int matches = 0; Plugin match = null; int matches = 0;
name = name.ToLower(); name = name.ToLower();
foreach (Plugin p in tempList) { foreach (Plugin p in tempList) {
if (p.name.ToLower() == name) return p; if (p.name.ToLower() == name) return p;
if (p.name.ToLower().Contains(name)) { if (p.name.ToLower().Contains(name)) {
match = p; matches++; match = p; matches++;
} }
} }
return matches == 1 ? match : null; return matches == 1 ? match : null;
} }
/// <summary> Load a plugin </summary> /// <summary> Load a plugin </summary>
/// <param name="name">The name of the plugin.</param> /// <param name="name">The name of the plugin.</param>
/// <param name="startup">Is this startup?</param> /// <param name="startup">Is this startup?</param>
public static void Load(string name, bool startup){ public static void Load(string name, bool startup){
string creator = ""; string creator = "";
string path = "plugins/" + name + ".dll"; string path = "plugins/" + name + ".dll";
try { try {
Plugin instance = null; Plugin instance = null;
Assembly lib = null; Assembly lib = null;
using (FileStream fs = File.Open(path, FileMode.Open)) { using (FileStream fs = File.Open(path, FileMode.Open)) {
using (MemoryStream ms = new MemoryStream()) { using (MemoryStream ms = new MemoryStream()) {
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
int read = 0; int read = 0;
while ((read = fs.Read(buffer, 0, 1024)) > 0) while ((read = fs.Read(buffer, 0, 1024)) > 0)
ms.Write(buffer, 0, read); ms.Write(buffer, 0, read);
lib = Assembly.Load(ms.ToArray()); lib = Assembly.Load(ms.ToArray());
} }
} }
try { try {
foreach (Type t in lib.GetTypes()) { foreach (Type t in lib.GetTypes()) {
if (!t.IsSubclassOf(typeof(Plugin))) continue; if (!t.IsSubclassOf(typeof(Plugin))) continue;
instance = (Plugin)Activator.CreateInstance(t); instance = (Plugin)Activator.CreateInstance(t);
break; break;
} }
} catch { } } catch { }
if (instance == null) { if (instance == null) {
Server.s.Log("The plugin " + name + " couldn't be loaded!"); Server.s.Log("The plugin " + name + " couldn't be loaded!");
return; return;
} }
creator = instance.creator; creator = instance.creator;
string ver = instance.MCGalaxy_Version; string ver = instance.MCGalaxy_Version;
if (!String.IsNullOrEmpty(ver) && new Version(ver) > Server.Version) { if (!String.IsNullOrEmpty(ver) && new Version(ver) > Server.Version) {
Server.s.Log("This plugin (" + instance.name + ") isn't compatible with this version of MCGalaxy!"); Server.s.Log("This plugin (" + instance.name + ") isn't compatible with this version of MCGalaxy!");
Thread.Sleep(1000); Thread.Sleep(1000);
if (!Server.unsafe_plugin) return; if (!Server.unsafe_plugin) return;
Server.s.Log("Will attempt to load!"); Server.s.Log("Will attempt to load!");
} }
Plugin.all.Add(instance); Plugin.all.Add(instance);
if (instance.LoadAtStartup) { if (instance.LoadAtStartup) {
instance.Load(startup); instance.Load(startup);
Server.s.Log("Plugin: " + instance.name + " loaded...build: " + instance.build); Server.s.Log("Plugin: " + instance.name + " loaded...build: " + instance.build);
} else { } else {
Server.s.Log("Plugin: " + instance.name + " was not loaded, you can load it with /pload"); Server.s.Log("Plugin: " + instance.name + " was not loaded, you can load it with /pload");
} }
Server.s.Log(instance.welcome); Server.s.Log(instance.welcome);
} catch (Exception e) { } catch (Exception e) {
Server.ErrorLog(e); Server.ErrorLog(e);
Server.s.Log("The plugin " + name + " failed to load!"); Server.s.Log("The plugin " + name + " failed to load!");
if (creator != "") Server.s.Log("You can go bug " + creator + " about it."); if (creator != "") Server.s.Log("You can go bug " + creator + " about it.");
Thread.Sleep(1000); Thread.Sleep(1000);
} }
} }
/// <summary> Unload a plugin </summary> /// <summary> Unload a plugin </summary>
/// <param name="p">The plugin to unload</param> /// <param name="p">The plugin to unload</param>
/// <param name="shutdown">Is this shutdown?</param> /// <param name="shutdown">Is this shutdown?</param>
public static void Unload(Plugin p, bool shutdown) { public static void Unload(Plugin p, bool shutdown) {
try { try {
p.Unload(shutdown); p.Unload(shutdown);
all.Remove(p); all.Remove(p);
Server.s.Log(p.name + " was unloaded."); Server.s.Log(p.name + " was unloaded.");
} catch { Server.s.Log("An error occurred while unloading a plugin."); } catch { Server.s.Log("An error occurred while unloading a plugin.");
} }
} }
/// <summary> Unload all plugins </summary> /// <summary> Unload all plugins </summary>
public static void Unload() { public static void Unload() {
all.ForEach(delegate(Plugin p) { for (int i = 0; i < all.Count; i++) {
Unload(p, true); Unload(all[i], true); i--;
}); }
} }
/// <summary> Load all plugins </summary> /// <summary> Load all plugins </summary>
public static void Load() { public static void Load() {
if (Directory.Exists("plugins")) { if (Directory.Exists("plugins")) {
foreach (string path in Directory.GetFiles("plugins", "*.dll")) { foreach (string path in Directory.GetFiles("plugins", "*.dll")) {
string name = Path.GetFileNameWithoutExtension(path); string name = Path.GetFileNameWithoutExtension(path);
Load(name, true); Load(name, true);
} }
} else { } else {
Directory.CreateDirectory("plugins"); Directory.CreateDirectory("plugins");
} }
// Load Internal Plugins // Load Internal Plugins
CTF.Setup temp = new CTF.Setup(); CTF.Setup temp = new CTF.Setup();
temp.Load(true); temp.Load(true);
Plugin.all.Add(temp); Plugin.all.Add(temp);
} }
} }
} }