* Germany *
* e-mail: info@artsoft.org *
*----------------------------------------------------------*
-* network.c *
+* netserv.c *
***********************************************************/
#include "libgame/platform.h"
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
#include <fcntl.h>
#include <sys/time.h>
#include <signal.h>
-#include <sys/socket.h>
#include <errno.h>
+
+#if defined(TARGET_SDL)
+#include "main.h"
+#else
+#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/select.h> /* apparently needed for OS/2 port */
+#endif
#include "libgame/libgame.h"
struct NetworkServerPlayerInfo
{
+#if defined(TARGET_SDL)
+ TCPsocket fd;
+#else
int fd;
+#endif
+
char player_name[16];
unsigned char number;
struct NetworkServerPlayerInfo *next;
#define NEXT(player) ((player)->next ? (player)->next : first_player)
+#if defined(TARGET_SDL)
+/* TODO: peer address */
+static TCPsocket lfd; /* listening socket */
+static SDLNet_SocketSet fds; /* socket set */
+#else
static struct sockaddr_in saddr;
-static int lfd;
+static int lfd; /* listening socket */
+static fd_set fds; /* socket set */
+static int tcp = -1;
+#endif
+
static unsigned char realbuffer[512], *buffer = realbuffer + 4;
static int interrupt;
-static int tcp = -1;
static unsigned long ServerFrameCounter = 0;
-static fd_set fds;
-
static void addtobuffer(struct NetworkServerPlayerInfo *player,
unsigned char *b, int len)
{
{
if (player->nwrite)
{
+#if defined(TARGET_SDL)
+ SDLNet_TCP_Send(player->fd, player->writbuffer, player->nwrite);
+#else
write(player->fd, player->writbuffer, player->nwrite);
+#endif
player->nwrite = 0;
}
}
}
}
}
+
+#if defined(TARGET_SDL)
+ SDLNet_TCP_DelSocket(fds, player->fd);
+ SDLNet_TCP_Close(player->fd);
+#else
close(player->fd);
+#endif
if (player->introduced)
{
}
}
+#if defined(TARGET_SDL)
+static void AddPlayer(TCPsocket fd)
+#else
static void AddPlayer(int fd)
+#endif
{
struct NetworkServerPlayerInfo *player, *v;
unsigned char nxn;
player->action = 0;
player->action_received = FALSE;
+#if defined(TARGET_SDL)
+ SDLNet_TCP_AddSocket(fds, fd);
+#endif
+
first_player = player;
nxn = 1;
#endif
player->number = nxn;
+#if !defined(TARGET_SDL)
if (options.verbose)
Error(ERR_NETWORK_SERVER, "client %d connecting from %s",
nxn, inet_ntoa(saddr.sin_addr));
+#endif
clients++;
buffer[0] = 0;
ServerFrameCounter++;
}
+#if defined(TARGET_SDL)
+/* the following is not used for a standalone server;
+ the pointer points to an integer containing the port-number */
+int NetworkServerThread(void *ptr)
+{
+ NetworkServer(*((int *) ptr), 0);
+
+ /* should never be reached */
+ return 0;
+}
+#endif
+
void NetworkServer(int port, int serveronly)
{
- int i, sl, on;
+ int sl;
struct NetworkServerPlayerInfo *player;
- int mfd;
int r;
unsigned int len;
+#if defined(TARGET_SDL)
+ IPaddress ip;
+#else
+ int i, on;
+ int is_daemon = 0;
struct protoent *tcpproto;
struct timeval tv;
- int is_daemon = 0;
+ int mfd;
+#endif
-#ifndef NeXT
+#if defined(PLATFORM_UNIX) && !defined(PLATFORM_NEXT)
struct sigaction sact;
#endif
if (!serveronly)
onceonly = 1;
+#if !defined(TARGET_SDL)
if ((tcpproto = getprotobyname("tcp")) != NULL)
tcp = tcpproto->p_proto;
+#endif
-#ifdef NeXT
+#if defined(PLATFORM_UNIX)
+#if defined(PLATFORM_NEXT)
signal(SIGPIPE, SIG_IGN);
#else
sact.sa_handler = SIG_IGN;
sact.sa_flags = 0;
sigaction(SIGPIPE, &sact, NULL);
#endif
+#endif
+
+#if defined(TARGET_SDL)
+
+ /* assume that SDL is already initialized */
+#if 0
+ if (SDLNet_Init() == -1)
+ Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_Init() failed");
+ atexit(SDLNet_Quit);
+#endif
+
+ if (SDLNet_ResolveHost(&ip, NULL, port) == -1)
+ Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed");
+ lfd = SDLNet_TCP_Open(&ip);
+ if (!lfd)
+ Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed");
+
+ fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1);
+ SDLNet_TCP_AddSocket(fds, lfd);
+
+#else
if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
Error(ERR_EXIT_NETWORK_SERVER, "socket() failed");
Error(ERR_EXIT_NETWORK_SERVER, "bind() failed");
listen(lfd, 5);
+#endif
+#if !defined(TARGET_SDL)
if (is_daemon)
{
/* become a daemon, breaking all ties with the controlling terminal */
open("/dev/null", O_WRONLY);
open("/dev/null", O_WRONLY);
}
+#endif
if (options.verbose)
{
for (player = first_player; player; player = player->next)
flushuser(player);
+#if defined(TARGET_SDL)
+ if ((sl = SDLNet_CheckSockets(fds, 500000)) < 1)
+ {
+ Error(ERR_NETWORK_SERVER, SDLNet_GetError());
+ perror("SDLNet_CheckSockets");
+ }
+
+#else
+
FD_ZERO(&fds);
mfd = lfd;
player = first_player;
else
continue;
}
+#endif
if (sl < 0)
continue;
if (sl == 0)
continue;
+ /* accept incoming connections */
+#if defined(TARGET_SDL)
+ if (SDLNet_SocketReady(lfd))
+ {
+ TCPsocket newsock;
+
+ newsock = SDLNet_TCP_Accept(lfd);
+
+ if (newsock)
+ AddPlayer(newsock);
+ }
+
+#else
+
if (FD_ISSET(lfd, &fds))
{
int newfd, slen;
}
continue;
}
+#endif
player = first_player;
do
{
+#if defined(TARGET_SDL)
+ if (SDLNet_SocketReady(player->fd))
+#else
if (FD_ISSET(player->fd, &fds))
+#endif
{
- r = read(player->fd, player->readbuffer + player->nread, MAX_BUFFER_SIZE - player->nread);
+#if defined(TARGET_SDL)
+ /* read only 1 byte, because SDLNet blocks when we want more than is
+ in the buffer */
+ r = SDLNet_TCP_Recv(player->fd, player->readbuffer + player->nread, 1);
+#else
+ r = read(player->fd, player->readbuffer + player->nread,
+ MAX_BUFFER_SIZE - player->nread);
+#endif
+
if (r <= 0)
{
if (options.verbose)
}
}
-#endif /* PLATFORM_UNIX */
+#endif /* NETWORK_AVALIABLE */