daily pastebin goal
52%
SHARE
TWEET

Untitled

a guest Feb 22nd, 2019 54 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top