Exemplo n.º 1
0
int parse_od_resource(struct H3MLIB_CTX *ctx,
    struct H3M_OD_ENTRY *od_entry, struct META_OD_ENTRY *meta_od_entry)
{
    struct H3M *p = &ctx->h3m;
    struct H3MLIB_PARSING *parsing = &ctx->parsing;
    const uint32_t fm = p->format;
    struct H3M_OD_BODY_DYNAMIC_RESOURCE *body = NULL;
    size_t n = 0;
    int ret = 0;

    if (0 == ((struct H3M_OD_BODY_STATIC_RESOURCE *)
        &parsing->raw[parsing->offset])->has_guardians) {
        meta_od_entry->binary_compatible = 1;
        meta_od_entry->body_size = sizeof(struct H3M_OD_BODY_STATIC_RESOURCE);
        return 0;
    }

    od_entry->body = calloc(1, sizeof(*body));
    body = (struct H3M_OD_BODY_DYNAMIC_RESOURCE *)od_entry->body;
    meta_od_entry->binary_compatible = 0;
    meta_od_entry->body_size = sizeof(*body);

    SAFE_READ_SIZEOF(&body->has_guardians, parsing)
    if (0 != body->has_guardians) {
        if (0 != (ret =
                parse_od_ext_guardians(ctx, &body->guardians, meta_od_entry))) {
            return ret;
        }
    }

    n = sizeof(body->quantity) + sizeof(body->unknown1);
    SAFE_READ_N(&body->quantity, n, parsing);

    return 0;
}
Exemplo n.º 2
0
static int _parse_player_ab(int idx, struct H3MLIB_CTX *ctx)
{
    struct H3M *p = &ctx->h3m;
    struct H3MLIB_META *meta = &ctx->meta;
    struct H3MLIB_PARSING *parsing = &ctx->parsing;
    int orig_off = ctx->parsing.offset;
    int ret = 0;
    size_t size = 0;
    const char *member = NULL;
    struct H3M_PLAYER_AB *ab = NULL;

    // TODO: Roll strnlen replacement for all language that may require it

    // Simply alloc enough space for all of the unions - no one cares about a few
    // bytes needlessly used up for the smaller unions
    ab = calloc(1, sizeof(*ab) + H3M_MAX_HERO_NAME + 1);        // + 1 for NULL terminator
    // TODO: safety check here
    SAFE_READ_N(ab, sizeof(*ab) + H3M_MAX_HERO_NAME, parsing);

    //// HACK FOR PLACEHOLDER HERO
    //if (0 == ab->has_main_town && 0xFF == ab->u.e0.starting_hero_type && 0 != ab->town_types)
    //{
    //    size = 10;
    //    member = "player (e4)";
    //    meta->player_has_ai[idx] = 1;
    //    meta->player_ext_types[idx] = 0;
    //}
    //// H3M_PLAYER_EXT_ABSOD
    //else 
    if (0 == ab->has_main_town && 0xFF == ab->u.e0.starting_hero_type) {
        size = sizeof(*ab) - sizeof(ab->u) + sizeof(ab->u.e0);
        member = "player (e0)";
        meta->player_ext_types[idx] = 0;
    }
    // H3M_PLAYER_EXT_WITH_TOWN_ABSOD
    else if (0 != ab->has_main_town && 0xFF == ab->u.e1.starting_hero_type) {
        size = sizeof(*ab) - sizeof(ab->u) + sizeof(ab->u.e1);
        member = "player (e1)";
        meta->player_ext_types[idx] = 1;
    }
    // H3M_PLAYER_EXT_WITH_HERO_ABSOD
    else if (0 == ab->has_main_town
        && (0 == ab->u.e2.starting_hero_name_size
            || (ab->u.e2.starting_hero_name_size <= H3M_MAX_HERO_NAME
                && ab->u.e2.starting_hero_name_size ==
                strnlen((char *)ab->u.e2.starting_hero_name,
                    H3M_MAX_HERO_NAME + 1)))) {
        size =
            sizeof(*ab) - sizeof(ab->u) + sizeof(ab->u.e2) +
            ab->u.e2.starting_hero_name_size;
        member = "player (e2)";
        meta->player_has_ai[idx] = 1;
        meta->player_ext_types[idx] = 2;
    }
    // H3M_PLAYER_EXT_WITH_TOWN_AND_HERO_ABSOD
    else if (0 != ab->has_main_town
        && (0 == ab->u.e3.starting_hero_name_size
            || (ab->u.e3.starting_hero_name_size <= H3M_MAX_HERO_NAME
                && ab->u.e3.starting_hero_name_size ==
                strnlen((char *)ab->u.e3.starting_hero_name,
                    H3M_MAX_HERO_NAME + 1)))) {
        size =
            sizeof(*ab) - sizeof(ab->u) + sizeof(ab->u.e3) +
            ab->u.e3.starting_hero_name_size;
        member = "player (e3)";
        meta->player_has_ai[idx] = 1;
        meta->player_ext_types[idx] = 3;
    } else {
#ifdef _WIN32
        OutputDebugStringA("unknown player");
#endif
        SAFE_CHECK_NOT_PASSED()
    }

    p->players[idx] = (union H3M_PLAYER *)ab;
    meta->player_sizes[idx] = size;
    if (NULL != ctx->callbacks.cb_parse) {
        ret =
            ctx->callbacks.cb_parse(orig_off, member, &parsing->raw[orig_off],
            size, ctx->callbacks.cb_data);
    }

    ctx->parsing.offset = orig_off + size;

    return ret;
}