Add function generate_working_directory()

Reporter: time-killer-games  |  Status: open  |  Last Modified: August 08, 2019, 08:18:37 AM

This code was tested in the GameMaker equivalent with the help of my File Manager extension and it is verified working.

This function will set the working directory to the app bundle's Resources folder like GM4Mac 7.5, GMStudio 1.4, GMS 2.x and most Mac apps do, if the executable is in an app bundle. If the executable is not in an app bundle, use the getcwd function.

ONLY use working_directory for loading read-only included files! When SAVING, use game_save_id. Mac app bundles must be read-only, otherwise your app will not work anymore after being code-signed because you were stupid enough to tamper with it. Your app will also get rejected from the Mac App Store if you do that. We still need to add game_save_id because not only is it the GM sandbox directory, Mac Apps require sandboxing as an operating system requirement, unless you distribute outside their store without code-signing.

time-killer-games  
@JoshDreamland @fundies Ready for you guys to review.
codecov[bot]  

Codecov Report

❗️ No coverage uploaded for pull request base (master@3031c06). Click here to learn what that means.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #1674   +/-   ##
=========================================
  Coverage          ?   18.82%           
=========================================
  Files             ?      169           
  Lines             ?    16782           
  Branches          ?        0           
=========================================
  Hits              ?     3159           
  Misses            ?    13623           
  Partials          ?        0
Impacted Files Coverage Δ
...m/SHELL/Platforms/General/POSIX/POSIXdirectory.cpp 0% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3031c06...82583d7. Read the comment docs.

time-killer-games  

if (os_type == os_macosx) {
  /*
    This function will set the working directory to the app bundle's Resources folder 
    like GM4Mac 7.5, GMStudio 1.4, GMS 2.x and most Mac apps do, if the executable is in
    an app bundle. If the executable is not in an app bundle, use the getcwd function
    
    ONLY use get_working_directory() for loading read-only included files! When SAVING, use game_save_id
    
    *_bname = base name - removes the full path from the string leaving just the file or folder name
    *_dname = directory name - removes final slash and base name from full path to file or folder name
    *_pname = path name - removes the base name from a full path while keeping the dir and final slash
    *_ename = extension name - includes everything in bname at and following the period if one exists
  */
  
  var success = false; 
  var exe_pname = get_program_directory();             // = "/Path/To/YourAppBundle.app/Contents/MacOS/";
  var macos_dname = filename_dir(exe_pname);           // = "/Path/To/YourAppBundle.app/Contents/MacOS";
  var macos_bname = filename_name(macos_dname);        // = "MacOS";
  var contents_dname = filename_dir(macos_dname);      // = "/Path/To/YourAppBundle.app/Contents";
  var contents_bname = filename_name(contents_dname);  // = "Contents";
  var app_dname = filename_dir(contents_dname);        // = "/Path/To/YourAppBundle.app";
  var app_ename = filename_ext(app_dname);             // = ".app";
  var contents_pname = filename_path(macos_dname);     // = "/Path/To/YourAppBundle.app/Contents/";
  var resources_pname = contents_pname + "Resources/"; // = "/Path/To/YourAppBundle.app/Contents/Resources/";
  
  // if "/Path/To/YourAppBundle.app/Contents/MacOS/YourExe" and "/Path/To/YourAppBundle.app/Contents/Resources/" exists
  if (macos_bname == "MacOS" && contents_bname == "Contents" && app_ename == ".app" && directory_exists(resources_pname)) {
    // set working directory to "/Path/To/YourAppBundle.app/Contents/Resources/" and allow loading normal included files
    success = set_working_directory(resources_pname);
  }
  
  /*
    if (success) show_message("Success!"); else show_message("Failure!");
    get_string_async("The current value of working_directory equals:", get_working_directory()); 
  */
}

Above you will see the GML equivalent of the code I wrote for this pull request and it uses my "File Manager" extension which may be downloaded here.

Uncommenting this part:

  /*
    if (success) show_message("Success!"); else show_message("Failure!");
    get_string_async("The current value of working_directory equals:", get_working_directory()); 
  */

...resulted in the "Success!" message and the working directory shown in the input box was indeed the correct "Resources" folder in the app bundle.

The source code to "File Manager" is doing all the same things this pull request is doing under-the-hood, so everything has been tested and is verified working.

time-killer-games  

@RobertBColton you ok with reviewing this one again briefly?
RobertBColton  

Not really, because I don't trust my judgement in looking for security vulnerabilities and buffer overflows. Even in my own code I am not good at looking for that. I can try to assist with the review, as far as formatting and such, like I was doing earlier. I am writing a very long pull request at the moment and about to post it to the forums, so that will have to be later if I do coreview.
time-killer-games  

Not really, because I don't trust my judgement in looking for security vulnerabilities and buffer overflows. Even in my own code I am not good at looking for that. I can try to assist with the review, as far as formatting and such, like I was doing earlier. I am writing a very long pull request at the moment and about to post it to the forums, so that will have to be later if I do coreview.

This doesn't effect buffer sizes at all from what was already merged into the engine. I just removed the +1. PATH_MAX on Mac/Linux is 4096, which is a power of 2. You told me in the past to never add one to a power of two buffer size, so I am only listening to your advice on that one and you always change your mind about these things it's really getting old now. Removing the +1 to the buffer seems more logical to me, anyway. Removing 1 byte from a buffer size honestly is a difference so small being made I don't get what your concern is.

time-killer-games  

@JoshDreamland please mudge this
time-killer-games  

@JoshDreamland u forgot to mudge
Please sign in to post comments, or you can view this issue on GitHub.