protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

commit f14601d31e05d8df37e5e5c1e0740967f33b941e
parent 5ac87cda57ab359f8bc268812541261f14e80db0
Author: William Casarin <jb55@jb55.com>
Date:   Sat,  3 Jul 2021 08:38:22 -0700

generalize message packets, add entity resources

Diffstat:
M.envrc | 2++
M.gitignore | 3+++
MMakefile | 5++++-
Mdefault.nix | 6++----
Aindex.space | 2++
Msatoshis-citadel.space | 2++
Msrc/client.c | 5++---
Asrc/debug.h | 15+++++++++++++++
Asrc/entity.h | 21+++++++++++++++++++++
Asrc/env.h | 10++++++++++
Msrc/net.c | 83++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/net.h | 18+++++++++++++-----
Asrc/object.h | 10++++++++++
Msrc/parse.c | 1-
Msrc/protoverse.c | 3+++
Asrc/resource.c | 236+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/resource.h | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/serve.c | 26++++++++++++++++++++++----
Msrc/serve.h | 2++
Msrc/test.c | 8++++----
Asrc/types.h | 17+++++++++++++++++
Msrc/wasm.c | 6+++---
Atodo/messages.gmi | 16++++++++++++++++
Atodo/todo.txt | 0
24 files changed, 502 insertions(+), 51 deletions(-)

diff --git a/.envrc b/.envrc @@ -1 +1,3 @@ use nix + +export TODO_DIR=$PWD/todo diff --git a/.gitignore b/.gitignore @@ -1,8 +1,11 @@ *.o +.buildcmd .build-result /protoverse /libprotoverse.a /TAGS +todo/report.txt +todo/done.txt /test *.wasm /tags diff --git a/Makefile b/Makefile @@ -1,5 +1,7 @@ -CFLAGS = -Wno-error=unused-function -Ofast -std=gnu90 -Wall -Wextra -Werror -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement +CFLAGS = -Wno-error=unused-function -Ofast -std=gnu90 -Wall -Wextra -Werror \ + -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes \ + -Wmissing-declarations -Wdeclaration-after-statement OBJS = src/io.o \ src/parse.o \ @@ -9,6 +11,7 @@ OBJS = src/io.o \ src/net.o \ src/varint.o \ src/parser.o \ + src/resource.o \ src/wasm.o WASMS = wasm/hello-c.wasm \ diff --git a/default.nix b/default.nix @@ -1,6 +1,4 @@ { pkgs ? import <nixpkgs> {} }: -with pkgs; -stdenv.mkDerivation { - name = "protoverse"; - nativeBuildInputs = [ gdb wabt emscripten ]; +pkgs.mkShell { + buildInputs = with pkgs; [ gdb wabt emscripten wasmtime ]; } diff --git a/index.space b/index.space @@ -0,0 +1 @@ +satoshis-citadel.space+ \ No newline at end of file diff --git a/satoshis-citadel.space b/satoshis-citadel.space @@ -17,6 +17,8 @@ (chair (id welcome-desk-chair) (name "fancy")) + (chair (name "throne") (material "invisible")) + (light (location ceiling) (name "ceiling") (state off) diff --git a/src/client.c b/src/client.c @@ -65,9 +65,8 @@ int protoverse_connect(const char *server_ip_str, int port) server_addr.sin_port = port == 0 || port == -1 ? 1988 : port; server_addr.sin_addr = server_in_addr; - packet.type = PKT_CHAT; - packet.data.chat.message = "hello, world"; - packet.data.chat.sender = 0xFFFFFF; + packet.type = PKT_MESSAGE; + packet.data.message.message = "hello, world"; send_packet(sockfd, &server_addr, &packet); recv_packet(sockfd, &cursor, &server_addr, &packet); diff --git a/src/debug.h b/src/debug.h @@ -0,0 +1,15 @@ + +#ifndef PROTOVERSE_DEBUG_H +#define PROTOVERSE_DEBUG_H + +#include <stdio.h> + +#define unusual(...) fprintf(stderr, "UNUSUAL: " __VA_ARGS__) + +#ifdef DEBUG +#define debug(...) fprintf(stderr, __VA_ARGS__) +#else +#define debug(...) +#endif + +#endif /* PROTOVERSE_DEBUG_H */ diff --git a/src/entity.h b/src/entity.h @@ -0,0 +1,21 @@ + +#ifndef PROTOVERSE_ENTITY_H +#define PROTOVERSE_ENTITY_H + +#include "resource.h" + +typedef struct resource_id entity_id; + +enum entity_type { + ENT_AVATAR, + ENT_OBJECT, +}; + +struct entity { + const char *name; + enum entity_type type; + int cell; + double pos[3]; +}; + +#endif /* PROTOVERSE_ENTITY_H */ diff --git a/src/env.h b/src/env.h @@ -0,0 +1,10 @@ +#ifndef PROTOVERSE_ENV +#define PROTOVERSE_ENV + +#include "resource.h" + +struct env { + struct resource_manager entities; +}; + +#endif /* PROTOVERSE_ENV */ diff --git a/src/net.c b/src/net.c @@ -3,6 +3,8 @@ #include "cursor.h" #include "util.h" #include "varint.h" +#include "env.h" +#include "entity.h" #include <sys/types.h> #include <assert.h> @@ -13,7 +15,8 @@ #include <stdio.h> #include <string.h> -static int push_fetch_response_packet(struct cursor *c, struct fetch_response_packet *resp) +static int push_fetch_response_packet(struct cursor *c, + struct fetch_response_packet *resp) { int ok; ok = push_prefixed_str(c, resp->path); @@ -40,23 +43,29 @@ static int push_fetch_packet(struct cursor *c, struct fetch_packet *fetch) } /* TODO: CPU-independent encoding */ -static int push_chat_packet(struct cursor *c, struct chat_packet *chat) +static int push_message_packet(struct cursor *c, struct message_packet *msg) { int ok; - ok = push_varint(c, chat->sender); + ok = push_varint(c, msg->type); if (!ok) return 0; - return push_prefixed_str(c, chat->message); + ok = push_varint(c, msg->receiver); + if (!ok) return 0; + + return push_prefixed_str(c, msg->message); } -static int pull_chat_packet(struct cursor *c, struct cursor *buf, struct chat_packet *chat) +static int pull_message_packet(struct cursor *c, struct cursor *buf, struct message_packet *msg) { int ok; - ok = pull_varint(c, &chat->sender); + ok = pull_varint(c, &msg->type); + if (!ok) return 0; + + ok = pull_varint(c, &msg->receiver); if (!ok) return 0; - return pull_prefixed_str(c, buf, &chat->message); + return pull_prefixed_str(c, buf, &msg->message); } static int pull_fetch_packet(struct cursor *c, struct cursor *buf, struct fetch_packet *fetch) @@ -73,10 +82,12 @@ int send_packet(int sockfd, struct sockaddr_in *to_addr, struct packet *packet) len = push_packet(buf, sizeof(buf), packet); if (!len) return 0; - ok = sendto(sockfd, buf, len, 0, (struct sockaddr*)to_addr, sizeof(*to_addr)); + ok = sendto(sockfd, buf, len, 0, (struct sockaddr*)to_addr, + sizeof(*to_addr)); if (ok != len) { - printf("sendto: sent %d != packet_len %d - %s\n", ok, len, strerror(errno)); + printf("sendto: sent %d != packet_len %d - %s\n", ok, len, + strerror(errno)); return 0; } @@ -90,7 +101,8 @@ int recv_packet(int sockfd, struct cursor *buf, struct sockaddr_in *from, struct socklen_t size = sizeof(*from); int bytes; - bytes = recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from, &size); + bytes = recvfrom(sockfd, tmp, sizeof(tmp), 0, (struct sockaddr*)from, + &size); assert(size == sizeof(*from)); make_cursor(tmp, tmp + sizeof(tmp), &tmp_cursor); @@ -114,7 +126,8 @@ static int push_envelope(struct cursor *cursor, enum packet_type type, int len) return env_len; } -static int pull_envelope(struct cursor *cursor, enum packet_type *type, int *len) +static int pull_envelope(struct cursor *cursor, enum packet_type *type, + int *len) { int ok, env_len; ok = pull_varint(cursor, (int*)type); @@ -139,9 +152,10 @@ static int push_packet_data(struct cursor *c, struct packet *packet) case PKT_FETCH_DATA: return push_fetch_packet(c, &packet->data.fetch); case PKT_FETCH_DATA_RESPONSE: - return push_fetch_response_packet(c, &packet->data.fetch_response); - case PKT_CHAT: - return push_chat_packet(c, &packet->data.chat); + return push_fetch_response_packet(c, + &packet->data.fetch_response); + case PKT_MESSAGE: + return push_message_packet(c, &packet->data.message); case PKT_NUM_TYPES: return 0; } @@ -184,8 +198,8 @@ static int pull_packet_data(struct cursor *c, struct cursor *buf, case PKT_FETCH_DATA_RESPONSE: return pull_fetch_response_packet(c, buf, &packet->data.fetch_response); - case PKT_CHAT: - return pull_chat_packet(c, buf, &packet->data.chat); + case PKT_MESSAGE: + return pull_message_packet(c, buf, &packet->data.message); case PKT_NUM_TYPES: break; } @@ -209,7 +223,8 @@ int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, capacity_left = cursor_remaining_capacity(c) - 1; if (len > capacity_left) { - printf("sanity: packet larger (%d) than remaining buffer size: %d", len, capacity_left); + printf("sanity: packet larger (%d)" + " than remaining buffer size: %d", len, capacity_left); return 0; } @@ -219,13 +234,13 @@ int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, return len + env_size; } -static int packet_chat_eq(struct chat_packet *a, struct chat_packet *b) +static int packet_message_eq(struct message_packet *a, struct message_packet *b) { /* fail if either is 0 but not both 0 or both not 0 */ if (!a->message ^ !b->message) return 0; - return a->sender == b->sender && !strcmp(a->message, b->message); + return !strcmp(a->message, b->message); } static int packet_fetch_eq(struct fetch_packet *a, struct fetch_packet *b) @@ -251,8 +266,8 @@ int packet_eq(struct packet *a, struct packet *b) return 0; switch (a->type) { - case PKT_CHAT: - return packet_chat_eq(&a->data.chat, &b->data.chat); + case PKT_MESSAGE: + return packet_message_eq(&a->data.message, &b->data.message); case PKT_FETCH_DATA: return packet_fetch_eq(&a->data.fetch, &b->data.fetch); case PKT_FETCH_DATA_RESPONSE: @@ -265,14 +280,30 @@ int packet_eq(struct packet *a, struct packet *b) return 0; } +static const char *entity_name(struct env *env, entity_id *id) +{ + struct entity *ent; + + if (!(ent = get_resource(&env->entities, id))) { + return "unknown"; + } + + return ent->name; +} + +static void print_message_packet(struct env *env, struct message_packet *msg) +{ + /* eventually print entity data from environment */ + (void)env; + printf("(message (to %d) (msg '%s'))\n", msg->receiver, + msg->message); +} -void print_packet(struct packet *packet) +void print_packet(struct env *env, struct packet *packet) { switch (packet->type) { - case PKT_CHAT: - printf("(chat (sender %d) (message \"%s\"))\n", - packet->data.chat.sender, - packet->data.chat.message); + case PKT_MESSAGE: + print_message_packet(env, &packet->data.message); return; case PKT_FETCH_DATA_RESPONSE: printf("(fetch-resp (path \"%s\") (data %d))\n", diff --git a/src/net.h b/src/net.h @@ -4,15 +4,22 @@ #include <sys/socket.h> #include <arpa/inet.h> + #include "cursor.h" +#include "env.h" enum packet_type { PKT_FETCH_DATA, PKT_FETCH_DATA_RESPONSE, - PKT_CHAT, + PKT_MESSAGE, PKT_NUM_TYPES, }; +enum message_type { + MSG_CHAT, + MSG_INTERACT, +}; + struct fetch_packet { const char *path; }; @@ -23,15 +30,16 @@ struct fetch_response_packet { unsigned char *data; }; -struct chat_packet { - int sender; +struct message_packet { + int receiver; + int type; const char *message; }; union packet_data { struct fetch_packet fetch; struct fetch_response_packet fetch_response; - struct chat_packet chat; + struct message_packet message; }; struct packet { @@ -46,6 +54,6 @@ int push_packet(unsigned char *buf, int bufsize, struct packet *packet); int pull_packet(struct cursor *c, struct cursor *buf, struct packet *packet, int received_bytes); int packet_eq(struct packet *a, struct packet *b); -void print_packet(struct packet *packet); +void print_packet(struct env *env, struct packet *packet); #endif /* PROTOVERSE_NET_H */ diff --git a/src/object.h b/src/object.h @@ -0,0 +1,10 @@ + +#ifndef _PROTOVERSE_OBJECT_ +#define _PROTOVERSE_OBJECT_ + +struct object { + int cell_id; + const char *name; +} + +#endif /* _PROTOVERSE_OBJECT_ */ diff --git a/src/parse.c b/src/parse.c @@ -163,7 +163,6 @@ void print_cell(struct cursor *attributes, struct cell *cell) : cell_type_str(cell->type)); /* print_attributes(attributes, cell); */ - printf("\n"); } diff --git a/src/protoverse.c b/src/protoverse.c @@ -25,12 +25,14 @@ static void print_all_cells(struct parser *parser) for (i = 0; i < ncells; i++) { cell = get_cell(parser->cells, i); print_cell(parser->attributes, cell); + printf("\n"); for (j = 0; j < cell->n_children; j++) { cell = get_cell(parser->cells, cell->children[j]); assert(cell); printf(" "); print_cell(parser->attributes, cell); + printf("\n"); } } } @@ -56,6 +58,7 @@ static int print_cell_tree(struct parser *parser, u16 root, int depth) } print_cell(&parser->attributes, cell); + printf("\n"); for (i = 0; i < cell->n_children; i++) { print_cell_tree(parser, cell->children[i], depth+1); diff --git a/src/resource.c b/src/resource.c @@ -0,0 +1,236 @@ + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "resource.h" +#include "debug.h" +#include "util.h" + +static u64 resource_uuids = 0; + +static inline void *index_resource_(u8 *res, u32 elem_size, int i) +{ + assert(res); + return res + (i * elem_size); +} + +static inline void *index_resource(struct resource_manager *r, int i) +{ + return index_resource_(r->resources, r->elem_size, i); +} + + +void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_id **ids) { + if (count != 0) + *count = r->resource_count; + + if (ids != 0) + *ids = r->ids; + + return r->resources; +} + +void init_id(struct resource_id *id) { + id->index = -1; + id->generation = -1; + id->uuid = -1; +} + +void null_id(struct resource_id *id) +{ + id->generation = 0; + id->uuid = -1; + id->index = -1; +} + +void init_resource_manager(struct resource_manager *r, u32 elem_size, + u32 initial_elements, u32 max_elements, + const char *name) +{ + r->generation = 1; + r->resource_count = 0; + r->elem_size = elem_size; + r->max_capacity = max_elements; + r->current_capacity = initial_elements; + r->name = name; + + assert(initial_elements != 0); + + r->resources = calloc(r->current_capacity, elem_size); + r->ids = calloc(r->current_capacity, sizeof(struct resource_id)); +} + +void destroy_resource_manager(struct resource_manager *r) { + free(r->ids); + free(r->resources); +} + +static int refresh_id(struct resource_manager *r, struct resource_id *id, + struct resource_id *new) +{ + u32 i; + // rollover is ok + /* assert(->generation <= esys.generation); */ + if (id->generation != r->generation) { + /* debug("id %llu gen %d != res gen %d, refreshing\n", */ + /* id->uuid, id->generation, r->generation); */ + /* try to find uuid in new memory layout */ + for (i = 0; i < r->resource_count; i++) { + struct resource_id *newer_id = &r->ids[i]; + if (newer_id->uuid == id->uuid) { + /* debug("found %llu, ind %d -> %d\n", new_id->uuid, new_id->index, new->index); */ + new->index = newer_id->index; + new->generation = r->generation; + return REFRESHED_ID; + } + } + + // entity was deleted + return RESOURCE_DELETED; + } + + // doesn't need refreshed + return REFRESH_NOT_NEEDED; +} + +int is_resource_destroyed(struct resource_id *id) { + return id->generation == 0; +} + +static void new_id(struct resource_manager *r, struct resource_id *id) +{ + id->index = r->resource_count; + id->uuid = ++resource_uuids; + id->generation = r->generation; + assert(id->generation); +} + +static void resize(struct resource_manager *r) +{ + void *new_mem; + u32 new_size; + + debug("resizing %s resources, count %d+1 > current capacity %d\n", + r->name, r->resource_count, r->current_capacity); + + new_size = r->resource_count * 1.5; + if (new_size >= r->max_capacity) { + new_size = r->max_capacity; + } + + /* debug("resizing new_size %d\n", new_size); */ + + new_mem = realloc(r->resources, (new_size+1) * r->elem_size); + if (!new_mem) { + // yikes, out of memory, bail + assert(new_mem); + return; + } + + r->resources = new_mem; + new_mem = realloc(r->ids, sizeof(struct resource_id) * (new_size+1)); + + if (!new_mem) { + // yikes, out of memory, bail + assert(new_mem); + return; + } + r->current_capacity = new_size; + r->ids = new_mem; +} + +void print_id(struct resource_id *id, int nl) +{ + printf("id(u:%llu i:%d g:%d)%s", + id->uuid, id->index, id->generation, nl?"\n":""); +} + + +void *new_resource(struct resource_manager *r, struct resource_id *id) +{ + struct resource_id *fresh_id; + + assert(id); + assert(id->index == 0xFFFFFFFF && "res_id is uninitialized"); + + if (r->resource_count + 1 > r->max_capacity) { + printf("new_resource: count %d > max cap %d\n", r->resource_count, r->max_capacity); + return NULL; + } + + if (r->resource_count + 1 > r->current_capacity) + resize(r); + + fresh_id = &r->ids[r->resource_count]; + new_id(r, fresh_id); + *id = *fresh_id; + + return index_resource(r, r->resource_count++); +} + + +void *get_resource(struct resource_manager *r, struct resource_id *id) { + enum refresh_status res; + + assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)"); + + if (id->generation == 0) { + /* unusual("getting already deleted resource %llu\n", id->uuid); */ + return NULL; + } + + res = refresh_id(r, id, id); + + if (res == RESOURCE_DELETED) { + /* unusual("getting deleted %s resource %llu\n", r->name, id->uuid); */ + return NULL; + } + + return index_resource(r, id->index); +} + + +void destroy_resource(struct resource_manager *r, struct resource_id *id) { + enum refresh_status res; + u32 i; + + if (is_resource_destroyed(id)) { + unusual("trying to destroy resource %llu which was already destroyed\n", id->uuid); + return; + } + + res = refresh_id(r, id, id); + + // entity already deleted + /* debug("refresh res %d uuid %llu gen %d index %d\n", res, */ + /* id->uuid, id->generation, id->index); */ + + if (res == RESOURCE_DELETED) { + unusual("trying to destroy resource %llu which was already destroyed (2)\n", id->uuid); + id->generation = 0; + return; + } + + /* debug("destroying %s resource %llu ind %d res_count %d\n", */ + /* r->name, id->uuid, id->index, r->resource_count); */ + + r->resource_count--; + r->generation++; + + assert((int)r->resource_count - (int)id->index >= 0); + + // TODO: we're copying OOB here + memmove(index_resource(r, id->index), + index_resource(r, id->index+1), + r->elem_size * (r->resource_count - id->index)); + + memmove(&r->ids[id->index], + &r->ids[id->index+1], + sizeof(struct resource_id) * (r->resource_count - id->index)); + + + for (i = id->index; i < r->resource_count; i++) { + r->ids[i].index--; + } +} diff --git a/src/resource.h b/src/resource.h @@ -0,0 +1,56 @@ + +#ifndef RESOURCE_H +#define RESOURCE_H + +#include "types.h" + +#define STATIC_UUID 0x5A51C00000000000 + +enum refresh_status { + RESOURCE_DELETED, + REFRESH_NOT_NEEDED, + REFRESHED_ID +}; + +struct resource_id { + u64 uuid; + u32 index; + u32 generation; +}; + +struct resource_manager { + u8 *resources; + struct resource_id *ids; + u32 resource_count; + u32 generation; + u32 elem_size; + u32 slots_used; + u32 max_capacity; + u32 current_capacity; + + const char *name; +}; + +#define ideq(a, b) ((a)->uuid == (b)->uuid) + +void init_id(struct resource_id *id); +void *get_resource(struct resource_manager *r, struct resource_id *id); +void *get_all_resources(struct resource_manager *, u32 *count, struct resource_id **ids); +void destroy_resource(struct resource_manager *, struct resource_id *id); +void destroy_resource_manager(struct resource_manager *); +void *new_resource(struct resource_manager *, struct resource_id *id); +void print_id(struct resource_id *, int nl); +void null_id(struct resource_id *id); +int is_resource_destroyed(struct resource_id *id); + +void init_resource_manager(struct resource_manager *r, u32 elem_size, + u32 initial_elements, u32 max_elements, const char *name); + + +static inline int is_null_id(struct resource_id *id) +{ + return id->generation == 0; +} + + +#endif /* RESOURCE_H */ diff --git a/src/serve.c b/src/serve.c @@ -10,10 +10,12 @@ #include <stdlib.h> #include "serve.h" +#include "entity.h" #include "net.h" #include "io.h" #define MAX_CACHED_FILES 12 +#define MAX_ENTITIES 1048576 int inet_aton(const char *cp, struct in_addr *inp); @@ -62,6 +64,7 @@ static int make_fetch_response(struct cursor *buf, } static int handle_packet(int sockfd, + struct env *env, struct cursor *buf, struct sockaddr_in *from, struct packet *packet) @@ -69,9 +72,9 @@ static int handle_packet(int sockfd, struct packet response; int ok; - print_packet(packet); + print_packet(env, packet); switch (packet->type) { - case PKT_CHAT: + case PKT_MESSAGE: return send_packet(sockfd, from, packet); case PKT_FETCH_DATA: ok = make_fetch_response(buf, &response, @@ -88,6 +91,17 @@ static int handle_packet(int sockfd, return 0; } +static void init_protoverse_server(struct protoverse_server *server) +{ + init_resource_manager(&server->env.entities, sizeof(struct entity), + 1024, MAX_ENTITIES, "entity"); +} + +static void free_protoverse_server(struct protoverse_server *server) +{ + destroy_resource_manager(&server->env.entities); +} + int protoverse_serve(struct protoverse_server *server) { #define FILEBUF_SIZE 31457280 @@ -105,6 +119,9 @@ int protoverse_serve(struct protoverse_server *server) buf_ = malloc(FILEBUF_SIZE); make_cursor(buf_, buf_ + FILEBUF_SIZE, &buf); + /* initialize object storage, etc */ + init_protoverse_server(server); + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { printf("socket creation failed: %s\n", strerror(errno)); return 0; @@ -133,14 +150,15 @@ int protoverse_serve(struct protoverse_server *server) continue; } - ok = handle_packet(fd, &buf, &from, &packet); + ok = handle_packet(fd, &server->env, &buf, &from, &packet); if (!ok) { printf("handle packet failed for "); - print_packet(&packet); + print_packet(&server->env, &packet); } buf.p = buf.start; } free(buf_); + free_protoverse_server(server); } diff --git a/src/serve.h b/src/serve.h @@ -7,10 +7,12 @@ struct sockaddr_in *from, struct packet *packet); */ +#include "env.h" struct protoverse_server { const char *bind; int port; + struct env env; /* void *closure; diff --git a/src/test.c b/src/test.c @@ -21,6 +21,7 @@ static void print_mem(unsigned char *a, int len) static void test_packet_serialization(struct packet packet) { struct packet packet_out; + struct env env; int pushed[2], pulled; int i; @@ -45,15 +46,14 @@ static void test_packet_serialization(struct packet packet) assert(!memcmp(bufs[0], bufs[2], pulled)); assert(packet_eq(&packet, &packet_out)); - print_packet(&packet); + print_packet(&env, &packet); } static void test_chat_packet_serialization(void) { struct packet packet; - packet.type = PKT_CHAT; - packet.data.chat.sender = 0xFFFF; - packet.data.chat.message = "hello there"; + packet.type = PKT_MESSAGE; + packet.data.message.message = "hello there"; printf("chat packet\n"); test_packet_serialization(packet); diff --git a/src/types.h b/src/types.h @@ -0,0 +1,17 @@ + +#ifndef PROTOVERSE_TYPES_H +#define PROTOVERSE_TYPES_H + +typedef unsigned char u8; +typedef signed char s8; + +typedef unsigned short u16; +typedef signed short s16; + +typedef unsigned int u32; +typedef signed int s32; + +typedef unsigned long long u64; +typedef signed long long s64; + +#endif /* PROTOVERSE_TYPES_H */ diff --git a/src/wasm.c b/src/wasm.c @@ -62,7 +62,7 @@ static void log_dbg_(const char *fmt, ...) #define log_dbg(...) #endif -static int is_valtype(unsigned char byte) +static inline int is_valtype(unsigned char byte) { switch ((enum valtype)byte) { case i32: @@ -95,7 +95,7 @@ static int stack_pushval(struct cursor *cur, struct val *val) return push_byte(cur, (unsigned char)val->type); } -static int cursor_popbyte(struct cursor *cur, unsigned char *byte) +static inline int cursor_popbyte(struct cursor *cur, unsigned char *byte) { if (cur->p - 1 < cur->start) return 0; @@ -106,7 +106,7 @@ static int cursor_popbyte(struct cursor *cur, unsigned char *byte) return 1; } -static int cursor_popdata(struct cursor *cur, unsigned char *dest, int len) +static inline int cursor_popdata(struct cursor *cur, unsigned char *dest, int len) { if (cur->p - len < cur->start) return 0; diff --git a/todo/messages.gmi b/todo/messages.gmi @@ -0,0 +1,16 @@ + +# General verbs + +* Interact + +# Probe object verbs + +"describe" message + +* list object capabilities and messages + +## Example + +> describe lamp + +actions: switch diff --git a/todo/todo.txt b/todo/todo.txt