none
c# User3DX Parser how can i use it ? RRS feed

  • Question

  • Hello all big thank you for User3DX for supplying me with code to help he asked to create a separate thread on how i would go about using it this is the code he provided 

    Code Provided

    and how i have used it is creating a class in my windows form application called parser 
    copied the code into there 

    reverenced it in my form by doing 

    parser bo3_parser_weapons;

    then in the button click event created this call 

    bo3_parser_weapons = new parser();

    and then i did 

    bo3_parser_weapons.Start()witch replaces the main function at the bottom due to the fact im using form. 

    it all goes though perfectly fine and find stuff i just not sure how to use it or retrieve information and display it in a text box 

    same with saving it back to the file but going though the debug it did populate list and did save all the keys/values just not sure how to restive say value of displyName ect.

    Again big thank you to User3DX for helping me this much. 

    Thursday, November 16, 2017 11:16 PM

All replies

  • Hello,

     

     When you want to access the object its easy to via indexer Item[ index ]

    Below is code example of using my Parser Class based on your game data file

    structure. Remember, its not perfect and lots of room for expanding functionality.

     

     Code Snippet

    // Declare local scope object for read access only, here is 'gdfEntry'
    //
    // Below is how manual indexing works
    //
    // In zero-base indexes, 0 is first element
    //
    Parser.GDF gdfEntry = bo3_parser_weapons.Items[ 0 ];
    
    // Access Key from Item[ 0 ]
    //
    string str1 = bo3_parser_weapons.Items[ 0 ].ItemKey;
    
    // Access Value from Item[ 0 ]
    //
    string str2 = bo3_parser_weapons.Items[ 0 ].ItemValue;
    
    // How to access Item properties
    //
    string str3 = bo3_parser_weapons.Items[ 0 ].properties[ 0 ].KeyProperty;
    string str4 = bo3_parser_weapons.Items[ 0 ].properties[ 0 ].ValueProperty;
    
    // How to change Item properties
    //
    bo3_parser_weapons.Items[ 0 ].properties[ 0 ] = new Parser.Properties( str3, str4 ); 
    
    // How to change Item
    //
    bo3_parser_weapons.Items[ 0 ] = new Parser.GDF( str1, str2 );

     How to get number of Item elements

    bo3_parser_weapons.Items.Count

     How to get number of Item property elements

    bo3_parser_weapons.Items[ 0 ].properties.Count

      All Item properties are contained in object type List<> so you get all the features of the class.

    The method Load() will trim strings of white-space characters, such as Tabs. So, you may want

    to reformat the string before write to file. You can use Foreach loop to Enumerate Item and Item

    properties, see below;

    Code snippet

    foreach ( Parser.Properties gdfEntryProp in gdfEntry.properties )
    {
        Console.WriteLine( "\tKey {0}\n\tValue {1}\n", gdfEntryProp.KeyProperty, gdfEntryProp.ValueProperty );
    }

     If you have any question or issues with code then just let me know.

     

     Thanks :)


    • Edited by User3DX Friday, November 17, 2017 1:04 AM spelling
    Friday, November 17, 2017 1:01 AM
  • Hello,

     

     When you want to access the object its easy to via indexer Item[ index ]

    Below is code example of using my Parser Class based on your game data file

    structure. Remember, its not perfect and lots of room for expanding functionality.

     

     Code Snippet

    // Declare local scope object for read access only, here is 'gdfEntry'
    //
    // Below is how manual indexing works
    //
    // In zero-base indexes, 0 is first element
    //
    Parser.GDF gdfEntry = bo3_parser_weapons.Items[ 0 ];
    
    // Access Key from Item[ 0 ]
    //
    string str1 = bo3_parser_weapons.Items[ 0 ].ItemKey;
    
    // Access Value from Item[ 0 ]
    //
    string str2 = bo3_parser_weapons.Items[ 0 ].ItemValue;
    
    // How to access Item properties
    //
    string str3 = bo3_parser_weapons.Items[ 0 ].properties[ 0 ].KeyProperty;
    string str4 = bo3_parser_weapons.Items[ 0 ].properties[ 0 ].ValueProperty;
    
    // How to change Item properties
    //
    bo3_parser_weapons.Items[ 0 ].properties[ 0 ] = new Parser.Properties( str3, str4 ); 
    
    // How to change Item
    //
    bo3_parser_weapons.Items[ 0 ] = new Parser.GDF( str1, str2 );

     How to get number of Item elements

    bo3_parser_weapons.Items.Count

     How to get number of Item property elements

    bo3_parser_weapons.Items[ 0 ].properties.Count

      All Item properties are contained in object type List<> so you get all the features of the class.

    The method Load() will trim strings of white-space characters, such as Tabs. So, you may want

    to reformat the string before write to file. You can use Foreach loop to Enumerate Item and Item

    properties, see below;

    Code snippet

    foreach ( Parser.Properties gdfEntryProp in gdfEntry.properties )
    {
        Console.WriteLine( "\tKey {0}\n\tValue {1}\n", gdfEntryProp.KeyProperty, gdfEntryProp.ValueProperty );
    }

     If you have any question or issues with code then just let me know.

     

     Thanks :)


    umm is there a way to get it to find a certain key/value text via tying a keyname like displayname finds the key and displays the value ? 

    also i get this error.

      Message=Index was out of range. Must be non-negative and less than the size of the collection.


    Sorry to be a pain but thank you for taking you're time out of your day to help me really do appreciateall you done for me :) 

    Friday, November 17, 2017 1:25 AM
  • Hello,

     In my Parser class, before any data can be accessed, you must do the following

    to prevent errors and in this order except step 5. Unless you have modified original code.

    1. Create the Parser instance.

        Example:  Parser parser = new Parser();

    2. Call Open to ensure access ready, return bool, true for success.

        Example: parser.Open( @"D:\Temp\wpn_t7_loot_pistol_m1911.gdt" );

    3. Call Load, which strips white-space characters and cache as string[] Lines.

        Example: parser.Load();

    4. Call Build, which will create Item and Item.Properties nested structure.

        Example: parser.Build();

    5. Call Close, only when no more need of the current Parser data.

     

     I am sure you figured out that the class was split into many parts. If you made

    code changes that is okay. However, the Parser flow from above must be correct.

     

     The line that you got the error from; that code depends on the Parser.Build()

    otherwise you have an empty collection, including type null. Examine the code

    for method Create() above the error line and verify correctness.

     I am always glad to help. Beside, I learn new information too. :)

    Friday, November 17, 2017 2:08 AM
  • Hello,

     In my Parser class, before any data can be accessed, you must do the following

    to prevent errors and in this order except step 5. Unless you have modified original code.

    1. Create the Parser instance.

        Example:  Parser parser = new Parser();

    2. Call Open to ensure access ready, return bool, true for success.

        Example: parser.Open( @"D:\Temp\wpn_t7_loot_pistol_m1911.gdt" );

    3. Call Load, which strips white-space characters and cache as string[] Lines.

        Example: parser.Load();

    4. Call Build, which will create Item and Item.Properties nested structure.

        Example: parser.Build();

    5. Call Close, only when no more need of the current Parser data.

     

     I am sure you figured out that the class was split into many parts. If you made

    code changes that is okay. However, the Parser flow from above must be correct.

     

     The line that you got the error from; that code depends on the Parser.Build()

    otherwise you have an empty collection, including type null. Examine the code

    for method Create() above the error line and verify correctness.

     I am always glad to help. Beside, I learn new information too. :)

    Thank you so much it works is there any way you can find out what numbers what because i have a file loaded as you see there 

    but there are more than one weapon files and some are bigger than others so say the weapon data im going though now say display name is item 66 on this file if i opened another file thats smaller or bigger it wont be in the same pair slot if you get what i mean 

    so say i have textbox that displays the below code and that item there 66 is say for example display name so what i would do is this 

    textedit1.text = str4 ( witch will display the value of item 66 but if i loaded up another file ) 

    textedit1.text would be something else as the file my contain less data. 

                string str3 = bo3_parser_weapons.Items[66].properties[66].KeyProperty;
                string str4 = bo3_parser_weapons.Items[66].properties[66].ValueProperty;
                MessageBox.Show("Key: " + str3 + "Value: " + str4);

    Friday, November 17, 2017 2:25 AM
  • Hello,

     You can instance Parser class as many time as you like until

    you get RAM errors or the like.  Just instance Parser class in

    an array,like this Parser[] multiParser, or in a container, like

    List<Parser>.  The same manner of access using indexer will

    work here too.

      Does that help to answer your question?


    Friday, November 17, 2017 4:23 AM
  • Hello,

     You can instance Parser class as many time as you like until

    you get RAM errors or the like.  Just instance Parser class in

    an array,like this Parser[] multiParser, or in a container, like

    List<Parser>.  The same manner of access using indexer will

    work here too.

      Does that help to answer your question?


         some what its just if i open another file the key/values are not in the same index like display name is index 33 but when i open up another file it shows something totally different in display name value is the issue im having is there a way to search via text ? like say look for display name instead of a index number so if thats possible look up displayname then have it show the value display name as im not sure of a work around as each weapon file is different hand has different values thats the issue im having here.
    Friday, November 17, 2017 2:35 PM
  • Hello,

     

     Remember, you can access any number of game files by declare

    another instance of Parser for that file. Now if you are having some

    issues of searches then I can help.

     

     Code Snippet

    // Search criteria for Items
    //
    string search = "45acp";
    
    Console.WriteLine( "FindAll with Indexer : {0}", search );
    
    for ( int x = 0; x < bo3_parser_weapons.Items.Count; x++ )
    {
        if ( bo3_parser_weapons.Items[ x ].ItemKey.Contains( search ) )
        {
            Console.WriteLine( "Item : {0} {1}", x, bo3_parser_weapons.Items[ x ].ItemKey );
        }
    }
    
    Console.WriteLine( "FindIndex, first element, using Lambda : {0}", search );
    
    int y = bo3_parser_weapons.Items.FindIndex( x => x.ItemKey.Contains( search ) );
    
    Console.WriteLine( "Item : {0}", y );
    
    Console.WriteLine( "FindAll using Lambda, List<> : {0}", search );
    
    List<Parser.GDF> multiFind = new List<Parser.GDF>();
    
    multiFind = bo3_parser_weapons.Items.FindAll( x => x.ItemKey.Contains( search ) );
    
    foreach ( Parser.GDF pg in multiFind )
    {
        Console.WriteLine( "Item : {0}", pg.ItemKey );
    }

      if you want to search for properties that all Items have then that

    a tiny more complex.  Just ittorate Items and search Items.Properties

    as seen above.

     Hope this helps :)

    Friday, November 17, 2017 5:38 PM
  • Hello,

     

     Remember, you can access any number of game files by declare

    another instance of Parser for that file. Now if you are having some

    issues of searches then I can help.

     

     Code Snippet

    // Search criteria for Items
    //
    string search = "45acp";
    
    Console.WriteLine( "FindAll with Indexer : {0}", search );
    
    for ( int x = 0; x < bo3_parser_weapons.Items.Count; x++ )
    {
        if ( bo3_parser_weapons.Items[ x ].ItemKey.Contains( search ) )
        {
            Console.WriteLine( "Item : {0} {1}", x, bo3_parser_weapons.Items[ x ].ItemKey );
        }
    }
    
    Console.WriteLine( "FindIndex, first element, using Lambda : {0}", search );
    
    int y = bo3_parser_weapons.Items.FindIndex( x => x.ItemKey.Contains( search ) );
    
    Console.WriteLine( "Item : {0}", y );
    
    Console.WriteLine( "FindAll using Lambda, List<> : {0}", search );
    
    List<Parser.GDF> multiFind = new List<Parser.GDF>();
    
    multiFind = bo3_parser_weapons.Items.FindAll( x => x.ItemKey.Contains( search ) );
    
    foreach ( Parser.GDF pg in multiFind )
    {
        Console.WriteLine( "Item : {0}", pg.ItemKey );
    }

      if you want to search for properties that all Items have then that

    a tiny more complex.  Just ittorate Items and search Items.Properties

    as seen above.

     Hope this helps :)

         for some reason it dont find any of the keys or values only finds 17 items and none of them are displayname ( also this way how could i look for a displayName and the value of display now out put to a textbox ? 
    Friday, November 17, 2017 10:48 PM
  • Hello,

     Where is displayName declared and the usage? Also,

    I am working with the game file you linked on your

    One Drive.  If that data structure differs then changes

    must be applied to Parser class.

     

    Thanks :)


    • Edited by User3DX Friday, November 17, 2017 10:55 PM spelling
    Friday, November 17, 2017 10:53 PM
  • Hello,

     Where is displayName declared and the usage? Also,

    I am working with the game file you linked on your

    One Drive.  If that data structure differs then changes

    must be applied to Parser class.

     

    Thanks :)


          how it would be key would be displayName : and value in this case should display greze_gun 

    latest weapon file

    they change but slightly the main area for the weapon file is 
    "greze_gun" ( "bulletweapon.gdf" )

    to have the others there as well would be great but the main area is evreything inside "greze_gun" ( "bulletweapon.gdf" )

    {

    }

    but its like this "displayName" "greze_gun"

    so is there anyway at all to get to be able to search by key name and display value in text box and on a button click save all stuff in text boxes back to the file with updated values. i never used parser classes before i only really touched on directory because it worked on old weapon files this is all different to me im sorry im not picking it up really quick but thank you for taking your time to help me though this i make sure to credit you in my program :) 

    Friday, November 17, 2017 11:40 PM
  • Hello,

     Are you asking about results from a parameters search?  

     BTW, there is a malfunction in Build(), well technically not but results

    are wrong.  Still, the Item and Item.Properties parser is faulty unless

    you have found and corrected.  See corrections below;

    public void Build()
    {
        int itemCount = 0;
        int mode = 0;
    
        if ( this.lines != null )
        {
            string input = this.lines.Dequeue();
    
            do
            {
                if ( mode == 0 )
                {
                    string src = this.lines.Dequeue();
    
                    // Correction Start
                    int x = src.IndexOf( ' ' );
    
                    if ( x != -1 )
                    {
                        string str1 = src.Substring( 0, x - 1 );
    
                        if ( str1.EndsWith( "\"" ).Equals( false ) )
                        {
                            str1 += "\"";
                        }
    
                        string str2 = src.Substring( x + 1 );
                                
                        this.Items.Add( new GDF( str1, str2 ) );
                    }
                    // Correction End
    
                    mode = 1;
                }
    
                if ( mode == 1 )
                {
                    input = this.lines.Dequeue();
    
                    if ( input == "{" )
                    {
                        mode = 2;
                    }
    
                    while ( mode.Equals( 2 ) )
                    {
                        input = this.lines.Dequeue();
    
                        if ( input == "}" )
                        {
                            itemCount++;
                            mode = 0;
                        }
                        else
                        {
                            // Correction Start
                            int x = input.IndexOf( ' ' );
    
                            if ( x != -1 )
                            {
                                string str1 = input.Substring( 0, x );
                                string str2 = input.Substring( x + 1 );
    
                                this.Items[ itemCount ].properties.Add( new Properties( str1, str2 ) );
                            }
                            // Correction End
                        }
    
                    } // end while mode 2
    
                } // end if
    
            } while ( input != null );
    
        } // end if null
    }

     After examine the input string split results, I found output was not as

    desired so I changed it.  Sorry, should work as expected now. 

     Below is an example of how to Create, Add Item with Properties.

    static void Main( string[] args )
    {
        // Create an emptry instance
        //
        Parser emptyParser = new Parser();
    
        Console.WriteLine( "New Parser Instance Count: {0}\n", emptyParser.Items.Count );
    
        // Create new Item
        //
        Parser.GDF newItem = new Parser.GDF( "something", "something2" );
    
        // Create new Item properties
        //
        newItem.properties.Add( new Parser.Properties( "something3", "somthing4" ) );
    
        // Add new Item
        //
        emptyParser.Items.Add( newItem );
    
        Console.WriteLine( "Add Item/Properties\n" );
        Console.WriteLine( "New Parser Count: {0}\n", emptyParser.Items.Count );
        Console.WriteLine( "\nConstruct GDT\n", emptyParser.Items.Count );
    
        // Construct GDT
        //
        Console.WriteLine( "{" );
        for (int x =0; x < emptyParser.Items.Count; x++)
        {
            Console.WriteLine( "{0} = {1}", emptyParser.Items[x].ItemKey, emptyParser.Items[x].ItemValue );
            Console.WriteLine( "\t{" );
    
            foreach ( Parser.Properties prop in emptyParser.Items[ x ].properties )
            {
    
                Console.WriteLine( "\t{0} = {1}", prop.KeyProperty, prop.ValueProperty );
            }
            Console.WriteLine( "\t}" );
        }
        Console.WriteLine( "}" );
    
        Console.Write( "\nPress ENTER key to exit..." );
        Console.ReadLine();
    }
     The code that displays the contents can be change to write the data

    to a files using Stream Writer class.

     

     Hope this helps :)

    Sunday, November 19, 2017 12:40 AM
  • Hello,

     Are you asking about results from a parameters search?  

     BTW, there is a malfunction in Build(), well technically not but results

    are wrong.  Still, the Item and Item.Properties parser is faulty unless

    you have found and corrected.  See corrections below;

    public void Build()
    {
        int itemCount = 0;
        int mode = 0;
    
        if ( this.lines != null )
        {
            string input = this.lines.Dequeue();
    
            do
            {
                if ( mode == 0 )
                {
                    string src = this.lines.Dequeue();
    
                    // Correction Start
                    int x = src.IndexOf( ' ' );
    
                    if ( x != -1 )
                    {
                        string str1 = src.Substring( 0, x - 1 );
    
                        if ( str1.EndsWith( "\"" ).Equals( false ) )
                        {
                            str1 += "\"";
                        }
    
                        string str2 = src.Substring( x + 1 );
                                
                        this.Items.Add( new GDF( str1, str2 ) );
                    }
                    // Correction End
    
                    mode = 1;
                }
    
                if ( mode == 1 )
                {
                    input = this.lines.Dequeue();
    
                    if ( input == "{" )
                    {
                        mode = 2;
                    }
    
                    while ( mode.Equals( 2 ) )
                    {
                        input = this.lines.Dequeue();
    
                        if ( input == "}" )
                        {
                            itemCount++;
                            mode = 0;
                        }
                        else
                        {
                            // Correction Start
                            int x = input.IndexOf( ' ' );
    
                            if ( x != -1 )
                            {
                                string str1 = input.Substring( 0, x );
                                string str2 = input.Substring( x + 1 );
    
                                this.Items[ itemCount ].properties.Add( new Properties( str1, str2 ) );
                            }
                            // Correction End
                        }
    
                    } // end while mode 2
    
                } // end if
    
            } while ( input != null );
    
        } // end if null
    }

     After examine the input string split results, I found output was not as

    desired so I changed it.  Sorry, should work as expected now. 

     Below is an example of how to Create, Add Item with Properties.

    static void Main( string[] args )
    {
        // Create an emptry instance
        //
        Parser emptyParser = new Parser();
    
        Console.WriteLine( "New Parser Instance Count: {0}\n", emptyParser.Items.Count );
    
        // Create new Item
        //
        Parser.GDF newItem = new Parser.GDF( "something", "something2" );
    
        // Create new Item properties
        //
        newItem.properties.Add( new Parser.Properties( "something3", "somthing4" ) );
    
        // Add new Item
        //
        emptyParser.Items.Add( newItem );
    
        Console.WriteLine( "Add Item/Properties\n" );
        Console.WriteLine( "New Parser Count: {0}\n", emptyParser.Items.Count );
        Console.WriteLine( "\nConstruct GDT\n", emptyParser.Items.Count );
    
        // Construct GDT
        //
        Console.WriteLine( "{" );
        for (int x =0; x < emptyParser.Items.Count; x++)
        {
            Console.WriteLine( "{0} = {1}", emptyParser.Items[x].ItemKey, emptyParser.Items[x].ItemValue );
            Console.WriteLine( "\t{" );
    
            foreach ( Parser.Properties prop in emptyParser.Items[ x ].properties )
            {
    
                Console.WriteLine( "\t{0} = {1}", prop.KeyProperty, prop.ValueProperty );
            }
            Console.WriteLine( "\t}" );
        }
        Console.WriteLine( "}" );
    
        Console.Write( "\nPress ENTER key to exit..." );
        Console.ReadLine();
    }
     The code that displays the contents can be change to write the data

    to a files using Stream Writer class.

     

     Hope this helps :)

         thank you :) i will update that now :) 
         and yes i am asking about the search basically when it stores all the values to the list 

        is there a way to retrieve a certain part of the key/value part so say in that big file 

        when the program runs and you select a file it goes though and sorts the file after the all the stuff as been saved to the list 

    is there a a way i can search a certain key by text so for example 

    Parser.GDF newItem = new Parser.GDF( "displayName", "something2" );

    basically need a search aspect to this so i can search certain parts of the data stored in the list and display its value to a textbox so say 

    so be something like displayname.key = textedit1.text;

    something like that so what it would do is when i search display name it will show its value in the textbox i can change a value in the text box then save back to the file if that makes sense ? 

    Sunday, November 19, 2017 1:01 AM
  • Hello,

     

     Yes, you can do searches. Review the previous posts and look for the

    Code Snippet

    // Search criteria for Items

     There are examples of how to search given criteria using Lambda. 

     Thanks :)

    Sunday, November 19, 2017 1:46 AM
  • Hello,

     

     Yes, you can do searches. Review the previous posts and look for the

    Code Snippet

    // Search criteria for Items

     There are examples of how to search given criteria using Lambda. 

     Thanks :)

          Yeah the search only finds a count of 17 - and none of them is the display name its the properties that holds the values i want 

     is there a way to search the properties list ? 
    Sunday, November 19, 2017 8:08 PM
  • Hello,

     Here is code that should provide a solution.  I suggest you run

    debugger and examine what the code is doing. Best way to see

    and learn "where what is doing with what" :) 

     

     MSDN Docs is a great source and some have examples.

     

     Code Snippet

    // Search entire GDF
    //
    // Display Item and PropertyKey matching criteria
    //
    string search = "Gloss";
                
    // Walk the GDF structure, manual Indexer
    //
    for ( int idx = 0; idx < parser.Items.Count; idx++ )
    {
        // gdfSource is same as parser.Items[ idx ]
        //
        Parser.GDF gdfSource = parser.Items[ idx ];
    
        // Where to store matches
        //
        List<Parser.Properties> multiFind = new List<Parser.Properties>();
    
        // Execute Lambda, FindAll KeyProperty matches
        //
        // Return as List<>
        //
        multiFind = gdfSource.properties.FindAll( x => x.KeyProperty.Contains( search ) );
     
        // Change x.KeyProperty to x.ValueProperty
        // For Properties.Value searches instead
    
        // Display GDF Item then any results
        //
        // Check multiFind.Count, skip empty results
        //
        Console.Write( "Item : {0}", gdfSource.ItemKey );
    
        if ( multiFind.Count == 0 )
        {
            Console.WriteLine( "\tNo Results" );
        }
        else
        {
            Console.WriteLine( "\tFound: {0}", multiFind.Count );
    
            foreach ( Parser.Properties p in multiFind )
            {
                Console.WriteLine( "\t{0}\t{1}", p.KeyProperty, p.ValueProperty );
            }
        }
    }
     

     Hope this helps :)

    Monday, November 20, 2017 12:11 AM
  • Hello,

     I think this posting has reached the end. So, if the OP

    doesn't closeout then would the Mods mind doing so.

     Thanks :)

    Friday, December 1, 2017 7:25 AM