3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/socket.h>
28 sockaddr_in sockName
; // "Jméno" soketu
29 sockaddr_in clientInfo
; // Informace o klientovi
37 unsigned players_curr
;
39 typedef struct client_context
{
40 struct client_context
*next
, *prev
;
45 sockaddr_in clientInfo
;
50 unsigned char position
;
55 unsigned char bonus_time
;
56 unsigned char pickup_time
;
61 unsigned char scatter
;
64 unsigned char bombball
;
70 client_t
*client_new (char *buffer
, unsigned len
)
75 /* first find out nick name start */
89 /* jump over space character before nick name */
92 /* alloc and init context */
93 client_t
*client
= (client_t
*) malloc (sizeof (client_t
));
101 memcpy (client
->name
, buffer
+x
, len
-x
);
103 memcpy (&client
->clientInfo
, &clientInfo
, addrlen
);
109 client
->next
= &client_list
;
110 client
->prev
= client_list
.prev
;
111 client
->prev
->next
= client
;
112 client
->next
->prev
= client
;
114 /* print message on screen */
115 puts ("-> New client connected: ");
124 sendto (sock
, "ping\n", 5, 0, &clientInfo
, (socklen_t
*) &addrlen
);
129 /* newtux <tux_id> <tux_x> <tux_y> <tux_status> <tux_position> <tux_frame> <tux_score> <tux_name> <tux_gun> <tux_bonus> <tux_shot_simple> <tux_shot_dual> <tux_shot_scatter> <tux_shot_tommy> <tux_shot_lasser> <tux_shot_mine> <tux_shot_bombball> <tux_bonus_time> <tux_pickup_time> */
130 int proto_newtux (client_t
*client
)
132 char *str
= (char *) malloc (128);
139 itoa (client
->id
, buf
, 10);
140 unsigned id_len
= strlen (buf
);
142 memcpy (str
, "newtux ", 7);
143 memcpy (str
+7, buf
, id_len
);
144 memcpy (str
+7+id_len
, " ", 1);
146 itoa (client
->x
, buf
, 10);
147 unsigned x_len
= strlen (buf
);
149 memcpy (str
+8+id_len
, buf
, x_len
);
150 memcpy (str
+8+id_len
+x_len
, " ", 1);
152 itoa (client
->y
, buf
, 10);
153 unsigned y_len
= strlen (buf
);
160 /* init <my_tux_id> <my_tux_x> <my_tux_y> <count_round> <arena_net_name> */
161 int proto_hello (char *buffer
, unsigned len
)
163 char *str
= (char *) malloc (128);
168 client_t
*client
= client_new (buffer
, len
);
175 itoa (tux_id
, buf
, 10);
177 unsigned tux_id_len
= strlen (buf
);
179 memcpy (str
, "init ", 5);
180 memcpy (str
+5, buf
, tux_id_len
);
182 itoa (client
->x
, buf
, 10);
183 unsigned x_len
= strlen (buf
);
185 memcpy (str
+5+tux_id_len
, " ", 1);
186 memcpy (str
+6+tux_id_len
, buf
, x_len
);
187 memcpy (str
+6+tux_id_len
+x_len
, " ", 1);
189 itoa (client
->y
, buf
, 10);
190 unsigned y_len
= strlen (buf
);
192 memcpy (str
+7+tux_id_len
+x_len
, buf
, y_len
);
193 memcpy (str
+7+tux_id_len
+x_len
+y_len
, " ", 1);
195 itoa (round
, buf
, 10);
196 unsigned round_len
= strlen (buf
);
198 memcpy (str
+8+tux_id_len
+x_len
+y_len
, buf
, round_len
);
199 memcpy (str
+8+tux_id_len
+x_len
+y_len
+round_len
, " ", 1);
201 memcpy (str
+9+tux_id_len
+x_len
+y_len
+round_len
, map
, map_len
);
203 str
[9+tux_id_len
+x_len
+y_len
+round_len
+map_len
] = '\n';
205 sendto (sock
, str
, 10+tux_id_len
+x_len
+y_len
+round_len
+map_len
, 0, &clientInfo
, &addrlen
);
209 puts ("-> hello ()\n");
211 /* send to new client message about currently joined players */
214 for (c
= client_list
.next
; c
!= &client_list
; c
= c
->next
)
224 /** HANDLER Function */
225 int proto_handler (char *buffer
, unsigned len
)
227 if (!strncmp (buffer
, "ping", 4))
228 return proto_ping ();
229 if (!strncmp (buffer
, "hello", 5))
230 return proto_hello (buffer
, len
);
231 //if (!strncmp (buffer, "end", 3))
232 // return proto_end (buffer, len);
240 sock
= socket (AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
245 // Zaplníme strukturu sockaddr_in
246 // 1) Rodina protokolù
247 sockName
.sin_family
= AF_INET
;
248 // 2) Èíslo portu, na kterém èekáme
249 sockName
.sin_port
= htons (2900);
251 if (bind (sock
, &sockName
, sizeof(sockName
)) == -1) {
252 puts ("-> bind () error");
256 addrlen
= sizeof (clientInfo
);
258 client_list
.next
= &client_list
;
259 client_list
.prev
= &client_list
;
264 memcpy (map
, "CS", 2);
267 /* round start on 0 */
270 /* players count is preset to 0 */
279 /* get new packets */
280 int ret
= recvfrom (sock
, buf
, 128, 0, &clientInfo
, &addrlen
);
282 /* when data are available, handle it */
286 proto_handler (buf
, ret
);
295 int main (int argc
, char **argv
)
297 puts ("tuxanci - game server\n");