2 * Netris -- A free networked version of T*tris
3 * Copyright (C) 1994,1995,1996 Mark H. Weaver <mhw@netris.org>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * $Id: inet.c,v 1.18 1996/02/09 08:22:13 mhw Exp $
24 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
36 #define HEADER_SIZE sizeof(netint2[2])
37 #define HEADER_SIZE3 sizeof(netint4[3])
39 MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event);
40 EventGenRec netGen = {
41 NULL, 0, FT_read, -1, NetGenFunc, EM_net, 0, "\0", 0, HEADER_SIZE3
45 static sigjmp_buf close_env;
47 void CatchInt(int sig)
49 siglongjmp(close_env, 1);
52 int InitiateConnection(char *hostStr, short port)
54 struct sockaddr_in addr;
57 if (sigsetjmp(close_env, 1))
59 signal(SIGINT, CatchInt); //handle exit (^C)
61 host = gethostbyname(hostStr);
64 assert(host->h_addrtype == AF_INET);
66 memset(&addr, 0, sizeof(addr));
67 addr.sin_family = host->h_addrtype;
68 memcpy(&addr.sin_addr, host->h_addr, host->h_length);
69 addr.sin_port = htons(port);
70 if ((netGen.fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
72 if (connect(netGen.fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
73 if (errno != ECONNREFUSED)
88 netint4 versiondata[2];
89 versiondata[0] = hton4(MAJOR_VERSION);
90 versiondata[1] = hton4(PROTOCOL_VERSION);
91 SendPacket(0, NP_hello, sizeof(versiondata), versiondata);
95 if (WaitMyEvent(&event, EM_net) == E_net)
96 switch (event.u.net.type) {
100 memcpy(&Players[me], &Players[0], sizeof(_Player));
101 fprintf(stderr, "Accepted (%s) as #%d (%s)\n",
102 event.u.net.data, me, Players[me].name);
103 SendPacket(0, NP_newPlayer,
104 sizeof(_Player) - sizeof(Players[me].host),
109 { //receive your teamnumber
110 memcpy(&Players[event.u.net.uid].team, event.u.net.data,
125 memcpy(&data, event.u.net.data, event.u.net.size);
126 memcpy(&Players[me].flags, &data, sizeof(data.playerflags));
127 memcpy(&Players[me].flags, &data, sizeof(data.playerflags));
128 memcpy(&Game, &data.maxplayers,
129 sizeof(data) - sizeof(data.playerflags));
134 fprintf(stderr, "Rejected by server: %s\n", event.u.net.data);
141 fatal("Hm, the party apparantly ended prematurely.");
143 while (event.u.net.type != NP_gamedata);
147 MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event)
150 short uid, type, size;
151 netint4 *data = (netint4*)&(gen->buf);
153 result = MyRead(gen->fd, gen->buf + gen->bufSize,
154 gen->bufGoal - gen->bufSize);
160 gen->bufSize += result;
161 if (gen->bufSize < gen->bufGoal)
163 // *ugly* memcpy(data, gen->buf, sizeof(data));
164 uid = ntoh4(data[0]);
165 type = ntoh4(data[1]);
166 size = ntoh4(data[2]);
168 if (gen->bufSize < gen->bufGoal)
171 gen->bufGoal = HEADER_SIZE3;
172 event->u.net.sender = gen->player;
173 event->u.net.uid = uid;
174 event->u.net.type = type;
175 event->u.net.size = size - HEADER_SIZE3;
176 event->u.net.data = gen->buf + HEADER_SIZE3;
177 if (type == NP_endConn) return E_lostConn;
181 void SendPacket(short uid, NetPacketType type, int size, void *data)
182 { //send shit to server
185 header[0] = hton4(uid);
186 header[1] = hton4(type);
187 header[2] = hton4(size + HEADER_SIZE3);
188 if (MyWrite(netGen.fd, header, HEADER_SIZE3) != HEADER_SIZE3)
189 die("write (header)");
190 if (size > 0 && data && MyWrite(netGen.fd, data, size) != size)
195 { //kick some connection's ass!
198 if (netGen.fd >= 0) {
199 SendPacket(0, NP_endConn, 0, NULL);
204 RemoveEventGen(&netGen);