Google
Web alhem.net
Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

ConnectThread.cpp

Go to the documentation of this file.
00001 00006 /* 00007 Copyright (C) 2004 Anders Hedstrom 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License 00011 as published by the Free Software Foundation; either version 2 00012 of the License, or (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 */ 00023 #include <stdincl.h> 00024 //#include <libcgi++.h> 00025 //#include <libiotm.h> 00026 00027 #include "defaults.h" 00028 #include "EventThread.h" 00029 #include "pprintf.h" 00030 #include "util/Parse.h" 00031 #include "Player.h" 00032 #include "Main.h" 00033 #include "events/Map.h" 00034 #include "Map.h" 00035 #include "ConnectThread.h" 00036 00037 using util::Parse; 00038 00039 00040 ConnectThread::ConnectThread() : IOThread() 00041 ,m_connected(0) 00042 ,m_port(0) 00043 ,m_pclEventThread(NULL) 00044 ,m_self(NULL) 00045 { 00046 *m_host = 0; 00047 m_port = 0; 00048 m_ip = 0L; 00049 } 00050 00051 ConnectThread::ConnectThread(char *host, int port) : IOThread(false) 00052 ,m_connected(0) 00053 ,m_port(port) 00054 ,m_pclEventThread(NULL) 00055 ,m_self(NULL) 00056 { 00057 printf("Connect thread constructor (%s, %d)\n",host,port); 00058 fflush(stdout); 00059 strcpy(m_host, host); 00060 printf("SetRelease(true)\n"); 00061 SetRelease(true); 00062 } 00063 00064 00065 ConnectThread::~ConnectThread() 00066 { 00067 DEB(printf("~ConnectThread()\n");) 00068 if (m_pclEventThread) 00069 { 00070 delete m_pclEventThread; 00071 } 00072 for (players_t::iterator it = m_players.begin(); it != m_players.end(); it++) 00073 { 00074 Player *p = it -> second; 00075 delete p; 00076 } 00077 { 00078 for (maps_t::iterator it = m_maps.begin(); it != m_maps.end(); it++) 00079 { 00080 Map *t = it -> second; 00081 delete t; 00082 } 00083 } 00084 } 00085 00086 00087 unsigned long ConnectThread::get_ip(char *ip) 00088 { 00089 Parse *pa; 00090 struct hostent *he; 00091 unsigned long l = 0L; 00092 int i,x = 1; 00093 00094 for (i = 0; i < (int)strlen(ip); i++) 00095 if ( (ip[i] < '0' || ip[i] > '9') && ip[i] != '.') 00096 x = 0; 00097 if (x) // ipaddr 00098 { 00099 pa = new Parse(ip,"."); 00100 l = pa -> getvalue(); 00101 l = (l << 8) + pa -> getvalue(); 00102 l = (l << 8) + pa -> getvalue(); 00103 l = (l << 8) + pa -> getvalue(); 00104 delete pa; 00105 l = htonl(l); 00106 } 00107 else // hostname 00108 { 00109 he = gethostbyname(ip); 00110 if (he) 00111 memmove(&l, he -> h_addr, 4); 00112 } 00113 DEB(printf(" ip %08lx\n", l);) 00114 return l; 00115 } 00116 00117 00118 void ConnectThread::Run() 00119 { 00120 struct sockaddr_in sa; 00121 struct timeval tv; 00122 fd_set rfds; 00123 fd_set wfds; 00124 socket_t s; 00125 int n; 00126 int i; 00127 00128 printf("Parsing host name '%s'\n",m_host); 00129 m_ip = get_ip(m_host); 00130 00131 s = ::socket(AF_INET, SOCK_STREAM, 0); 00132 if (s == INVALID_SOCKET) 00133 { 00134 perror("connect_thread: socket() failed"); 00135 goto off0; 00136 } 00137 00138 sa.sin_family = AF_INET; 00139 sa.sin_port = htons(m_port); 00140 memmove(&sa.sin_addr,&m_ip,4); 00141 00142 if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) 00143 { 00144 perror("connect() failed"); 00145 goto off; 00146 } 00147 00148 m_pclEventThread = new EventThread(); //event_thread); 00149 m_pclEventThread -> SetConnectThread( this ); 00150 00151 SetFileDescriptor(s); 00152 DEB(printf("Socket#%d\n", s);) 00153 while (IsRunning()) 00154 { 00155 tv.tv_sec = 1; 00156 tv.tv_usec = 0; //250000; // 0.05 00157 FD_ZERO(&rfds); 00158 FD_ZERO(&wfds); 00159 FD_SET(s, &rfds); 00160 if (get_oq() > 0) 00161 { 00162 FD_SET(s, &wfds); 00163 } 00164 #ifdef WIN32 00165 n = select(0, &rfds, &wfds, NULL, &tv); 00166 #else 00167 n = select(s + 1, &rfds, &wfds, NULL, &tv); 00168 #endif 00169 if (n == -1) 00170 { 00171 DEB(printf("select() failed\n");) 00172 perror("select() failed"); 00173 SetRunning(false); 00174 } 00175 if (n > 0 && FD_ISSET(s, &rfds)) 00176 { 00177 DEB(printf("rfds event\n");) 00178 i = fd_read(); // read(s, slask, 200); 00179 if (i == -1) 00180 { 00181 #ifdef WIN32 00182 int err; 00183 int errlen = sizeof(err); 00184 getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&err, &errlen); 00185 if (err != WSAEWOULDBLOCK) 00186 #endif 00187 { 00188 DEB(printf("read() failed (-1)\n");) 00189 perror("read() failed"); 00190 SetRunning(false); 00191 } 00192 } 00193 else 00194 if (!i) 00195 { 00196 pprintf("You have been disconnected from the server.\n"); 00197 fprintf(stderr,"disconnected (read() returns 0)\n"); 00198 SetRunning(false); 00199 } 00200 else 00201 { 00202 DEB(printf(" %d chars read\n",i);) 00203 } 00204 n--; 00205 } 00206 if (n > 0 && FD_ISSET(s, &wfds)) 00207 { 00208 DEB(printf("wfds event\n");) 00209 i = fd_write(); 00210 if (i == -1) 00211 { 00212 perror("write() failed"); 00213 SetRunning(false); 00214 } 00215 n--; 00216 } 00217 } 00218 if (m_pclEventThread) 00219 { 00220 m_pclEventThread -> SetRunning(false); 00221 } 00222 00223 // All done. 00224 pprintf("Disconnected from server.\n"); 00225 off: 00226 shutdown(s, 1); 00227 #pragma warning( "send an sdl event about the disconnect to clean up cache's") 00228 #ifdef WIN32 00229 closesocket(s); 00230 #else 00231 close(s); 00232 #endif 00233 SDL_Event e; 00234 e.type = SDL_USEREVENT; 00235 e.user.code = SDL_USEREVENT_DISCONNECT; 00236 e.user.data1 = NULL; 00237 e.user.data2 = NULL; 00238 SDL_PushEvent(&e); 00239 off0: 00240 SetRunning(false); 00241 } 00242 00243 00244 IOMessage *ConnectThread::GetClass(IO_IDTYPE id) 00245 { 00246 return m_pclEventThread ? m_pclEventThread -> GetClass(id) : NULL; 00247 } 00248 00249 00250 Player *ConnectThread::AddPlayer(long num) 00251 { 00252 Player *p; 00253 p = m_players[num]; 00254 if (!p) 00255 { 00256 p = new Player(num); 00257 m_players[num] = p; 00258 } 00259 return p; 00260 } 00261 00262 00263 Player *ConnectThread::AddPlayer(long num,const string &name) 00264 { 00265 Player *p = AddPlayer(num); 00266 p -> SetName(name); 00267 return p; 00268 } 00269 00270 00271 void ConnectThread::SetSelf(long num,const string &name) 00272 { 00273 m_self = GetPlayer(num); 00274 } 00275 00276 00277 Player *ConnectThread::GetPlayer(long num) 00278 { 00279 return m_players[num]; 00280 } 00281 00282 00283 Player *ConnectThread::GetSelf() 00284 { 00285 return m_self; 00286 } 00287 00288 00289 Map *ConnectThread::AddMap(long x,long y,Event::Map *e) 00290 { 00291 Map *map; 00292 long key = ((x / MAPSIZE) << 16) + (y / MAPSIZE); 00293 00294 map = m_maps[key]; 00295 if (!map) 00296 { 00297 map = new Map; 00298 m_maps[key] = map; 00299 } 00300 if (e) 00301 { 00302 map -> Populate(e); 00303 } 00304 return map; 00305 } 00306 00307 00308 Map *ConnectThread::GetMap(long x,long y) 00309 { 00310 long key = ((x / MAPSIZE) << 16) + (y / MAPSIZE); 00311 00312 return m_maps[key]; 00313 } 00314 00315

Generated for SDL C++ GUI by doxygen 1.3.6