diff options
| -rw-r--r-- | assets/board.js | 6 | ||||
| -rw-r--r-- | assets/pieces/bb.webp (renamed from assets/bb.webp) | bin | 538 -> 538 bytes | |||
| -rw-r--r-- | assets/pieces/bk.webp (renamed from assets/bk.webp) | bin | 1028 -> 1028 bytes | |||
| -rw-r--r-- | assets/pieces/bn.webp (renamed from assets/bn.webp) | bin | 740 -> 740 bytes | |||
| -rw-r--r-- | assets/pieces/bp.png (renamed from assets/bp.png) | bin | 692 -> 692 bytes | |||
| -rw-r--r-- | assets/pieces/bq.png (renamed from assets/bq.png) | bin | 1563 -> 1563 bytes | |||
| -rw-r--r-- | assets/pieces/br.webp (renamed from assets/br.webp) | bin | 274 -> 274 bytes | |||
| -rw-r--r-- | assets/pieces/wb.webp (renamed from assets/wb.webp) | bin | 834 -> 834 bytes | |||
| -rw-r--r-- | assets/pieces/wk.webp (renamed from assets/wk.webp) | bin | 946 -> 946 bytes | |||
| -rw-r--r-- | assets/pieces/wn.png (renamed from assets/wn.png) | bin | 1263 -> 1263 bytes | |||
| -rw-r--r-- | assets/pieces/wp.png (renamed from assets/wp.png) | bin | 898 -> 898 bytes | |||
| -rw-r--r-- | assets/pieces/wq.webp (renamed from assets/wq.webp) | bin | 1388 -> 1388 bytes | |||
| -rw-r--r-- | assets/pieces/wr.png (renamed from assets/wr.png) | bin | 748 -> 748 bytes | |||
| -rw-r--r-- | build.c | 53 | ||||
| -rw-r--r-- | shell.nix | 10 | ||||
| -rw-r--r-- | src/server.c | 151 |
16 files changed, 210 insertions, 10 deletions
diff --git a/assets/board.js b/assets/board.js index fdfeb28..6e20344 100644 --- a/assets/board.js +++ b/assets/board.js @@ -11,7 +11,7 @@ const assets = [ "bb.webp", "bn.webp", "bp.png" -].map(x => "./assets/" + x); +].map(x => "./assets/pieces/" + x); let hoveringPiece = -1; const bitboards = [ @@ -112,8 +112,8 @@ function addMoves(moves) { window.onload = () => { const socket = new WebSocket("ws://localhost:3456"); - socket.addEventListener("moves", (event) => addMoves(event.data)); - // socket.addEventListener("do_move", (event) => addMoves(event.data)); + socket.onmessage = e => console.log(e.data); + socket.onopen = () => socket.send("hello"); const output = document.getElementById("output"); const board = document.getElementById("board"); diff --git a/assets/bb.webp b/assets/pieces/bb.webp Binary files differindex f780b4d..f780b4d 100644 --- a/assets/bb.webp +++ b/assets/pieces/bb.webp diff --git a/assets/bk.webp b/assets/pieces/bk.webp Binary files differindex 23d2e3b..23d2e3b 100644 --- a/assets/bk.webp +++ b/assets/pieces/bk.webp diff --git a/assets/bn.webp b/assets/pieces/bn.webp Binary files differindex 68a6d63..68a6d63 100644 --- a/assets/bn.webp +++ b/assets/pieces/bn.webp diff --git a/assets/bp.png b/assets/pieces/bp.png Binary files differindex fa57435..fa57435 100644 --- a/assets/bp.png +++ b/assets/pieces/bp.png diff --git a/assets/bq.png b/assets/pieces/bq.png Binary files differindex 6334dd4..6334dd4 100644 --- a/assets/bq.png +++ b/assets/pieces/bq.png diff --git a/assets/br.webp b/assets/pieces/br.webp Binary files differindex 8d078e1..8d078e1 100644 --- a/assets/br.webp +++ b/assets/pieces/br.webp diff --git a/assets/wb.webp b/assets/pieces/wb.webp Binary files differindex 5020e5e..5020e5e 100644 --- a/assets/wb.webp +++ b/assets/pieces/wb.webp diff --git a/assets/wk.webp b/assets/pieces/wk.webp Binary files differindex 72fdcf7..72fdcf7 100644 --- a/assets/wk.webp +++ b/assets/pieces/wk.webp diff --git a/assets/wn.png b/assets/pieces/wn.png Binary files differindex a03ccac..a03ccac 100644 --- a/assets/wn.png +++ b/assets/pieces/wn.png diff --git a/assets/wp.png b/assets/pieces/wp.png Binary files differindex d968278..d968278 100644 --- a/assets/wp.png +++ b/assets/pieces/wp.png diff --git a/assets/wq.webp b/assets/pieces/wq.webp Binary files differindex bfbd57a..bfbd57a 100644 --- a/assets/wq.webp +++ b/assets/pieces/wq.webp diff --git a/assets/wr.png b/assets/pieces/wr.png Binary files differindex 69811d8..69811d8 100644 --- a/assets/wr.png +++ b/assets/pieces/wr.png @@ -6,6 +6,14 @@ #include <time.h> #include <string.h> +void print_cmd(char** args) { + int i = 0; + while (args[i] != NULL) { + printf("%s ", args[i++]); + } + printf("\n"); +} + // https://github.com/tsoding/nob.h/blob/0a08926d8094fc4ae678155c5d73ae21d1f96f3f/nob.h#L2413 int needs_rebuild(char* bin_file, char* source_file) { struct stat statbuf = {0}; @@ -28,26 +36,39 @@ int main(int argc, char** argv) { if (needs_rebuild(argv[0], __FILE__)) { if (fork() == 0) { char* args[] = {"gcc", __FILE__, "-o", argv[0], NULL}; + print_cmd(args); execvp(args[0], args); return 0; } else { wait(NULL); + print_cmd(argv); execvp(argv[0], argv); } } + if (fork() == 0) { + char* args[] = {"mkdir", "-p", "output", NULL}; + print_cmd(args); + execvp(args[0], args); + return 0; + } else { + wait(NULL); + } + if (argc > 1) { if (strcmp(argv[1], "test") == 0) { printf("Test mode\n"); if (fork() == 0) { - char* args[] = {"gcc", "generate/find_tests.c", "-o", "find_tests.o", NULL}; + char* args[] = {"gcc", "generate/find_tests.c", "-o", "output/find_tests.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } else { wait(NULL); } if (fork() == 0) { - char* args[] = {"./find_tests.o", NULL}; + char* args[] = {"./output/find_tests.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } else { @@ -55,28 +76,48 @@ int main(int argc, char** argv) { } printf("\n"); if (fork() == 0) { - char* args[] = {"gcc", "tests/main.c", "-o", "test.o", NULL}; + char* args[] = {"gcc", "tests/main.c", "-o", "output/test.o", NULL}; + print_cmd(args); + execvp(args[0], args); + return 0; + } else { + wait(NULL); + } + + char* args[] = {"./output/test.o", NULL}; + print_cmd(args); + execvp(args[0], args); + return 0; + } + if (strcmp(argv[1], "server") == 0) { + printf("Server mode\n"); + if (fork() == 0) { + char* args[] = {"gcc", "src/server.c", "-lcrypto", "-o", "output/server.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } else { wait(NULL); } - char* args[] = {"./test.o", NULL}; + char* args[] = {"./output/server.o", "./output/main.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } } if (fork() == 0) { - char* args[] = {"gcc", "src/main.c", "-o", "main.o", NULL}; + char* args[] = {"gcc", "src/main.c", "-o", "output/main.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } else { wait(NULL); } - char* args[] = {"./main.o", NULL}; + char* args[] = {"./output/main.o", NULL}; + print_cmd(args); execvp(args[0], args); return 0; } diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..9d0bdbb --- /dev/null +++ b/shell.nix @@ -0,0 +1,10 @@ +{ pkgs ? import <nixpkgs> {} }: + +pkgs.mkShell { + packages = with pkgs; [ + gcc + openssl + pkg-config + gnumake + ]; +} diff --git a/src/server.c b/src/server.c index 8409611..8de6d01 100644 --- a/src/server.c +++ b/src/server.c @@ -1,5 +1,154 @@ +#include <arpa/inet.h> +#include <netinet/in.h> +#include <openssl/sha.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <unistd.h> +#define PORT 3456 -int main() { +static const char *GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; +static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; +void base64_encode( + const unsigned char *in, + size_t len, + char *out +) { + size_t i, j = 0; + + for (i = 0; i < len; i += 3) { + unsigned v = in[i] << 16; + + if (i + 1 < len) v |= in[i + 1] << 8; + if (i + 2 < len) v |= in[i + 2]; + + out[j++] = b64[(v >> 18) & 63]; + out[j++] = b64[(v >> 12) & 63]; + + out[j++] = (i + 1 < len) ? b64[(v >> 6) & 63] : '='; + out[j++] = (i + 2 < len) ? b64[v & 63] : '='; + } + + out[j] = 0; +} + +void websocket_accept_key(const char *client_key, char *output) { + char buf[256]; + snprintf(buf, sizeof(buf), "%s%s", client_key, GUID); + + unsigned char hash[SHA_DIGEST_LENGTH]; + SHA1((unsigned char *)buf, strlen(buf), hash); + base64_encode(hash, SHA_DIGEST_LENGTH, output); +} + +char *find_websocket_key(char *req) { + char *p = strstr(req, "Sec-WebSocket-Key:"); + + if (!p) return NULL; + + p += strlen("Sec-WebSocket-Key:"); + + while (*p == ' ') p++; + + static char key[128]; + int i = 0; + while (*p && *p != '\r' && *p != '\n') + key[i++] = *p++; + + key[i] = 0; + return key; +} + +int main(void) { + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + int opt = 1; + + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = INADDR_ANY, + .sin_port = htons(PORT) + }; + + bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)); + listen(server_fd, 16); + printf("Listening on %d\n", PORT); + + for (;;) { + int client = accept(server_fd, NULL, NULL); + + if (client < 0) continue; + char req[4096]; + + int n = recv(client, req, sizeof(req) - 1, 0); + if (n <= 0) { + close(client); + continue; + } + + req[n] = 0; + + char *key = find_websocket_key(req); + + if (!key) { + close(client); + continue; + } + + char accept_key[128]; + + websocket_accept_key(key, accept_key); + char response[512]; + + snprintf( + response, + sizeof(response), + "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: %s\r\n" + "\r\n", + accept_key + ); + + send(client, response, strlen(response), 0); + printf("WebSocket connected\n"); + + for (;;) { + unsigned char hdr[2]; + + if (recv(client, hdr, 2, MSG_WAITALL) != 2) + break; + + unsigned opcode = hdr[0] & 0x0F; + unsigned len = hdr[1] & 0x7F; + if (opcode == 0x8) break; + if (len >= 126) break; + + unsigned char mask[4]; + recv(client, mask, 4, MSG_WAITALL); + + unsigned char payload[126]; + recv(client, payload, len, MSG_WAITALL); + + for (unsigned i = 0; i < len; i++) + payload[i] ^= mask[i % 4]; + + printf("Message: %.*s\n", len, payload); + + unsigned char out[128]; + out[0] = 0x81; + out[1] = len; + + memcpy(out + 2, payload, len); + send(client, out, len + 2, 0); + } + close(client); + } } |
