]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Fix client disconnect threading problems
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 23 Mar 2021 19:28:32 +0000 (20:28 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 23 Mar 2021 19:28:32 +0000 (20:28 +0100)
client.c
linkedlist.c
map.c
network.c
servercommands.c
servercommands.h

index 91401bb9a70a86640a5b3b6cf5aa9ae519953ec4..5bce71841f19b64da3c6ef808f46958d6c4718b2 100644 (file)
--- a/client.c
+++ b/client.c
 
 void client_disconnect(Client *client, bool send, const char *detail)
 {
-       client->state = CS_DISCONNECTED;
-
-       if (send)
-               send_command(client, SC_DISCONNECT);
-
        pthread_mutex_lock(&client->mtx);
-       close(client->fd);
-       pthread_mutex_unlock(&client->mtx);
+       if (client->state != CS_DISCONNECTED) {
+               if (send)
+                       write_u32(client->fd, SC_DISCONNECT);
 
-       printf("Disconnected %s%s%s\n", INBRACES(detail));
+               client->state = CS_DISCONNECTED;
+               printf("Disconnected %s%s%s\n", INBRACES(detail));
+               close(client->fd);
+       }
+       pthread_mutex_unlock(&client->mtx);
 }
 
 static void *reciever_thread(void *cliptr)
@@ -30,12 +30,10 @@ static void *reciever_thread(void *cliptr)
 
        handle_packets(client);
 
-       if (client->state != CS_DISCONNECTED) {
-               if (errno == EINTR)
-                       client_disconnect(client, true, NULL);
-               else
-                       client_disconnect(client, false, "network error");
-       }
+       if (errno == EINTR)
+               client_disconnect(client, true, NULL);
+       else
+               client_disconnect(client, false, "network error");
 
        if (client->name)
                free(client->name);
@@ -127,6 +125,14 @@ static void client_loop(Client *client)
                                                break;
                                }
                                printf("%s\n", nodename);
+                       } else if (strcmp(buffer, "kick") == 0) {
+                               char target_name[NAME_MAX];
+                               if (scanf("%s", target_name) == EOF)
+                                       return;
+                               pthread_mutex_lock(&client->mtx);
+                               if (write_u32(client->fd, SC_KICK))
+                                       write(client->fd, target_name, strlen(target_name) + 1);
+                               pthread_mutex_unlock(&client->mtx);
                        } else {
                                printf("Invalid command: %s\n", buffer);
                        }
@@ -179,10 +185,8 @@ int main(int argc, char **argv)
        pthread_create(&recv_thread, NULL, &reciever_thread, &client);
 
        client_loop(&client);
-       perror("client_loop");
 
-       if (client.state != CS_DISCONNECTED)
-               client_disconnect(&client, true, NULL);
+       client_disconnect(&client, true, NULL);
 
        pthread_join(recv_thread, NULL);
 }
index b762ed5040331b48ca69077f2ff8314b7b8b3d78..5618c6559b69151286151a10a8ddfe930c537197 100644 (file)
@@ -58,3 +58,11 @@ void linked_list_delete(LinkedList *list, const char *key)
                }
        }
 }
+
+void *linked_list_get(LinkedList *list, const char *key)
+{
+       for (LinkedListPair *pair = list->first; pair != NULL; pair = pair->next)
+               if (strcmp(pair->key, key) == 0)
+                       return pair->value;
+       return NULL;
+}
diff --git a/map.c b/map.c
index 27afd0f9c820682d34833146ec837c24f889ee60..d85455c1d89ee8b9ba1da063e492aaa3cc4f6b67 100644 (file)
--- a/map.c
+++ b/map.c
@@ -123,14 +123,11 @@ bool map_deserialize_block(int fd, Map *map)
        return true;
 }
 
-#include <stdio.h>
-
 
 v3s32 map_node_to_block_pos(v3s32 pos, v3u8 *offset)
 {
        if (offset)
                *offset = (v3u8) {(u32) pos.x % 16, (u32) pos.y % 16, (u32) pos.z % 16};
-       printf("%d %d %d [ %d %d %d ]\n", pos.x, pos.y, pos.z, offset ? offset->x : 0, offset ? offset->y : 0, offset ? offset->z : 0);
        return (v3s32) {floor((double) pos.x / 16), floor((double) pos.y / 16), floor((double) pos.z / 16)};
 }
 
index 801e1c556a47ed5ef71899c06f733f6d973ab805..27bc5ed591dd3dc3c7c7abc771306a6d680d3655 100644 (file)
--- a/network.c
+++ b/network.c
@@ -1,3 +1,5 @@
+#include <poll.h>
+
 bool send_command(Client *client, RemoteCommand cmd)
 {
        pthread_mutex_lock(&client->mtx);
@@ -8,6 +10,28 @@ bool send_command(Client *client, RemoteCommand cmd)
 
 static void handle_packets(Client *client) {
        while (client->state != CS_DISCONNECTED) {
+               struct pollfd pfd = {
+                       .fd = client->fd,
+                       .events = POLLIN,
+                       .revents = 0,
+               };
+
+               int pstate = poll(&pfd, 1, 0);
+
+               if (pstate == -1) {
+                       perror("poll");
+                       return;
+               }
+
+               if (client->state == CS_DISCONNECTED)
+                       return;
+
+               if (pstate == 0)
+                       continue;
+
+               if (! (pfd.revents & POLLIN))
+                       return;
+
                HostCommand command;
                if (! read_u32(client->fd, &command))
                        return;
@@ -24,7 +48,7 @@ static void handle_packets(Client *client) {
                        if (! handler->func(client, good))
                                return;
                } else {
-                       printf("Recieved invalid command %d (max = %d)\n", command, HOST_COMMAND_COUNT);
+                       printf("Recieved invalid command %d\n", command);
                }
        }
 }
index 1703c3c841ecea4207ae47c9f6270b08584c3d6d..89742db0ba9712415d4b32899e918cbcc6ec1fec 100644 (file)
@@ -52,8 +52,6 @@ static bool getblock_handler(Client *client, bool good)
 
        MapBlock *block = map_get_block(client->server->map, pos, false);
        if (block) {
-               printf("Sending block %d %d %d\n", pos.x, pos.y, pos.z);
-
                pthread_mutex_lock(&client->mtx);
                bool ret = write_u32(client->fd, CC_BLOCK) && map_serialize_block(client->fd, block);
                pthread_mutex_unlock(&client->mtx);
@@ -82,10 +80,28 @@ static bool setnode_handler(Client *client, bool good)
        return true;
 }
 
+static bool kick_handler(Client *client, bool good)
+{
+       char *target_name = read_string(client->fd, NAME_MAX);
+
+       if (! target_name)
+               return false;
+
+       if (good) {
+               Client *target = linked_list_get(&client->server->clients, target_name);
+               if (target)
+                       server_disconnect_client(target, 0, "kicked");
+       }
+
+       free(target_name);
+       return true;
+}
+
 CommandHandler command_handlers[SERVER_COMMAND_COUNT] = {
        {0},
        {&disconnect_handler, "DISCONNECT", CS_CREATED | CS_ACTIVE},
        {&auth_handler, "AUTH", CS_CREATED},
        {&getblock_handler, "GETBLOCK", CS_ACTIVE},
        {&setnode_handler, "SETNODE", CS_ACTIVE},
+       {&kick_handler, "KICK", CS_ACTIVE},
 };
index cede0017fce2ded895a023d8eddb00c1dc385bfc..4e306fa06bb0c0c498b8eeca78fdc9fd0817285b 100644 (file)
@@ -8,6 +8,7 @@ typedef enum
        SC_AUTH,
        SC_GETBLOCK,
        SC_SETNODE,
+       SC_KICK,
        SERVER_COMMAND_COUNT,
 } ServerCommand;