Announcement

Collapse
No announcement yet.

How to list/delete file contents of the main UDK exe file directory while _In-Game_

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    How to list/delete file contents of the main UDK exe file directory while _In-Game_

    Dear Community,

    Here is the entire copy/paste code that you need to be able to get an in-game file select system up and running.

    With this core code I am providing to you in this thread, I can now do all these things while in-game:

    1. fully browse the entire main game directory (multi-page scrolling)
    2. browse subdirectories
    3. delete files
    4. click on files to load into my game save/load engine.


    I use this code in my game to allow the player to use the HUD to see the contents of the main UDK exe directory and click on files that all have my custom file extension of .joy (these files are the different levels that you can make in my in-game level editor).

    Here's a video where I use my in-game file browser:

    The names you see appear on the list are actual filenames on my computer harddrive, and I double click to load the hard-disk file using basicloadobject




    User can click on file in the list to have it appear as current filename:


    User can choose to refresh the list manually


    So this code has been thoroughly tested by me, so I assure you it works well with no memory leaks (hard thing to deal with in the realm of converting UDK strings to DLL and getting filenames and pointers etc etc etc).

    So with this code I can now enable the user to make level files, and at any time see a full directory listing of the files they've made that are all stored in the udk main dir.

    For info on how to actually save/load files, please look up class'Engine'.static.BasicSaveObject


    Advanced:

    If you want the user to be able to delete files while in-game, you can use c++ Remove

    UPDATE:

    Deleting Files
    I've added the code to delete files from the main udk exe file directory in the main DLL file!

    Refreshing the List During Game Time
    I also modified my code to allow for "refreshing" the file listing during game time, in case files are created/deleted/moved into the binaries/win32 folder during game time.

    Enjoy!

    I"ve tested this, it wooooorks!

    ~~~

    Fully Functional File System while In-Game

    So in this post I am telling you that you really can give UDK games an entirely functional file system for saving/loading and deleting levels/files of their own creation.

    I am already doing this with my game so I assure you it's possible.

    Here's the core code you need!


    ~~~

    What the Code Below Does

    While you are In-game, the code below will generate an array of strings that contain a list of all the files in the main udk directory, where BasicSaveObject files get created.

    You can modify the search string in the DLL if you only want to search for a specific file extension.

    1. You need to create a DLL and a UnrealScript class, and then bind the UnrealScript class to the DLL.

    2. You can only do this in the binaries/Win32 as far as I know, so make sure to compile your code there.

    Once again I must thank Spoof, for it was his tutorial on the concept of DLL binding that taught me about 1/2 of what I needed to know. The rest I researched on MSDN.

    ~~~

    How to Create a DLL

    See Spoof's tutorial above.

    I used Code::Blocks

    It's free!

    For Code::Blocks:

    1. Create a new project, that is a Dynamic Link Library (DLL)

    2. Only make a final release version, not a debug version

    3. Delete the contents of main and the header, and copy in my code below

    4. Under Project Properties set the output for your DLL to be your UDK binaries/win32/usercode directory.

    that way each time you recompile your dLL it is already ready to go with your UDK.

    Make sure the name of your DLL matches the DLLBind(yourDLLname) in the unreal class

    Let's say the DLL name is "joyDLL"

    ~~~

    My DLL Code for You

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <assert.h>
    
    extern "C"
    {
    
    	//c++ implmentation of Unreal var string as per UDN
       struct FString
    	{
    	  wchar_t* Data;
    	  int ArrayNum;
    	  int ArrayMax;
    
    	  void UpdateArrayNum()
    	  {
    	     ArrayNum = wcslen(Data)+1;
    	     assert(ArrayNum <= ArrayMax);
    	  }
    	};
      
        //Global Vars for the DLL
        //must be global as the func runs many times  
        //and depends on the fileHandle being the same
        HANDLE fileHandle;
        bool runOnce = false;
    
        //============= Get File Names ==================
    
    
    //returns the length of the filename found
    //or -1 if no more files found.
        __declspec(dllexport) int getFileNames(FString inStr) {
            size_t cSize ;
            WIN32_FIND_DATA fdata;
    
            if(!runOnce){
    
                //obtain the file data and the file handle
                //for future calls
    
                // "..\\* says get all the files in the just-prior directory"
                //this dll runs inside of usercode, a subdir of main exe
                //so we must go up one directory first
               
               //* means get all the files
    
                fileHandle = FindFirstFile("..\\*", &fdata );
    
                //use "..\\*.ext" where ext is your desired file extension
               //to get listing of all the files of your file type.
    
                //if no filename was found
                if( fileHandle == INVALID_HANDLE_VALUE){
                    return -1;
                }
    
                //so that future calls do not use FindFirst
                runOnce = true;
            }
            else {
                if (FindNextFile(fileHandle,&fdata) == 0){
                    return -1;
                }
            }
    
            //get size of filename found;
            //+1 is for the null at end of a string that strlen does not include.
    
            cSize = strlen(fdata.cFileName)+1;
    
            
            //check if acquired filename is larger than Unreal string
            if( cSize  >= (size_t)inStr.ArrayMax){
    		return -1;
            }
    
            //copies from a char* into a wchar_t* of cSize
            //the var from unreal, inStr is the destination
            mbstowcs (inStr.Data, fdata.cFileName, cSize);
    
            //unreal needs the actual string length to be up to date
            //see above struct def for details
            inStr.UpdateArrayNum();
    
            return cSize;
        }
    
    //call this from unreal and then call above function
    //to "refresh" your listing.
    __declspec(dllexport) int  resetFile() {
        
       fileHandle = NULL;
        runOnce = false;
        return 0;
    }
    
      __declspec(dllexport) int fileDeleteDLL(FString inStr) {
        
        //initialize str to the maxsize of the incoming unreal string
       //see struct declaration at top
        char* str = new char[inStr.ArrayMax];
        char filenameWithPath[1024];
    
        //memory safety check
        if(strlen(filenameWithPath) < strlen(str)){
    
            delete[] str;
            return -1;
        }
    
        //copy the inStr from Unreal to the char* string
        wcstombs(str, inStr.Data,inStr.ArrayMax);
    
        strcpy(filenameWithPath, "..\\");
        strcat( filenameWithPath,str);
        if (remove(filenameWithPath) == 0){
         
            delete[] str;
            return 0;
        }
     
        //clear allocated memory
        delete[] str;
    
        return -1;
    }
    
    /*
    you can perform cleanup in your
    DLL's DllMain()
    function by responding to the
    DLL_PROCESS_DETACH fdwReason. -UDN
    
    in this case we don't have much to clean up,
    you could just call refresh to null the file handle
    */
    
    } //end of extern C
    ~~~

    The Unreal Script Class

    You must instantiate this object in one of your custom classes, as so:

    Code:
    //global class var
    var UnrealClassDLL yourDLL;
    
    function someFunctionInYourControllerClassProbably() {
      
        yourDLL = new Class'UnrealClassDLL';
      
       //prints array contents to log, 
      //make sure -log is in your udk executable command line
       yourDLL.refresh();
       //call refresh as often as you want, as contents of udk win32 file dir change
    }
    Code:
    class UnrealClassDLL extends Object
        DLLBind(joyDLL); 
       //joyDLL = the filename of your DLL
    
      var array<String> filenames;
      var bool runOnce;
    
      //these must match what is in your DLL
      dllimport final function int getFileNames(out String s);
      dllimport final function int deAllocateMemory();
      dllimport final function int resetFile();
      dllimport final function int fileDeleteDLL(out String s);
    
    function deleteFile(string s) {
    	
            //0 indicates success, -1 indicates failure to delete file
    	`log("File Deleted? ========>>>>>>>"@ fileDeleteDLL(s));
    }
    //you can run this as many times as you want while in-game
    //each time the player wants to see the dir contents
    function displayFileNames() {
    	local int v;
    	
    	if (!runOnce) {
    		obtainFileNames_runOnce();
    	}
    	
           //cycle thru array and log 
           //(make sure you have -log in your udk commandline when u test)
    	for (v = 0; v < filenames.length; v++ ) {
    		`log(""$filenames[v]);
    	}
    }
    
    function refresh() {
    	
    	//empty array
    	filenames.length = 0;
    	
    	runOnce = false;
    	
    	//Reset file for future calls
    	//DLL function
    	resetFile();
    	
            //re-populate array and display
           //you can test this by adding a file
          //to your udk win32 main dir during game-time
           displayFileNames();
    	
    }
    
    //use refresh() not this. 
    function obtainFileNames_runOnce() {
      local String s;
      local int len;
    	
      //DLL returns -1 when no more files matching search are found
      len = 0;
      while (len != -1) {
    		
      //initialize s to a looong filename so it is likely to be larger 
      //than any filename found by the DLL
    		
      //This is necessary because if we do not initialize s 
      //and DLL tries to pass a string larger
      //than s into itself, there will be memory crash. 
    		
      //must constantly re-initialize s because its length gets changed in the DLL 
    s = "joyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoyjoy";
    		
      //getFileNames returns the length of the filename acquired;
      len = getFileNames(s);
    		
      //add to array for future use!
       if(len != -1){
          filenames.addItem(s);
       }
      }
    	
      runOnce = true;
    }
    DefaultProperties
    {
    	runOnce = false
    }

    The most notable line is the s = "joyjoyjoy..." etc

    This line is necessary because otherwise we'd have to try and allocate memory for the unreal string AFTER it has been passed into the DLL, something I don't even want to think about.

    You might know of a way you like better than mine, but I assure you mine works under the most important test of actual game experience, so I am happy.

    I chose my method because there is actually a great deal of easy memory leaks and crashes that can be caused when working with DLLs and unreal strings, so I used the method that I thought was the safest.

    Note that the dLL does a check to see if the filename it found is longer than the unreal script var.

    If you're really concerned, just initialize s to an even longer string than I did.


    Again, I promise you this codes works perfectly in-game, and does what I am saying it will do for you.



    So I hope you find it as useful as I do.



    Rama


    Some more pics for you!


    You can browse to subdirectories, while in game!



    Hee hee (read filename for details)

    #2
    UPDATE:

    Deleting Files
    I've added the code to delete files from the main udk exe file directory in the DLL file!

    Refreshing the List During Game Time
    I also modified my code to allow for "refreshing" the file listing during game time, in case files are created/deleted/moved into the binaries/win32 folder during game time.

    Enjoy!

    I"ve tested this, it wooooorks!

    Comment


      #3
      I added some more pics of my file system!

      You can browse to subdirectories, while in game!
       
      Spoiler



      Hee hee (read filename for details)
       
      Spoiler

      Comment


        #4
        This is amazing.
        I'm definitely going to be using this at some point.

        Thanks for sharing!

        Comment


          #5
          You're welcome!

          Your QUBE game look awesome!



          Rama

          Comment


            #6
            I take it you'll need Microsoft visual for this?

            Comment


              #7
              Good stuff, thanks for sharing!

              Comment


                #8
                You're welcome Angel_Mapper!

                Thanks for all the ways you've helped the Community!



                Rama

                Comment


                  #9
                  U are really good. But each time I watch your tuts my eyes bleed.. Too much toxic colors. And weed!

                  Comment


                    #10
                    Hahha no weed, I've never done a drug stronger than caffeine

                    Bright colors are good for your brain.

                    Stimulates you to think in new ways!

                    Rama

                    Comment

                    Working...
                    X