]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/server/server.c
Add items
[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_player.h"
11 #include "server/server_terrain.h"
12
13 DragonnetListener *server;
14
15 static bool on_recv(DragonnetPeer *peer, DragonnetTypeId type, __attribute__((unused)) void *pkt)
16 {
17         // this is recv thread, so we don't need lock_auth
18         return ((ServerPlayer *) peer->extra)->auth != (type == DRAGONNET_TYPE_ToServerAuth);
19 }
20
21 static void on_ToServerAuth(DragonnetPeer *peer, ToServerAuth *pkt)
22 {
23         if (server_player_auth(peer->extra, pkt->name))
24                 pkt->name = NULL;
25 }
26
27 // set a node on the map
28 static void on_ToServerSetnode(__attribute__((unused)) DragonnetPeer *peer, ToServerSetnode *pkt)
29 {
30         terrain_set_node(server_terrain, pkt->pos,
31                 terrain_node_create(pkt->node, (Blob) {0, NULL}),
32                 false, NULL);
33 }
34
35 // update player's position
36 static void on_ToServerPosRot(DragonnetPeer *peer, ToServerPosRot *pkt)
37 {
38         server_player_move(peer->extra, pkt->pos, pkt->rot);
39 }
40
41 // tell server map manager client requested the chunk
42 static void on_ToServerRequestChunk(DragonnetPeer *peer, ToServerRequestChunk *pkt)
43 {
44         server_terrain_requested_chunk(peer->extra, pkt->pos);
45 }
46
47 // server entry point
48 int main(int argc, char **argv)
49 {
50 #ifdef __GLIBC__ // check whether bloat is enabled
51         pthread_setname_np(pthread_self(), "main");
52 #endif // __GLIBC__
53
54         if (argc < 2) {
55                 fprintf(stderr, "[error] missing address\n");
56                 return EXIT_FAILURE;
57         }
58
59         if (!(server = dragonnet_listener_new(argv[1]))) {
60                 fprintf(stderr, "[error] failed to listen to connections\n");
61                 return EXIT_FAILURE;
62         }
63
64         printf("[info] listening on %s\n", server->address);
65
66         server->on_connect = &server_player_add;
67         server->on_disconnect = &server_player_remove;
68         server->on_recv = &on_recv;
69         server->on_recv_type[DRAGONNET_TYPE_ToServerAuth        ] = (void *) &on_ToServerAuth;
70         server->on_recv_type[DRAGONNET_TYPE_ToServerSetnode     ] = (void *) &on_ToServerSetnode;
71         server->on_recv_type[DRAGONNET_TYPE_ToServerPosRot      ] = (void *) &on_ToServerPosRot;
72         server->on_recv_type[DRAGONNET_TYPE_ToServerRequestChunk] = (void *) &on_ToServerRequestChunk;
73
74         srand(time(0));
75
76         interrupt_init();
77         if (!database_init())
78                 return EXIT_FAILURE;
79         server_terrain_init();
80         server_player_init();
81
82         server_terrain_prepare_spawn();
83         dragonnet_listener_run(server);
84
85         flag_slp(&interrupt);
86
87         printf("[info] shutting down\n");
88         dragonnet_listener_close(server);
89
90         server_player_deinit();
91         server_terrain_deinit();
92         database_deinit();
93         interrupt_deinit();
94
95         dragonnet_listener_delete(server);
96
97         return EXIT_SUCCESS;
98 }