PageRenderTime 69ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/php/base/EventHandler.inc.php

https://bitbucket.org/obsidian/selador
PHP | 1501 lines | 1142 code | 198 blank | 161 comment | 276 complexity | f519452a994c26d3d52ca9bd82f5a55e MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* EventHandler.inc.php - Event handler
  3. *
  4. * Copyright (C) 2006, 2007, 2008 Kevin Read, Simone Schaefer
  5. *
  6. * This file is part of Selador, a browser-based fantasy strategy game
  7. *
  8. * This program is distributed under the terms of the GNU Affero General Public License.
  9. *
  10. *
  11. * Selador is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as published by
  13. * the Free Software Foundation, either version 3 of the License, or
  14. * any later version.
  15. *
  16. * Selador is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with Selador. If not, see <http://www.gnu.org/licenses/>.
  23. **/
  24. // Producer-consumer pattern. Acceptable style and design.
  25. require_once ("event.php");
  26. require_once ("eventmap.php");
  27. class EventHandler
  28. {
  29. private $users = array ();
  30. private $queued_villages = array ();
  31. private $events = array ();
  32. private $mainuid;
  33. private $mainuser;
  34. private $running = false;
  35. private $deleids = array ();
  36. private $seen_eids = array ();
  37. private $user_row = null;
  38. private $refresh_villages = array ();
  39. private $startvillage = 0;
  40. public $gui = null;
  41. public $dummygui = null;
  42. public $fails = false;
  43. public function __construct ($user, $gui, &$user_row, $db, $startvillage=0)
  44. {
  45. $this->users[$user->uid] =& $user;
  46. $this->mainuid = $user->uid;
  47. $this->mainuser =& $this->users[$this->mainuid];
  48. $this->gui =& $gui;
  49. $this->user_row =& $user_row;
  50. $this->db = $db;
  51. if ($startvillage)
  52. $this->startvillage = $startvillage;
  53. else
  54. $this->startvillage = $this->mainuser->activevillageid;
  55. /* $query = "lock tables event write";
  56. if (!mysql_query ($query))
  57. {
  58. $this->mainuser->log_err ("Cannot lock table events. Query: ".$query.", ".mysql_error ());
  59. } */
  60. /*$query = "unlock tables event write";
  61. if (!mysql_query ($query))
  62. {
  63. $this->mainuser->log_err ("Cannot unlock table events. Query: ".$query.", ".mysql_error ());
  64. } */
  65. }
  66. public function run ()
  67. {
  68. return ($this->fetchmyevents ($this->mainuid, $this->startvillage));
  69. }
  70. private function log_this_event ($str, $dif, $eid, $ev)
  71. {
  72. $this->mainuser->log_debug ($str." event with DIF ".$dif." EID ".$eid." has uid1 ".$ev['uid1']." vid1 ".$ev['village1']." uid2 ".$ev['uid2']." vid2 ".$ev['village2']." stamp ".$ev['timestamp']." type ".$ev['type']." param ".$ev['param']." param2 ".$ev['param2']." score ".$ev['score']." flag ".$ev['flag']);
  73. }
  74. private function log_events ($str)
  75. {
  76. foreach ($this->events as $dif=>$timegroup)
  77. {
  78. foreach ($timegroup as $eid=>$ev)
  79. {
  80. $this->log_this_event ($str, $dif, $eid, $ev);
  81. }
  82. }
  83. }
  84. public function fetchmyevents ($uid, $village)
  85. {
  86. if (!isset ($this->users[$uid]) || !isset ($this->users[$uid]->villages[$village]))
  87. {
  88. $this->mainuser->log_err ("Cannot find user ".$this->mainuid." or his village ".$village." in fetchevents");
  89. return (false);
  90. }
  91. // Now check to see if this village is up-to-date
  92. if ($this->users[$uid]->villages[$village]->dirty)
  93. $this->users[$uid]->villages[$village]->update_to_latest (true, $this->user_row['time']);
  94. $this->users[$uid]->villages[$village]->updated = true;
  95. $query = "select A.*, time_to_sec(timediff(A.timestamp,\"" . $this->user_row['time'] . "\")) as dif, time(A.timestamp) as time_arrival from event A where (A.flag=1 and A.village1>0 and (A.timestamp<=\"" . $this->user_row['time'] . "\" or A.uid1=".$this->mainuid.")) or A.village1=".$village." or A.uid2=".$this->mainuid." for update";
  96. // $query = "select *, time_to_sec(timediff(timestamp,now())) as dif from event where (flag=1 and village1>0 and (timestamp<=now() or uid1=".$this->mainuid.")) or village1=".$this->mainuid." or uid2=".$this->mainuid." order by dif asc for update";
  97. if (!($evres = $this->db->query ($query)))
  98. {
  99. $this->mainuser->log_err ("Cannot calc events. Query: ".$query.", error: ".mysql_error ());
  100. // selects often fail in the events table because of the high level of locking.
  101. // This is not fatal. Just roll the transaction back and start over
  102. if ($this->db->isTimeOut ())
  103. {
  104. $this->mainuser->log_err ("fetchmyevents: Rolling back");
  105. $this->db->query ("rollback");
  106. $this->fails = true;
  107. }
  108. return false;
  109. }
  110. else
  111. {
  112. while ($row = mysql_fetch_array ($evres))
  113. {
  114. if (!isset ($this->seen_eids[$row['eid']]))
  115. {
  116. $this->seen_eids[$row['eid']] = true;
  117. $this->events[$row['dif']][$row['eid']] = $row;
  118. }
  119. }
  120. ksort ($this->events);
  121. $this->queued_villages[$village] = true;
  122. $this->log_events ("Queued ");
  123. return ($this->run_queue ());
  124. }
  125. }
  126. public function query_secondary_events ($uid, $newvillage)
  127. {
  128. if (count ($this->users[$uid]->villages[$newvillage]->outposts))
  129. $targetstr = " in (".$newvillage.",".implode (",", array_keys ($this->users[$uid]->villages[$newvillage]->outposts)).")";
  130. else
  131. $targetstr = "=".$newvillage;
  132. $query = "select *, time_to_sec(timediff(A.timestamp,\"" . $this->user_row['time'] . "\")) as dif, time(A.timestamp) as time_arrival from event A where (((A.uid1=".$uid." and A.village1=".$newvillage.") or (A.uid2=".$uid." and A.village2".$targetstr.")) and A.timestamp<=\"" . $this->user_row['time'] . "\") for update";
  133. return $query;
  134. }
  135. private function check_user ($uid, $log=false, $logstr="")
  136. {
  137. if (!isset ($this->users[$uid]))
  138. {
  139. // Deleting old events may fail because of table locking concurrency in events
  140. if (!$this->delete_old_events ())
  141. return false;
  142. $victim = new User ();
  143. $victim->BecomeUserByUid ($uid);
  144. $victim->invoked_by = $this->mainuid; // This is not exactly correct :)
  145. $victim->fetch_villages();
  146. $victim->master_time = $this->user_row['time'];
  147. $this->users[$uid] =& $victim;
  148. if ($log)
  149. $this->mainuser->log_debug ("Didn't have user ".$logstr." ".$uid." while running event queue");
  150. }
  151. return true;
  152. }
  153. private function check_village1 (&$evrow)
  154. {
  155. if ($evrow['village1'] > 0)
  156. {
  157. $this->mainuser->log_debug ("check_village1: ".$evrow['uid1'].", ".$evrow['village1']);
  158. return ($this->check_village ($evrow['uid1'], $evrow['village1']));
  159. }
  160. }
  161. private function check_village2 (&$evrow)
  162. {
  163. if (($evrow['uid2'] > 0) && ($evrow['village2'] > 0))
  164. {
  165. $this->mainuser->log_debug ("check_village2: ".$evrow['uid2'].", ".$evrow['village2']);
  166. return ($this->check_village ($evrow['uid2'], $evrow['village2']));
  167. }
  168. }
  169. // Check to see if this village is up-to-date, and also if it's events have been queued
  170. private function check_village (&$uid, $vid)
  171. {
  172. // Don't run queries if we run into deadlock already
  173. if ($this->fails)
  174. return (false);
  175. if (!isset ($this->users[$uid]))
  176. {
  177. if (!$this->check_user ($uid))
  178. {
  179. if ($this->db->isTimeOut ())
  180. {
  181. $this->mainuser->log_err ("Rolling back, cannot delete old events");
  182. $this->db->query ("rollback");
  183. $this->fails = true;
  184. return false;
  185. }
  186. }
  187. }
  188. if (!isset ($this->users[$uid]->villages[$vid]))
  189. {
  190. $targetvill = $this->users[$uid]->lookup_outpost ($vid);
  191. if (!$targetvill)
  192. {
  193. $this->users[$uid]->log_err ("Blech in check_village: Can't find village ".$vid." for ".$uid);
  194. // This is a serious problem. For now we read the true owner of the village/outpost from the village table
  195. // and then pretend this is his event.
  196. $uid = 0;
  197. return (false);
  198. // FIXME: Don't return false here but just use the uid from the village table
  199. }
  200. $outpostid = $vid;
  201. $vid = $targetvill;
  202. }
  203. if ($this->users[$uid]->villages[$vid]->dirty)
  204. $this->users[$uid]->villages[$vid]->update_to_latest (true, $this->user_row['time']);
  205. if (!isset ($this->queued_villages[$vid]))
  206. {
  207. $this->mainuser->log_debug ("village ".$vid." not queued");
  208. // Differentiate here between mainuid's events and other peoples events
  209. // mainuids events already have attack-type events included, so we only need
  210. // events for this village for them
  211. if ($uid == $this->mainuid)
  212. $query = "select *, time_to_sec(timediff(timestamp,\"" . $this->user_row['time'] . "\")) as dif, time(timestamp) as time_arrival from event where uid1=".$uid." and village1=".$vid." order by dif asc for update";
  213. else
  214. $query = $this->query_secondary_events ($uid, $vid);
  215. if (!($evres = $this->db->query ($query)))
  216. {
  217. $this->users[$uid]->log_err ("Cannot calc events when checking village. Query: ".$query.", error: ".$this->db->error ());
  218. // selects often fail in the events table because of the high level of locking.
  219. // This is not fatal. Just roll the transaction back and start over
  220. if ($this->db->isTimeOut ())
  221. {
  222. $this->mainuser->log_err ("Rolling back");
  223. $this->db->query ("rollback");
  224. $this->fails = true;
  225. return false;
  226. }
  227. }
  228. else
  229. {
  230. while ($row = mysql_fetch_array ($evres))
  231. {
  232. if (!isset ($this->seen_eids[$row['eid']]))
  233. {
  234. $this->seen_eids[$row['eid']] = true;
  235. $this->events[$row['dif']][$row['eid']] = $row;
  236. }
  237. }
  238. ksort ($this->events);
  239. $this->queued_villages[$vid] = true;
  240. return (true);
  241. }
  242. }
  243. return (false);
  244. }
  245. private function delete_this_eid ($evrow)
  246. {
  247. if ($evrow['eid'] > 0)
  248. $this->deleids[] = $evrow['eid'];
  249. }
  250. private function delete_old_events ()
  251. {
  252. if (count ($this->deleids) > 0)
  253. {
  254. $query = "delete from event where eid in (".implode (",", $this->deleids).")\n";
  255. $this->mainuser->log_debug ("delquery: ".$query);
  256. if (!mysql_query ($query))
  257. {
  258. $this->mainuser->log_err ("Cannot delete old events. Query: ".$query.", ".$this->db->error ());
  259. return false;
  260. }
  261. else
  262. $this->deleids = array ();
  263. }
  264. return true;
  265. }
  266. private function update_all_users ()
  267. {
  268. $dummygui = false;
  269. foreach ($this->users as $this_user)
  270. {
  271. // Only the calling user gets his activity upped
  272. if ($this_user->uid == $this->mainuid)
  273. $this_user->save_score (true);
  274. else
  275. $this_user->save_score (false);
  276. $this_user->hero->regenerate ();
  277. $deleids_to_add = array ();
  278. foreach ($this_user->villages as $this_village)
  279. {
  280. if (count ($this_village->recruiting))
  281. {
  282. if (($this_user->uid == $this->mainuid) && ($this_village->villageid == $this->startvillage))
  283. $this_user->update_score ($this_village->recruit_handler ($this->gui, $deleids_to_add));
  284. else
  285. $this_user->update_score ($this_village->recruit_handler ($dummygui, $deleids_to_add));
  286. $this_village->recruiting = array ();
  287. }
  288. if ($this_village->updated)
  289. {
  290. $this_village->do_income (true);
  291. if ($this_village->villageid != $this->mainuser->activevillageid)
  292. $this_village->update_stamp_nounlock (true, "nounlock", $this->user_row['time']);
  293. }
  294. }
  295. $this->deleids = array_merge ($deleids_to_add, $this->deleids);
  296. }
  297. }
  298. // Iterate through all queued events and handle each of them in chronological order
  299. public function run_queue ()
  300. {
  301. $this->running = true;
  302. // We might have to start the process multiple times
  303. while ($this->running)
  304. {
  305. $this->delete_old_events ();
  306. $this->running = false;
  307. foreach ($this->events as $dif=>$eventlist)
  308. {
  309. foreach ($eventlist as $eid=>$ev)
  310. {
  311. if ($ev['dif'] <= 0) // Events in the past, to be parsed - what a laugh
  312. {
  313. // First, we need to check some preconditions
  314. $this->check_user ($ev['uid1'], true, $logstr="uid1");
  315. if ($ev['uid2'] > 0)
  316. {
  317. $this->check_user ($ev['uid2'], true, $logstr="uid2");
  318. }
  319. // Check if we have run into the deadlock or lock timeout
  320. if ($this->fails)
  321. {
  322. // Yes, return and start over
  323. $this->mainuser->log_debug ("Returning from run_queue because of deadlock");
  324. return false;
  325. }
  326. $this->log_this_event ("Handling ", $dif, $eid, $ev);
  327. // Now start the run through the queue
  328. if ($this->handle_past ($ev))
  329. {
  330. $this->running = true;
  331. $this->mainuser->log_debug ("run_queue: Starting over!!");
  332. break 2;
  333. }
  334. else
  335. {
  336. unset ($this->events[$dif][$eid]);
  337. // Record an eventlog entry for all history
  338. // FIXME: Do this in BATCH!!!!
  339. if (($ev['type'] != RECRUITING) && ($ev['type'] != BUILDING_DELEGATE) && ($ev['type'] != RESEARCH_DELEGATE) && ($ev['type'] != RESSOURCE_DELEGATE))
  340. {
  341. $query = "insert into eventlog values (".$ev['eid'].", ".$ev['uid1'].", ".$ev['village1'].", ".$ev['uid2'].", ".$ev['village2'].", now(), '".$ev['timestamp']."', ".$ev['type'].", ".$ev['param'].", ".$ev['param2'].", ".$ev['score'].", 1)";
  342. if (!mysql_query ($query))
  343. $this->mainuser->log_err ("Cannot update eventlog. Query: ".$query.", ".mysql_error());
  344. }
  345. }
  346. }
  347. else
  348. {
  349. // Future events that don't match up with pre-loaded users are of no interest to us
  350. if (($ev['uid1'] == $this->mainuid) || ($ev['uid2'] == $this->mainuid))
  351. $this->handle_future ($ev);
  352. }
  353. }
  354. }
  355. }
  356. $this->update_all_users ();
  357. $this->delete_old_events ();
  358. return (true);
  359. }
  360. // Handle one past event
  361. // Returns true if the list of events might have changed and we have to re-iterate over all
  362. private function handle_past ($evrow)
  363. {
  364. if ($this->check_village1 ($evrow))
  365. return (true);
  366. // check_village might have told us this entry is botched
  367. if ($evrow['uid1'] == 0)
  368. $this->mainuser->log_err ("Skipping event ".$evrow['eid'].": Cannot find uid1/vid1 combo");
  369. switch ($evrow['type'])
  370. {
  371. // Building construction
  372. // Params:
  373. // village1 = village_id where construction takes place
  374. // village2 = building_id (not building type!!)
  375. // param = level that building is raised to
  376. // param2 = builing id
  377. case BUILDING:
  378. $this->handle_past_building ($evrow);
  379. $this->delete_this_eid ($evrow);
  380. break;
  381. case BUILDING_DELEGATE:
  382. if ($evrow['uid1'] == $this->mainuid)
  383. {
  384. $this->handle_past_building_delegate ($evrow);
  385. $this->delete_this_eid ($evrow);
  386. }
  387. break;
  388. case RL_ALLY_DIPL:
  389. // Reload diplomacy for my ally_reload_diplomacy
  390. if ($this->users[$evrow['uid1']]->aid && ($evrow['uid1'] == $this->mainuid))
  391. {
  392. $this->handle_past_diplomacy_reload ($evrow);
  393. $this->delete_this_eid ($evrow);
  394. }
  395. break;
  396. case 100:
  397. if ($evrow['uid1'] == $this->mainuid)
  398. {
  399. $this->mainuser->CalcCommanders ();
  400. $this->mainuser->log_info ("Recalced Commanders");
  401. $this->delete_this_eid ($evrow);
  402. }
  403. break;
  404. case RESEARCH:
  405. $this->handle_past_research ($evrow);
  406. $this->delete_this_eid ($evrow);
  407. break;
  408. case RESEARCH_DELEGATE:
  409. if ($evrow['uid1'] == $this->mainuid)
  410. {
  411. $this->mainuser->CalcResearch(true);
  412. $this->delete_this_eid ($evrow);
  413. }
  414. break;
  415. case RECRUITING:
  416. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->recruiting[] = $evrow;
  417. break;
  418. case RETURNING:
  419. // Will this save the village later on???
  420. $this->users[$evrow['uid1']]->merge_troops ($evrow['village1'], $evrow['village1'], $evrow['param'], $evrow['param2'], abs ($evrow['dif']));
  421. $this->delete_this_eid ($evrow);
  422. break;
  423. case MOVE:
  424. $this->users[$evrow['uid1']]->merge_troops ($evrow['village2'], $evrow['village2'], $evrow['param'], 0, abs ($evrow['dif']));
  425. $this->delete_this_eid ($evrow);
  426. break;
  427. case SUPPORT:
  428. $this->users[$evrow['uid1']]->merge_troops ($evrow['village1'], $evrow['village2'], $evrow['param']);
  429. $this->delete_this_eid ($evrow);
  430. break;
  431. case GROUPATTACK_PART:
  432. $this->delete_this_eid ($evrow);
  433. break;
  434. case ATTACK:
  435. case GROUPATTACK:
  436. $fightrounds = 6;
  437. case SIEGE:
  438. if ($evrow['type'] == SIEGE) // Looks stupid, I know :)
  439. $fightrounds = 9;
  440. case RAID:
  441. if ($evrow['type'] == RAID) // Looks stupid, I know :)
  442. $fightrounds = 3;
  443. case SPY:
  444. if ($this->check_village2 ($evrow))
  445. return (true);
  446. else
  447. {
  448. // check_village might have told us this entry is botched
  449. if ($evrow['uid2'] == 0)
  450. $this->mainuser->log_err ("Skipping type ".$evrow['type']." event ".$evrow['eid']." uid1:".$evrow['uid1'].", village1: ".$evrow['village1'].": Cannot find uid2/vid2 combo");
  451. else
  452. {
  453. $retev = $this->handle_past_attack ($evrow, $fightrounds);
  454. if (is_array ($retev) && count($retev))
  455. {
  456. return (true);
  457. }
  458. }
  459. }
  460. break;
  461. case TRANSPORT:
  462. $olduid2 = $evrow['uid2'];
  463. $oldvid2 = $evrow['village2'];
  464. if ($this->check_village2 ($evrow))
  465. return (true);
  466. else
  467. {
  468. // check_village might have told us this entry is botched
  469. // if ($evrow['uid2'] == 0)
  470. // $this->mainuser->log_err ("Skipping transport event ".$evrow['eid']." uid1:".$evrow['uid1'].", village1: ".$evrow['village1'].": uid2:".$olduid2.", village2: ".$oldvid2."; Cannot find uid2/vid2 combo");
  471. if ($this->handle_past_transport ($evrow))
  472. {
  473. return (true);
  474. }
  475. }
  476. break;
  477. // Ressource fields
  478. case 1000:
  479. case 1001:
  480. case 1002:
  481. case 1003:
  482. case 1004:
  483. $this->handle_past_ressource_event ($evrow);
  484. $this->delete_this_eid ($evrow);
  485. break;
  486. case RESSOURCE_DELEGATE:
  487. if ($evrow['uid1'] == $this->mainuid)
  488. {
  489. if (isset ($this->mainuser->villages[$evrow['param2']]))
  490. $this->mainuser->villages[$evrow['param2']]->update_production();
  491. else
  492. $this->mainuser->villages[$evrow['village1']]->update_production();
  493. $this->delete_this_eid ($evrow);
  494. }
  495. break;
  496. }
  497. return (false);
  498. }
  499. private function handle_past_building ($evrow)
  500. {
  501. if (!is_object ($this->users[$evrow['uid1']]))
  502. {
  503. $this->mainuser->log_error ("User ".$evrow['uid1']." not instantiated for eid ".$evrow['eid']);
  504. }
  505. $this->users[$evrow['uid1']]->log_debug ("Fertig: building level for uid ".$evrow['uid1'].", village ".$evrow['village1'].", buildid ".$evrow['param2'].", level ".$evrow['param']);
  506. $query = "replace into villbuild values (".$evrow['village1'].", ".$evrow['param2'].", ".$evrow['param'].")";
  507. if (!mysql_query ($query))
  508. $this->users[$evrow['uid1']]->log_error ("Cannot insert new building level for uid ".$evrow['uid1'].", village ".$evrow['village1'].", buildid ".$evrow['param2'].", level ".$evrow['param'].". Query: ".$query.", error ".mysql_error());
  509. // Delete the cached files
  510. $city_path="precity/";
  511. $precalcpath = $city_path.$evrow['village1'];
  512. $files = glob ($precalcpath."*");
  513. if (count ($files))
  514. {
  515. foreach ($files as $file)
  516. while (!@unlink ($file)) usleep (2000);
  517. }
  518. // Update the score
  519. $this->users[$evrow['uid1']]->update_score ($evrow['score'], $evrow['village1']);
  520. // All events that might affect values in the session object must add a delegate event
  521. if ($evrow['uid1'] != $this->mainuid)
  522. $this->users[$evrow['uid1']]->add_delegate (BUILDING_DELEGATE, false, $evrow['param2'], $evrow['village1']);
  523. // Some buildings have an effect on other events, like the alchemist or zunfthaus
  524. // Others change global flags, like storage. This is the building type we are
  525. // looking at
  526. switch ($evrow['param2'])
  527. {
  528. case 2: // Marketplace
  529. $merchants_to_add = ($evrow['param'] * 5) + 10;
  530. $query = "update village set merchants=merchants+".$merchants_to_add." where villageid=".$evrow['village1'];
  531. if (!mysql_query ($query))
  532. $this->users[$evrow['uid1']]->log_err ("Event marketplace update failed: ".$query.": ".mysql_error());
  533. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->merchants += $merchants_to_add; // refresh merchants
  534. break;
  535. case 1: // Bergfried
  536. // Every 4 levels we gain an expansion slot
  537. if (($evrow['param'] % 4) == 0)
  538. {
  539. if ($evrow['param'] > 16)
  540. {
  541. $query = "update village set out_expansion=out_expansion+1 where villageid=".$evrow['village1'];
  542. $this->users[$evrow['uid1']]->log_debug ("Updating outpost expansion slots. Slots now: ".$this->users[$evrow['uid1']]->villages[$evrow['village1']]->outpost_expansion.", query: ".$query);
  543. if (!mysql_query ($query))
  544. $this->users[$evrow['uid1']]->log_err ("Event bergfried update failed: ".$query.": ".mysql_error ());
  545. }
  546. else
  547. {
  548. $query = "update village set expansion=expansion+1 where villageid=".$evrow['village1'];
  549. $this->users[$evrow['uid1']]->log_debug ("Updating expansion slots. Slots now: ".$this->users[$evrow['uid1']]->villages[$evrow['village1']]->expansion_slots.", query: ".$query);
  550. if (!mysql_query ($query))
  551. $this->users[$evrow['uid1']]->log_err ("Event bergfried update failed: ".$query.": ".mysql_error ());
  552. }
  553. if ($evrow['uid1'] == $this->mainuid)
  554. {
  555. $query = "select expansion, out_expansion from village where villageid=".$evrow['village1'];
  556. if (!($res = mysql_query ($query)))
  557. $this->users[$evrow['uid1']]->log_err ("Cannot read back expansion slots. Query: ".$query.", ".mysql_error());
  558. else
  559. {
  560. if (!($row = mysql_fetch_row ($res)))
  561. $this->users[$evrow['uid1']]->log_err ("No rows returned while reading back expansion slots. Query: ".$query);
  562. else
  563. {
  564. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->expansion_slots = $row[0];
  565. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->outpost_expansion = $row[1];
  566. }
  567. }
  568. }
  569. }
  570. break;
  571. case 5: // zunfthaus
  572. $factor = ConstructionTime ($evrow['param']);
  573. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->speed_build = $factor;
  574. $query = "update village set buildspeed=\"".$factor."\" where villageid=".$evrow['village1'];
  575. // echo $query;
  576. if (!mysql_query ($query))
  577. $this->users[$evrow['uid1']]->log_err ("Event buildspeed update failed: ".$query.": ".mysql_error());
  578. break;
  579. case 6: // Storage
  580. // Storage space for level 1 is special
  581. if ($evrow['param'] == 1)
  582. $newstorage = LVL1_STORAGE;
  583. else
  584. $newstorage = LevelGadgetNice ($evrow['param'], LVL2_STORAGE);
  585. $query = "update village set resmax=".$newstorage." where villageid=".$evrow['village1'];
  586. // echo $query;
  587. if (!mysql_query ($query))
  588. $this->users[$evrow['uid1']]->log_err ("Event storage update failed: ".$query.": ".mysql_error());
  589. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->ress_max = $newstorage; // refresh ressource production - could be handled more efficiently FIXME
  590. if ($this->mainuid != $evrow['uid1'])
  591. {
  592. $query = "update user set flags=flags|8 where uid=".$evrow['uid1'];
  593. if (!mysql_query($query))
  594. $this->users[$evrow['uid1']]->log_err ("Could not update user flags for village storage refresh");
  595. }
  596. break;
  597. case 10: // alchemist
  598. $factor = ConstructionTime ($evrow['param']);
  599. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->speed_research = $factor;
  600. $query = "update village set resspeed=\"".$factor."\" where villageid=".$evrow['village1'];
  601. // echo $query;
  602. if (!mysql_query ($query))
  603. $this->users[$evrow['uid1']]->log_err ("Event resspeed update failed: ".$query.": ".mysql_error());
  604. break;
  605. case 3: // garrison
  606. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_recrspeed (1, $evrow);
  607. break;
  608. case 19: // stables
  609. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_recrspeed (2, $evrow);
  610. break;
  611. case 18: // archery yard
  612. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_recrspeed (3, $evrow);
  613. break;
  614. case 9: // workshop
  615. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_recrspeed (4, $evrow);
  616. break;
  617. case 20: // castle
  618. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_recrspeed (5, $evrow);
  619. break;
  620. }
  621. }
  622. private function handle_past_building_delegate ($evrow)
  623. {
  624. switch ($evrow['param2'])
  625. {
  626. case 2: // Marketplace
  627. $this->mainuser->villages[$evrow['village1']]->merchants += $evrow['param'] + 10; // refresh merchants
  628. break;
  629. case 1: // Bergfried
  630. $query = "select expansion from village where villageid=".$evrow['village1'];
  631. if (!($res = mysql_query ($query)))
  632. $this->mainuser->log_err ("Cannot read back expansion slots. Query: ".$query.", ".mysql_error());
  633. else
  634. {
  635. if (!($row = mysql_fetch_row ($res)))
  636. $this->mainuser->log_err ("No rows returned while reading back expansion slots. Query: ".$query);
  637. else
  638. $this->mainuser->villages[$evrow['village1']]->expansion_slots = $row[0];
  639. }
  640. break;
  641. case 5:
  642. case 6:
  643. case 10:
  644. case 3:
  645. case 19:
  646. case 18:
  647. case 9:
  648. case 20:
  649. $query = "select * from village where villageid=".$evrow['village1'];
  650. if (!($res = mysql_query ($query)))
  651. $this->mainuser->log_err ("Cannot read in delegate info: speeds. Query: ".$query.", ".mysql_error ());
  652. else
  653. {
  654. if (!($villageInfo = mysql_fetch_array ($res)))
  655. $this->mainuser->log_err ("No rows returned for delegate info: speeds. Query: ".$query.", ".mysql_error ());
  656. else
  657. {
  658. $this->mainuser->villages[$evrow['village1']]->speed_build = $villageInfo['buildspeed'];
  659. $this->mainuser->villages[$evrow['village1']]->speed_research = $villageInfo['resspeed'];
  660. $this->mainuser->villages[$evrow['village1']]->speed_recruit[1] = $villageInfo['recrspeed1']; // foot
  661. $this->mainuser->villages[$evrow['village1']]->speed_recruit[2] = $villageInfo['recrspeed2']; // horse
  662. $this->mainuser->villages[$evrow['village1']]->speed_recruit[3] = $villageInfo['recrspeed3']; // bow
  663. $this->mainuser->villages[$evrow['village1']]->speed_recruit[4] = $villageInfo['recrspeed4']; // siege
  664. $this->mainuser->villages[$evrow['village1']]->speed_recruit[5] = $villageInfo['recrspeed5']; // castle
  665. }
  666. }
  667. break;
  668. }
  669. }
  670. private function handle_past_diplomacy_reload ($evrow)
  671. {
  672. require_once ("ally.inc.php");
  673. $this->mainuser->allymeta = array ();
  674. if ($this->mainuser->aid)
  675. $this->mainuser->allymeta[] = $this->mainuser->aid;
  676. $this->mainuser->allydipl = ally_reload_diplomacy ($this->mainuser->aid, $this->mainuser->allymeta);
  677. $newallywars = ally_reload_wars ($this->mainuser->aid);
  678. // print_r ($newallywars);
  679. $this->mainuser->allywars = $newallywars;
  680. }
  681. private function handle_past_research ($evrow)
  682. {
  683. $this->users[$evrow['uid1']]->log_debug ("Fertig: research level for uid ".$evrow['uid1'].", village ".$evrow['village1'].", resid ".$evrow['param2'].", level ".$evrow['param']);
  684. $query = "replace into userresearch values (".$evrow['uid1'].", ".$evrow['param2'].", ".$evrow['param'].")";
  685. mysql_query ($query);
  686. // Update the score
  687. $this->users[$evrow['uid1']]->update_score ($evrow['score']);
  688. // Delete the cached city files
  689. $city_path="precity/";
  690. $precalcpath = $city_path.$evrow['village1'];
  691. @unlink ($precalcpath."-0.php");
  692. @unlink ($precalcpath."-1.php");
  693. @unlink ($precalcpath."-2.php");
  694. // We should recalc all research influenced variables
  695. $this->users[$evrow['uid1']]->CalcResearch(true, $evrow['dif']);
  696. // All events that might affect values in the session object must add a delegate event
  697. if ($evrow['uid1'] != $this->mainuid)
  698. {
  699. $query = "update user set flags=flags|2 where uid=".$evrow['uid1'];
  700. if (!mysql_query ($query))
  701. $this->users[$evrow['uid1']]->log_err ("Cannot add research delegate. Query: ".$query.", ".mysql_error ());
  702. }
  703. }
  704. private function handle_past_attack ($evrow, $fightrounds)
  705. {
  706. global $debug, $user_row;
  707. $dummygui = false;
  708. $report_spying = false;
  709. // Big special here: People are able to attack outposts
  710. // So check if the target is an outpost
  711. if (!isset ($this->users[$evrow['uid2']]->villages[$evrow['village2']]))
  712. {
  713. $targetvill = $this->users[$evrow['uid2']]->lookup_outpost ($evrow['village2']);
  714. $this->users[$evrow['uid2']]->log_debug ("Looked up ".$evrow['village2'].", found ".$targetvill);
  715. $outpost_obj = $this->users[$evrow['uid2']]->villages[$targetvill]->outposts[$evrow['village2']];
  716. }
  717. else
  718. {
  719. $targetvill = $evrow['village2'];
  720. $outpost_obj = null;
  721. }
  722. $report_spying = false;
  723. $this->users[$evrow['uid2']]->log_debug ("Being attacked (type ".$evrow['type'].") in ".$evrow['village2']." - ".$targetvill);
  724. // Decrease yield, so that only income up to the point of attack is calculated
  725. $this->users[$evrow['uid2']]->villages[$targetvill]->do_income_partial (abs ($evrow['dif']), true);
  726. $this->delete_this_eid ($evrow);
  727. // Then check if this guy has some units to recruit
  728. if (count ($this->users[$evrow['uid2']]->villages[$evrow['village2']]->recruiting))
  729. {
  730. // We have to differentiate here again: Only use the "real" gui instance if this is the active village
  731. // of the main user
  732. if ($evrow['village2'] == $this->startvillage)
  733. $this->users[$evrow['uid2']]->update_score ($this->users[$evrow['uid2']]->villages[$evrow['village2']]->recruit_handler ($this->gui, $this->deleids, -$evrow['dif']));
  734. else
  735. $this->users[$evrow['uid2']]->update_score ($this->users[$evrow['uid2']]->villages[$evrow['village2']]->recruit_handler ($dummygui, $this->deleids, -$evrow['dif']));
  736. }
  737. $this->users[$evrow['uid2']]->hero->regenerate (-$evrow['dif']);
  738. // Check if this event is happening in an attack break
  739. if (START_OF_BREAK && END_OF_BREAK)
  740. {
  741. if (($_SERVER['REQUEST_TIME'] >= START_OF_BREAK) && ($_SERVER['REQUEST_TIME'] < END_OF_BREAK) && !is_ghost($evrow['uid2']))
  742. {
  743. $name1 = ghostify_name ($evrow['uid1'], $this->users[$evrow['uid1']]->user);
  744. $name2 = ghostify_name ($evrow['uid2'], $this->users[$evrow['uid2']]->user);
  745. // Yes, so just insert a dummy event with seasons greetings.
  746. // Technically, this is an entry in reports with a special type
  747. $query = "insert into battles values (NULL, 7)";
  748. if (!mysql_query ($query))
  749. $this->users[$evrow['uid1']]->log_err ("Greetings battle insert failed: ".$query.": ".mysql_error());
  750. $battleid = mysql_insert_id();
  751. $query = 'insert into reports (battleid, touid, uid1, village1, uid2, village2, stamp, type, subject, toaid, msg) values ('.$battleid.', '.$evrow['uid1'].', '.$evrow['uid1'].', '.$evrow['village1'].', '.$evrow['uid2'].', '.$evrow['village2'].', now(), 7, "'.sprintf (BREAK_SUBJECT, $name1, $name2).'", '.(int)$this->users->$evrow['uid2']->aid.', "'.sprintf (BREAK_MESSAGE, $name1, $name2).'")';
  752. if (!mysql_query ($query))
  753. $this->users[$evrow['uid1']]->log_err ("Greetings report insert1 failed: ".$query.": ".mysql_error());
  754. $query = 'insert into reports (battleid, touid, uid1, village1, uid2, village2, stamp, type, subject, toaid, msg) values ('.$battleid.', '.$evrow['uid2'].', '.$evrow['uid1'].', '.$evrow['village1'].', '.$evrow['uid2'].', '.$evrow['village2'].', now(), 7, "';
  755. $query .= sprintf (BREAK_SUBJECT, $name1, $name2);
  756. $query .= '", '.(int)$this->users->$evrow['uid2']->aid.', "'.sprintf (BREAK_MESSAGE, $name1, $name2).'")';
  757. if (!mysql_query ($query))
  758. $this->users[$evrow['uid1']]->log_err ("Greetings report insert failed: ".$query.": ".mysql_error());
  759. $query = "update armies set flag=10 where troopid=".$evrow['param'];
  760. if (!mysql_query ($query))
  761. $this->users[$evrow['uid1']]->log_err ("Greetings army update failed: ".$query.": ".mysql_error());
  762. $query = "insert into event (uid1, village1, uid2, village2, timestamp, type, param, param2, flag) values (".$evrow['uid1'].", ".$evrow['village1'].", 0, ".$evrow['village2'].", addtime(now(), sec_to_time(".($evrow['dif'] + $evrow['param2']).")), 10, ".$evrow['param'].", ".$battleid.", 0)";
  763. if (!mysql_query ($query))
  764. $this->users[$evrow['uid1']]->log_err ("Greetings event insert failed: ".$query.": ".mysql_error());
  765. $query = "update user set changed=changed,reports=reports+1 where uid in (".$evrow['uid1'].", ".$evrow['uid2'].")";
  766. if (!mysql_query ($query))
  767. $this->users[$evrow['uid1']]->log_err ("Greetings user update failed: ".$query.": ".mysql_error());
  768. // Update local cached report number
  769. if (($this->mainuid == $evrow['uid1']) || ($this->mainuid == $evrow['uid1']))
  770. {
  771. $user_row[2]++;
  772. }
  773. return (false);
  774. }
  775. }
  776. if ($evrow['type'] == SPY)
  777. {
  778. $this->users[$evrow['uid2']]->log_debug ("I'm being spyed!!");
  779. require_once ("php/spy.php");
  780. if (!do_spying ($evrow, $this->users[$evrow['uid2']], $this->users[$evrow['uid1']], $targetvill))
  781. {
  782. $evrow['type'] = RAID;
  783. $fightrounds = 3;
  784. $report_spying = true;
  785. }
  786. }
  787. if ($evrow['type'] != SPY)
  788. {
  789. $this->users[$evrow['uid2']]->log_debug ("I'm being attacked!! Fightrounds: ".$fightrounds);
  790. require_once ("php/battle.php");
  791. $idmap = array ();
  792. $capacity = array ();
  793. $armyinfo = array ();
  794. $in_units = prepare_battle ($evrow['uid1'], $evrow['param'], $evrow['village2'], $this->users[$evrow['uid2']]->hero, $armyinfo, $report_spying, $evrow['type'], $evrow['score']);
  795. $num_units = checkup_battle ($in_units);
  796. $extra_result = array ();
  797. if ($debug || $_SESSION['always_debug'])
  798. {
  799. print_r ($num_units);
  800. $bflags = 1;
  801. }
  802. else
  803. $bflags = 0;
  804. // Out-take: We took this out because if there are catapults involved, there should always be a battle...
  805. // if (($num_units[0] > 0) && ($num_units[1] > 0)) // FIXME: Can this really be correct?
  806. {
  807. $survivors = do_battle ($in_units, $idmap, $capacity, $fightrounds, $armyinfo, $num_units, $bflags, $extra_result, $report_spying);
  808. $result = $survivors[count($survivors)];
  809. require_once ("php/postbattle.php");
  810. $post_battle = new Postbattle ($evrow['uid1'], $evrow['village1'], $evrow['uid2'], $evrow['village2'], $evrow['type'], $evrow['dif'], $in_units, $result, $idmap, $evrow['param2'], $capacity, $this->users[$evrow['uid2']]->villages[$targetvill], $report_spying, $armyinfo, true, $extra_result, $evrow['param'], $evrow['score'], $outpost_obj, $this->users[$evrow['uid1']], $this->users[$evrow['uid2']]);
  811. $retev = $post_battle->post_battle ();
  812. // Finished sieges need special consideration
  813. if ($evrow['type'] == SIEGE)
  814. {
  815. if ($post_battle->siege_successful)
  816. {
  817. // Set delegate flags and also move around the score
  818. $query = "update user set changed=changed,flags=flags|8,score=score-(select score from village where villageid=".$evrow['village2'].") where uid=".$evrow['uid2'];
  819. $this->mainuser->log_debug ($query);
  820. if (!mysql_query ($query))
  821. $this->mainuser->log_err ("Cannot reduce score in postsiege. Query: ".$query.", ".mysql_error ());
  822. $query = "update user set changed=changed,flags=flags|8,score=score+(select score from village where villageid=".$evrow['village2'].") where uid=".$evrow['uid1'];
  823. $this->mainuser->log_debug ($query);
  824. if (!mysql_query ($query))
  825. $this->mainuser->log_err ("Cannot add score in postsiege. Query: ".$query.", ".mysql_error ());
  826. $this->mainuser->log_debug ("Siege successful. Refreshing both participants (".$evrow['uid1']." and ".$evrow['uid2'].") and changing slots.");
  827. // First move village score to new owner
  828. $this->users[$evrow['uid1']]->update_score ($score_move);
  829. $this->users[$evrow['uid2']]->update_score (-$score_move);
  830. // Reload villages
  831. $this->users[$evrow['uid1']]->refresh_villages ();
  832. $this->users[$evrow['uid2']]->refresh_villages ();
  833. // Now zero the upgrade slots for the besieged village, we will recalculate it anyway
  834. $query = "update village set expansion=0 where villageid=".$evrow['village2'];
  835. if (!mysql_query ($query))
  836. $this->mainuser->log_err ("Cannot zero expansion slots for target after siege. Query: ".$query.", ".mysql_error ());
  837. $num_vill = count ($this->users[$evrow['uid1']]->villages);
  838. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->recalculate_upgrade ($evrow['village2'], $num_vill);
  839. // Up outexpansion slots for victim
  840. $query = "update village set out_expansion=out_expansion+1 where villageid=".$targetvill;
  841. $this->users[$evrow['uid2']]->log_debug ("Post-Siege expansion: ".$query);
  842. if (!mysql_query ($query))
  843. {
  844. $this->mainuser->log_err ("Cannot reduce outpost expansion slots in postsiege. Query: ".$query.", ".mysql_error ());
  845. }
  846. $this->users[$evrow['uid2']]->villages[$targetvill]->outpost_expansion++;
  847. //finally, give building events from the stolen outpost to its new owner
  848. $query = 'update event set uid1='.$evrow['uid1'].',village1='.$evrow['village1'].' where (type >= 1000) AND param2='.$evrow['village2'];
  849. if (!mysql_query($query))
  850. $this->mainuser->log_err ('could not update building events for stolen outpost: '.$query);
  851. }
  852. else
  853. {
  854. // Up outexpansion slots for attacker
  855. $query = "update village set out_expansion=out_expansion+1 where villageid=".$evrow['village1'];
  856. $this->mainuser->log_debug ("Siege failed: ".$query);
  857. if (!mysql_query ($query))
  858. {
  859. log_err ("Cannot reduce outpost expansion slots in postsiege. Query: ".$query.", ".mysql_error ());
  860. }
  861. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->outpost_expansion++;
  862. }
  863. }
  864. // increase unread message count if the main user is involved in this combat
  865. if (($this->mainuid == $evrow['uid1']) || ($this->mainuid == $evrow['uid2']))
  866. $this->user_row[2]++;
  867. }
  868. if (is_array ($retev) && count ($retev))
  869. {
  870. unset ($this->events[$evrow['dif']][$evrow['eid']]);
  871. foreach ($retev as $this_retevent)
  872. {
  873. $this->events[$this_retevent['dif']][] = $this_retevent;
  874. }
  875. }
  876. return ($retev);
  877. }
  878. return (array ());
  879. }
  880. // Handle a transport
  881. // FIXME: No GUI stuff at the moment, but maybe we will do this with delegates?
  882. private function handle_past_transport ($evrow)
  883. {
  884. // Did the transport just return?
  885. if ($evrow['uid2'] == 0)
  886. {
  887. // Then just delete the transport record
  888. $query = "delete from transport where merchantid = ".$evrow['param'];
  889. if (!mysql_query ($query))
  890. {
  891. $this->users[$evrow['uid2']]->log_err ("Cannot delete transport entry in event handler. Query: ".$query.", ".mysql_error ());
  892. }
  893. // We didn't delete the event before, because the blacklist might have deleted them too early
  894. $this->delete_this_eid ($evrow);
  895. return (false);
  896. }
  897. $sender = $this->users[$evrow['uid1']]->user;
  898. // We didn't delete the event before, because the blacklist might have deleted them too early
  899. $this->delete_this_eid ($evrow);
  900. // Decrease yield, so that only income up to the point of transport is calculated
  901. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->do_income_partial (abs ($evrow['dif']), true);
  902. // Fetch the details of the transport
  903. $query = "select * from transport where merchantid = ".$evrow['param'];
  904. if (!($res = mysql_query ($query)))
  905. {
  906. $this->users[$evrow['uid2']]->log_err ("Cannot fetch transport details in event handler. Query: ".$query.", ".mysql_error ());
  907. }
  908. else
  909. {
  910. if (!($row = mysql_fetch_array ($res)))
  911. {
  912. $this->users[$evrow['uid2']]->log_err ("No transport details found in event handler. Query: ".$query.", ".mysql_error ());
  913. }
  914. else
  915. {
  916. $this->users[$evrow['uid2']]->log_debug ("Transport: Ress before: ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[1].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[2].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[3].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[4]);
  917. $happy_message = $row['trade_msg'];
  918. // Hand 'em off
  919. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->spend (-$row['ress1'], -$row['ress2'], -$row['ress3'], -$row['ress4']);
  920. /*
  921. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[1] = min ($row['ress1'] + $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[1], $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress_max);
  922. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[2] = min ($row['ress2'] + $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[2], $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress_max);
  923. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[3] = min ($row['ress3'] + $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[3], $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress_max);
  924. $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[4] = min ($row['ress4'] + $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[4], $this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress_max); */
  925. $this->users[$evrow['uid2']]->log_debug ("Transport: Ress after: ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[1].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[2].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[3].", ".$this->users[$evrow['uid2']]->villages[$evrow['village2']]->ress[4]);
  926. // Log the transport
  927. $query = "insert into old_transport select * from transport where merchantid=".$evrow['param'];
  928. if (!mysql_query ($query))
  929. $this->users[$evrow['uid2']]->log_err ("Cannot save old transport. Query: ".$query.", ".mysql_error());
  930. else
  931. {
  932. // Check param2 to see if the return is within the timeframe of this event handlement
  933. // and if so, push the event on the local event stack instead of the DB
  934. if ($evrow['param2'] > abs ($evrow['dif']))
  935. {
  936. // No, we need to issue a return event
  937. $query = "insert into event (uid1, village1, uid2, village2, type, param, param2, timestamp, flag) values (".$evrow['uid1'].", ".$evrow['village1'].", 0, ".$evrow['village2'].", ".TRANSPORT.", ".$evrow['param'].", ".$evrow['param2'].", addtime(addtime(now(), sec_to_time(".$evrow['dif'].")), sec_to_time(".$evrow['param2'].")), 0)";
  938. if (!mysql_query ($query))
  939. $this->users[$evrow['uid2']]->log_err ("Cannot set transport return event. Query: ".$query.", ".mysql_error ());
  940. // Then send the merchants home empty-handed
  941. $query = "update transport set ress1=0,ress2=0,ress3=0,ress4=0,flag=1 where merchantid=".$evrow['param'];
  942. if (!mysql_query ($query))
  943. $this->users[$evrow['uid2']]->log_err ("Cannot set transport return data. Query: ".$query.", ".mysql_error());
  944. // In this case, we also want the transport displayed in the merchant overview
  945. $evrow['dif'] += $evrow['param2'];
  946. $this->add_past_transport_gui_item ($evrow);
  947. }
  948. else
  949. {
  950. // Yes, the merchants should return immediately (this trick doesn't disturb anything)
  951. $query = "delete from transport where merchantid=".$evrow['param'];
  952. if (!mysql_query ($query))
  953. $this->users[$evrow['uid2']]->log_err ("Cannot delete transport while instant-home-transporting. Query: ".$query.", ".mysql_error ());
  954. }
  955. $query = "insert into battles values (NULL, 5)";
  956. if (!mysql_query ($query))
  957. $this->users[$evrow['uid2']]->log_err ("Cannot insert transport misnamed battle entry. Query: ".$query.", ".mysql_error());
  958. else
  959. {
  960. $battleid = mysql_insert_id ();
  961. $query_end = ", ".$evrow['uid1'].", ".$evrow['village1'].", ".$evrow['uid2'].", ".$evrow['village2'].", \"".$evrow['timestamp']."\", 5, 0, 0,";
  962. $subject = mysql_real_escape_string (profile_link ($evrow['uid1'], $sender).' beliefert <a href="land.php?z='.$this->users[$evrow['uid2']]->villages[$evrow['village2']]->give_z ().'">'.$this->users[$evrow['uid2']]->villages[$evrow['village2']]->name.'</a> von '.profile_link ($evrow['uid2'], $this->users[$evrow['uid2']]->user));
  963. if ($evrow['uid1'] == $evrow['uid2'])
  964. $query = 'insert into reports values (NULL, '.$battleid.', '.$evrow['uid1'].$query_end.' "'.$subject.'", 0, "'.$happy_message.'")';
  965. else
  966. $query = 'insert into reports values (NULL, '.$battleid.', '.$evrow['uid1'].$query_end.' "'.$subject.'", 0, "'.$happy_message.'"),(NULL, '.$battleid.', '.$evrow['uid2'].$query_end.' "'.$subject.'",0, "'.$happy_message.'")';
  967. if (!mysql_query ($query))
  968. $this->users[$evrow['uid2']]->log_err ("Cannot insert transport reports. Query: ".$query.", ".mysql_error());
  969. else
  970. {
  971. $query = "insert into rep_loot values (".$battleid.", 0, ".$evrow['uid2'].", ".$row['ress1']."), (".$battleid.", 1, ".$evrow['uid2'].", ".$row['ress2']."), (".$battleid.", 2, ".$evrow['uid2'].", ".$row['ress3']."), (".$battleid.", 3, ".$evrow['uid2'].", ".$row['ress4'].")";
  972. if (!mysql_query ($query))
  973. $this->users[$evrow['uid2']]->log_err ("Cannot insert transport report loot entry for uid1. Query: ".$query.", ".mysql_error ());
  974. else
  975. {
  976. // Bump the unread reports count for the user in the DB...
  977. $query = "update user set changed=changed,reports=reports+1 where uid in (".$evrow['uid1'].", ".$evrow['uid2'].")";
  978. if (!mysql_query ($query))
  979. $this->users[$evrow['uid2']]->log_err ("Cannot update report count after transport. Query: ".$query.", ".mysql_error());
  980. // ...and also in the row read from the DB if the main user is either sender or receiver of the transport
  981. if (($this->mainuid == $evrow['uid1']) || ($this->mainuid == $evrow['uid2']))
  982. $this->user_row[2]++;
  983. }
  984. }
  985. }
  986. }
  987. }
  988. mysql_free_result ($res);
  989. }
  990. }
  991. private function handle_past_ressource_event ($evrow)
  992. {
  993. global $world;
  994. $up_z = $evrow['village2'];
  995. $x = ($up_z % $world->sizex);
  996. $y = ((int)($up_z / $world->sizex));
  997. if (FINITE_RESSOURCES)
  998. {
  999. $this->users[$evrow['uid1']]->UpdateResTile ($x, $y, $evrow['param'], $evrow['dif']);
  1000. }
  1001. else
  1002. {
  1003. // First update the tile level in the DB, just to be sure
  1004. $query = "update tileres set level=".$evrow['param']." where x=".$x." and y=".$y;
  1005. $this->users[$evrow['uid1']]->log_debug ("Fertig: Ausbau Feld ".$evrow['type']." in ".$up_z." auf Stufe ".$evrow['param']." vor ".$evrow['dif']." Sekunden");
  1006. if (!mysql_query ($query))
  1007. $this->users[$evrow['uid1']]->log_err ("Cannot update tileres after resstile is done. Query: ".$query.", ".mysql_error ());
  1008. }
  1009. // Now make ressource ticks up to the time of the enhancement deadline
  1010. // $this->villages[$did]->do_income_partial (abs ($evrow['dif']), true);
  1011. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->do_income_partial (abs ($evrow['dif']), true);
  1012. // It this ress field is in an outpost, special consideration is needed
  1013. if ($evrow['param2'])
  1014. {
  1015. // Yes, 'tis an outpost
  1016. if (!isset ($this->users[$evrow['uid1']]->villages[$evrow['param2']]))
  1017. {
  1018. $num_vill = count ($this->users[$evrow['uid1']]->villages);
  1019. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->recalculate_upgrade ($evrow['param2'], $num_vill);
  1020. }
  1021. // Count the score towards the outpost, not the village
  1022. $query = "update village set stamp=stamp,score=score+".$evrow['score']." where villageid=".$evrow['param2'];
  1023. // Also give the man his due, of course :)
  1024. $this->users[$evrow['uid1']]->update_score ($evrow['score']);
  1025. if (!mysql_query ($query))
  1026. $this->users[$evrow['uid1']]->log_err ("Cannot update outpost score after resstile is done. Query: ".$query.", ".mysql_error ());
  1027. $this->users[$evrow['uid1']]->CalculateVillageProd ($evrow['param2']);
  1028. if (isset ($this->users[$evrow['uid1']]->villages[$evrow['param2']]))
  1029. $this->users[$evrow['uid1']]->villages[$evrow['param2']]->update_production();
  1030. else
  1031. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->update_production();
  1032. }
  1033. else
  1034. {
  1035. // Count the score towards the village then
  1036. $this->users[$evrow['uid1']]->update_score ($evrow['score'], $evrow['village1']);
  1037. // This is a hack.
  1038. // If this is not an outpost, we count the number of used ressource tiles.
  1039. // If it 8 or greater, outposts can be founded. This is recorded as expansion_slots >= 127,
  1040. // but only if it is not already greater of course :)
  1041. $this->users[$evrow['uid1']]->log_debug ("Checking expansion slots for outpost enabling for vid ".$evrow['village1'].": ".$this->users[$evrow['uid1']]->villages[$evrow['village1']]->expansion_slots);
  1042. if ($this->users[$evrow['uid1']]->villages[$evrow['village1']]->expansion_slots < 127)
  1043. {
  1044. $query = "select count(villageid) from tileres where level>0 and villageid=".$evrow['village1'];
  1045. if (!($res = mysql_query ($query)))
  1046. {
  1047. $this->users[$evrow['uid1']]->log_err ("Cannot fetch tile count after upgrading res field. Query: ".$query.", ".mysql_error ());
  1048. }
  1049. else
  1050. {
  1051. if (($row = mysql_fetch_row ($res)))
  1052. {
  1053. $this->users[$evrow['uid1']]->log_debug ("Checking tile count for outpost enabling for vid ".$evrow['village1'].": ".$row[0]);
  1054. // Now check if there are already 8 tiles
  1055. if ($row[0] >= 8)
  1056. {
  1057. $query = "update village set expansion=expansion+127 where villageid=".$evrow['village1'];
  1058. if (!mysql_query ($query))
  1059. $this->users[$evrow['uid1']]->log_err ("Cannot update slots for outpost settling after upgrading res field. Query: ".$query.", ".mysql_error ());
  1060. else
  1061. $this->users[$evrow['uid1']]->villages[$evrow['village1']]->expansion_slots += 127;
  1062. }
  1063. }
  1064. else
  1065. $this->users[$evrow['uid1']]->log_err ("No tile count after upgrading res field. Query: ".$query.", …

Large files files are truncated, but you can click here to view the full file