00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <stdincl.h>
00024
00025
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)
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
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();
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;
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();
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
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