aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/apps/helloworld
diff options
context:
space:
mode:
Diffstat (limited to 'client/libacron/apps/helloworld')
-rw-r--r--client/libacron/apps/helloworld/main.c370
-rw-r--r--client/libacron/apps/helloworld/net.c181
-rw-r--r--client/libacron/apps/helloworld/net.h45
3 files changed, 0 insertions, 596 deletions
diff --git a/client/libacron/apps/helloworld/main.c b/client/libacron/apps/helloworld/main.c
deleted file mode 100644
index c112fcb..0000000
--- a/client/libacron/apps/helloworld/main.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Created by yuuta on 7/20/22.
- */
-
-#include "libac.h"
-#include "net.h"
-
-#include <stdio.h>
-
-#ifndef WIN32
-
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-
-#endif
-
-#ifdef __STDC_NO_THREADS__
-# ifdef WIN32
-#define THREAD_WIN32
-#include <windows.h>
-static HANDLE mtx_conn;
-
-int lock(void) { \
-DWORD _dwlck = WaitForSingleObject(mtx_conn, 0); \
-if (_dwlck == WAIT_FAILED) { _dwlck = GetLastError(); } \
-if (_dwlck) { fprintf(stderr, "Cannot lock the mutex: %d.\n", _dwlck); return _dwlck; } \
-return 0; \
-}
-
-int unlock(void) { \
-if (!ReleaseMutex(mtx_conn)) { \
-int r = GetLastError(); \
-fprintf(stderr, "Cannot release the mutex: %d.\n", r); \
-return r; \
-} \
-return 0; \
-}
-
-# else
-#error "Either C11 threading or Win32 API is required for concurrency."
-# endif
-#else
-
-#define THREAD_C11
-
-#include <threads.h>
-
-static mtx_t mtx_conn;
-
-int lock(void) {
- \
-if (mtx_lock(&mtx_conn) != thrd_success) {
- \
-fprintf(stderr, "Cannot lock the mutex.\n"); \
-return 1; \
-
- } \
-return 0; \
-
-}
-
-int unlock(void) {
- \
-if (mtx_unlock(&mtx_conn) != thrd_success) {
- \
-fprintf(stderr, "Cannot release the mutex.\n"); \
-return 1; \
-
- } \
-return 0; \
-
-}
-
-#endif
-
-static const char *world_name(const enum ac_world world) {
- switch (world) {
- case overworld:
- return "overworld";
- case nether:
- return "nether";
- case end:
- return "end";
- default:
- return "unknown world";
- }
-}
-
-static void handle_event(const ac_event_t *event) {
- switch (event->type) {
- case AC_EVENT_LAGGING: {
- ac_event_lagging_t *o = (ac_event_lagging_t *) event;
- printf("Server lagging: running %ld milliseconds (%ld ticks) behind.\n",
- o->ms,
- o->ticks);
- break;
- }
- case AC_EVENT_ENTITY_DEATH: {
- ac_event_entity_death_t *o = (ac_event_entity_death_t *) event;
- printf("Entity '%s' died at %s(%.2f, %.2f, %.2f): %s.\n",
- o->entity.name,
- world_name(o->entity.world),
- o->entity.pos.x,
- o->entity.pos.y,
- o->entity.pos.z,
- o->message);
- break;
- }
- case AC_EVENT_PLAYER_MESSAGE: {
- ac_event_player_message_t *o = (ac_event_player_message_t *) event;
- printf("Player '%s' said at %s(%.2f, %.2f, %.2f): %s.\n",
- o->player.name,
- world_name(o->player.world),
- o->player.pos.x,
- o->player.pos.y,
- o->player.pos.z,
- o->text);
- break;
- }
- case AC_EVENT_PLAYER_DISCONNECT: {
- ac_event_player_disconnect_t *o = (ac_event_player_disconnect_t *) event;
- printf("Player '%s' disconnected at %s(%.2f, %.2f, %.2f): %s.\n",
- o->player.name,
- world_name(o->player.world),
- o->player.pos.x,
- o->player.pos.y,
- o->player.pos.z,
- o->reason);
- break;
- }
- case AC_EVENT_PLAYER_JOIN: {
- ac_event_player_join_t *o = (ac_event_player_join_t *) event;
- printf("Player '%s' joined at %s(%.2f, %.2f, %.2f).\n",
- o->player.name,
- world_name(o->player.world),
- o->player.pos.x,
- o->player.pos.y,
- o->player.pos.z);
- break;
- }
- default: {
- printf("Received an unrecognized event of type '%u'.\n",
- event->type);
- }
- }
-}
-
-static void handle_response(const ac_response_t *response) {
- switch (response->type) {
- case AC_RESPONSE_OK: {
- ac_response_ok_t *o = (ac_response_ok_t *) response;
- printf("Request %d OK.\n",
- o->id);
- break;
- }
- case AC_RESPONSE_ERROR: {
- ac_response_error_t *o = (ac_response_error_t *) response;
- printf("Request %d failed: %s (%d).\n",
- o->id,
- o->message,
- o->code);
- break;
- }
- case AC_RESPONSE_CMD_OUT: {
- ac_response_cmd_out_t *o = (ac_response_cmd_out_t *) response;
- printf("Request %d output by %s: %s.\n",
- o->id,
- o->sender,
- o->out);
- break;
- }
- case AC_RESPONSE_CMD_RESULT: {
- ac_response_cmd_result_t *o = (ac_response_cmd_result_t *) response;
- printf("Request %d is done: %s (%d).\n",
- o->id,
- o->success ? "Success" : "Failed",
- o->result);
- break;
- }
- default: {
- printf("Received an unrecognized response of type '%u'.\n",
- response->type);
- }
- }
-}
-
-#ifndef WIN32
-
-static void intr(int signum) {}
-
-#endif
-
-static int on_send(const void *sock,
- const void *buffer,
- const size_t len) {
- int r;
- printf("Writing %lu bytes.\n", len);
- if ((r = net_send(sock, buffer, len))) {
- fprintf(stderr, "Cannot write %lu bytes to server: %s (%d).\n",
- len,
- net_strerror(r),
- r);
- }
- return r;
-}
-
-static int say(void *connection) {
- int r;
- ac_config_t conf = {
- .name = "helloworld"
- };
- ac_request_cmd_t req = {
- .type = AC_REQUEST_CMD,
- .id = 100,
- .config = &conf,
- .cmd = "say Hi"
- };
- if ((r = ac_request(connection, (ac_request_t *) &req))) {
- return r;
- }
- return 0;
-}
-
-int main(int argc, char **argv) {
- int r;
- if ((r = net_init())) {
- return r;
- }
-#if defined(THREAD_WIN32)
- if (!(mtx_conn = CreateMutex(NULL, TRUE, NULL))) {
- r = GetLastError();
- fprintf(stderr, "Cannot create mutex: %d.\n", r);
- return r;
- }
-#elif defined(THREAD_C11)
- if (mtx_init(&mtx_conn, mtx_plain) != thrd_success) {
- fprintf(stderr, "Cannot create mutex.\n");
- return 1;
- }
-#endif
-
-#ifdef WIN32
- fprintf(stderr, "Warning: ^C handler on Windows is not yet available.\n");
-#else
- struct sigaction sa;
- sa.sa_handler = intr;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGINT, &sa, NULL) ||
- sigaction(SIGTERM, &sa, NULL)) {
- const int e = errno;
- fprintf(stderr, "Cannot set SIGINT or SIGTERM handlers: %s (%d).\n",
- strerror(e),
- e);
- return e;
- }
-#endif
- libac_config_t config = {
-#ifdef DEBUG
- .out = stderr,
-#else
- .out = NULL,
-#endif
- .tok = NULL
- };
- if ((r = ac_init(&config))) return r;
- void *connection;
- SOCKET sock;
- ac_connection_parameters_t parameters = {
- .host = "localhost",
- .port = 25575,
- .id = "1",
- .token = "123",
- .version = 0,
- .sock = NULL,
- .on_send = on_send
- };
- if ((r = net_connect(parameters.host, parameters.port, &sock))) {
- fprintf(stderr, "Cannot connect to server: %s (%d).\n",
- net_strerror(r),
- r);
- ac_free();
- net_free();
- return r;
- }
- parameters.sock = &sock;
- if ((r = ac_connect(parameters, &connection))) {
- net_close(&sock);
- ac_free();
- net_free();
- return r;
- }
- ac_obj_t *obj;
- int nr;
- uint8_t buffer[1000U];
- size_t bytes;
- enum ac_connection_state state;
- printf("Waiting until the connection is established.\n");
- bool ready = false;
- while (1) {
- if ((nr = net_read(&sock, buffer, sizeof(buffer), &bytes, 10))) {
- if (nr == NET_TIMEOUT) {
- printf("Receive timeout.\n");
- continue;
- } else {
- goto end;
- }
- }
- if ((r = lock())) { goto end; }
- if ((r = ac_receive(connection, buffer, bytes, &obj))) {
- if ((r = unlock())) { goto end; }
- goto end;
- }
- if (!ready) {
- /* Wait until ready. */
- if ((r = ac_get_state(connection, &state))) {
- if ((r = unlock())) { goto end; }
- goto end;
- }
- switch (state) {
- case AC_STATE_INIT:
- continue;
- case AC_STATE_READY:
- printf("Connection is established.\n");
- ready = true;
- say(connection);
- if ((r = unlock())) { goto end; }
- continue;
- default:
- fprintf(stderr, "Unexpected state.\n");
- if ((r = unlock())) { goto end; }
- goto end;
- }
- }
- if ((r = unlock())) { goto end; }
-
- if (!obj) {
- continue;
- }
- if (AC_IS_EVENT(obj->type)) {
- handle_event((ac_event_t *) obj);
- } else if (AC_IS_RESPONSE(obj->type)) {
- handle_response((ac_response_t *) obj);
- }
- ac_object_free(obj);
- }
- end:
- if (nr) {
- if (nr == NET_CLOSED) {
- fprintf(stderr, "Connection is closed while reading from the server.\n");
- } else {
- fprintf(stderr, "Cannot receive from server: %s (%d).\n",
- net_strerror(nr),
- nr);
- }
- }
- if ((r = lock())) { goto end; }
- ac_disconnect(connection, false);
- if ((r = unlock())) { goto end; }
- net_close(&sock);
- ac_free();
- net_free();
-#if defined(THREAD_WIN32)
- CloseHandle(mtx_conn);
-#elif defined(THREAD_C11)
- mtx_destroy(&mtx_conn);
-#endif
- return r;
-} \ No newline at end of file
diff --git a/client/libacron/apps/helloworld/net.c b/client/libacron/apps/helloworld/net.c
deleted file mode 100644
index 83192e0..0000000
--- a/client/libacron/apps/helloworld/net.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Created by yuuta on 7/22/22.
- *
- * A simple cross-platform (Unix and Windows) implementation of a socket client.
- */
-
-#include "net.h"
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef WIN32
-#include <windows.h> /* For DWORD */
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#define errno_sock WSAGetLastError()
-
-#else
-
-#include <sys/socket.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#define closesocket(socket) close(socket)
-#define errno_sock errno
-
-#endif
-
-int net_connect(const char *host,
- const uint16_t port,
- SOCKET *sock) {
- int r;
- struct addrinfo *res;
- char service[6];
-
- snprintf(service, 6, "%u", port);
- if ((r = getaddrinfo(host, service, NULL, &res))) {
- return r;
- }
-
- SOCKET fd;
- if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) <= 0) {
- const int e = errno_sock;
- freeaddrinfo(res);
- return e;
- }
- if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
- const int e = errno_sock;
- closesocket(fd);
- freeaddrinfo(res);
- return e;
- }
- freeaddrinfo(res);
- *sock = fd;
- return 0;
-}
-
-int net_read(const SOCKET *sock,
- void *buffer,
- const size_t length,
- size_t *read,
- const unsigned int timeout) {
-
-#ifdef WIN32
- DWORD to = timeout * 1000;
- if (setsockopt(*sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&to, sizeof to)) {
-#else
- struct timeval tv;
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- if (setsockopt(*sock, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv, sizeof tv)) {
-#endif
- return errno_sock;
- }
-
- int bytes;
- if ((bytes = (int) recv(*sock, buffer, length, 0)) <= 0) {
- if (bytes < 0) {
- const int e = errno_sock;
-#ifdef WIN32
- if (e == WSAETIMEDOUT) {
-#else
- if (e == EAGAIN) {
-#endif
- return NET_TIMEOUT;
- }
- return e;
- }
- return NET_CLOSED;
- }
- *read = bytes;
- return 0;
-}
-
-int net_send(const SOCKET *sock,
- const void *buffer,
- size_t len) {
- size_t pos;
- const uint8_t *ptr = buffer;
- int retval;
-
- for (pos = 0U; pos < len; pos += retval) {
- size_t n = len - pos;
- retval = (int) send(*sock, &ptr[pos], (int) n, 0);
- if (retval <= 0) {
- return errno_sock;
- }
- }
- return 0;
-}
-
-int net_init(void) {
-#ifdef WIN32
- int r;
- WORD wVersionRequested;
- WSADATA wsaData;
- wVersionRequested = MAKEWORD(2, 2);
- if ((r = WSAStartup(wVersionRequested, &wsaData))) {
- fprintf(stderr, "WSAStartup failed with error: %d\n", r);
- return r;
- }
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
- fprintf(stderr, "Could not find a usable version of Winsock.dll\n");
- WSACleanup();
- return 1;
- }
-#endif
- return 0;
-}
-
-void net_close(const SOCKET *sock) {
- closesocket(*sock);
-}
-
-#ifdef WIN32
-static __declspec( thread ) LPTSTR err_buf = NULL;
-#else
-static _Thread_local char err_buf[1024];
-#endif
-
-void net_free(void) {
-#ifdef WIN32
- WSACleanup();
- if (err_buf) {
- LocalFree(err_buf);
- err_buf = NULL;
- }
-#endif
-}
-
-char *net_strerror(int errnum) {
-#ifdef WIN32
- if (err_buf) {
- LocalFree(err_buf);
- err_buf = NULL;
- }
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- errnum,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &err_buf,
- 0,
- NULL);
- if (!err_buf) {
- return "Unknown error";
- }
-#else
- int r;
- if ((r = strerror_r(errnum, err_buf, sizeof(err_buf) / sizeof(char)))) {
- snprintf(err_buf, 1024, "%d (%d)", errnum, r);
- }
-#endif
- return err_buf;
-} \ No newline at end of file
diff --git a/client/libacron/apps/helloworld/net.h b/client/libacron/apps/helloworld/net.h
deleted file mode 100644
index 1a49709..0000000
--- a/client/libacron/apps/helloworld/net.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Created by yuuta on 7/23/22.
- */
-
-#ifndef ACRONC_NET_H
-#define ACRONC_NET_H
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef WIN32
-#include <winsock2.h>
-
-#else
-
-#define SOCKET int
-
-#endif
-
-#define NET_CLOSED -2
-#define NET_TIMEOUT -1
-
-int net_connect(const char *host,
- uint16_t port,
- SOCKET *sock);
-
-int net_read(const SOCKET *sock,
- void *buffer,
- size_t length,
- size_t *read,
- unsigned int timeout);
-
-int net_send(const SOCKET *sock,
- const void *buffer,
- size_t len);
-
-void net_close(const SOCKET *sock);
-
-int net_init(void);
-
-void net_free(void);
-
-char *net_strerror(int errnum);
-
-#endif /* ACRONC_NET_H */