Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.35 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6.  
  7. namespace MacTranslocator {
  8. class TranslocateHandler {
  9. /// <summary>
  10. /// This is the name of the game, the name of the folder in local storage where the game will be run from,
  11. /// and the name of the .app folder that contains the game.
  12. /// It is not the name of the executable file, use Platform_FilenameExecutable for that.
  13. /// </summary>
  14. public const string APPLICATION_NAME = "MacTranslocator";
  15.  
  16. private readonly Action<string> _ShowMessage;
  17. private readonly Action _OnFail;
  18. private readonly Action _OnSuccess;
  19.  
  20. /// <summary>
  21. /// This mode will show an update screen while it checks for patches and then downloads any updates.
  22. /// Normally this will only run on compiled versions, not in the debugger.
  23. /// Pass parameter forceUpdate==true to force an update regardless of what exe is running.
  24. /// </summary>
  25. public TranslocateHandler(Action<string> writeDebug, Action onSuccess, Action onFail) {
  26. _ShowMessage = writeDebug;
  27. _OnSuccess = onSuccess;
  28. _OnFail = onFail;
  29. }
  30.  
  31. public void Initialize() {
  32. ShowMessage($"ModeLoading initializing.");
  33. ShowMessage($" Platform is: {PlatformType}");
  34. ShowMessage($" Running in: {Platform_PathCurrentRunningDirectory}");
  35. ShowMessage($" PathExeDir: {Platform_PathExeDirectory}");
  36. ShowMessage($" FilenameExe: {Platform_FilenameExecutable}");
  37. Task.Factory.StartNew(() => {
  38. if (!RunUpdateFunctions()) {
  39. _OnFail?.Invoke();
  40. }
  41. else {
  42. _OnSuccess?.Invoke();
  43. }
  44. });
  45. }
  46.  
  47. private void ShowMessage(string msg, int waitMS = 0) {
  48. _ShowMessage?.Invoke(msg);
  49. if (waitMS > 0) {
  50. Thread.Sleep(waitMS);
  51. }
  52. }
  53.  
  54. // === Patch / Update routines live here =====================================================================
  55. // ============================================================================================================
  56.  
  57. private bool RunUpdateFunctions() {
  58. if (!VerifyRunningInClientAppFolder()) {
  59. // don't continue with update, allow called method to end program.
  60. return false;
  61. }
  62. return true;
  63. }
  64.  
  65. private bool VerifyRunningInClientAppFolder() {
  66. string currentDirectory = Platform_PathCurrentRunningDirectory;
  67. if (!currentDirectory.Contains(Platform_PathClientApp)) {
  68. ShowMessage("Application must be restarted in correct location.", 2000);
  69. if (!VerifyDirectoryContents(currentDirectory, Platform_PathClientApp)) {
  70. // delete client.app folder, copy in all files in this folder
  71. ShowMessage($"Copying application to {Platform_PathClientApp}");
  72. CopyAndReplace(currentDirectory, Platform_PathClientApp);
  73. }
  74. if (Platform_IsRunningInDebugger) {
  75. ShowMessage("Debugger: will not restart.");
  76. }
  77. else {
  78. string pathToExe = Path.Combine(Platform_PathExeDirectory, Platform_FilenameExecutable);
  79. Process.Start(pathToExe);
  80. return false;
  81. }
  82. }
  83. return true;
  84. }
  85.  
  86. private bool VerifyDirectoryContents(string pathSource, string pathDestination, string specificFilenameToCheck = null) {
  87. string filePattern = specificFilenameToCheck ?? "*.exe";
  88. ShowMessage($" Verifying files with pattern '{filePattern}':");
  89. ShowMessage($" {pathSource} vs");
  90. ShowMessage($" {pathDestination}");
  91. foreach (string filePath in Directory.GetFiles(pathSource, filePattern, SearchOption.AllDirectories)) {
  92. string fileLocalPath = filePath.Remove(0, pathSource.Length);
  93. if (fileLocalPath.Length > 0 && fileLocalPath[0] == Path.DirectorySeparatorChar) {
  94. fileLocalPath = fileLocalPath.Remove(0, 1);
  95. }
  96. if (IgnoreLogsAndPbds(fileLocalPath)) {
  97. continue;
  98. }
  99. string fileWeWant = Path.Combine(pathDestination, fileLocalPath);
  100. if (File.Exists(fileWeWant)) {
  101. ShowMessage($" Path exists: {Platform_RemoveUserPath(fileWeWant)}");
  102. // We should replace files that are older than the current version...
  103. // but I haven't written that code yet.
  104. }
  105. else {
  106. ShowMessage($" Path missing: {fileLocalPath}");
  107. return false;
  108. }
  109. }
  110. return true;
  111. }
  112.  
  113. private bool IgnoreLogsAndPbds(string filename) {
  114. if (Path.GetFileName(filename).StartsWith("log") && Path.GetFileName(filename).EndsWith(".txt"))
  115. return true;
  116. if (Path.GetExtension(filename) == ".pdb") {
  117. return true;
  118. }
  119. return false;
  120. }
  121.  
  122. private void CopyAndReplace(string pathSource, string pathDestination) {
  123. if (Directory.Exists(pathDestination)) {
  124. Directory.Delete(pathDestination, true);
  125. }
  126. if (!pathDestination.EndsWith(Path.DirectorySeparatorChar.ToString())) {
  127. pathDestination += Path.DirectorySeparatorChar;
  128. }
  129. //Now Create all of the directories
  130. foreach (string dirPath in Directory.GetDirectories(pathSource, "*", SearchOption.AllDirectories)) {
  131. Directory.CreateDirectory(dirPath.Replace(pathSource, pathDestination));
  132. }
  133. //Copy all the files & Replaces any files with the same name
  134. foreach (string newPath in Directory.GetFiles(pathSource, "*.*", SearchOption.AllDirectories)) {
  135. if (IgnoreLogsAndPbds(newPath)) {
  136. continue;
  137. }
  138. File.Copy(newPath, newPath.Replace(pathSource, pathDestination), true);
  139. }
  140. }
  141.  
  142. // === Platform code lives here ===============================================================================
  143. // ============================================================================================================
  144.  
  145. private const int NOT_SET = 0;
  146. public const int WINDOWS = 1;
  147. public const int MACOS = 2;
  148. public const int LINUX = 3;
  149.  
  150. private int _PlatformType = NOT_SET;
  151.  
  152. /// <summary>
  153. /// Returns an integer corresponding to the platform type we are running on.
  154. /// Possible values are Platform.WINDOWS, Platform.MACOS, and Platform.LINUX.
  155. /// Will throw a critical error if it cannot determine the platform.
  156. /// </summary>
  157. public int PlatformType {
  158. get {
  159. if (_PlatformType == NOT_SET) {
  160. #if SDL
  161. string platform = SDL.SDL_GetPlatform();
  162. if (platform.Equals("Windows")) {
  163. _PlatformType = WINDOWS;
  164. }
  165. else if (platform.Equals("Mac OS X")) {
  166. _PlatformType = MACOS;
  167. }
  168. else if (platform.Equals("Linux")) {
  169. _PlatformType = LINUX;
  170. }
  171. else {
  172. Tracer.Critical($"Could not determine platform type (unknown type '{platform}').");
  173. }
  174. #else
  175. _PlatformType = WINDOWS;
  176. #endif
  177. }
  178. return _PlatformType;
  179. }
  180. }
  181.  
  182. /// <summary>
  183. /// Path to the client application folder in the local storage.
  184. /// This is not necessarily the path to the folder containing the exectuable file and resources.
  185. /// Use PathExeDirectory for that.
  186. /// </summary>
  187. public string Platform_PathClientApp => Platform_GetPlatformSubDirectory($"{APPLICATION_NAME}.app");
  188.  
  189.  
  190. /// <summary>
  191. /// This will be true if we are running in the Visual Studio debugger.
  192. /// </summary>
  193. public bool Platform_IsRunningInDebugger => Debugger.IsAttached;
  194.  
  195. /// <summary>
  196. /// This is the filename that is used to start the game.
  197. /// On Windows, it will be the name of the client executable.
  198. /// On mac, it will be the kickstart binary.
  199. /// </summary>
  200. public string Platform_FilenameExecutable {
  201. get {
  202. switch (PlatformType) {
  203. case WINDOWS:
  204. return AppDomain.CurrentDomain.FriendlyName;
  205. case MACOS:
  206. return "CommunityClient"; // this is the kickstart script
  207. default:
  208. return "NoExeFile";
  209. }
  210. }
  211. }
  212.  
  213. /// <summary>
  214. /// This is the directory the application is currently running in. It is not necessarily local storage.
  215. /// If it is not local storage, then the application should be copied to local storage and run from there.
  216. /// </summary>
  217. public string Platform_PathCurrentRunningDirectory {
  218. get {
  219. switch (PlatformType) {
  220. case WINDOWS:
  221. return AppDomain.CurrentDomain.BaseDirectory;
  222. case MACOS:
  223. DirectoryInfo basePath = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent;
  224. return basePath.ToString();
  225. default:
  226. return "NoPathBaseDirectory";
  227. }
  228. }
  229. }
  230.  
  231. /// <summary>
  232. /// Path to the folder in local storage containing the executable file.
  233. /// This is where all the resource/dll/etc. files will be found.
  234. /// </summary>
  235. public string Platform_PathExeDirectory {
  236. get {
  237. #if SERVER
  238. return PathCurrentRunningDirectory;
  239. #else
  240. switch (PlatformType) {
  241. case WINDOWS:
  242. return Platform_PathClientApp;
  243. case MACOS:
  244. return $"{Platform_PathClientApp}/Contents/MacOS";
  245. default:
  246. return "NoPathExeDirectory";
  247. }
  248. #endif
  249. }
  250. }
  251.  
  252. private string Platform_GetPlatformSubDirectory(string subDirectory) {
  253. return Path.Combine(Platform_GetPlatformDirectory(), subDirectory);
  254. }
  255.  
  256. private string Platform_GetPlatformDirectory() {
  257. switch (PlatformType) {
  258. case WINDOWS:
  259. return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Games", APPLICATION_NAME);
  260. case MACOS: {
  261. string osConfigDir = Environment.GetEnvironmentVariable("HOME");
  262. if (string.IsNullOrEmpty(osConfigDir)) {
  263. return "."; // Oh well.
  264. }
  265. return Path.Combine(osConfigDir, "Library", "Application Support", APPLICATION_NAME);
  266. }
  267. case LINUX: {
  268. string osConfigDir = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
  269. if (string.IsNullOrEmpty(osConfigDir)) {
  270. osConfigDir = Environment.GetEnvironmentVariable("HOME");
  271. if (string.IsNullOrEmpty(osConfigDir)) {
  272. return "."; // Oh well.
  273. }
  274. osConfigDir += "/.local/share";
  275. }
  276. return Path.Combine(osConfigDir, APPLICATION_NAME);
  277. }
  278. default:
  279. return "NoPlatformDirectory";
  280. }
  281. }
  282.  
  283. /// <summary>
  284. /// This is the user path.
  285. /// </summary>
  286. private readonly string Platform_PathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
  287.  
  288. private string Platform_RemoveUserPath(string path) => path.Replace(Platform_PathUser, ".");
  289. }
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement