PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/php/spy.php

https://bitbucket.org/obsidian/selador
PHP | 405 lines | 336 code | 29 blank | 40 comment | 28 complexity | 8c60ca1862585aafd4444807ebe0016d MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1
  1. <?php
  2. /* spy.php - Back-end code for spying on cities
  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. // Fairly ok but needs more documentation
  25. require_once ("php/battle.php");
  26. function do_spying ($evrow, $defuser, $attuser, $targetvill, $always_successfull=false)
  27. {
  28. global $debug;
  29. $attvillage = $evrow['village1'];
  30. $targetvillage = $evrow['village2'];
  31. // var_dump ($defuser);
  32. // var_dump ($attfuser);
  33. if ($targetvill == $evrow['village2'])
  34. {
  35. $tvillage = $defuser->villages[$targetvill];
  36. $outpost = false;
  37. }
  38. else
  39. {
  40. $tvillage = $defuser->villages[$targetvill]->outposts[$evrow['village2']];
  41. $outpost = true;
  42. }
  43. // We need the attackers spying level
  44. $query = "select A.level, B.class, B.hero_health from user B left join userresearch A on (B.uid=A.uid and A.resid in (2, 46)) where B.uid=".$evrow['uid1'];
  45. if (!($res = mysql_query ($query)))
  46. log_err ("Cannot fetch spy level. Query: ".$query.", ".mysql_error());
  47. else
  48. {
  49. //echo $query;
  50. // echo "<br>hiro!<br>".$hero_health;
  51. if (!($row = mysql_fetch_row ($res)))
  52. $att_spy = 0;
  53. else
  54. {
  55. $att_spy = (int)$row[0];
  56. $hero_health = $row[2];
  57. // Thieves spy better :)
  58. if ($row[1] == CLASS_THIEF)
  59. {
  60. $attacker_is_thief = true;
  61. $att_spy += 2;
  62. }
  63. }
  64. }
  65. mysql_free_result ($res);
  66. $armyinfo = array ();
  67. // Now the numbers of all involved units;
  68. $in_units = prepare_battle ($evrow['uid1'], $evrow['param'], $evrow['village2'], $defuser->hero, $armyinfo, false);
  69. $num_units = checkup_battle ($in_units);
  70. // The third root of the village score is the detection base
  71. if ($tvillage->score == 0)
  72. $villsize = 1;
  73. else
  74. $villsize = $tvillage->score;
  75. if (!$always_successfull)
  76. $detection = $num_units[0] / pow ($villsize, 1/4); // Formel: scouts/pow(groesse,1/3)
  77. else
  78. $detection = 0;
  79. // If the village has troops in it, the chance of detection rises
  80. if ($num_units[1] > 0)
  81. $detection *= (1 + sqrt ($num_units[1] / $villsize * 4)); // sqrt ($defuser->villages[$targetvillage]->score);
  82. $dice = rand (0, 99);
  83. log_debug ("Spy attempt. Hero-spyspy: ".$attuser->hero->spyspy_bonus.", Hero-spydef: ".$defuser->hero->spydef_bonus.", Detection: ".$detection." (".($detection * $attuser->hero->spyspy_bonus * $defuser->hero->spydef_bonus)."), ".$dice.", Num units: ".$num_units[1].", num spies: ".$num_units[0].", villsize: ".$villsize);
  84. $detection *= $attuser->hero->spyspy_bonus * $defuser->hero->spydef_bonus;
  85. if ($debug)
  86. {
  87. echo "Detection: ".$detection."\n";
  88. print_r ($num_units);
  89. echo "Attspy: ".$att_spy.", Defspy: ".$defuser->antispy_level.", dice: ".$dice."\n";
  90. }
  91. // Lets see how far these guys can see
  92. // if ($defuser->spy_level > 0)
  93. $espied = $att_spy - $defuser->antispy_level + 1 + (int)($num_units[0] / 10);
  94. // else
  95. // $espied = $att_spy + 1 + (int)($num_units[0] / 10);
  96. if ($always_successfull)
  97. $espied = rand (1, 6);
  98. if ($espied > 6)
  99. $espied = 6;
  100. // Where we seen?
  101. if ($dice <= ceil ($detection))
  102. {
  103. return (false);
  104. }
  105. log_debug ("Attspy: ".$att_spy.", Defspy: ".$defuser->antispy_level.", espied: ".$espied);
  106. $query = "";
  107. if ($debug)
  108. echo "Espied: ".$espied."\n";
  109. $query = "insert into battles values (NULL, 1)";
  110. if (!mysql_query ($query))
  111. log_err ("Cannot insert new battle entry while spying. Query: ".$query.", ".mysql_error());
  112. else
  113. {
  114. $battleid = mysql_insert_id ();
  115. // Now insert an army entry for each battle participant
  116. foreach ($in_units as $this_troopid => $his_values)
  117. {
  118. unset ($query);
  119. $this_uid = $his_values[2001];
  120. if ($his_values[2000] == 1) // Is this a defender?
  121. {
  122. if ($espied > 1)
  123. {
  124. $spy_units = true;
  125. if (!isset ($baids[$this_uid]))
  126. $query = "insert into bat_armies values (".$battleid.", NULL, 1, ".$this_uid.", ".$targetvillage.")";
  127. }
  128. else
  129. {
  130. // $query = "insert into bat_armies values (".$battleid.", NULL, 1, ".$this_uid.", ".$targetvillage.")";
  131. $spy_units = false;
  132. }
  133. }
  134. else
  135. {
  136. $spy_units = true;
  137. if (!isset ($baids[$this_uid]))
  138. $query = "insert into bat_armies values (".$battleid.", NULL, 0, ".$this_uid.", ".$attvillage.")";
  139. }
  140. if ($spy_units)
  141. {
  142. if (isset ($query))
  143. {
  144. if ($debug)
  145. echo "Bat query: ".$query."\n";
  146. if (!mysql_query ($query))
  147. {
  148. log_err ("Cannot write bat_army entry. ".$query.", error: ".mysql_error());
  149. return (false);
  150. }
  151. // Now we need the troop entry for this army
  152. $reparmyid = $baids[$this_uid] = mysql_insert_id ();
  153. }
  154. else
  155. $reparmyid = $baids[$this_uid];
  156. unset ($query);
  157. foreach ($his_values as $unitid=>$resultid)
  158. {
  159. if ($unitid < 1000)
  160. {
  161. $repqueries[$this_uid][$unitid] += $in_units[$this_troopid][$unitid];
  162. }
  163. else
  164. {
  165. if ($debug)
  166. echo "<br><br>You're supposed to be a hero! ".$hero_health;
  167. if ($unitid == 1000)
  168. $repqueries[$this_uid][1000] = (int)($resultid*100);
  169. //$repqueries[$this_uid][1000] = (int)($hero_health*100);
  170. }
  171. // print_r ($repqueries);
  172. }
  173. } // did we spy units?
  174. } // foreach
  175. if (count ($repqueries))
  176. {
  177. unset ($query);
  178. foreach ($repqueries as $repuid=>$unitentry)
  179. {
  180. foreach ($unitentry as $repunitid=>$entry)
  181. {
  182. if (isset ($query))
  183. $query .= ", (".$baids[$repuid].", ".$repunitid.", ".$entry.", 0)";
  184. else
  185. $query = "(".$baids[$repuid].", ".$repunitid.", ".$entry.", 0)";
  186. }
  187. }
  188. $query = "insert into bat_troops values ".$query;
  189. if (!mysql_query ($query))
  190. {
  191. log_err ("Cannot insert troops in spy.php. Query: ".$query.", error: ".mysql_error ());
  192. return (false);
  193. }
  194. }
  195. switch ($espied)
  196. {
  197. case 6: // items
  198. case 5: // hero stats
  199. case 4: // research
  200. if (!$outpost)
  201. {
  202. $query = "select resid, level from userresearch where uid=".$evrow['uid2'];
  203. if (!($res = mysql_query ($query)))
  204. log_err ("Cannot read user research levels in spy. Query: ".$query." ", mysql_error());
  205. else
  206. {
  207. if (isset ($lquery))
  208. $lquery .= ", (".$battleid.", 21, 0, 0)";
  209. else
  210. $lquery = "(".$battleid.", 21, 0, 0)";
  211. while ($row = mysql_fetch_row ($res))
  212. {
  213. $lquery .= ", (".$battleid.", 21, ".$row[0].", ".$row[1].")";
  214. }
  215. }
  216. }
  217. case 3: // city buildings
  218. if (!$outpost)
  219. {
  220. $query = "select type, level from villbuild where villageid=".$targetvillage;
  221. if (!($res = mysql_query ($query)))
  222. log_err ("Cannot read city building levels in spy. Query: ".$query." ", mysql_error());
  223. else
  224. {
  225. while ($row = mysql_fetch_row ($res))
  226. {
  227. if (isset ($lquery))
  228. $lquery .= ", (".$battleid.", 20, ".$row[0].", ".$row[1].")";
  229. else
  230. $lquery = "(".$battleid.", 20, ".$row[0].", ".$row[1].")";
  231. }
  232. }
  233. }
  234. case 2: // army
  235. case 1: // ressources
  236. if (WORLD_SPEED > 4)
  237. $hidden_div = sqrt (WORLD_SPEED / 2);
  238. else
  239. $hidden_div = 1;
  240. if (!$outpost)
  241. {
  242. foreach ($tvillage->ress_prod as $currency => $amount)
  243. $hidden[$currency] = min ($amount * 5, ($amount / $hidden_div) + (pow ($tvillage->ress_max, 0.36) * 10));
  244. log_debug ("Storage level ".$row[0].", hidden ".$hidden[1].", ".$hidden[2].", ".$hidden[3].", ".$hidden[4].", ress are ".$defuser->villages[$targetvillage]->ress_val (1).", ".$defuser->villages[$targetvillage]->ress_val (2).", ".$defuser->villages[$targetvillage]->ress_val (3).", ".$defuser->villages[$targetvillage]->ress_val (4));
  245. for ($currency = 1; $currency <= 4; ++$currency)
  246. {
  247. $amount = $defuser->villages[$targetvillage]->ress_val ($currency);
  248. if ($currency == 4)
  249. {
  250. if ($attacker_is_thief)
  251. $this_loot = max (0, (int)(($amount - $hidden[$currency]) / 2));
  252. else
  253. $this_loot = max (0, (int)(($amount - $hidden[$currency]) / 10));
  254. }
  255. else
  256. $this_loot = $amount - $hidden[$currency];
  257. if (isset ($lquery))
  258. $lquery .= ", (".$battleid.", ".($currency-1).", ".$evrow['uid2'].", ".$this_loot.")";
  259. else
  260. $lquery = "(".$battleid.", ".($currency-1).", ".$evrow['uid2'].", ".$this_loot.")";
  261. }
  262. }
  263. else
  264. {
  265. foreach ($tvillage->ress_prod as $ressid=>$amount)
  266. {
  267. if ($ressid == 4)
  268. {
  269. if ($attacker_is_thief)
  270. $amount = (int)($amount / 2);
  271. else
  272. $amount = (int)($amount / 10);
  273. }
  274. if (isset ($lquery))
  275. $lquery .= ", (".$battleid.", ".($ressid-1).", ".$evrow['uid2'].", ".$amount.")";
  276. else
  277. $lquery = "(".$battleid.", ".($ressid-1).", ".$evrow['uid2'].", ".$amount.")";
  278. }
  279. }
  280. break;
  281. }
  282. if (isset ($lquery))
  283. {
  284. // If this report is because we have questioned foreign spies, add a message about this to the event
  285. if ($always_successfull)
  286. $lquery .= ",(".$battleid.", 72, ".$evrow['uid1'].", 1)";
  287. $lquery = "insert into rep_loot values ".$lquery;
  288. if ($debug)
  289. echo "Lquery: ".$lquery;
  290. if (!mysql_query ($lquery))
  291. log_err ("Cannot insert loot entries when spying. Query: ".$lquery.", ".mysql_error());
  292. }
  293. $query = "select user from user where uid=".$evrow['uid1'];
  294. if (!($res = mysql_query ($query)))
  295. log_err ("Cannot read username for attacker when spying. Query: ".$query.", ".mysql_error());
  296. else
  297. {
  298. if (!$row = mysql_fetch_row ($res))
  299. {
  300. log_err ("No username found for attacker when spying. Query: ".$query);
  301. $attackername = "(gelĂśscht)";
  302. }
  303. else
  304. $attackername = $row[0];
  305. }
  306. if (!$always_successfull)
  307. $subject = mysql_real_escape_string (profile_link ($evrow['uid1'], $attackername)." späht <a href=\"land.php?z=".$tvillage->give_z ().'">'.$tvillage->name.'</a> von '.profile_link ($defuser->uid, $defuser->user)." aus");
  308. else
  309. $subject = mysql_real_escape_string (profile_link ($evrow['uid1'], $attackername)."'s Gefangenenbericht &uuml;ber <a href=\"land.php?z=".$tvillage->give_z ().'">'.$tvillage->name.'</a> von '.profile_link ($defuser->uid, $defuser->user));
  310. // print_r($armyinfo);
  311. $query = "insert into reports values (NULL, ".$battleid.", ".$evrow['uid1'].", ".$evrow['uid1'].", ".$evrow['village1'].", ".$evrow['uid2'].", ".$evrow['village2'].", addtime(now(),sec_to_time(".$evrow['dif'].")), 1, 0, 0, '".$subject."', ".(int)$attuser->aid.", '')";
  312. $receip_uids[] = $evrow['uid1'];
  313. if ($dice <= ceil ($detection))
  314. {
  315. $receip_uids[] = $evrow['uid2'];
  316. $query .= ",(NULL, ".$battleid.", ".$evrow['uid2'].", ".$evrow['uid1'].", ".$evrow['village1'].", ".$evrow['uid2'].", ".$evrow['village2'].", addtime(now(),sec_to_time(".$evrow['dif'].")), 1, 0, 0, '".$subject."', ".(int)$defuser->aid.", '')";
  317. }
  318. if ($debug)
  319. echo "Reportquery: ".$query."\n";
  320. if (!mysql_query ($query))
  321. log_err ("Cannot insert reports when spying. Query: ".$query.", ".mysql_error());
  322. // And give them all an update on their unread report count
  323. $query = "update user set reports=reports+1 where uid in (".implode (",", $receip_uids).")";
  324. if (!mysql_query ($query))
  325. log_err ("Cannot update unread report cound in spying. Query: ".$query.", ".mysql_error());
  326. } // insert into battles
  327. if (!$always_successfull)
  328. {
  329. // Now set the troops on the path towards home
  330. $query = "update armies set flag=10 where troopid=".$evrow['param'];
  331. if ($debug)
  332. echo "\n".$query;
  333. if (!mysql_query ($query))
  334. {
  335. log_err ("Cannot set troops to RETURNING state in spy ".$battleid.". Query: ".$query.", ".mysql_error ());
  336. }
  337. // Insert the event for the trip home
  338. $query = "insert into event (uid1, village1, uid2, village2, timestamp, type, param, param2, flag) values (".$evrow['uid1'].", ".$evrow['village1'].", ".$evrow['uid1'].", ".$evrow['village1'].", addtime(addtime(now(), sec_to_time(".$evrow['dif'].")), sec_to_time(".$evrow['param2'].")), 10, ".$evrow['param'].", ".$battleid.", 0)";
  339. if ($debug)
  340. echo "\n".$query;
  341. if (!@mysql_query ($query))
  342. {
  343. log_err ("Cannot insert return event when spying: ".$query.", error: ".mysql_error ());
  344. }
  345. }
  346. return (true);
  347. }