unofficial version 0.6: first major updates
[netris.git] / inet.c
diff --git a/inet.c b/inet.c
index 6aadecc07165db5e1c6d422f26c15283b20853d0..85b1b70a1fc384f6911e306cd7cc6ce6d3e504e5 100644 (file)
--- a/inet.c
+++ b/inet.c
 #define HEADER_SIZE sizeof(netint2[2])
 #define HEADER_SIZE3 sizeof(netint4[3])
 
-static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event);
+ExtFunc MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event);
 
-static int sock = -1;
-static EventGenRec netGen = { NULL, 0, FT_read, -1, NetGenFunc, EM_net };
+EventGenRec netGen[MAX_SCREENS] = {
+       { NULL, 0, FT_read, -1, NetGenFunc, EM_net, 0, "\0", 0, HEADER_SIZE3 } };
 
-static char netBuf[64];
-static int netBufSize, netBufGoal = HEADER_SIZE3;
-static int isServer, lostConn, gotEndConn;
+//static char netBuf[64];
+//static int netBufSize, netBufGoal = HEADER_SIZE3;
 
-ExtFunc void InitNet(void)
+ExtFunc void make_netGen(void)
 {
-       AtExit(CloseNet);
-}
+       int i;
 
-ExtFunc int WaitForConnection(char *portStr)
-{
-       struct sockaddr_in addr;
-       struct hostent *host;
-       int sockListen;
-       int addrLen;
-       short port;
-       int val1;
-       struct linger val2;
+       for (i = 1; i <= MAX_SCREENS; i++)
+               memcpy(netGen+i, &netGen[0], sizeof(EventGenRec));
+} //Make_netGen
 
-       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");
-
- //    while(1) {
-       addrLen = sizeof(addr);
-       if ((sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen)) < 0)
-               die("accept");
-       fprintf(stderr, "Connection: %s\n", inet_ntoa(addr.sin_addr));
- //    if (!fork()) {
-               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);
-//             close(sock);
- //            exit(0);
- //    }
-//     close(sock);
- //    }
-       isServer = 1;
-       return 0;
-}
 
 ExtFunc int InitiateConnection(char *hostStr, char *portStr)
-{
+{ //connect to host
        struct sockaddr_in addr;
        struct hostent *host;
        short port;
-       int mySock;
 
+//     make_netGen();
+       AtExit(CloseNet);
        if (portStr)
                port = atoi(portStr);   /* XXX Error checking */
        else
@@ -121,105 +65,207 @@ ExtFunc int InitiateConnection(char *hostStr, char *portStr)
        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[0].fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                die("socket");
-       if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+       if (connect(netGen[0].fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                if (errno != ECONNREFUSED)
                        die("connect");
-               close(mySock);
+               close(netGen[0].fd);
                sleep(1);
                goto again;
        }
-       netGen.fd = sock = mySock;
-       AddEventGen(&netGen);
+       AddEventGen(&netGen[0]);
+       totalPlayers = 0;
        return 0;
+} //InitiateConnection
+
+ExtFunc 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) - sizeof(Players[me].spy),
+                                       &Players[me]);
+                               break;
+                       }
+                       case NP_gamedata:
+                       {
+                               fprintf(stderr, ": %d\n", event.type);
+                               break;
+                       }
+                       case NP_newPlayer:
+                       {
+                               totalPlayers++;
+                               memcpy(&Players[event.u.net.uid],
+                                       event.u.net.data, event.u.net.size);
+                               fprintf(stderr, "Receiving player #%d (%s)\n",
+                                       event.u.net.uid, Players[event.u.net.uid].name);
+                               break;
+                       }
+                       case NP_error:
+                       {
+                               fprintf(stderr, "Rejected by server: %s\n", event.u.net.data);
+                               exit(1);
+                       }
+                       default:
+                               break;
+               }
+               else
+                       fatal("Hm, the party apparantly ended prematurely.");
+       }
+       while (event.u.net.type != NP_goAhead);
+
+       // send Players[0]
+       // receive seed, initspeed
+               // receive #players
+               // receive Players[*]
+
+       /*
+                       {
+                       netint4 data[3];
+                       int len;
+                       int seed;
+
+                       if (protocolVersion >= 3)
+                               len = sizeof(data);
+                       else
+                               len = sizeof(netint4[2]);
+                       if ((Players[0].flags & SCF_setSeed))
+                               seed = Game.seed;
+                       else
+                               seed = time(0);
+                       if (waitConn)
+                               SRandom(seed);
+                       data[0] = hton4(Players[0].flags);
+                       data[1] = hton4(seed);
+                       data[2] = hton4(Game.initspeed);
+                       SendPackets(0, NP_startConn, len, data);
+                       if (WaitMyEvent(&event, EM_net) != E_net ||
+                                       event.u.net.type != NP_startConn)
+                               fatal("Network negotiation failed");
+                       memcpy(data, event.u.net.data, len);
+                       Players[1].flags = ntoh4(data[0]);
+                       seed = ntoh4(data[1]);
+                       if (initConn) {
+                               if ((Players[0].flags & SCF_setSeed) != (Players[1].flags & SCF_setSeed))
+                                       fatal("If one player sets the random number seed, "
+                                                       "both must.");
+                               if ((Players[0].flags & SCF_setSeed) && seed != Game.seed)
+                                       fatal("Both players have set the random number seed, "
+                                                       "and they are unequal.");
+                               if (protocolVersion >= 3 && Game.initspeed != ntoh4(data[2]))
+                                       fatal("Your opponent is using a different step-down "
+                                               "interval (-i).\nYou must both use the same one.");
+                               SRandom(seed);
+                       }
+               }
+               */
+//             SendPackets(0, NP_initData, strlen(Players[0].name) + 1, Players[0].name);
+
+/*
+                       if (WaitMyEvent(&event, EM_net) != E_net ||
+                                       event.u.net.type != NP_userName)
+                               fatal("Network negotiation failed");
+                       strncpy(Players[1].name, event.u.net.data,
+                               sizeof(Players[1].name) - 1);
+                       Players[1].name[sizeof(Players[1].name)-1] = 0;
+                       for (i = 0; Players[1].name[i]; ++i)
+                               if (!isprint(Players[1].name[i]))
+                                       Players[1].name[i] = '?';
+                       for (i = 0; Players[1].host[i]; ++i)
+                               if (!isprint(Players[1].host[i]))
+                                       Players[1].host[i] = '?';
+*/
+} //HandShake
+
+ExtFunc void CheckNetConn(void)
+{ //am I necessary?
 }
 
-static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event)
-{
+
+ExtFunc MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event)
+{ //receive
        int result;
        short uid, type, size;
-       netint4 data[3];
+       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));
+       // *ugly* memcpy(data, gen->buf, sizeof(data));
        uid = ntoh4(data[0]);
        type = ntoh4(data[1]);
        size = ntoh4(data[2]);
-       netBufGoal = size;
-       if (netBufSize < netBufGoal)
+       gen->bufGoal = size;
+       if (gen->bufSize < gen->bufGoal)
                return E_none;
-       netBufSize = 0;
-       netBufGoal = HEADER_SIZE3;
+       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_SIZE3;
-       event->u.net.data = netBuf + HEADER_SIZE3;
+       event->u.net.data = gen->buf + HEADER_SIZE3;
        if (type == NP_endConn) {
-               gotEndConn = 1;
-               return E_lostConn;
-       }
-       else if (type == NP_byeBye) {
-               lostConn = 1;
+               fprintf(stderr, "Close connection\n");
                return E_lostConn;
        }
        return E_net;
-}
-
-ExtFunc void CheckNetConn(void)
-{
-}
+} //NetGenFunc
 
 ExtFunc void SendPacket(short uid, NetPacketType type, int size, void *data)
-{
+{ //send shit to server
        netint4 header[3];
 
        header[0] = hton4(uid);
        header[1] = hton4(type);
        header[2] = hton4(size + HEADER_SIZE3);
-       if (MyWrite(sock, header, HEADER_SIZE3) != HEADER_SIZE3)
+       if (MyWrite(netGen[0].fd, header, HEADER_SIZE3) != HEADER_SIZE3)
+               die("write (header)");
+       if (size > 0 && data && MyWrite(netGen[0].fd, data, size) != size)
                die("write");
-       if (size > 0 && data && MyWrite(sock, data, size) != size)
-               die("write");
-}
+} //SendPacket
 
 ExtFunc void CloseNet(void)
-{
+{ //kick some connection's ass!
        MyEvent event;
 
-       if (sock >= 0) {
-               if (!lostConn) {
-                       SendPacket(0, NP_endConn, 0, NULL);
-                       if (isServer) {
-                               while (!lostConn)
-                                       WaitMyEvent(&event, EM_net);
-                       }
-                       else {
-                               while (!gotEndConn)
-                                       WaitMyEvent(&event, EM_net);
-                               SendPacket(0, NP_byeBye, 0, NULL);
-                       }
-               }
-               close(sock);
-               sock = -1;
+       if (netGen[0].fd >= 0) {
+               SendPacket(0, NP_endConn, 0, NULL);
+               close(netGen[0].fd);
+               netGen[0].fd = -1;
        }
-       if (netGen.next)
-               RemoveEventGen(&netGen);
-}
+       if (netGen[0].next)
+               RemoveEventGen(&netGen[0]);
+} //CloseNet
 
 /*
  * vi: ts=4 ai