Read DBC strings through marshaling [or something else]? menu

User Tag List

Results 1 to 2 of 2
  1. #1
    XTZGZoReX's Avatar Active Member
    Reputation
    32
    Join Date
    Apr 2008
    Posts
    173
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Read DBC strings through marshaling [or something else]?

    For the last couple of days, I've been tinkering with reading DBC structures from the .dbc files without manually defining mappers (which is especially needed because of their annoying way to lay out strings (the string table)).

    Here's what I'm currently doing:

    Code:
            public void LoadRecords()
            {
                _reader.BaseStream.Position = DataStoreHeader.Size;
    
                var list = new List<T>(Header.RecordCount);
    
                var type = typeof(T);
                var size = Marshal.SizeOf(type);
                for (var i = 0; i < Header.RecordCount; i++)
                {
                    var bytes = _reader.ReadBytes(size);
                    var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                    var obj = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), type);
                    handle.Free();
    
                    list.Add(obj);
                }
    
                Records = list.AsReadOnly();
            }
    Now, obviously, that won't work too well for strings, given that they are stored in the string table. Would anyone have an idea as to how one could grab them and marshal them to a string[] (or just string, if you disregard localization) field in the DBC struct?

    Sample struct for AreaTable.dbc that I'm using (with a nice hack for the area name):

    Code:
        [DataStoreRecord("AreaTable.dbc")]
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct AreaTableRecord
        {
            public int Id;
    
            public int MapId;
    
            public int ZoneId;
    
            public int ExplorationFlag;
    
            public int Flags;
    
            public int SoundPreferences1;
    
            public int SoundPreferences2;
    
            public int SoundAmbience;
    
            public int ZoneMusic;
    
            public int ZoneIntroMusicTable;
    
            public int AreaLevel;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public int[] AreaName;
    
            public int NameFlags;
    
            public int TeamId;
    
            public int Unknown1;
    
            public int Unknown2;
    
            public int Unknown3;
    
            public int Unknown4;
    
            public float MinimumZ;
    
            public float CharacterAmbientLighting;
    
            public int Unknown5;
        }
    I was considering just annotating each field with a DataStoreIndexAttribute and then define some LocalizedStringAttribute to put on the strings. I could then loop over the type's fields manually and set their values [reason for the index attribute would be that Type.GetFields() doesn't return the fields in a reliable order (see MSDN)]. However, that pretty much beats the purpose of 'nice and clean' automatic marshaling. Then again, it'd still be nicer than defining mapper classes and manually reaidng data.

    Any suggestions?

    Read DBC strings through marshaling [or something else]?
  2. #2
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Unfortunately custom marashalers are a pain in the ass. Really. Marshal.SizeOf will fail in structs when you define custom marshalers (atleast they did for me). I recommend that you just use an uint and then use a Dictionary<uint, string> for the string table when you need to access it. That's what I did. Of course, you can handle it manually with reflection like the solution you proposed. That would be relatively easy and would work very well.
    The only problem is that the marshaler will enrage when it sees a string and tries to marshal it from the data in the struct.
    Last edited by MaiN; 05-13-2010 at 06:32 AM.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

Similar Threads

  1. Question about DBC string reading
    By Game2Mesh in forum WoW Memory Editing
    Replies: 0
    Last Post: 01-12-2015, 10:45 AM
  2. [Guide][VB.NET] Reading a String From Memory
    By Gothian in forum WoW Memory Editing
    Replies: 14
    Last Post: 01-18-2008, 12:08 PM
  3. Scorch/Icelance > Something else?
    By nonono in forum WoW ME Questions and Requests
    Replies: 1
    Last Post: 06-14-2007, 04:50 PM
  4. [REQUEST] Troll Male to Something else
    By Yum1999 in forum WoW ME Questions and Requests
    Replies: 0
    Last Post: 04-03-2007, 08:22 PM
All times are GMT -5. The time now is 12:51 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search