Asset - Extension File Manager (for Windows, macOS, and Ubuntu)

Discussion in 'Marketplace' started by Samuel Venable, Jun 6, 2017.

  1. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    [​IMG]
    [Made for GameMaker Studio 2]

    This extension is for Windows, macOS, and Ubuntu.

    Manage files/folders without a sandbox; overrides GameMaker Studio 2's built-in functions.

    Each function that does not return a string, will return true on success, and false on failure.

    Functions included:
    • real file_copy(string fname,string newname)
    • real file_rename(string oldname,string newname)
    • real file_exists(string fname)
    • real file_delete(string fname)
    • real directory_create(string dname)
    • real directory_copy(string dname,string newname)
    • real directory_rename(string oldname,string newname)
    • real directory_exists(string dname)
    • real directory_destroy(string dname)
    • string environment_get_variable(string name)
    • real environment_set_variable(string name, string value)
    • string get_working_directory()
    • real set_working_directory(string dname)
    • string get_program_directory()
    • string get_temp_directory()
    The DLL's full source code included.

    Very big thanks to Josh Ventura, for writing the widen() and shorten() scripts, enabling UTF-8 support on Windows.

    get_working_directory() will return the Unix working directory on Mac, which defaults to your system root "/". At the beginning of your game, you may change this to whatever you like, but I recommend your app bundle's "Resources" folder, which you may set it to with the GML Script - generate_working_directory():
    Code:
    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());
      */
    }
    Download Free for GameMaker Studio 2
     
    Last edited: Apr 17, 2019 at 6:05 AM
    IndianaBones, Morne, slojanko and 4 others like this.
  2. slayer 64

    slayer 64 Member

    Joined:
    Jun 26, 2016
    Posts:
    66
    Dealing with files in studio can be such a hassle sometimes. This looks pretty good.
     
    Samuel Venable likes this.
  3. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Thank you! :)
     
  4. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Added directory functions.
     
    Last edited: Aug 17, 2017
  5. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Bumpercars. :D
     
  6. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Just wanted to point out that new to version 1.0.2, directory_delete_fmns is now recursive, meaning that it can delete non-empty directories.

    Mac users will have to compile the dylib using the provided source code. Contact me either by a private message or the marketplace contact form if you need further assistance.

    Be aware that sandboxing is a requirement of the Mac App Store, so if you manage files outside the sandbox, you will need to release your game outside of the Mac App Store.
     
  7. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Added function program_directory_fmns(). Unlike the built-in program_directory variable, program_directory_fmns() returns a string that includes the final slash at the end, ("\" on Windows and "/" on Linux/Mac). program_directory_fmns() should also be more reliable than program_directory, as program_directory has been broken several times in the past...
     
  8. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Ok so I don't know why I didn't think to implement this originally, but now these functions have a return value that determines either success or failure of the given operation, (1 or 0):

    file_copy_fmns
    file_move_fmns
    file_rename_fmns
    file_delete_fmns
    directory_create_fmns
    directory_delete_fmns

    Be sure to replace the scripts and included files in your existing projects to apply the changes made in this important update.
     
  9. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Added functions:
    • real directory_copy_fmns(string dname,string newname)

    • real directory_move_fmns(string oldname,string newname)

    • real directory_rename_fmns(string oldname,string newname)
     
    Last edited: Oct 6, 2017
  10. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    I updated this extension so that it no longer uses SHFileOperation for directory_copy_fmns and directory_delete_fmns. This mean all functions now support both absolute and relative paths.

    As usual, to apply this update to your existing projects, replace your current scripts and included/data files with the newest versions thereof. :)
     
    johnny-o likes this.
  11. johnny-o

    johnny-o Member

    Joined:
    Sep 1, 2017
    Posts:
    5
    Thanks for the fantastic extension. I'm using it everywhere!

    I didn't realize it was continually being updated. Having a return value would have saved me some time this week. :-D
     
    Samuel Venable likes this.
  12. rIKmAN

    rIKmAN Member

    Joined:
    Sep 6, 2016
    Posts:
    3,793
    Hey @Samuel Venable, I checked this asset out a few days ago and the reviews were very entertaining.

    You basically were arguing with customers who reported issues with the extension, even going so far as to call one a troll and liar.

    I check back today to see how things had developed and both the reviews in question have been edited to 5* reviews with no text and your replies also gone - both edited on the same date.

    Am I to believe 2 random people having issues with your extension, and then who you abused for reporting these issues in the replies, both decided on the exact same date that actually - this asset deserves 5* after all?

    Smells fishy, what's going on?

    It's pretty bad either way, but I hope you are deleting / editing feedback yourself and this selective / falsifying of reviews isn't being done by YYG?
     
  13. johnny-o

    johnny-o Member

    Joined:
    Sep 1, 2017
    Posts:
    5
    What you're saying makes no sense. Why would YYG have an incentive to mess around with reviews of a free extension? and why would the developer?

    I left a negative review for a different extension and after a discussion with the developer he ironed out the problems and I changed it to 5 stars. @Samuel Venable probably solved a problem that both reviewers had received emails at the same time about an update and they decided to edit their reviews because they had received *FREE* support on a ****FREE*** extension
     
  14. rIKmAN

    rIKmAN Member

    Joined:
    Sep 6, 2016
    Posts:
    3,793
    You have no idea why the developer would want to remove negative feedback from his asset?
    Are you being serious?

    I don't have a seller account so I have no idea whether a dev can edit his own feedback or not - seems odd if they could.
    If not then YYG must had to have changed it - which also seems quite odd as what's the point in feedback at all if it can be edited at will to only make things seem super positive?
    That's great for you, and look at you shouting in just your 3rd whole post - congrats.
    Also in your case the dev fixed your issues and was more than likely civil - in the replies I am talking about Sam was downright accusing "customers" of being liars and trolls when reporting issues and generally acting like an abusive idiot towards them. Big difference.

    Being free or not is irrelevant, and whether or not the asset worked after his "support" - if a dev spoke to me the way Samual replied to his customers on his asset page I can tell you now I would not be leaving a 5* review.
    If the reviews had just disappeared altogether then I could believe Sam had regrets about how he acted (seems to be a common theme for Sam lately) and deleted them, but for them both to change to 5* reviews on the same day? Not a chance, so as I said it smells fishy.

    Hopefully Sam will find time to explain things, because it looks like either devs or YYG can just edit feedback to make something appear to be something it isn't. As a customer I'd like to know which of those scenarios it is.
     
  15. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    In under 48 hours I recieved 3 zero-star ratings on the same asset (2 of which were a couple hours apart I think), sounded just as fishy to me at the time, which was why I had the doubtless impression I was being trolled. Whether I was or not - I still don't know - but that is irrelevant. I should've not lashed out regardless. If they were being trolls - I was feeding them. If they weren't being trolls - I was the first one to be a jerk. In any case, in times past I have been trolled with over HUNDREDS of 1-star ratings by people who didn't like me and admitted that's why they rated - to get on my nerves - so it should be nothing but understandable why I was quick to make this assumption, but I still should've kept it to myself.

    YYG resolved all this and their exact words to me: "I can see why you are annoyed". I asked them in my helpdesk ticket to test it and verify my extension works. That's why they removed the original reviews and my comments. They are aware of the things I said and were nice enough to try to cover that up for me as an act of forgiveness. Believe me, I'll think twice before making that mistake again because if I did I could get in trouble for it, and that's on top of it not being the right thing to do. Whether people are being nice, descriptive, or otherwise in reviews, I need to not make a scene and make sure I respond well.

    @johnny-o You're welcome! Thanks for the appreciation. It's appreciated. :)
     
    Last edited: Sep 28, 2017
    rIKmAN likes this.
  16. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Added support for UTF-8 encoding in file and path names on Windows, for those of you who need special characters. Before this update, Linux was the only platform to support UTF-8. But anyway, now Windows supports it as well. program_directory_fmns() also works with UTF-8, as of v1.5.0, which means all functions support it on all platforms. :D
     
    Last edited: Oct 6, 2017
    YellowAfterlife likes this.
  17. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Now that I finally have a Mac, I am able to compile and test DYLIB's on my own...

    Version 1.9.3 Released!

    Please replace all Scripts and Included Files in your existing projects to apply this update!!!
    • Added support for macOS.
    • Added function working_directory_fmns().
    • file_rename_fmns() can now both rename and move files, therefore file_move_fmns() was removed.
    • directory_delete_fmns() was renamed to directory_destroy_fmns().
    • Bug fixed with program_directory_fmns() on Windows and Linux.
    The new screenshots will be uploaded within the next couple days.
     
    Last edited: Aug 15, 2018
  18. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Version 1.9.9 Released!
    • Added function set_working_directory_fmns().
    Note: working_directory_fmns() is not the same thing as GM's internal working_directory constant. For instance, if you change the value of working_directory_fmns() with set_working_directory_fmns(), GM's internal working_directory will not be effected, as it is a constant, not a variable or function. Depending on the target platform, GM's working_directory and the extension's working_directory_fmns() will not equal the same value by default even if working_directory_fmns() hasn't been changed by set_working_directory_fmns() yet. This is because the extension has its own working directory separate from the game, and when a relative path is given, the the value of working_directory_fmns() is assumed as a starting point for the relative path.

    Setting the value of working_directory_fmns() with set_working_directory_fmns() is known to currently cause problems on Linux such as your included files no longer being readable, this is because on Linux YoYoGames forgot to make the game's default working_directory sandboxed, which means it can be modified by my extension. The value of GM's working_directory on Linux will always equal the relative path "assets/" but unfortunately, my extension does in fact modify where the game looks for that "assets" folder on Linux. I have reported this bug to YoYoGames. Windows and Mac are not effected by this issue.
     
  19. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Version 2.4.0 Released!
    • [macOS] [Ubuntu] Fixed a safety issue with the use of the POSIX functions dirname() and basename().
     
  20. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Version 3.0.0 Released!
    • [All Platforms] Added function temp_directory_fmns().
     
  21. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    <post removed>
     
    Last edited: Mar 2, 2019
  22. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Version 4.5.0 Released!

    Please REMOVE all Scripts and Included Files in your existing projects, that came from older versions of this asset, to apply this update!!!
    • [All Plaforms] Removed the *_fmns() suffix from function names. Now the extension overrides the built-in functions, and no longer uses any script resources. Please remove that suffix from all of your functions that have it from this extension in your projects.
     
  23. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Version 6.0.0 Released!
    • [All Plaforms] Added function environment_set_variable(). (Set an environment variable to an empty string to remove it completely).
     
  24. RobotoSkunk

    RobotoSkunk Member

    Joined:
    Dec 24, 2018
    Posts:
    38
    The extension is not working in Game Maker Studio 2
    Code:
    switch(os_type){
        case os_windows:
            if(!directory_exists("\\users\\<username>\\documents\\PixelMan files\\")){
                directory_create("\\users\\<username>\\documents\\PixelMan files\\");
            }
            docu_directory = "\\users\\<username>\\documents\\PixelMan files\\";
            break;
    }
    
     
  25. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    Are you using environment_get_variable to get the documents folder? It's working for me just fine, although I am either using relative paths or including the drive letter and colon, i.e. "C:" in the beginning of relative paths. You mind giving more information on what you are doing in your code? Is it just the functions in that snippet that aren't working or is other stuff not working as well?

    are you literally trying it without listing the current drive and are you actually putting your username or are you literally using the text "<username>" in your string? You need the drive and correct username, which can be gotten with the correct environment variable.

    As a general rule of thumb, never assume, regardless of who made it, that an extension doesn't work until you can verify with the developer whether or not you are using it correctly. The only exception being if they refuse to get back to you when you contact them for support after an unreasonable period of time. If more people did this, there would be much less misleading reviews or comments being left. You might be right that it doesn't work in your case, but we don't know that for sure without working together and doing a little debugging. :)

    P.S. what runtime are you using?

    I'm trying this, and it works fine for me:
    Code:
    if (os_type == os_windows)
      f = get_open_filename_ext(
      "Saved Game Files (*.sav)|*.sav",
      environment_get_variable("USERPROFILE") + "Untitled.sav",
      environment_get_variable("USERPROFILE"),
      "Load a Previously Saved Game File");
    
    if (os_type == os_macosx || os_type == os_linux)
      f = get_open_filename_ext(
      "Saved Game Files (*.sav)|*.sav",
      "Untitled.sav",environment_get_variable("HOME"),
      "Load a Previously Saved Game File");
    
    if (file_exists(f))
    {
      file_copy(f,game_save_id + filename_name(f));
     
      ini_open(game_save_id + filename_name(f));
      c = ini_read_real("savegame","color",c_white);
      score = ini_read_real("savegame","score",0);
      ini_close();
     
      file_copy(game_save_id + filename_name(f),f);
     
      room_goto(rm_main);
    }
    Note that I'm also using Dialog Module which overrides get_open_filename and does not break the sandbox without the help of File Manager.

    On Windows, to get the Documents folder you may do:
    Code:
    environment_get_variable("USERPROFILE") + "Documents\\"
    On Mac and Linux, you may use this OS equivalent:
    Code:
    environment_get_variable("HOME") + "Documents/"
    Also, be aware, if you or the end-user changed the environment variable to something that is not the system's default, this code will not work, and there is no universal workaround. It will be whatever folder it was set to, if the folder exists.
     
    Last edited: Apr 12, 2019
  26. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    I added this important information to the extension's description:
     
    Last edited: Apr 17, 2019 at 6:02 AM
  27. RobotoSkunk

    RobotoSkunk Member

    Joined:
    Dec 24, 2018
    Posts:
    38
    OOOHHHHHHHH!!!! IT WORKS!!!!! THX SO MUCH!!! <3

    Code:
    if (os_type == os_windows){
        if(!directory_exists(environment_get_variable("USERPROFILE") + "\\documents\\PMTEST"))
        directory_create(environment_get_variable("USERPROFILE") + "\\documents\\PMTEST");
     
    }
    
     
    Samuel Venable likes this.
  28. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,084
    As @RobotoSkunk pointed out in a private message to me, I want to make it clear to everyone that set_working_directory() does not effect the value of GameMaker's built-in variables such as game_save_id (the sandbox write directory) and working_directory (included files directory). It only effects the value of get_working_directory() provided by the extension, so when saving files you will still need to copy or move them over to get_working_directory() regardless of what value you set it to. :/ On mac please make sure you never modify the app bundle and only save and/or modify files outside of it.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice