X-Git-Url: http://git.shiar.net/netris.git/blobdiff_plain/ec797c133bd83404f6167fb46c098c236333d168..eb820d60637feceb84f559675344cf24a2c2f1cd:/inet.c diff --git a/inet.c b/inet.c index dbfe748..4300eb7 100644 --- a/inet.c +++ b/inet.c @@ -15,11 +15,10 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * $Id: inet.c,v 1.18 1996/02/09 08:22:13 mhw Exp $ */ #include "netris.h" + #include #include #include @@ -28,189 +27,177 @@ #include #include #include +#include -#define HEADER_SIZE sizeof(netint2[2]) +#include "inet.h" -static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event); +#define HEADER_SIZE sizeof(netint2[2]) +#define HEADER_SIZE3 sizeof(netint4[3]) -static int sock = -1; -static EventGenRec netGen = { NULL, 0, FT_read, -1, NetGenFunc, EM_net }; +MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event); +EventGenRec netGen = { + NULL, 0, FT_read, -1, NetGenFunc, EM_net, 0, "\0", 0, HEADER_SIZE3 +}; -static char netBuf[64]; -static int netBufSize, netBufGoal = HEADER_SIZE; -static int isServer, lostConn, gotEndConn; -ExtFunc void InitNet(void) -{ - AtExit(CloseNet); -} +static sigjmp_buf close_env; -ExtFunc int WaitForConnection(char *portStr) +void CatchInt(int sig) { - struct sockaddr_in addr; - struct hostent *host; - int sockListen; - int addrLen; - short port; - int val1; - struct linger val2; - - if (portStr) - port = atoi(portStr); /* XXX Error checking */ - else - port = DEFAULT_PORT; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = htons(port); - sockListen = socket(AF_INET, SOCK_STREAM, 0); - if (sockListen < 0) - die("socket"); - val1 = 1; - setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, - (void *)&val1, sizeof(val1)); - if (bind(sockListen, (struct sockaddr *)&addr, sizeof(addr)) < 0) - die("bind"); - if (listen(sockListen, 1) < 0) - die("listen"); - addrLen = sizeof(addr); - sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen); - if (sock < 0) - die("accept"); - close(sockListen); - val2.l_onoff = 1; - val2.l_linger = 0; - setsockopt(sock, SOL_SOCKET, SO_LINGER, - (void *)&val2, sizeof(val2)); - netGen.fd = sock; - strcpy(opponentHost, "???"); - if (addr.sin_family == AF_INET) { - host = gethostbyaddr((void *)&addr.sin_addr, - sizeof(struct in_addr), AF_INET); - if (host) { - strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); - opponentHost[sizeof(opponentHost)-1] = 0; - } - } - AddEventGen(&netGen); - isServer = 1; - return 0; + siglongjmp(close_env, 1); } -ExtFunc int InitiateConnection(char *hostStr, char *portStr) -{ +int InitiateConnection(char *hostStr, short port) +{ //connect to host struct sockaddr_in addr; struct hostent *host; - short port; - int mySock; - if (portStr) - port = atoi(portStr); /* XXX Error checking */ - else - port = DEFAULT_PORT; + if (sigsetjmp(close_env, 1)) + exit(0); + signal(SIGINT, CatchInt); //handle exit (^C) + AtExit(CloseNet); host = gethostbyname(hostStr); if (!host) die("gethostbyname"); assert(host->h_addrtype == AF_INET); - strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); - opponentHost[sizeof(opponentHost)-1] = 0; again: memset(&addr, 0, sizeof(addr)); addr.sin_family = host->h_addrtype; memcpy(&addr.sin_addr, host->h_addr, host->h_length); addr.sin_port = htons(port); - mySock = socket(AF_INET, SOCK_STREAM, 0); - if (mySock < 0) + if ((netGen.fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) die("socket"); - if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (connect(netGen.fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { if (errno != ECONNREFUSED) die("connect"); - close(mySock); + close(netGen.fd); sleep(1); goto again; } - netGen.fd = sock = mySock; AddEventGen(&netGen); return 0; } -static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event) -{ +void HandShake(void) +{ //talk to your host + MyEvent event; + + { + netint4 versiondata[2]; + versiondata[0] = hton4(MAJOR_VERSION); + versiondata[1] = hton4(PROTOCOL_VERSION); + SendPacket(0, NP_hello, sizeof(versiondata), versiondata); + } + + do { + if (WaitMyEvent(&event, EM_net) == E_net) + switch (event.u.net.type) { + case NP_hello: + { + me = event.u.net.uid; + memcpy(&Players[me], &Players[0], sizeof(_Player)); + fprintf(stderr, "Accepted (%s) as #%d (%s)\n", + event.u.net.data, me, Players[me].name); + SendPacket(0, NP_newPlayer, + sizeof(_Player) - sizeof(Players[me].host), + &Players[me]); + break; + } + case NP_team: + { //receive your teamnumber + memcpy(&Players[event.u.net.uid].team, event.u.net.data, + event.u.net.size); + break; + } //NP_team + case NP_gamedata: + { + static struct { + int playerflags; + int maxplayers; //1 + int started; //2 + int continuous; //3 + long seed; //4 + int initspeed; //5 + } data; + + memcpy(&data, event.u.net.data, event.u.net.size); + memcpy(&Players[me].flags, &data, sizeof(data.playerflags)); + memcpy(&Players[me].flags, &data, sizeof(data.playerflags)); + memcpy(&Game, &data.maxplayers, + sizeof(data) - sizeof(data.playerflags)); + break; + } //NP_gamedata + case NP_error: + { + fprintf(stderr, "Rejected by server: %s\n", event.u.net.data); + exit(1); + } //NP_error + default: + break; + } + else + fatal("Hm, the party apparantly ended prematurely."); + } while (event.u.net.type != NP_gamedata); +} + + +MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event) +{ //receive int result; - short type, size; - netint2 data[2]; + short uid, type, size; + netint4 *data = (netint4*)&(gen->buf); - result = MyRead(sock, netBuf + netBufSize, netBufGoal - netBufSize); + result = MyRead(gen->fd, gen->buf + gen->bufSize, + gen->bufGoal - gen->bufSize); if (result < 0) { - lostConn = 1; + close(gen->fd); + gen->fd = -1; return E_lostConn; } - netBufSize += result; - if (netBufSize < netBufGoal) + gen->bufSize += result; + if (gen->bufSize < gen->bufGoal) return E_none; - memcpy(data, netBuf, sizeof(data)); - type = ntoh2(data[0]); - size = ntoh2(data[1]); - netBufGoal = size; - if (netBufSize < netBufGoal) + // *ugly* memcpy(data, gen->buf, sizeof(data)); + uid = ntoh4(data[0]); + type = ntoh4(data[1]); + size = ntoh4(data[2]); + gen->bufGoal = size; + if (gen->bufSize < gen->bufGoal) return E_none; - netBufSize = 0; - netBufGoal = HEADER_SIZE; + gen->bufSize = 0; + gen->bufGoal = HEADER_SIZE3; + event->u.net.sender = gen->player; + event->u.net.uid = uid; event->u.net.type = type; - event->u.net.size = size - HEADER_SIZE; - event->u.net.data = netBuf + HEADER_SIZE; - if (type == NP_endConn) { - gotEndConn = 1; - return E_lostConn; - } - else if (type == NP_byeBye) { - lostConn = 1; - return E_lostConn; - } + event->u.net.size = size - HEADER_SIZE3; + event->u.net.data = gen->buf + HEADER_SIZE3; + if (type == NP_endConn) return E_lostConn; return E_net; } -ExtFunc void CheckNetConn(void) -{ -} +void SendPacket(short uid, NetPacketType type, int size, void *data) +{ //send shit to server + netint4 header[3]; -ExtFunc void SendPacket(NetPacketType type, int size, void *data) -{ - netint2 header[2]; - - header[0] = hton2(type); - header[1] = hton2(size + HEADER_SIZE); - if (MyWrite(sock, header, HEADER_SIZE) != HEADER_SIZE) - die("write"); - if (size > 0 && data && MyWrite(sock, data, size) != size) + header[0] = hton4(uid); + header[1] = hton4(type); + header[2] = hton4(size + HEADER_SIZE3); + if (MyWrite(netGen.fd, header, HEADER_SIZE3) != HEADER_SIZE3) + die("write (header)"); + if (size > 0 && data && MyWrite(netGen.fd, data, size) != size) die("write"); } -ExtFunc void CloseNet(void) -{ +void CloseNet(void) +{ //kick some connection's ass! MyEvent event; - if (sock >= 0) { - if (!lostConn) { - SendPacket(NP_endConn, 0, NULL); - if (isServer) { - while (!lostConn) - WaitMyEvent(&event, EM_net); - } - else { - while (!gotEndConn) - WaitMyEvent(&event, EM_net); - SendPacket(NP_byeBye, 0, NULL); - } - } - close(sock); - sock = -1; + if (netGen.fd >= 0) { + SendPacket(0, NP_endConn, 0, NULL); + close(netGen.fd); + netGen.fd = -1; } if (netGen.next) RemoveEventGen(&netGen); } -/* - * vi: ts=4 ai - * vim: noai si - */