3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid
[] =
21 "$Id: net.c,v 1.4 2003/11/27 22:39:11 nsubtil Exp $";
31 static UDPsocket sock
= NULL
;
32 static IPaddress srv_addr
;
33 static UDPpacket
*packet
= NULL
;
35 int server_running
= 0;
36 int client_running
= 0;
39 starts a listener for the network server
41 void net_server_init(void)
46 sock
= SDLNet_UDP_Open(NET_PACMAN_PORT
);
49 printf("net_server_init: SDLNet_UDP_Open: %s\n", SDLNet_GetError());
56 packet
= SDLNet_AllocPacket(NET_MAX_PACKET_SIZE
);
59 printf("net_send_packet: SDLNet_AllocPacket: %s\n", SDLNet_GetError());
65 printf("net_server_init: listening on port %d\n", NET_PACMAN_PORT
);
70 connects to a server on a given host
72 void net_client_init(char *hostname
)
74 struct packet_r_connok p
;
79 packet
= SDLNet_AllocPacket(NET_MAX_PACKET_SIZE
);
82 printf("net_send_packet: SDLNet_AllocPacket: %s\n", SDLNet_GetError());
88 sock
= SDLNet_UDP_Open(0);
91 printf("net_client_init: SDLNet_UDP_Open: %s\n", SDLNet_GetError());
96 if(SDLNet_ResolveHost(&srv_addr
, hostname
, NET_PACMAN_PORT
) == -1)
98 printf("net_client_init: SDLNet_ResolveHost(%s): %s\n", hostname
, SDLNet_GetError());
103 if(SDLNet_UDP_Bind(sock
, 0, &srv_addr
) == -1)
105 printf("net_client_init: SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
110 printf("net_client_init: connecting to %s port %d...\n", hostname
, NET_PACMAN_PORT
);
111 /* send a connection packet */
112 net_send_packet(sock
, PTYPE_REQ_NEWCONN
, NULL
, srv_addr
);
114 net_wait_packet(sock
, packet
);
116 if(net_decode_ptype(packet
) != PTYPE_REPLY_CONNOK
)
118 printf("net_client_init: connection refused\n");
123 net_decode_pdata(packet
, &p
);
124 printf("net_client_init: connection established, id %d\n", p
.player_id
);
132 void net_wait_packet(UDPsocket usock
, UDPpacket
*pack
)
134 while(SDLNet_UDP_Recv(usock
, pack
) != 1)
139 builds and sends a packet of a given type to a destination
141 void net_send_packet(UDPsocket usock
, Uint8 ptype
, void *pdata
, IPaddress dest
)
144 net_encode(packet
, ptype
, pdata
);
145 packet
->address
= dest
;
146 if(SDLNet_UDP_Send(usock
, -1, packet
) == 0)
148 printf("net_send_packet: SDLNet_UDP_Send: %s\n", SDLNet_GetError());
155 encodes a packet of a given type
157 void net_encode(UDPpacket
*pack
, Uint8 ptype
, void *pdata
)
161 - packet type (1 byte)
162 - packet flags (1 byte)
163 - packet data (variable)
167 net_pack_byte(pack
, ptype
);
169 net_pack_byte(pack
, 0);
173 case PTYPE_REQ_NEWCONN
:
177 case PTYPE_REPLY_CONNOK
:
179 struct packet_r_connok
*p
;
181 p
= (struct packet_r_connok
*)pdata
;
182 net_pack_int32(pack
, p
->player_id
);
188 printf("net_send_packet: unknown ptype %d\n", ptype
);
195 decodes the packet type
196 returns the type of packet, or -1 on error
198 int net_decode_ptype(UDPpacket
*pack
)
200 switch(pack
->data
[0])
202 case PTYPE_REQ_NEWCONN
:
203 return PTYPE_REQ_NEWCONN
;
205 case PTYPE_REPLY_CONNOK
:
206 return PTYPE_REPLY_CONNOK
;
214 decodes the data in pack
216 void net_decode_pdata(UDPpacket
*pack
, void *data
)
218 switch(pack
->data
[0])
220 case PTYPE_REQ_NEWCONN
:
223 case PTYPE_REPLY_CONNOK
:
225 struct packet_r_connok
*p
;
227 p
= (struct packet_r_connok
*)data
;
229 p
->player_id
= SDLNet_Read32(&pack
->data
[2]);
237 packs a byte on the end of a packet
239 void net_pack_byte(UDPpacket
*pack
, Uint8 value
)
241 if(pack
->len
+ 1 > pack
->maxlen
)
243 printf("net_pack_byte: packet too small (%d)\n", pack
->maxlen
);
248 pack
->data
[pack
->len
] = value
;
253 packs a 32-bit value on the end of a packet
255 void net_pack_int32(UDPpacket
*pack
, Uint32 value
)
257 if(pack
->len
+ 4 > pack
->maxlen
)
259 printf("net_pack_int32: packet too small (%d)\n", pack
->maxlen
);
264 SDLNet_Write32(value
, &pack
->data
[pack
->len
]);
271 void net_server_update(void)
273 while(SDLNet_UDP_Recv(sock
, packet
) == 1)
275 switch(net_decode_ptype(packet
))
277 case PTYPE_REQ_NEWCONN
:
279 struct packet_r_connok p
= {1};
281 printf("net_server_update: new connection from %s\n", SDLNet_ResolveIP(&packet
->address
));
282 audio_play_sample("sfx/ghost-return.wav");
283 net_send_packet(sock
, PTYPE_REPLY_CONNOK
, &p
, packet
->address
);
292 void net_client_update(void)