2021-05-03 22:44:39 +00:00
|
|
|
#pragma once
|
2021-05-03 23:38:47 +00:00
|
|
|
#include "zpl.h"
|
2021-05-03 22:44:39 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "cwpack/cwpack.h"
|
|
|
|
|
2021-05-04 17:39:50 +00:00
|
|
|
#ifndef PKT_IF
|
|
|
|
#define PKT_IF(c) if (c < 0) return -1;
|
|
|
|
#endif
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline void pkt_pack_msg(cw_pack_context *pc, uint32_t args) {
|
2021-05-03 22:44:39 +00:00
|
|
|
cw_pack_context_init(pc, pkt_buffer, PKT_BUFSIZ, 0);
|
|
|
|
cw_pack_array_size(pc, args);
|
|
|
|
}
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_unpack_msg(cw_unpack_context *uc, pkt_header *header, uint32_t args) {
|
2021-05-03 22:44:39 +00:00
|
|
|
cw_unpack_context_init(uc, header->data, header->datalen, 0);
|
|
|
|
|
|
|
|
cw_unpack_next(uc);
|
|
|
|
if (uc->item.type != CWP_ITEM_ARRAY || uc->item.as.array.size != args) {
|
|
|
|
return -1;//todo: error
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_unpack_msg_raw(cw_unpack_context *uc, uint8_t *data, uint32_t datalen, uint32_t args) {
|
2021-05-03 22:44:39 +00:00
|
|
|
pkt_header header = {.data = data, .datalen = datalen};
|
|
|
|
return pkt_unpack_msg(uc, &header, args);
|
|
|
|
}
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_validate_eof_msg(cw_unpack_context *uc) {
|
2021-05-03 22:44:39 +00:00
|
|
|
if (uc->return_code != CWP_RC_OK) return -1; // unpacking failed somwwhere
|
|
|
|
cw_unpack_next(uc);
|
|
|
|
if (uc->return_code != CWP_RC_END_OF_INPUT) return -1; // not finished yet but should be?
|
|
|
|
return 0;
|
|
|
|
}
|
2021-05-03 23:38:47 +00:00
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline size_t pkt_pack_msg_size(cw_pack_context *pc) {
|
2021-05-04 08:08:00 +00:00
|
|
|
return pc->current - pc->start; // NOTE(zaklaus): length
|
|
|
|
}
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, size_t pkt_size, int8_t is_reliable) {
|
2021-05-04 17:39:50 +00:00
|
|
|
zpl_zero_item(pkt);
|
|
|
|
static uint8_t pkt_data[PKT_BUFSIZ] = {0};
|
|
|
|
zpl_memcopy(pkt_data, pkt_buffer, pkt_size);
|
|
|
|
|
|
|
|
pkt->data = pkt_buffer;
|
2021-05-06 15:30:38 +00:00
|
|
|
pkt->view_id = view_id;
|
|
|
|
pkt->datalen = pkt_header_encode(id, view_id, pkt_data, pkt_size);
|
2021-05-04 17:39:50 +00:00
|
|
|
pkt->is_reliable = is_reliable;
|
|
|
|
pkt->id = id;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-05-04 19:22:55 +00:00
|
|
|
extern int32_t world_write(pkt_header *pkt, void *udata);
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, uint16_t view_id, void *udata) {
|
2021-05-04 19:22:55 +00:00
|
|
|
pkt_header pkt;
|
2021-05-06 15:30:38 +00:00
|
|
|
PKT_IF(pkt_prep_msg(&pkt, id, view_id, pkt_size, is_reliable));
|
2021-05-04 19:22:55 +00:00
|
|
|
return world_write(&pkt, udata);
|
|
|
|
}
|
|
|
|
|
2021-05-03 23:38:47 +00:00
|
|
|
#ifndef PKT_OFFSETOF
|
|
|
|
#if defined(_MSC_VER) || defined(ZPL_COMPILER_TINYC)
|
|
|
|
# define PKT_OFFSETOF(Type, element) ((size_t) & (((Type *)0)->element))
|
|
|
|
#else
|
|
|
|
# define PKT_OFFSETOF(Type, element) __builtin_offsetof(Type, element)
|
|
|
|
#endif
|
|
|
|
# define PKT_FIELD_SIZEOF(type, member) sizeof(((type *)0)->member)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_STRUCT_PTR
|
2021-05-03 23:57:19 +00:00
|
|
|
#define PKT_STRUCT_PTR(a) (void*)(a), (uint32_t)sizeof(*(a))
|
2021-05-03 23:38:47 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_FIELD
|
2021-05-04 11:04:15 +00:00
|
|
|
#define PKT_FIELD(k, t, a) .type = k, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a)
|
2021-05-06 16:26:52 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_UINT
|
|
|
|
#define PKT_UINT(t, a) .type = CWP_ITEM_POSITIVE_INTEGER, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_SINT
|
|
|
|
#define PKT_SINT(t, a) .type = CWP_ITEM_NEGATIVE_INTEGER, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_REAL
|
|
|
|
#define PKT_REAL(t, a) .type = CWP_ITEM_DOUBLE, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_HALF
|
|
|
|
#define PKT_HALF(t, a) .type = CWP_ITEM_FLOAT, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a)
|
2021-05-04 11:04:15 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_ARRAY
|
|
|
|
#define PKT_ARRAY(t, a) .type = CWP_ITEM_BIN, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a[0])
|
2021-05-03 23:38:47 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PKT_END
|
|
|
|
#define PKT_END .type = CWP_NOT_AN_ITEM
|
|
|
|
#endif
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
#ifndef PKT_GET_ENT
|
|
|
|
#define PKT_GET_ENT(h) (ecs_entity_t)(h->udata)
|
|
|
|
#endif
|
|
|
|
|
2021-05-03 23:38:47 +00:00
|
|
|
typedef struct pkt_desc {
|
|
|
|
cwpack_item_types type;
|
|
|
|
size_t offset;
|
|
|
|
size_t size;
|
2021-05-04 11:04:15 +00:00
|
|
|
size_t it_size;
|
2021-05-03 23:38:47 +00:00
|
|
|
} pkt_desc;
|
|
|
|
|
|
|
|
int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob, uint32_t blob_size);
|
2021-05-04 08:08:00 +00:00
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline int32_t pkt_msg_decode(pkt_header *header, pkt_desc* desc, uint32_t args, void *raw_blob, uint32_t blob_size) {
|
2021-05-04 08:08:00 +00:00
|
|
|
cw_unpack_context uc = {0};
|
2021-05-04 11:04:15 +00:00
|
|
|
PKT_IF(pkt_unpack_msg(&uc, header, args));
|
|
|
|
PKT_IF(pkt_unpack_struct(&uc, desc, raw_blob, blob_size));
|
2021-05-04 08:08:00 +00:00
|
|
|
|
|
|
|
return pkt_validate_eof_msg(&uc);
|
2021-05-04 21:12:32 +00:00
|
|
|
}
|
|
|
|
|
2021-05-07 14:43:54 +00:00
|
|
|
static inline size_t pkt_pack_desc_args(pkt_desc *desc) {
|
2021-05-04 21:12:32 +00:00
|
|
|
size_t cnt = 0;
|
|
|
|
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field, ++cnt) {}
|
|
|
|
return cnt;
|
|
|
|
}
|