Git Product home page Git Product logo

dbclientfiles.net's Introduction

Hi there ๐Ÿ‘‹

I'm a (mostly) self-taught software developer; my actual degree is a MSc in Theoretical Chemistry. I started writing my first programs when I was 12. Nowadays, I regularly develop in C++, C#, Java, TypeScript, and have started picking up Rust. Here are some of my public projects that you may find of interest, including some I have contributed to.

C++

  1. TrinityCore is an open-source cross-platform MMORPG server framework. It uses Boost, MariaDB, Grafana, InfluxDB, CMake, and OpenSSL.
  2. tactmon is a C++20 library providing monitoring tools for Blizzard CDNs and product versions, leveraging Boost (namely, Asio and Beast), with a Discord bot and HTTP server frontend backed up by an instance of PostgreSQL to allow proxyfied download of specific files off of Blizzard's CDNs. Development is ongoing.
  3. Dread is an IDA Pro plugin designed to help static analysis of Metroid Dread. It uses IDA's own APIs as well as Clang (specifically, Clang's AST matchers) to analyze pseudocode and derive information that is then used to produce C header files, or automate reverse engineering. Development is on halt.
  4. hzdnptr is an injectable DLL designed to patch offending assembly in Horizon Zero Dawn's early PC releases (*((volatile int*)0) = 0xDEADCA7; to be exact), which triggering during play and caused the game to crash. It uses Boost, minhook, fmt, Zydis and spdlog.
  5. snippetspp is an umbrella repository where I push code I use in some of my projects (some of which are not on GitHub). One in particular is a simple single-header command parser. None of the pieces of code here have been production-tested.
  6. vk_jenkins is an experiment in writing compute shaders to bruteforce Jenkins hashes, using Vulkan.

C#

  1. DBClientFiles.NET is a library designed to parse DBC, DB2 and derivate file formats from World of Warcraft's game client, with a focus on speed and memory efficiency, by leveraging System.Linq.Expressions to generate code at runtime. It is a newer version of DBFilesClient.NET. Development is on halt.
  2. ADBC is very similar to the above, except that it interfaces with World of Warcraft's actual archive files, and provides a fully featured GUI with support for foreign keys, export to CSV, and visualization of textures referenced by DBC files. It is now outdated, due to changes to Blizzard's internal data formats and file relationships.
  3. WowSniffExplorer is an attempt at creating a GUI to process and analyze network dumps of World of Warcraft's protocol. It is a continuation of WowPacketParser, but got superceded by other solutions such as WowDatabaseEditor.
  4. MeshViewer is a .NET application able to render serverside geometry at the location of the player in World of Warcraft, by externally reading process memory. It uses OpenTK

dbclientfiles.net's People

Contributors

barncastle avatar warpten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

dbclientfiles.net's Issues

Support for DBs without an Index

Hopefully not a major implementation issue but WDBC and WDB2 don't necessarily have an Index constraint, for example pre-WotLK CharBaseInfo. The client handles this by generating Ids based on the record index on load.

struct CharBaseInfoRec // Alpha 0.5.3.3368
{
  char m_raceID;
  char m_classID;
  int m_proficiency;
  int m_generatedID; // not in file
};

P.S. Great work, I'll be using this for WDBX once write support is in!

property order

Type.GetProperties and associates return an array of PropertyInfo in no particular order. They coincidentally match order in declaration but that might change, as theres, per MSDN:

The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order.

might be a problem in the future

Deserializing arrays

The two-fold approach to arrays leads to a glaring issue (not really a bug).

Given this declaration

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public Substructure[] SomeMember {get;set;}

But the corresponding file metadata instead says that the member is not of cardinality 5, the generator will produce this kind of code:

{
    var structure = new ...();
    structure.SomeMember = new Substructure [5];
    for (var i = 0; i < 5; ++i)
        structure.SomeMember[i]= new Substructure();

    // Deserialization happens now
    structure.SomeMember[i] = reader.ReadArray<Substructure>(3);
    // ...

    return structure;
}

User code should never have to hardcode array sizes but instead use SomeMember.Length, which here will yield two extra elements.

This is an even more glaring issue when the declared structure has cardinality lower than what the file declares.

structureless loaders

Steps needed

  • Separate loading logic from parsing logic
  • Provide front-facing code that hides away all the type generation code and lets the user specify members using an IEnumerable<some interface>.
  • Either expand on the existing code, which means:
    • Runtime type generation: slow, needs to be cached, no user control, not pretty
    • ???

Possible issues:

  • Input structurew will need to match file definitions 1:1 to not fail.
  • Provide clear errors to the user if something is done wrong.

Surface layer

public interface IMember
{
    tring Name { get; }
    MemberType Type { get; } /* enumeration of int, etc */
    int Cardinality { get; } /* cardinality, default to 1 */
    // ?
}

Example of user code

using (var fileStreram = ...)
{
    var storage = new Storage(fileStream, new DynamicStructure().field("ID", MemberType.Int32).field("Name", MemberType.String).build(), StorageOptions.Default);

    // 0 is the record key (different from ID - it's still the user's task to create a dictionary)
    Console.WriteLine("{0} - {1}", storage[0]["ID"].Integer, storage[0]["Name"].String);

    var allNames = storage["Name"].Strings; // IEnumerable<(int, string)>
}

Property detection

We currently force get and set to not be null (barring IgnoreAttribute). get is however enough to create a backing field if autogenerated. Maybe allow private protected (or internal protected) setters?

writing files

Problems to expect:

  • Heuristics for section assignment of each member:
    1. Bitpacking (bit counting if column.max_value < (column.type.max_value >> 8)
    2. Choosing between pallet and common (default value heuristic?)
  • Maintain a string pool - whenever an item is added to the container, we need to extract strings from it
  • Subsidiary: when is a string pool not needed?

headers

Headers are poorly handled and need a rewrite. stat.

Current implementation:

  • A front-facing Header type is provided to the user - it only exposes record count, signature, and uh, that's it I think ? Takes an implementation of IFileHeader or another instance of itself as ctor argument.
  • IFileHeader is an interface that acts as a base for all header types, which are defined per-signature. This means that header implementations turn into property hell.

Desirable properties of new headers:

  • value types (struct), bonus points for immutability (readonly struct).
  • Unsafe.SizeOf<T>() must match the binary size of the header in the file (give or take the 4 bytes for magic identifier).
  • Avoid copying as much as possible (ref readonly getter returns).
  • Can leverage existing block handling mechanics for serialization.
  • Avoid property hell where => throw new NotImplementedException(); is the default "i shouldn't be called" implementation. If you don't have it, don't expose it.

Avoid using property getters and setters when deserializing

This is not a pretty solution but it would help avoiding the issue of value type getters returning temporary copies of the underlying types. The problem is that autogenerated getters typically retrieve a field named <prop>k_BackingField, (IsSpecialName returns true) which is compiler-specific. So not exactly portable.

The idea is to not limit the user to reference type substructures:

    public class C3Vector // Runtime exception if value type.
    {
        public float X { get; set; }
        public float Y { get; set; }
        public float Z { get; set; }
    }

    public struct AreaTriggerEntry
    {
        public uint ID { get; set; }
        public uint MapID { get; set; }
        public C3Vector Position { get; set; }
        public float Radius { get; set; }
        public C3Vector BoxSize { get; set; }
        public float BoxOrientation { get; set; }
    }

write support

this is an entirely new can of worms, but something that must be done eventually.

[ ] find heuristics for section assignment
[ ] write more code for emitting serializers

Encrypted sections

WDC2 and WDC3 allows blizzard to roll out encrypted sections until they push tact keys out. WDC2 isn't known to use this.

StorageDictionary<TKey, TValue>

There's currently no way to know the type of the index field as declared in the structure, because it only happens once segments are read (this is when field mapping happens).

This leads to issues where StorageDictionary is just unable to check if _keyGetter HAS to be set.

This is currently done in a very ugly way which forces users to decorate the proper field with IndexAttribute, which is pointless and shouldn't be needed since an index is either:

  • for wdbc/wdb2: first column, always
  • else: column index specified by header

wdb5/6

those need to be tested, might be bugged

proper index table handling

Possible bug to investigate as i was redacting #2.

if header.flags & 0x04, index is not in record, and thus

        public FileMemberInfo IndexFileMember => FileMembers.FirstOrDefault(m => m.Index == IndexColumn);

is wrong.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.