]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/server/server.c
Implement node breaking
[dragonblocks_alpha.git] / src / server / server.c
1 #define _GNU_SOURCE // don't worry, GNU extensions are only used when available
2 #include <dragonnet/addr.h>
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <time.h>
7 #include "interrupt.h"
8 #include "server/database.h"
9 #include "server/server.h"
10 #include "server/server_item.h"
11 #include "server/server_player.h"
12 #include "server/server_terrain.h"
13
14 DragonnetListener *server;
15
16 static bool on_recv(DragonnetPeer *peer, DragonnetTypeId type, __attribute__((unused)) void *pkt)
17 {
18         // this is recv thread, so we don't need lock_auth
19         return ((ServerPlayer *) peer->extra)->auth != (type == DRAGONNET_TYPE_ToServerAuth);
20 }
21
22 static void on_ToServerAuth(DragonnetPeer *peer, ToServerAuth *pkt)
23 {
24         if (server_player_auth(peer->extra, pkt->name))
25                 pkt->name = NULL;
26 }
27
28 static void on_ToServerInteract(DragonnetPeer *peer, ToServerInteract *pkt)
29 {
30         ServerPlayer *player = peer->extra;
31         pthread_mutex_lock(&player->mtx_inv);
32
33         ItemStack *stack = pkt->left ? &player->inventory.left : &player->inventory.right;
34         if (server_item_defs[stack->type].use)
35                 server_item_defs[stack->type].use(player, stack, pkt->pointed, pkt->pos);
36
37         pthread_mutex_unlock(&player->mtx_inv);
38 }
39
40 // update player's position
41 static void on_ToServerPosRot(DragonnetPeer *peer, ToServerPosRot *pkt)
42 {
43         server_player_move(peer->extra, pkt->pos, pkt->rot);
44 }
45
46 // tell server map manager client requested the chunk
47 static void on_ToServerRequestChunk(DragonnetPeer *peer, ToServerRequestChunk *pkt)
48 {
49         server_terrain_requested_chunk(peer->extra, pkt->pos);
50 }
51
52 // server entry point
53 int main(int argc, char **argv)
54 {
55 #ifdef __GLIBC__ // check whether bloat is enabled
56         pthread_setname_np(pthread_self(), "main");
57 #endif // __GLIBC__
58
59         if (argc < 2) {
60                 fprintf(stderr, "[error] missing address\n");
61                 return EXIT_FAILURE;
62         }
63
64         if (!(server = dragonnet_listener_new(argv[1]))) {
65                 fprintf(stderr, "[error] failed to listen to connections\n");
66                 return EXIT_FAILURE;
67         }
68
69         printf("[info] listening on %s\n", server->address);
70
71         server->on_connect = &server_player_add;
72         server->on_disconnect = &server_player_remove;
73         server->on_recv = &on_recv;
74         server->on_recv_type[DRAGONNET_TYPE_ToServerAuth        ] = (void *) &on_ToServerAuth;
75         server->on_recv_type[DRAGONNET_TYPE_ToServerInteract    ] = (void *) &on_ToServerInteract;
76         server->on_recv_type[DRAGONNET_TYPE_ToServerPosRot      ] = (void *) &on_ToServerPosRot;
77         server->on_recv_type[DRAGONNET_TYPE_ToServerRequestChunk] = (void *) &on_ToServerRequestChunk;
78
79         srand(time(0));
80
81         interrupt_init();
82         if (!database_init())
83                 return EXIT_FAILURE;
84         server_terrain_init();
85         server_player_init();
86
87         server_terrain_prepare_spawn();
88         dragonnet_listener_run(server);
89
90         flag_slp(&interrupt);
91
92         printf("[info] shutting down\n");
93         dragonnet_listener_close(server);
94
95         server_player_deinit();
96         server_terrain_deinit();
97         database_deinit();
98         interrupt_deinit();
99
100         dragonnet_listener_delete(server);
101
102         return EXIT_SUCCESS;
103 }