mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2024-11-26 05:24:21 +01:00
Added, probably not be used
This commit is contained in:
parent
1a3f569c44
commit
435014ecdb
374
Src/Network.cpp
Normal file
374
Src/Network.cpp
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/*
|
||||||
|
* Network.h - Network handling
|
||||||
|
*
|
||||||
|
* Frodo (C) 2009 Simon Kagstrom
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
#include "Network.h"
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#define N_SQUARES_W 6
|
||||||
|
#define N_SQUARES_H 4
|
||||||
|
|
||||||
|
#define SQUARE_W (DISPLAY_X / N_SQUARES_W)
|
||||||
|
#define SQUARE_H (DISPLAY_Y / N_SQUARES_H)
|
||||||
|
|
||||||
|
#define SQUARE_TO_X(square) ( ((square) % N_SQUARES_W) * SQUARE_W )
|
||||||
|
#define SQUARE_TO_Y(square) ( ((square) / N_SQUARES_W) * SQUARE_H )
|
||||||
|
|
||||||
|
#define RAW_SIZE ( (SQUARE_W * SQUARE_H) / 2 )
|
||||||
|
|
||||||
|
size_t Network::EncodeDisplayRaw(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
|
int x_start, int y_start)
|
||||||
|
{
|
||||||
|
const int raw_w = SQUARE_W / 2;
|
||||||
|
dst->type = DISPLAY_UPDATE_RAW;
|
||||||
|
|
||||||
|
for (int y = y_start; y < y_start + SQUARE_W; y++)
|
||||||
|
{
|
||||||
|
for (int x = x_start; x < x_start + SQUARE_H; x += 2)
|
||||||
|
{
|
||||||
|
Uint8 a = screen[ y * DISPLAY_X + x ];
|
||||||
|
Uint8 b = screen[ y * DISPLAY_X + (x + 1) ];
|
||||||
|
|
||||||
|
dst->data[ (y - y_start) * raw_w + (x - x_start) / 2 ] =
|
||||||
|
(a << 4) | b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RAW_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Network::EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
|
int x_start, int y_start)
|
||||||
|
{
|
||||||
|
size_t out = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
Uint8 color = screen[ y_start * DISPLAY_X + x_start ];
|
||||||
|
|
||||||
|
dst->type = DISPLAY_UPDATE_RLE;
|
||||||
|
|
||||||
|
for (int y = y_start; y < y_start + SQUARE_W; y++)
|
||||||
|
{
|
||||||
|
for (int x = x_start; x < x_start + SQUARE_H; x++)
|
||||||
|
{
|
||||||
|
if (color != screen[ y * DISPLAY_X + x ] ||
|
||||||
|
len >= 255)
|
||||||
|
{
|
||||||
|
dst->data[out] = len;
|
||||||
|
dst->data[out + 1] = color;
|
||||||
|
out += 2;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
color = screen[ y * DISPLAY_X + x];
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Network::EncodeSoundRLE(struct NetworkSoundUpdate *dst,
|
||||||
|
Uint8 *buffer, size_t buf_len)
|
||||||
|
{
|
||||||
|
size_t out = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
Uint8 volume = buffer[0];
|
||||||
|
|
||||||
|
dst->type = SOUND_UPDATE_RLE;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < buf_len; i++)
|
||||||
|
{
|
||||||
|
if (volume != buffer[i] ||
|
||||||
|
len >= 255)
|
||||||
|
{
|
||||||
|
dst->data[out] = len;
|
||||||
|
dst->data[out + 1] = volume;
|
||||||
|
out += 2;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
volume = buffer[i];
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Network::EncodeSoundRaw(struct NetworkSoundUpdate *dst,
|
||||||
|
Uint8 *buffer, size_t len)
|
||||||
|
{
|
||||||
|
dst->type = SOUND_UPDATE_RAW;
|
||||||
|
memcpy(dst->data, buffer, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Network::DecodeDisplayRLE(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
|
int x_start, int y_start)
|
||||||
|
{
|
||||||
|
int p = 0;
|
||||||
|
int x = x_start;
|
||||||
|
int y = y_start;
|
||||||
|
|
||||||
|
/* Something is wrong if this is true... */
|
||||||
|
if (src->size % 2 != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (p < src->size)
|
||||||
|
{
|
||||||
|
Uint8 len = src->data[p];
|
||||||
|
Uint8 color = src->data[p+1];
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
screen[y * DISPLAY_X + x] = color;
|
||||||
|
len--;
|
||||||
|
x++;
|
||||||
|
if ((x - x_start) % SQUARE_W == 0)
|
||||||
|
{
|
||||||
|
x = x_start;
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::DecodeDisplayRaw(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
|
int x_start, int y_start)
|
||||||
|
{
|
||||||
|
const int raw_w = SQUARE_W / 2;
|
||||||
|
|
||||||
|
for (int y = y_start; y < y_start + SQUARE_W; y++)
|
||||||
|
{
|
||||||
|
for (int x = x_start; x < x_start + SQUARE_H; x += 2)
|
||||||
|
{
|
||||||
|
Uint8 x = src->data[(y - y_start) * raw_w + (x - x_start) / 2];
|
||||||
|
Uint8 a = x >> 4;
|
||||||
|
Uint8 b = x & 0xf;
|
||||||
|
|
||||||
|
screen[ y * DISPLAY_X + x ] = a;
|
||||||
|
screen[ y * DISPLAY_X + x + 1 ] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public methods */
|
||||||
|
size_t Network::EncodeDisplaySquare(struct NetworkDisplayUpdate *dst,
|
||||||
|
Uint8 *screen, int square)
|
||||||
|
{
|
||||||
|
const int square_x = SQUARE_TO_X(square);
|
||||||
|
const int square_y = SQUARE_TO_Y(square);
|
||||||
|
size_t out;
|
||||||
|
|
||||||
|
dst->square = square;
|
||||||
|
/* Try encoding as RLE, but if it's too large, go for RAW */
|
||||||
|
out = this->EncodeDisplayRLE(dst, screen, square_x, square_y);
|
||||||
|
if (out > RAW_SIZE)
|
||||||
|
out = this->EncodeDisplayRaw(dst, screen, square_x, square_y);
|
||||||
|
dst->size = out + sizeof(struct NetworkDisplayUpdate);
|
||||||
|
|
||||||
|
return dst->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::DecodeDisplayUpdate(Uint8 *screen,
|
||||||
|
struct NetworkDisplayUpdate *src)
|
||||||
|
{
|
||||||
|
int square = src->square;
|
||||||
|
const int square_x = SQUARE_TO_X(square);
|
||||||
|
const int square_y = SQUARE_TO_Y(square);
|
||||||
|
|
||||||
|
if (src->type == DISPLAY_UPDATE_RAW)
|
||||||
|
return this->DecodeDisplayRaw(screen, src, square_x, square_y);
|
||||||
|
if (src->type == DISPLAY_UPDATE_RLE)
|
||||||
|
return this->DecodeDisplayRLE(screen, src, square_x, square_y);
|
||||||
|
|
||||||
|
/* Error */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Network::EncodeSoundBuffer(struct NetworkSoundUpdate *dst, Uint8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t out;
|
||||||
|
|
||||||
|
dst->size = 0;
|
||||||
|
/* Try encoding as RLE, but if it's too large, go for RAW */
|
||||||
|
out = this->EncodeSoundRLE(dst, buf, len);
|
||||||
|
if (out > len)
|
||||||
|
out = this->EncodeSoundRaw(dst, buf, len);
|
||||||
|
dst->size = out + sizeof(struct NetworkSoundUpdate);
|
||||||
|
|
||||||
|
return dst->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::EncodeJoystickUpdate(struct NetworkJoystickUpdate *dst, Uint8 which, Uint8 v)
|
||||||
|
{
|
||||||
|
dst->type = JOYSTICK_UPDATE;
|
||||||
|
dst->which = which;
|
||||||
|
dst->data = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Network::DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf)
|
||||||
|
{
|
||||||
|
size_t out;
|
||||||
|
|
||||||
|
if (src->type == SOUND_UPDATE_RAW)
|
||||||
|
{
|
||||||
|
out = src->size - sizeof(struct NetworkSoundUpdate);
|
||||||
|
memcpy(buf, src->data, out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out = 0;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkUpdate *Network::GetNetworkUpdate(void)
|
||||||
|
{
|
||||||
|
static NetworkUpdate *out;
|
||||||
|
const size_t size = NETWORK_UPDATE_SIZE;
|
||||||
|
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
/* "big enough" static buffer */
|
||||||
|
out = (NetworkUpdate*)malloc( size );
|
||||||
|
}
|
||||||
|
memset(out, 0, size);
|
||||||
|
|
||||||
|
out->type = HEADER;
|
||||||
|
out->size = 0;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
memset(&tv, 0, sizeof(tv));
|
||||||
|
return this->ReceiveUpdate(dst, sock, &tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Network::ReceiveUpdateBlock(NetworkUpdate *dst, int sock)
|
||||||
|
{
|
||||||
|
return this->ReceiveUpdate(dst, sock, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::MarshalData(NetworkUpdate *ud)
|
||||||
|
{
|
||||||
|
Uint8 *p = ud->data;
|
||||||
|
int len = 0;
|
||||||
|
int sz = ud->size;
|
||||||
|
|
||||||
|
ud->size = htons(ud->size);
|
||||||
|
while (len < ud->size)
|
||||||
|
{
|
||||||
|
p = p + len;
|
||||||
|
|
||||||
|
switch (p[0])
|
||||||
|
{
|
||||||
|
case DISPLAY_UPDATE_RAW:
|
||||||
|
case DISPLAY_UPDATE_RLE:
|
||||||
|
case SOUND_UPDATE_RAW: /* Not really true, but looks the same */
|
||||||
|
case SOUND_UPDATE_RLE:
|
||||||
|
{
|
||||||
|
NetworkDisplayUpdate *tmp = (NetworkDisplayUpdate *)p;
|
||||||
|
|
||||||
|
len = tmp->size;
|
||||||
|
tmp->size = htons(tmp->size);
|
||||||
|
} break;
|
||||||
|
case JOYSTICK_UPDATE:
|
||||||
|
len = sizeof(NetworkJoystickUpdate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown data... */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::DeMarshalData(NetworkUpdate *ud)
|
||||||
|
{
|
||||||
|
Uint8 *p = ud->data;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
ud->size = ntohs(ud->size);
|
||||||
|
while (len < ud->size)
|
||||||
|
{
|
||||||
|
p = p + len;
|
||||||
|
|
||||||
|
switch (p[0])
|
||||||
|
{
|
||||||
|
case DISPLAY_UPDATE_RAW:
|
||||||
|
case DISPLAY_UPDATE_RLE:
|
||||||
|
case SOUND_UPDATE_RAW: /* Not really true, but looks the same */
|
||||||
|
case SOUND_UPDATE_RLE:
|
||||||
|
{
|
||||||
|
NetworkDisplayUpdate *tmp = (NetworkDisplayUpdate *)p;
|
||||||
|
|
||||||
|
len = tmp->size;
|
||||||
|
tmp->size = ntohl(tmp->size);
|
||||||
|
} break;
|
||||||
|
case JOYSTICK_UPDATE:
|
||||||
|
len = sizeof(NetworkJoystickUpdate);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown data... */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkUpdate *Network::IterateFirst(NetworkUpdate *p, unsigned int *cookie)
|
||||||
|
{
|
||||||
|
Uint8 *p8 = (Uint8*)p;
|
||||||
|
NetworkUpdate *cur = (NetworkUpdate *)p->data;
|
||||||
|
|
||||||
|
*cookie = (unsigned int)(p->data - p8);
|
||||||
|
if ( *cookie >= p->size )
|
||||||
|
return NULL;
|
||||||
|
*cookie = *cookie + cur->size;
|
||||||
|
|
||||||
|
return (NetworkUpdate *)p->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkUpdate *Network::IterateNext(NetworkUpdate *p, unsigned int *cookie)
|
||||||
|
{
|
||||||
|
NetworkUpdate *cur = (NetworkUpdate *)(p->data + *cookie);
|
||||||
|
|
||||||
|
/* End of iteration */
|
||||||
|
if ( *cookie >= p->size )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*cookie = *cookie + cur->size;
|
||||||
|
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "NetworkUnix.h"
|
153
Src/Network.h
Normal file
153
Src/Network.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#ifndef NETWORK_H
|
||||||
|
#define NETWORK_H
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#define NETWORK_UPDATE_SIZE (256 * 1024)
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HEADER = 0,
|
||||||
|
DISPLAY_UPDATE_RAW = 1,
|
||||||
|
DISPLAY_UPDATE_RLE = 2,
|
||||||
|
SOUND_UPDATE_RAW = 3,
|
||||||
|
SOUND_UPDATE_RLE = 4,
|
||||||
|
KEYBOARD_UPDATE = 5,
|
||||||
|
JOYSTICK_UPDATE = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NetworkDisplayUpdate
|
||||||
|
{
|
||||||
|
Uint8 type; /* raw data or RLE */
|
||||||
|
Uint8 square;
|
||||||
|
Uint16 size;
|
||||||
|
Uint8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NetworkSoundUpdate
|
||||||
|
{
|
||||||
|
Uint8 type; /* raw data or RLE */
|
||||||
|
Uint8 dummy;
|
||||||
|
Uint16 size;
|
||||||
|
Uint8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NetworkJoystickUpdate
|
||||||
|
{
|
||||||
|
Uint8 type;
|
||||||
|
Uint8 which;
|
||||||
|
Uint8 data; /* New value */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NetworkUpdate
|
||||||
|
{
|
||||||
|
Uint8 type;
|
||||||
|
Uint8 dummy;
|
||||||
|
Uint16 size;
|
||||||
|
|
||||||
|
/* The rest is just data of some type */
|
||||||
|
Uint8 data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
class Network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Encode part of a screen into @a dst
|
||||||
|
*
|
||||||
|
* @param dst the destination update structure
|
||||||
|
* @param screen the screen to encode
|
||||||
|
* @param square the square index of the screen to encode
|
||||||
|
*
|
||||||
|
* @return the size of the encoded message
|
||||||
|
*/
|
||||||
|
size_t EncodeDisplaySquare(struct NetworkDisplayUpdate *dst,
|
||||||
|
Uint8 *screen, int square);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the @a buf sound buffer into @a dst
|
||||||
|
*
|
||||||
|
* @param dst the destination update structure
|
||||||
|
* @param buf the buffer to encode
|
||||||
|
* @param len the length of the in-buffer
|
||||||
|
*
|
||||||
|
* @return the size of the encoded message
|
||||||
|
*/
|
||||||
|
size_t EncodeSoundBuffer(struct NetworkSoundUpdate *dst,
|
||||||
|
Uint8 *buf, size_t len);
|
||||||
|
|
||||||
|
void EncodeJoystickUpdate(struct NetworkJoystickUpdate *dst,
|
||||||
|
Uint8 which, Uint8 v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a display update message onto @a screen
|
||||||
|
*
|
||||||
|
* @param screen the screen to draw to
|
||||||
|
* @param src the message to decode
|
||||||
|
*/
|
||||||
|
bool DecodeDisplayUpdate(Uint8 *screen, struct NetworkDisplayUpdate *src);
|
||||||
|
|
||||||
|
size_t DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf);
|
||||||
|
|
||||||
|
NetworkUpdate *GetNetworkUpdate(void);
|
||||||
|
|
||||||
|
bool SendUpdate(NetworkUpdate *src, int sock);
|
||||||
|
|
||||||
|
bool ReceiveUpdate(NetworkUpdate *dst, int sock);
|
||||||
|
|
||||||
|
bool ReceiveUpdateBlock(NetworkUpdate *dst, int sock);
|
||||||
|
|
||||||
|
NetworkUpdate *IterateFirst(NetworkUpdate *p, unsigned int *cookie);
|
||||||
|
|
||||||
|
NetworkUpdate *IterateNext(NetworkUpdate *p, unsigned int *cookie);
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
|
int x, int y);
|
||||||
|
size_t EncodeDisplayRaw(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
|
int x, int y);
|
||||||
|
size_t EncodeSoundRLE(struct NetworkSoundUpdate *dst,
|
||||||
|
Uint8 *buffer, size_t len);
|
||||||
|
size_t EncodeSoundRaw(struct NetworkSoundUpdate *dst,
|
||||||
|
Uint8 *buffer, size_t len);
|
||||||
|
|
||||||
|
bool DecodeDisplayRLE(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
|
int x, int y);
|
||||||
|
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
|
int x, int y);
|
||||||
|
|
||||||
|
bool ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv);
|
||||||
|
|
||||||
|
void MarshalData(NetworkUpdate *ud);
|
||||||
|
|
||||||
|
void DeMarshalData(NetworkUpdate *ud);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkClient : public Network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetworkClient(int sock);
|
||||||
|
|
||||||
|
bool ConnectToServer(const char *hostname, int port);
|
||||||
|
|
||||||
|
Uint8 *screen;
|
||||||
|
int joystick_port;
|
||||||
|
private:
|
||||||
|
int sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkServer : public Network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NetworkServer();
|
||||||
|
|
||||||
|
NetworkClient *CheckNewConnection();
|
||||||
|
|
||||||
|
NetworkClient **clients;
|
||||||
|
int n_clients;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int listen_sock;
|
||||||
|
fd_set listen_fds;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* NETWORK_H */
|
115
Src/NetworkUnix.h
Normal file
115
Src/NetworkUnix.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
/* From glibc docs */
|
||||||
|
static int make_socket (uint16_t port)
|
||||||
|
{
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in name;
|
||||||
|
|
||||||
|
/* Create the socket. */
|
||||||
|
sock = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock < 0)
|
||||||
|
{
|
||||||
|
perror ("socket");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give the socket a name. */
|
||||||
|
name.sin_family = AF_INET;
|
||||||
|
name.sin_port = htons (port);
|
||||||
|
name.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
|
||||||
|
{
|
||||||
|
perror ("bind");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkServer::NetworkServer()
|
||||||
|
{
|
||||||
|
this->n_clients = 0;
|
||||||
|
this->listen_sock = make_socket(27697);
|
||||||
|
|
||||||
|
FD_ZERO(&this->listen_fds);
|
||||||
|
FD_SET(this->listen_sock, &this->listen_fds);
|
||||||
|
|
||||||
|
if (listen(this->listen_sock, 4) < 0)
|
||||||
|
{
|
||||||
|
perror("listen");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkClient *NetworkServer::CheckNewConnection()
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
struct sockaddr_in client_name;
|
||||||
|
size_t size;
|
||||||
|
int client_sock;
|
||||||
|
|
||||||
|
/* If something connects, create a new client */
|
||||||
|
memset(&tv, 0, sizeof(tv));
|
||||||
|
if (select(1, &this->listen_fds, NULL, NULL, &tv) <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
client_sock = accept(this->listen_sock, (struct sockaddr*)&client_name, &size);
|
||||||
|
if (client_sock < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Accepting client failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NetworkClient(client_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkClient::NetworkClient(int sock)
|
||||||
|
{
|
||||||
|
this->sock = sock;
|
||||||
|
|
||||||
|
/* Assume black screen */
|
||||||
|
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
|
||||||
|
{
|
||||||
|
fd_set fds;
|
||||||
|
int sz;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(sock, &fds);
|
||||||
|
|
||||||
|
v = select(1, &fds, NULL, NULL, tv);
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Select failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sz = read(sock, (void*)dst, NETWORK_UPDATE_SIZE);
|
||||||
|
|
||||||
|
if (sz < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Byte swap stuff */
|
||||||
|
this->DeMarshalData(dst);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Network::SendUpdate(NetworkUpdate *src, int sock)
|
||||||
|
{
|
||||||
|
int sz = src->size;
|
||||||
|
|
||||||
|
this->MarshalData(src);
|
||||||
|
sz = write(sock, (void*)src, sz);
|
||||||
|
if (sz < src->size)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user