PageRenderTime 59ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/class.scan.php

https://bitbucket.org/Intrepid-Web/cron-dupe-scanner
PHP | 412 lines | 333 code | 35 blank | 44 comment | 28 complexity | a98095c8363909bbecb86054b456d086 MD5 | raw file
  1. <?php
  2. if(!defined('in_main')) exit;
  3. class SCAN
  4. {
  5. private $is_locked;
  6. private $cfg;
  7. var $updated_files = array();
  8. var $storage_dir = './storage/';
  9. var $runlog_dir = './run_logs/';
  10. var $dupelog_dir = './dupe_logs/';
  11. var $datafile = 'data.txt';
  12. var $download_files = array();
  13. var $total_dupes = 0;
  14. private $caught_users;
  15. private $account_serial = array();
  16. private $account_name = array();
  17. private $character_serial = array();
  18. private $character_name = array();
  19. // ------------------
  20. // Initalize the SCAN class
  21. // Usage:
  22. // $scan = new SCAN('storage_path');
  23. // -------------------
  24. public function SCAN($cfg, $storage_dir = '', $datafile = '')
  25. {
  26. $this->cfg = $cfg;
  27. $this->download_files = (is_array($cfg['download_files']) && !empty($cfg['download_files'])) ? $cfg['download_files'] : $this->download_files;
  28. $this->storage_dir = ($storage_dir != '') ? $storage_dir : $this->storage_dir;
  29. $this->datafile = ($datafile != '') ? $datafile : $this->datafile;
  30. // Quick checks on our folders and etc
  31. if(!file_exists($this->storage_dir.$this->datafile)) die('Data file does not exist');
  32. if(!is_writable($this->storage_dir.$this->datafile)) die('Data file is not writable');
  33. if(!is_writable($this->runlog_dir)) die('Not enough permissions for the run log folder');
  34. if(!is_writable($this->dupelog_dir)) die('Not enough permissions for the dupe log folder');
  35. // Check locked process
  36. $this->is_locked = $this->check_lock_process();
  37. if($this->is_locked === true) {
  38. die('Process is locked, please wait...');
  39. }
  40. // Okay, now lets download our latest info
  41. $this->downloadLatest();
  42. // Get data info
  43. $datainfo = $this->get_datafile();
  44. # Run through any of the latest files
  45. foreach($this->updated_files as $file)
  46. {
  47. // Get the data of our latest file (old/new sizes and name)
  48. $file_data = $datainfo[$file];
  49. // Open a file handle for the file on our server
  50. $handle = fopen($this->storage_dir.$file, "r");
  51. if($file_data['new_size'] > $file_data['old_size'])
  52. {
  53. fseek($handle, $file_data['old_size']);
  54. }
  55. $contents = fread($handle, filesize($this->storage_dir.$file));
  56. // Close the on-server file handle
  57. fclose($handle);
  58. // Now we will just unleash dupe checks here
  59. $checks_dir = './inc/checks/';
  60. if($dh = opendir($checks_dir)) {
  61. # DEBUG
  62. if($cfg['enable_debug']) echo "Opend directory: ".$checks_dir."\r\n";
  63. while(false !== ($check_file = readdir($dh))) {
  64. # DEBUG
  65. if($cfg['enable_debug']) echo "Checking file: ".$check_file."\r\n";
  66. if(preg_match("/check\.([a-zA-Z_\-]*)\.php/", $check_file, $custom))
  67. {
  68. # DEBUG
  69. if($cfg['enable_debug']) echo "Accepted file: ".$custom[0]."\r\n";
  70. if(include_once $checks_dir.$custom[0]) {
  71. $function_name = "check_".$custom[1];
  72. if(is_callable($function_name)) {
  73. # DEBUG
  74. if($cfg['enable_debug']) echo "Called function: ".$function_name."\r\n";
  75. call_user_func_array($function_name, array($file, $contents, $this));
  76. } else {
  77. die("Unable to call function: $function_name (from: ".$custom[0].")");
  78. }
  79. }
  80. }
  81. }
  82. }
  83. closedir($dh);
  84. }
  85. }
  86. // ------------------
  87. // Downloads the latest data via ftp
  88. // Usage:
  89. // $this->downloadLatest()
  90. // -------------------
  91. private function downloadLatest()
  92. {
  93. // set up basic connection
  94. $conn_id = ftp_connect($this->cfg['ftp_host'], $this->cfg['ftp_port'], 5) or die('Could not connect to ftp server');
  95. // login with username and password
  96. $login_result = ftp_login($conn_id, $this->cfg['ftp_user'], $this->cfg['ftp_pass']);
  97. ftp_pasv ($conn_id, true);
  98. // Change directory
  99. if(!ftp_chdir($conn_id, $this->cfg['ftp_logs_dir'])) {
  100. die('Could not change FTP directory');
  101. }
  102. // Now lock the process, do not want anything else going on right now!
  103. $this->lock_process();
  104. // Loop through our dupe files
  105. foreach($this->download_files as $check_files)
  106. {
  107. $split = preg_split("/\//", $check_files, -1, PREG_SPLIT_NO_EMPTY);
  108. $dir = $split[0];
  109. $regex_file = $split[1];
  110. # Get a list of files
  111. $list_files = ftp_nlist($conn_id, $dir);
  112. # Narrow down the files to those we only want
  113. $list_files = preg_grep("/$regex_file/", $list_files);
  114. # Run through these files
  115. foreach($list_files as $file)
  116. {
  117. # Full file path
  118. $filepath = $dir.'/'.$file;
  119. // First, check if we have the file downloaded
  120. // If we do, we'll see if we need to re-download it
  121. if(file_exists($this->storage_dir.$file))
  122. {
  123. // If this file exists then we do some checks to see
  124. // if we need to update our local file
  125. // get the size of $file
  126. $res = ftp_size($conn_id, $filepath);
  127. // Get current file size
  128. $cur_size = filesize($this->storage_dir.$file);
  129. if ($res != -1) {
  130. if($res > $cur_size) {
  131. echo "Change in size of $file, $res bytes\r\n";
  132. // New file? Awsome, pretty simple
  133. // We download it and shove it in our latest_data file
  134. $handle = fopen($this->storage_dir.$file, 'a');
  135. // try to download $remote_file and save it to $handle
  136. if (ftp_fget($conn_id, $handle, $filepath, FTP_ASCII, $cur_size)) {
  137. echo "Successfully written to ".$this->storage_dir." $file\r\n";
  138. } else {
  139. echo "There was a problem while downloading $remote_file to $local_file\r\n";
  140. }
  141. // Set the latest files
  142. $this->updated_files[] = $file;
  143. // Update latest data
  144. $this->update_datafile($file,$cur_size,$res);
  145. // close the file
  146. fclose($handle);
  147. }
  148. } else {
  149. echo "couldn't get the size";
  150. }
  151. }
  152. else
  153. {
  154. // New file? Awsome, pretty simple
  155. // We download it and shove it in our latest_data file
  156. $handle = fopen($this->storage_dir.$file, 'w');
  157. // try to download $remote_file and save it to $handle
  158. if (ftp_fget($conn_id, $handle, $filepath, FTP_ASCII, 0)) {
  159. echo "Successfully written to ".$this->storage_dir." $file\r\n";
  160. } else {
  161. echo "There was a problem while downloading $remote_file to $local_file\r\n";
  162. }
  163. // Set the latest files
  164. $this->updated_files[] = $file;
  165. // Get filesize
  166. $cur_size = filesize($this->storage_dir.$file);
  167. // Update latest data
  168. $this->update_datafile($file,$cur_size,$cur_size);
  169. // close the file
  170. fclose($handle);
  171. }
  172. }
  173. }
  174. // and unlock it
  175. $this->unlock_process();
  176. // close the connection and the ftp server
  177. ftp_close($conn_id);
  178. }
  179. // ------------------
  180. // Updates our latest data file
  181. // Usage:
  182. // $this->update_datafile('datafile.txt', 0,0)
  183. // -------------------
  184. private function update_datafile($filename, $oldsize, $filesize)
  185. {
  186. $data_file = $this->storage_dir.$this->datafile;
  187. $handle = fopen($data_file, "rw+");
  188. $contents = @fread($handle, @filesize($data_file));
  189. rewind($handle);
  190. // We search the content for this file and update its size if it exists
  191. // pattern is: filename,filesize\n
  192. if(preg_match_all("/$filename,[0-9]*,[0-9]*\n/", $contents, $matches)) {
  193. $contents = preg_replace("/".$matches[0][0]."/", "$filename,$oldsize,$filesize\r\n", $contents);
  194. } else {
  195. $contents .= "$filename,$oldsize,$filesize\r\n";
  196. }
  197. fwrite($handle, $contents);
  198. fclose($handle);
  199. }
  200. // ------------------
  201. // Gets the information from the 'latest data' file
  202. // Usage:
  203. // $this->get_latestdata
  204. // -------------------
  205. private function get_datafile()
  206. {
  207. $return = array();
  208. $data_file = $this->storage_dir.$this->datafile;
  209. $handle = fopen($data_file, "r");
  210. $contents = fread($handle, filesize($data_file));
  211. $files = explode("\r\n",$contents);
  212. foreach($files as $file)
  213. {
  214. if($file != "") {
  215. $param = explode(",", $file);
  216. $return[$param[0]] = array("old_size" => $param[1], "new_size" => $param[2]);
  217. }
  218. }
  219. fclose($handle);
  220. return $return;
  221. }
  222. // ------------------
  223. // Adds to the $this->caught_users, making sure
  224. // there are no duplicates
  225. // Usage:
  226. // $this->add_caughtuser(...all required...)
  227. // -------------------
  228. public function add_caughtuser($dupe_type, $log, $account_serial, $account_name, $character_serial, $character_name, $time)
  229. {
  230. // Incriment total dupes, even if its not added to the caught users
  231. $this->total_dupes++;
  232. // Make sure to skip if we already have caught this user!
  233. if(!$this->add_to_array($account_serial, $this->account_serial)) return;
  234. if(!$this->add_to_array($account_name, $this->account_name)) return;
  235. if(!$this->add_to_array($character_serial, $this->character_serial)) return;
  236. if(!$this->add_to_array($character_name, $this->character_name)) return;
  237. // New user? Add it to the catch
  238. $this->caught_users[] = array(
  239. 'dupe_type' => $dupe_type,
  240. 'log' => $log,
  241. 'account_serial' => $account_serial,
  242. 'account_name' => $account_name,
  243. 'character_serial' => $character_serial,
  244. 'character_name' => $character_name,
  245. 'time' => strtotime($time)
  246. );
  247. return true;
  248. }
  249. // ------------------
  250. // Adds to an array only if uni uw
  251. // Usage:
  252. // $this->add_to_array(...all required...)
  253. // -------------------
  254. private function add_to_array($needle, &$haystack)
  255. {
  256. if($needle != 0 && $needle != '') {
  257. if(in_array($needle, $haystack)) {
  258. return false;
  259. } else {
  260. $haystack[] = $needle;
  261. return true;
  262. }
  263. } else {
  264. return true;
  265. }
  266. }
  267. // ------------------
  268. // Returns the array of caught users
  269. // Usage:
  270. // $this->list_caught_users()
  271. // -------------------
  272. public function list_caught_users()
  273. {
  274. return $this->caught_users;
  275. }
  276. // ------------------
  277. // Writes run data to a log file
  278. // Usage:
  279. // $this->lock_process
  280. // -------------------
  281. public function runLog($content)
  282. {
  283. $date = date("d-m-y_G-i");
  284. $fp = fopen($this->runlog_dir."$date.log", 'w');
  285. fwrite($fp, $content);
  286. fclose($fp);
  287. return true;
  288. }
  289. // ------------------
  290. // Dupe Log files
  291. // Usage:
  292. // $this->dupeLog('reward','asdoasd')
  293. // -------------------
  294. public function dupeLog($type, $content)
  295. {
  296. $date = date("d-m-y_G-i");
  297. $fp = fopen($this->dupelog_dir."[$date]$type.log", 'a+');
  298. fwrite($fp, $content);
  299. fwrite($fp, "\r\n");
  300. fclose($fp);
  301. return true;
  302. }
  303. // ------------------
  304. // Creates a locked file
  305. // Usage:
  306. // $this->lock_process
  307. // -------------------
  308. public function lock_process()
  309. {
  310. $fp = fopen('.lock', 'w');
  311. fwrite($fp, '1');
  312. fclose($fp);
  313. return true;
  314. }
  315. // ------------------
  316. // Deletes the lock file
  317. // Usage:
  318. // $this->unlock_process
  319. // -------------------
  320. public function unlock_process()
  321. {
  322. unlink('.lock');
  323. return true;
  324. }
  325. // ------------------
  326. // Returns boolean for the lock process
  327. // Usage:
  328. // $this->check_lock_process
  329. // -------------------
  330. public function check_lock_process()
  331. {
  332. if(file_exists('.lock')) {
  333. return true;
  334. } else {
  335. return false;
  336. }
  337. }
  338. }
  339. ?>