1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.IO;
6 using System.Text;
7 using LibRender2.Primitives;
8 using OpenBveApi;
9 using OpenBveApi.Colors;
10 using OpenBveApi.Hosts;
11 using OpenBveApi.Interface;
12 using OpenBveApi.Packages;
13 using OpenBveApi.Textures;
14 using RouteManager2;
15 using Path = OpenBveApi.Path;
16 
17 namespace OpenBve
18 {
19 	public partial class Menu
20 	{
21 		private static BackgroundWorker routeWorkerThread;
22 		private static BackgroundWorker packageWorkerThread;
23 		private static string SearchDirectory;
24 		private static string currentFile;
25 		private static Encoding RouteEncoding;
26 		private static RouteState RoutefileState;
27 		private static readonly Picturebox routePictureBox = new Picturebox(Program.Renderer);
28 		private static readonly Textbox routeDescriptionBox = new Textbox(Program.Renderer, Program.Renderer.Fonts.NormalFont, Color128.White, Color128.Black);
29 		private static Dictionary<string, Texture> iconCache = new Dictionary<string, Texture>();
30 		private static Package currentPackage;
31 		private static PackageOperation currentOperation;
32 		private static bool packagePreview;
33 		private static string installedFiles;
34 
packageWorkerThread_doWork(object sender, DoWorkEventArgs e)35 		private static void packageWorkerThread_doWork(object sender, DoWorkEventArgs e)
36 		{
37 			if (string.IsNullOrEmpty(currentFile))
38 			{
39 				return;
40 			}
41 
42 			switch (currentOperation)
43 			{
44 				case PackageOperation.Installing:
45 					if (packagePreview)
46 					{
47 						try
48 						{
49 							currentPackage = Manipulation.ReadPackage(currentFile);
50 						}
51 						catch
52 						{
53 							// Ignored
54 						}
55 
56 					}
57 					break;
58 			}
59 		}
60 
packageWorkerThread_completed(object sender, RunWorkerCompletedEventArgs e)61 		private static void packageWorkerThread_completed(object sender, RunWorkerCompletedEventArgs e)
62 		{
63 			if (currentPackage != null)
64 			{
65 				routePictureBox.Texture = new Texture(new Bitmap(currentPackage.PackageImage));
66 				routeDescriptionBox.Text = currentPackage.Description;
67 				packagePreview = false;
68 			}
69 			Database.SaveDatabase();
70 		}
71 
routeWorkerThread_doWork(object sender, DoWorkEventArgs e)72 		private static void routeWorkerThread_doWork(object sender, DoWorkEventArgs e)
73 		{
74 			if (string.IsNullOrEmpty(currentFile))
75 			{
76 				return;
77 			}
78 			RouteEncoding = TextEncoding.GetSystemEncodingFromFile(currentFile);
79 			Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\loading.png"), new TextureParameters(null, null), out routePictureBox.Texture);
80 			routeDescriptionBox.Text = Translations.GetInterfaceString("start_route_processing");
81 			Game.Reset(false);
82 			bool loaded = false;
83 			for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++)
84 			{
85 				if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.CanLoadRoute(currentFile))
86 				{
87 					object Route = (object)Program.CurrentRoute; //must cast to allow us to use the ref keyword.
88 					string RailwayFolder = Loading.GetRailwayFolder(currentFile);
89 					string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object");
90 					string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound");
91 					if (Program.CurrentHost.Plugins[i].Route.LoadRoute(currentFile, RouteEncoding, null, ObjectFolder, SoundFolder, true, ref Route))
92 					{
93 						Program.CurrentRoute = (CurrentRoute) Route;
94 					}
95 					else
96 					{
97 						if (Program.CurrentHost.Plugins[i].Route.LastException != null)
98 						{
99 							throw Program.CurrentHost.Plugins[i].Route.LastException; //Re-throw last exception generated by the route parser plugin so that the UI thread captures it
100 						}
101 						routeDescriptionBox.Text = "An unknown error was enountered whilst attempting to parse the routefile " + currentFile;
102 						RoutefileState = RouteState.Error;
103 					}
104 					loaded = true;
105 					break;
106 				}
107 			}
108 
109 			if (!loaded)
110 			{
111 				throw new Exception("No plugins capable of loading routefile " + currentFile + " were found.");
112 			}
113 		}
114 
routeWorkerThread_completed(object sender, RunWorkerCompletedEventArgs e)115 		private static void routeWorkerThread_completed(object sender, RunWorkerCompletedEventArgs e)
116 		{
117 			RoutefileState = RouteState.Processed;
118 			if (e.Error != null || Program.CurrentRoute == null)
119 			{
120 				Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\route_error.png"), new TextureParameters(null, null), out routePictureBox.Texture);
121 				if (e.Error != null)
122 				{
123 					routeDescriptionBox.Text = e.Error.Message;
124 					RoutefileState = RouteState.Error;
125 				}
126 				routeWorkerThread.Dispose();
127 				return;
128 			}
129 			try
130 			{
131 				// image
132 				if (!string.IsNullOrEmpty(Program.CurrentRoute.Image))
133 				{
134 
135 					try
136 					{
137 						if (File.Exists(Program.CurrentRoute.Image))
138 						{
139 							Program.CurrentHost.RegisterTexture(Program.CurrentRoute.Image, new TextureParameters(null, null), out routePictureBox.Texture);
140 						}
141 						else
142 						{
143 							Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\route_unknown.png"), new TextureParameters(null, null), out routePictureBox.Texture);
144 						}
145 
146 					}
147 					catch
148 					{
149 						routePictureBox.Texture = null;
150 					}
151 				}
152 				else
153 				{
154 					string[] f = {".png", ".bmp", ".gif", ".tiff", ".tif", ".jpeg", ".jpg"};
155 					int i;
156 					for (i = 0; i < f.Length; i++)
157 					{
158 						string g = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(currentFile),
159 							System.IO.Path.GetFileNameWithoutExtension(currentFile) + f[i]);
160 						if (System.IO.File.Exists(g))
161 						{
162 							try
163 							{
164 								using (var fs = new FileStream(g, FileMode.Open, FileAccess.Read))
165 								{
166 									//pictureboxRouteImage.Image = new Bitmap(fs);
167 								}
168 							}
169 							catch
170 							{
171 								//pictureboxRouteImage.Image = null;
172 							}
173 							break;
174 						}
175 					}
176 					if (i == f.Length)
177 					{
178 						Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\route_unknown.png"), new TextureParameters(null, null), out routePictureBox.Texture);
179 					}
180 				}
181 
182 				// description
183 				string Description = Program.CurrentRoute.Comment.ConvertNewlinesToCrLf();
184 				if (Description.Length != 0)
185 				{
186 					routeDescriptionBox.Text = Description;
187 				}
188 				else
189 				{
190 					routeDescriptionBox.Text = System.IO.Path.GetFileNameWithoutExtension(currentFile);
191 				}
192 			}
193 			catch (Exception ex)
194 			{
195 				Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\route_error.png"), new TextureParameters(null, null), out routePictureBox.Texture);
196 				routeDescriptionBox.Text = ex.Message;
197 				currentFile = null;
198 			}
199 		}
200 
OnWorkerProgressChanged(object sender, ProgressReport e)201 		private static void OnWorkerProgressChanged(object sender, ProgressReport e)
202 		{
203 			routeDescriptionBox.Text = "Processing:" + Environment.NewLine + e.Progress + "%" + Environment.NewLine + Environment.NewLine + e.CurrentFile;
204 		}
205 
OnWorkerReportsProblem(object sender, ProblemReport e)206 		private static void OnWorkerReportsProblem(object sender, ProblemReport e)
207 		{
208 			routeDescriptionBox.Text = Translations.GetInterfaceString("packages_creation_failure_error") + Environment.NewLine;
209 			if (e.Exception is UnauthorizedAccessException && currentOperation != PackageOperation.Creating)
210 			{
211 				//User attempted to install in a directory which requires UAC access
212 				routeDescriptionBox.Text += e.Exception.Message + Environment.NewLine + Environment.NewLine + Translations.GetInterfaceString("errors_security_checkaccess");
213 				if (Program.CurrentHost.Platform == HostPlatform.MicrosoftWindows)
214 				{
215 					routeDescriptionBox.Text += Environment.NewLine + Environment.NewLine + Translations.GetInterfaceString("errors_security_badlocation");
216 				}
217 			}
218 			else
219 			{
220 				//Non-localised string as this is a specific error message
221 				routeDescriptionBox.Text += e.Exception + @"\r\n \r\n encountered whilst processing the following file: \r\n\r\n" +
222 				                             e.CurrentFile + @" at " + e.Progress + @"% completion.";
223 				//Create crash dump file
224 				CrashHandler.LogCrash(e.Exception + Environment.StackTrace);
225 			}
226 		}
227 
OnPackageOperationCompleted(object sender, CompletionReport e)228 		private static void OnPackageOperationCompleted(object sender, CompletionReport e)
229 		{
230 			switch (e.Operation)
231 			{
232 				case PackageOperation.Installing:
233 					routeDescriptionBox.Text = Translations.GetInterfaceString("packages_install_success") + Environment.NewLine + Environment.NewLine + Translations.GetInterfaceString("packages_install_success_files") + Environment.NewLine + installedFiles;
234 					currentFile = string.Empty;
235 					installedFiles = string.Empty;
236 					switch (currentPackage.PackageType)
237 					{
238 						case PackageType.Route:
239 							Database.currentDatabase.InstalledRoutes.Remove(currentPackage);
240 							Database.currentDatabase.InstalledRoutes.Add(currentPackage);
241 							break;
242 						case PackageType.Train:
243 							Database.currentDatabase.InstalledTrains.Remove(currentPackage);
244 							Database.currentDatabase.InstalledTrains.Add(currentPackage);
245 							break;
246 						default:
247 							Database.currentDatabase.InstalledOther.Remove(currentPackage);
248 							Database.currentDatabase.InstalledOther.Add(currentPackage);
249 							break;
250 					}
251 					currentPackage = null;
252 					Database.SaveDatabase();
253 					break;
254 			}
255 		}
256 
257 
258 	}
259 }
260