/// <summary>Loads the specified plugin for the specified train.</summary>
/// <param name="pluginFile">The file to the plugin.</param>
/// <param name="trainFolder">The train folder.</param>
/// <returns>Whether the plugin was loaded successfully.</returns>
internal bool LoadPlugin(string pluginFile, string trainFolder)
{
string pluginTitle = System.IO.Path.GetFileName(pluginFile);
if (!System.IO.File.Exists(pluginFile))
{
Interface.AddMessage(MessageType.Error, true, "The train plugin " + pluginTitle + " could not be found.");
return(false);
}
/*
* Unload plugin if already loaded.
* */
if (Plugin != null)
{
UnloadPlugin();
}
/*
* Prepare initialization data for the plugin.
* */
BrakeTypes brakeType = (BrakeTypes)Cars[DriverCar].CarBrake.brakeType;
int brakeNotches;
int powerNotches;
bool hasHoldBrake;
if (brakeType == BrakeTypes.AutomaticAirBrake)
{
brakeNotches = 2;
powerNotches = Handles.Power.MaximumNotch;
hasHoldBrake = false;
}
else
{
brakeNotches = Handles.Brake.MaximumNotch + (Handles.HasHoldBrake ? 1 : 0);
powerNotches = Handles.Power.MaximumNotch;
hasHoldBrake = Handles.HasHoldBrake;
}
bool hasLocoBrake = Handles.HasLocoBrake;
int cars = Cars.Length;
VehicleSpecs specs = new VehicleSpecs(powerNotches, brakeType, brakeNotches, hasHoldBrake, hasLocoBrake, cars);
InitializationModes mode = (InitializationModes)Interface.CurrentOptions.TrainStart;
/*
* Check if the plugin is a .NET plugin.
* */
Assembly assembly;
try
{
assembly = Assembly.LoadFile(pluginFile);
}
catch (BadImageFormatException)
{
assembly = null;
}
catch (Exception ex)
{
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " could not be loaded due to the following exception: " + ex.Message);
return(false);
}
if (assembly != null)
{
Type[] types;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
foreach (Exception e in ex.LoaderExceptions)
{
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " raised an exception on loading: " + e.Message);
}
return(false);
}
foreach (Type type in types)
{
if (typeof(IRuntime).IsAssignableFrom(type))
{
if (type.FullName == null)
{
//Should never happen, but static code inspection suggests that it's possible....
throw new InvalidOperationException();
}
IRuntime api = assembly.CreateInstance(type.FullName) as IRuntime;
Plugin = new NetPlugin(pluginFile, trainFolder, api, this);
if (Plugin.Load(specs, mode))
{
return(true);
}
else
{
Plugin = null;
return(false);
}
}
}
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " does not export a train interface and therefore cannot be used with openBVE.");
return(false);
}
/*
* Check if the plugin is a Win32 plugin.
*
*/
try
{
if (!PluginManager.CheckWin32Header(pluginFile))
{
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " is of an unsupported binary format and therefore cannot be used with openBVE.");
return(false);
}
}
catch (Exception ex)
{
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " could not be read due to the following reason: " + ex.Message);
return(false);
}
if (!Program.CurrentlyRunningOnWindows | IntPtr.Size != 4)
{
Interface.AddMessage(MessageType.Warning, false, "The train plugin " + pluginTitle + " can only be used on 32-bit Microsoft Windows or compatible.");
return(false);
}
if (Program.CurrentlyRunningOnWindows && !System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\AtsPluginProxy.dll"))
{
Interface.AddMessage(MessageType.Warning, false, "AtsPluginProxy.dll is missing or corrupt- Please reinstall.");
return(false);
}
Plugin = new Win32Plugin(pluginFile, this);
if (Plugin.Load(specs, mode))
{
return(true);
}
else
{
Plugin = null;
Interface.AddMessage(MessageType.Error, false, "The train plugin " + pluginTitle + " does not export a train interface and therefore cannot be used with openBVE.");
return(false);
}
}