/* * file com_query.c - client queryes for local network game * * $Id: com_query.c,v 1.3 2004/05/14 10:00:33 alfie Exp $ * * Program XBLAST * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net) * * 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; or (at your option) * any later version * * This program is distributed in the hope that it will be entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY 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 "com_query.h" #include "com_browse.h" #include "version.h" #include "client.h" #include "gui.h" #include "str_util.h" /* * local types */ typedef struct { XBCommBrowse browse; unsigned short port; unsigned char serial; char *addrBroadcast; struct timeval tvSend; } XBCommQuery; /* * local */ void Query_Send (XBComm *comm, const struct timeval *tv) { XBBrowseTeleQuery tele; XBCommQuery *qComm = (XBCommQuery *) comm; assert (NULL != qComm); assert (NULL != tv); /* send cyclic datagram */ tele.any.type = XBBT_Query; tele.any.serial = ++ qComm->serial; /* send data */ Browse_Send (&qComm->browse, qComm->addrBroadcast, qComm->port, XBTrue, &tele.any); /* mark time */ qComm->tvSend = *tv; } /* Query_Poll */ /* * ein server hat eine Antwort geschickt */ static void HandleReply (XBCommQuery *qComm, const XBBrowseTeleReply *tele, const char *host) { long msec; struct timeval tv; char version[32]; /* calculate sping time */ gettimeofday (&tv, NULL); msec = (tv.tv_sec - qComm->tvSend.tv_sec) * 1000L + (tv.tv_usec - qComm->tvSend.tv_usec) / 1000L; sprintf (version, "V%u.%u.%u", (unsigned) tele->version[0], (unsigned) tele->version[1], (unsigned) tele->version[2]); // Dbg_Out("%u %u\n",tele->version[0],VERSION_MAJOR); //Dbg_Out("%u %u\n",tele->version[0]==VERSION_MINOR); && (tele->version[2]==VERSION_PATCH)) { if(((tele->version[0]==VERSION_MAJOR) && (tele->version[1]==VERSION_MINOR) && (tele->version[2]==VERSION_PATCH)) || (tele->frameRate==0)) { /* inform application */ if(strlen(tele->host)<=0) { Dbg_Out ("game \"%s\" found at %s:%hu (%ld msec)\n", tele->game, host, tele->port, msec); Client_ReceiveReply (host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } else { // XBCC server response Dbg_Out ("game \"%s\" found at %s:%hu (from central %s %ld msec)\n", tele->game, tele->host, tele->port, host, msec); Client_ReceiveReply (tele->host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } } else { if(strlen(tele->host)<=0) { Dbg_Out ("game \"%s\" found at %s:%hu (%ld msec) WRONG VERSION\n", tele->game, host, tele->port, msec); //Client_ReceiveReply (host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } else { // XBCC server response Dbg_Out ("game \"%s\" found at %s:%hu (from central %s %ld msec) WRONG VERSION\n", tele->game, tele->host, tele->port, host, msec); //Client_ReceiveReply (tele->host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } } /* sprintf (version, "V%u.%u.%u", (unsigned) tele->version[0], (unsigned) tele->version[1], (unsigned) tele->version[2]); if(strlen(tele->host)<=0) { Dbg_Out ("game \"%s\" found at %s:%hu (%ld msec)\n", tele->game, host, tele->port, msec); Client_ReceiveReply (host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } else { Dbg_Out ("game \"%s\" found at %s:%hu (from central %s %ld msec)\n", tele->game, tele->host, tele->port, host, msec); Client_ReceiveReply (tele->host, tele->port, msec, version, tele->game, tele->numLives, tele->numWins, tele->frameRate); } */ } /* HandleReply */ /* * receive query data */ static void ReceiveQuery (XBCommBrowse *bComm, const XBBrowseTele *tele, const char *host, unsigned short port) { assert (NULL != bComm); assert (NULL != tele); assert (NULL != host); switch (tele->type) { case XBBT_Reply: HandleReply ((XBCommQuery *) bComm, &tele->reply, host); break; default: break; } } /* ReceiveQuery */ /* * */ static XBCommResult DeleteQuery (XBComm *comm) { XBCommQuery *qComm = (XBCommQuery *) comm; /* */ assert (NULL != qComm); Browse_Finish (&qComm->browse); assert (NULL != qComm->addrBroadcast); free (qComm->addrBroadcast); free (qComm); qComm = NULL; return XCR_OK; } /* DeleteQuery */ /* * create broadcast socket to query for network games */ XBComm * Query_CreateComm (const char *addrDevice, unsigned short port, const char *addrBroadcast) { XBSocket *pSocket; XBCommQuery *qComm; assert (NULL != addrBroadcast); /* create socket */ pSocket = Net_BindUdp (addrDevice, 0); if (NULL == pSocket) { return NULL; } /* create communication data structure */ qComm = calloc (1, sizeof (*qComm)); assert (NULL != qComm); /* set values */ Browse_CommInit (&qComm->browse, COMM_Query, pSocket, ReceiveQuery, DeleteQuery); qComm->port = port; qComm->serial = 0; qComm->addrBroadcast = DupString (addrBroadcast); qComm->tvSend.tv_sec = 0; qComm->tvSend.tv_usec = 0; /* that's all ? */ return &qComm->browse.comm; } /* C4S_CreateComm */ /* * end of file com_query.c */