YAPOG  0.0.1
Yet Another Pokemon Online Game
FileChecker.cpp
Go to the documentation of this file.
2 
3 namespace yap
4 {
6  : vfile_ ()
7  , vstring_ ()
8  , path_ (path)
9  , filename_ ("")
10  , filesize_ (0)
11  , md5_ ("")
12  , sizeDownloaded_ (0)
13  , fileDownloaded_ (0)
14  , vfiletodl_ ()
15  , dlend_ (true)
16  {
18  }
19 
21  : vfile_ ()
22  , vstring_ ()
23  , path_ ("")
24  , filename_ (filename)
25  , filesize_ (0)
26  , md5_ ("")
27  , sizeDownloaded_ (0)
28  , fileDownloaded_ (0)
29  , vfiletodl_ ()
30  , dlend_ (true)
31  {
32  }
33 
35  String md5,
36  size_t filesize)
37  : vfile_ ()
38  , vstring_ ()
39  , path_ ("")
40  , filename_ (filename)
41  , filesize_ (filesize)
42  , md5_ (md5)
43  , sizeDownloaded_ (0)
44  , fileDownloaded_ (0)
45  , vfiletodl_ ()
46  , dlend_ (true)
47  {
48  }
49 
51  size_t fs)
52  : Filename (fn)
53  , Filesize (fs)
54  {
55  }
56 
58  {
60  VFilesType::ItType it_end (vfile_.end ());
61 
63  VFileType::ItType its_end (vstring_.end ());
64 
65  for (; it != it_end; it++)
66  delete (*it);
67  for (; its != its_end; its++)
68  delete (*its);
69  }
70 
72  {
73  filename_ = filename;
74  }
75 
77  {
78  md5_ = md5;
79  }
80 
81  void FileChecker::SetDlEnd (bool dl)
82  {
83  dlend_ = dl;
84  }
85 
87  {
88  return filename_;
89  }
90 
92  {
93  return md5_;
94  }
95 
97  {
98  return filesize_;
99  }
100 
102  {
103  return vfile_;
104  }
105 
107  {
108  return vfiletodl_;
109  }
110 
112  {
113  return sizeDownloaded_;
114  }
115 
117  {
118  return fileDownloaded_;
119  }
120 
122  {
123  return dlend_;
124  }
125 
127  FileChecker* const s)
128  {
129  return (c->GetFilename () == s->GetFilename ()
130  && c->GetMd5 () == s->GetMd5 ());
131  }
132 
134  {
135  VPathType vp;
136  try
137  {
138  if (boost::filesystem::exists (path_))
139  {
140  yap::Md5 md5;
141  std::copy (
142  boost::filesystem::recursive_directory_iterator (path_),
143  boost::filesystem::recursive_directory_iterator (),
144  std::back_inserter (vp)
145  );
146 
147  VPathType::const_iterator it (vp.begin ());
148  VPathType::const_iterator it_end (vp.end ());
149 
150  for (; it != it_end; it++)
151  {
152  if (boost::filesystem::is_regular_file (*it))
153  {
154  int i = ((*it).string ()).length () + 1;
155  int j = path_.string ().length ();
156  i -= j;
157  std::ifstream f;
158  f.open(((*it).string ()).c_str ());
159  String mymd5 = md5.Calculate (f);
160  vfile_.Add(
161  new FileChecker (
162  ((*it).string ()).substr (path_.string ().length () + 1, i),
163  mymd5,
164  boost::filesystem::file_size ((*it).string ()))
165  );
166  f.close ();
167  }
168  if (boost::filesystem::is_directory((*it)))
169  {
170  int i = ((*it).string ()).length () + 1;
171  int j = path_.string ().length ();
172  i -= j;
173  vfile_.Add (
174  new FileChecker (((*it).string ()).
175  substr(path_.string ().length () + 1, i),
176  String ("0"), 0)
177  );
178  }
179  }
180  }
181  }
182  catch (const boost::filesystem::filesystem_error& ex)
183  {
184  std::cout << ex.what () << std::endl;
185  }
186  }
187 
189  FileChecker* elt)
190  {
191  VFilesType::ItType it (vc.begin ());
192  VFilesType::ItType it_end (vc.end ());
193  String name;
194 
195  for (; it != it_end; it++)
196  {
197  name = (*it)->GetFilename ();
198  if (name == elt->GetFilename ())
199  if ((*it)->GetMd5 () != elt->GetMd5 ())
200  {
201  std::replace(name.begin (), name.end (), '\\', '/');
202  return ((*it)->GetMd5 ().compare ("0") == 0 ? name + "0" : name);
203  }
204  else
205  return "";
206  }
207 
208  name = elt->GetFilename ();
209  std::replace(name.begin (), name.end (), '\\', '/');
210  return (elt->GetMd5 ().compare ("0") == 0 ? name + "0" : name);
211  }
212 
214  {
215  Thread* th = new Thread (MEMBER_WORKER(FileChecker::Update), this);
216  th->Launch ();
217  }
218 
219  void FileChecker::Launch (String sourcePath)
220  {
221  sourcepath_ = sourcePath;
222  Thread* th = new Thread (MEMBER_WORKER(FileChecker::Update), this);
223  th->Launch ();
224  }
225 
227  {
228  VFileType& vbis = fc->GetVFileToDl ();
229 
230  try
231  {
232  if (boost::filesystem::exists (path_))
233  {
235  VFilesType::ItType it_end (vfile_.end ());
236 
237  for (; it != it_end; it++)
238  {
239  String ret = VectorFind (fc->GetVfile (), (*it));
240  if (!ret.empty())
241  vbis.Add (new MyFile (ret, (*it)->GetFilesize ()));
242  }
243  }
244  }
245  catch (const boost::filesystem::filesystem_error& ex)
246  {
247  std::cout << ex.what () << std::endl;
248  }
249 
250  if (!vbis.IsEmpty ())
251  fc->SetDlEnd (false);
252  }
253 
255  {
256  sf::Ftp server;
260  String path = path_.string ();
261  String address = "";
262  String login = "";
263  String pw = "";
264  std::replace (path.begin (), path.end (), '\\', '/');
265 
266  if (server.connect (address).isOk ())
267  {
268  if (server.login (login, pw).isOk ())
269  {
270  server.changeDirectory ("test");
271  server.keepAlive ();
272  for (; it != it_end; it++)
273  {
274  String n = (*it)->Filename;
275  std::replace (n.begin (), n.end (), '\\', '/');
276  String newpath = "";
277 
278  int i = n.rfind ('/');
279  bool dl = true;
280  String name = n;
281  server.keepAlive ();
282  if (n[n.size () - 1] == '0')
283  {
284  dl = false;
285  name = n.substr(0, n.size () - 1);
286  boost::filesystem::create_directory(path + "/" + name);
287  }
288  else
289  {
290  if (i != String::npos)
291  {
292  name.assign (n, i + 1, n.size ());
293  newpath.assign (n, 0, i);
294  }
295  }
296  if (dl)
297  {
298  server.download (
299  (newpath.empty () ? name : (newpath + "/" + name)).c_str (),
300  (newpath.empty () ? path : (path + "/" + newpath)).c_str (), sf::Ftp::Binary);
301  }
302  }
303  }
304  server.disconnect ();
305  }
306  else
307  {
308  std::cout << "Failed to connect" << std::endl;
309  return false;
310  }
311 
312  fc->SetDlEnd (true);
313  return true;
314  }
315 
317  {
318  try
319  {
320  boost::asio::io_service io_service;
322  size_t vectorSize = vs.Count ();
323 
324  // Get a list of endpoints corresponding to the server name.
325  // Try each endpoint until we successfully establish a connection.
328 
329  for (; it != it_end; it++)
330  {
331  sizeDownloaded_ = 0;
332  boost::asio::ip::tcp::resolver resolver (io_service);
333  boost::asio::ip::tcp::resolver::query query ("yapog.free.fr", "http");
334  boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query);
335  boost::asio::ip::tcp::socket socket (io_service);
336  boost::asio::connect (socket, endpoint_iterator);
337 
338  boost::asio::streambuf request;
339  OStream request_stream (&request);
340  String n = (*it)->Filename;
341  std::replace (n.begin (), n.end (), '\\', '/');
342  String path = path_.string ();
343  String newpath = "";
344 
345  int i = n.rfind ('/');
346  bool dl = true;
347  String name = n;
348  if (n[n.size () - 1] == '0')
349  {
350  dl = false;
351  name = n.substr(0, n.size () - 1);
352  boost::filesystem::create_directory (path + "/" + name);
353  }
354  else
355  {
356  if (i != String::npos)
357  {
358  name.assign (n, i + 1, n.size ());
359  newpath.assign (n, 0, i);
360  }
361  }
362  if (dl)
363  {
364  filename_ = name;
365  request_stream << "GET " << ("/test/" + (newpath.empty () ? name : (newpath + "/" + name)))
366  << " HTTP/1.0\r\n"
367  << "Host: " << "yapog.free.fr" << "\r\n"
368  << "Accept: */*\r\n"
369  << "Connection: close\r\n\r\n";
370  boost::asio::write (socket, request);
371 
372  boost::asio::streambuf response;
373  boost::asio::read_until (socket, response, "\r\n");
374 
375  IStream response_stream (&response);
376  String http_version;
377  response_stream >> http_version;
378  UInt32 status_code;
379  response_stream >> status_code;
380  String status_message;
381  std::getline (response_stream, status_message);
382  if (!response_stream || http_version.substr(0, 5) != "HTTP/")
383  {
384  std::cout << "Invalid response\r\n";
385  return false;
386  }
387  if (status_code != 200)
388  {
389  std::cout << "Response returned with status code "
390  << status_code << "\r\n";
391  return false;
392  }
393 
394  size_t bytes = (*it)->Filesize;
395  boost::system::error_code error;
396  OFStream outfile;
397  std::stringstream ss;
398  String str;
399  outfile.open((newpath.empty () ? path + "/" + name :
400  (path + "/" + newpath + "/" + name)),
401  std::ios::binary);
402  size_t sizetotal = 0;
403 
404  while (boost::asio::read (socket, response,
405  boost::asio::transfer_at_least (1), error))
406  {
407  float percentageSize = 0;
408  sizetotal += response.size ();
409  percentageSize = (((float) sizetotal / (float) bytes) * 100);
410  sizeDownloaded_ = percentageSize;
411  ss << &response;
412  }
413  str = ss.str ();
414  if (sizetotal > bytes)
415  str.erase (0, sizetotal - bytes);
416  outfile << str;
417  outfile.close();
418  if (error != boost::asio::error::eof)
419  throw boost::system::system_error (error);
420  fileDownloaded_++;
421  }
422  }
423  }
424  catch (std::exception& e)
425  {
426  std::cout << "Exception: " << e.what () << std::endl;
427  return false;
428  }
429 
430  fc->SetDlEnd (true);
431  return true;
432  }
433 
435  {
437  size_t vectorSize = vs.Count ();
438 
439  // Get a list of endpoints corresponding to the server name.
440  // Try each endpoint until we successfully establish a connection.
443 
444  for (; it != it_end; it++)
445  {
446  sizeDownloaded_ = 0;
447  String n = (*it)->Filename;
448  std::replace (n.begin (), n.end (), '\\', '/');
449  String path = path_.string ();
450  String newpath = "";
451 
452  int i = n.rfind ('/');
453  bool dl = true;
454  String name = n;
455  if (n[n.size () - 1] == '0')
456  {
457  dl = false;
458  name = n.substr(0, n.size () - 1);
459  boost::filesystem::create_directory (path + "/" + name);
460  }
461  else
462  {
463  if (i != String::npos)
464  {
465  name.assign (n, i + 1, n.size ());
466  newpath.assign (n, 0, i);
467  }
468  }
469  if (dl)
470  {
471  filename_ = name;
472  IFStream in (sourcepath_ + "/" + n, IFStream::binary);
473  OFStream out (path + "/" + n, OFStream::trunc|OFStream::binary);
474  out << in.rdbuf ();
475  fileDownloaded_++;
477  }
478  }
479 
480  fc->SetDlEnd (true);
481  return true;
482  }
483 }