Beispiel #1
0
void
CD_BufferRemoveFormat (CDBuffer* self, const char* format, ...)
{
    va_list ap;

    va_start(ap, format);

    while (*format != '\0') {
        CDPointer pointer = va_arg(ap, CDPointer);

        switch (*format) {
            case 'b': *((MCByte*) pointer)    = CD_BufferRemoveByte(self);    break;
            case 's': *((MCShort*) pointer)   = CD_BufferRemoveShort(self);   break;
            case 'i': *((MCInteger*) pointer) = CD_BufferRemoveInteger(self); break;
            case 'l': *((MCLong*) pointer)    = CD_BufferRemoveLong(self);    break;

            case 'f': *((MCFloat*)  pointer) = CD_BufferRemoveFloat(self);  break;
            case 'd': *((MCDouble*) pointer) = CD_BufferRemoveDouble(self); break;

            case 'B': *((MCBoolean*) pointer)   = CD_BufferRemoveBoolean(self);  break;
            case 'S': *((MCString*) pointer)    = CD_BufferRemoveString(self);   break;
            case 'M': *((MCMetadata**) pointer) = CD_BufferRemoveMetadata(self); break;
        }

        format++;
    }

    va_end(ap);
}
Beispiel #2
0
CDPacket*
CD_PacketFromBuffers (CDBuffers* buffers)
{
    CDPacket* self = CD_malloc(sizeof(CDPacket));

    assert(self);

    self->chain = CDRequest;
    self->type  = (uint32_t) (uint8_t) CD_BufferRemoveByte(buffers->input);
    self->data  = CD_GetPacketDataFromBuffer(self, buffers->input);

    if (!self->data) {
        ERR("unparsable packet 0x%.2X", self->type);

        CD_DestroyPacket(self);

        errno = EILSEQ;

        return NULL;
    }

    return self;
}
Beispiel #3
0
MCMetadata*
CD_BufferRemoveMetadata (CDBuffer* self)
{
    MCMetadata* metadata = MC_CreateMetadata();
    MCData*     current  = NULL;
    MCByte      type     = 0;

    // Format strings of the different metadata types
    static char* formats[] = { "b", "s", "i", "f", "S" };

    while (!CD_BufferEmpty(self)) {
        type = CD_BufferRemoveByte(self);

        if (type == 127) {
            break;
        }

        current       = MC_CreateData();
        current->type = type >> 5;

        if (current->type == MCTypeShortByteShort) {
            CD_BufferRemoveFormat(self, "sbs",
                &current->data.sbs.first,
                &current->data.sbs.second,
                &current->data.sbs.third
            );
        }
        else {
            CD_BufferRemoveFormat(self, formats[current->type], &current->data);
        }

        MC_AppendData(metadata, current);
    }

    return metadata;
}
Beispiel #4
0
CDPointer
CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input)
{
    assert(self);
    assert(input);

    switch (self->type) {
        case CDKeepAlive: {
            return (CDPointer) CD_malloc(sizeof(CDPacketKeepAlive));
        }

        case CDLogin: {
            CDPacketLogin* packet = (CDPacketLogin*) CD_malloc(sizeof(CDPacketLogin));

            CD_BufferRemoveFormat(input, "iSSlb",
                &packet->request.version,
                &packet->request.username,
                &packet->request.password,
                &packet->request.mapSeed,
                &packet->request.dimension
            );

            return (CDPointer) packet;
        }

        case CDHandshake: {
            CDPacketHandshake* packet = (CDPacketHandshake*) CD_malloc(sizeof(CDPacketHandshake));

            packet->request.username = CD_BufferRemoveString(input);

            return (CDPointer) packet;
        }

        case CDChat: {
            CDPacketChat* packet = (CDPacketChat*) CD_malloc(sizeof(CDPacketChat));

            packet->request.message = CD_BufferRemoveString(input);

            return (CDPointer) packet;
        }

        case CDUseEntity: {
            CDPacketUseEntity* packet = (CDPacketUseEntity*) CD_malloc(sizeof(CDPacketUseEntity));

            CD_BufferRemoveFormat(input, "iib",
                &packet->request.user,
                &packet->request.target,
                &packet->request.leftClick
            );

            return (CDPointer) packet;
        }

        case CDRespawn: {
            return (CDPointer) CD_malloc(sizeof(CDPacketRespawn));
        }

        case CDOnGround: {
            CDPacketOnGround* packet = (CDPacketOnGround*) CD_malloc(sizeof(CDPacketOnGround));

            packet->request.onGround = CD_BufferRemoveBoolean(input);

            return (CDPointer) packet;
        }

        case CDPlayerPosition: {
            CDPacketPlayerPosition* packet = (CDPacketPlayerPosition*) CD_malloc(sizeof(CDPacketPlayerPosition));

            CD_BufferRemoveFormat(input, "ddddb",
                &packet->request.position.x,
                &packet->request.position.y,
                &packet->request.stance,
                &packet->request.position.z,
                &packet->request.is.onGround
            );

            return (CDPointer) packet;
        }

        case CDPlayerLook: {
            CDPacketPlayerLook* packet = (CDPacketPlayerLook*) CD_malloc(sizeof(CDPacketPlayerLook));

            CD_BufferRemoveFormat(input, "ffb",
                &packet->request.yaw,
                &packet->request.pitch,
                &packet->request.is.onGround
            );

            return (CDPointer) packet;
        }

        case CDPlayerMoveLook: {
            CDPacketPlayerMoveLook* packet = (CDPacketPlayerMoveLook*) CD_malloc(sizeof(CDPacketPlayerMoveLook));

            CD_BufferRemoveFormat(input, "ddddffb",
                &packet->request.position.x,
                &packet->request.stance,
                &packet->request.position.y,
                &packet->request.position.z,
                &packet->request.yaw,
                &packet->request.pitch,
                &packet->request.is.onGround
            );

            return (CDPointer) packet;
        }

        case CDPlayerDigging: {
            CDPacketPlayerDigging* packet = (CDPacketPlayerDigging*) CD_malloc(sizeof(CDPacketPlayerDigging));

            CD_BufferRemoveFormat(input, "bibib",
                &packet->request.status,
                &packet->request.position.x,
                &packet->request.position.y,
                &packet->request.position.z,
                &packet->request.face
            );

            return (CDPointer) packet;
        }

        case CDPlayerBlockPlacement: {
            CDPacketPlayerBlockPlacement* packet = (CDPacketPlayerBlockPlacement*) CD_malloc(sizeof(CDPacketPlayerBlockPlacement));

            CD_BufferRemoveFormat(input, "ibibs",
                &packet->request.position.x,
                &packet->request.position.y,
                &packet->request.position.z,

                &packet->request.direction,
                &packet->request.item.id
            );

            if (packet->request.item.id != -1) {
                CD_BufferRemoveFormat(input, "bs",
                    &packet->request.item.count,
                    &packet->request.item.uses
                );
            }

            return (CDPointer) packet;
        }

        case CDHoldChange: {
            CDPacketHoldChange* packet = (CDPacketHoldChange*) CD_malloc(sizeof(CDPacketHoldChange));

            packet->request.item.id = CD_BufferRemoveShort(input);

            return (CDPointer) packet;
        }

        case CDAnimation: {
            CDPacketAnimation* packet = (CDPacketAnimation*) CD_malloc(sizeof(CDPacketAnimation));

            CD_BufferRemoveFormat(input, "ib",
                &packet->request.entity.id,
                &packet->request.type
            );

            return (CDPointer) packet;
        }

        case CDEntityAction: {
            CDPacketEntityAction* packet = (CDPacketEntityAction*) CD_malloc(sizeof(CDPacketEntityAction));

            CD_BufferRemoveFormat(input, "ib",
                &packet->request.entity.id,
                &packet->request.action
            );

            return (CDPointer) packet;
        }

        case CDEntityMetadata: {
            CDPacketEntityMetadata* packet = (CDPacketEntityMetadata*) CD_malloc(sizeof(CDPacketEntityMetadata));

            CD_BufferRemoveFormat(input, "iM",
                &packet->request.entity.id,
                &packet->request.metadata
            );

            return (CDPointer) packet;
        }

        case CDCloseWindow: {
            CDPacketCloseWindow* packet = (CDPacketCloseWindow*) CD_malloc(sizeof(CDPacketCloseWindow));

            packet->request.id = CD_BufferRemoveByte(input);

            return (CDPointer) packet;
        }

        case CDWindowClick: {
            CDPacketWindowClick* packet = (CDPacketWindowClick*) CD_malloc(sizeof(CDPacketWindowClick));

            CD_BufferRemoveFormat(input, "bsBss",
                &packet->request.id,
                &packet->request.slot,
                &packet->request.rightClick,
                &packet->request.action,
                &packet->request.item.id
            );

            if (packet->request.item.id != -1) {
                CD_BufferRemoveFormat(input, "bs",
                    &packet->request.item.count,
                    &packet->request.item.uses
                );
            }

            return (CDPointer) packet;
        }

        case CDTransaction: {
            CDPacketTransaction* packet = (CDPacketTransaction*) CD_malloc(sizeof(CDPacketTransaction));

            CD_BufferRemoveFormat(input, "bsB",
                &packet->request.id,
                &packet->request.action,
                &packet->request.accepted
            );

            return (CDPointer) packet;
        }

        case CDUpdateSign: {
            CDPacketUpdateSign* packet = (CDPacketUpdateSign*) CD_malloc(sizeof(CDPacketUpdateSign));

            CD_BufferRemoveFormat(input, "iisiSSSS",
                &packet->request.position.x,
                &packet->request.position.y,
                &packet->request.position.z,

                &packet->request.first,
                &packet->request.second,
                &packet->request.third,
                &packet->request.fourth
            );

            return (CDPointer) packet;
        }

        case CDDisconnect: {
            CDPacketDisconnect* packet = (CDPacketDisconnect*) CD_malloc(sizeof(CDPacketDisconnect));

            packet->request.reason = CD_BufferRemoveString(input);

            return (CDPointer) packet;
        }

        default: {
            return (CDPointer) NULL;
        }
    }
}