/// <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); } }