Controller.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. <?php
  2. /**
  3. * Controller file.
  4. *
  5. * Provides a class to handle all posible request.
  6. *
  7. * @category Constroller
  8. */
  9. /**
  10. * Include some required files.
  11. */
  12. require_once(__DIR__ . "/config.php");
  13. require_once(PATH::HELPER . "DB_Helper.php");
  14. require_once(PATH::HELPER . "TEXT_Helper.php");
  15. require_once(PATH::HELPER . "NET_Helper.php");
  16. require_once(PATH::HELPER . "HTML_Helper.php");
  17. require_once(PATH::HELPER . "APPLICATION_Helper.php");
  18. require_once(PATH::ENTITY . "User.php");
  19. require_once(PATH::ENTITY . "Player.php");
  20. require_once(__DIR__ . "/Constant.php");
  21. require_once(__DIR__ . "/Context.php");
  22. /**
  23. * Application controller.
  24. *
  25. * Handles every request, creating the required models and selecting the
  26. * view.
  27. *
  28. * @category Controller
  29. */
  30. class Controller extends Context{
  31. private $player;
  32. private $user;
  33. private $mode;
  34. private $page;
  35. private $db;
  36. private $component; // web, api, action
  37. private $command;
  38. private $source;
  39. private $params = [];
  40. private $context;
  41. public function action(){
  42. // API call: Use API controller
  43. if (count($this->params) > 0 && strtoupper($this->params[0]) == "API"){
  44. if (count($this->params) == 1){
  45. // TODO: API MAIN PAGE
  46. }
  47. else{
  48. $version = strtolower($this->params[1]);
  49. $api_params = $this->params;
  50. array_shift($api_params);
  51. array_shift($api_params);
  52. switch ($version){
  53. case "v1":
  54. require_once(__DIR__ . "/API/v1/API_Controller.php");
  55. new API_Controller($this->params);
  56. break;
  57. }
  58. }
  59. return;
  60. }
  61. // Special case: Actions.
  62. // Not redirecting to page, just execute a function
  63. // TODO: Secure actions
  64. elseif (count($this->params) > 1 && strtoupper($this->params[0]) == "ACTION"){
  65. switch (strtoupper($this->params[1])){
  66. case "CHANGE_GAME_MODE":
  67. require_once(PATH::ACTION . "change_game_mode.php");
  68. action();
  69. return;
  70. break;
  71. case "LOGIN":
  72. require_once(PATH::ACTION . "login.php");
  73. action();
  74. return;
  75. break;
  76. case "LOGOUT":
  77. require_once(PATH::ACTION . "logout.php");
  78. action();
  79. return;
  80. break;
  81. case "NEW_TEAM":
  82. require_once(PATH::ACTION . "new_team.php");
  83. action();
  84. return;
  85. break;
  86. case "DELETE_TEAM":
  87. require_once(PATH::ACTION . "delete_team.php");
  88. action();
  89. return;
  90. break;
  91. case "RATE_TEAM":
  92. require_once(PATH::ACTION . "rate_team.php");
  93. action();
  94. return;
  95. break;
  96. case "SAVE_RUN_TEAM":
  97. require_once(PATH::ACTION . "save_run_team.php");
  98. action();
  99. return;
  100. break;
  101. case "OPTIMIZE_GET_RUNE_LIST":
  102. require_once(PATH::ACTION . "optimize_get_rune_list.php");
  103. $response = action();
  104. if (strlen($response) > 1){
  105. echo($response);
  106. return;
  107. }
  108. else{
  109. return;
  110. }
  111. break;
  112. case "OPTIMIZE_GET_OPTIONS":
  113. require_once(PATH::ACTION . "optimize_get_options.php");
  114. $response = action();
  115. if (strlen($response) > 1){
  116. echo($response);
  117. return;
  118. }
  119. else{
  120. return;
  121. }
  122. break;
  123. case "EDIT_PROFILE":
  124. require_once(PATH::ACTION . "edit_profile.php");
  125. $response = action();
  126. if (strlen($response) > 1){
  127. echo($response);
  128. return;
  129. }
  130. else{
  131. return;
  132. }
  133. break;
  134. default:
  135. require_once(PATH::PAGE . "Error_Page.php");
  136. $page = new Error_Page(404);
  137. http_response_code(404);
  138. }
  139. }
  140. // Select the model to load.
  141. array_shift($this->params); // Remove first one, should be player_id
  142. if (sizeof($this->params) == 0){
  143. require_once(PATH::PAGE . "Home_Page.php");
  144. $page = new Home_Page();
  145. }
  146. else{
  147. if (strtoupper($this->params[0]) == "RUNES"){
  148. require_once(PATH::PAGE . "Runes_Page.php");
  149. $page = new Runes_Page();
  150. }
  151. elseif (strtoupper($this->params[0]) == "ENCHANTMENTS"){
  152. require_once(PATH::PAGE . "Enchantments_Page.php");
  153. $page = new Enchantments_Page();
  154. }
  155. elseif (strtoupper($this->params[0]) == "ARTIFACTS"){
  156. require_once(PATH::PAGE . "Artifacts_Page.php");
  157. $page = new Artifacts_Page();
  158. }
  159. elseif (strtoupper($this->params[0]) == "GUILD"){
  160. require_once(PATH::PAGE . "Guild_Page.php");
  161. $page = new Guild_Page();
  162. }
  163. elseif (strtoupper($this->params[0]) == "RUNS"){
  164. require_once(PATH::PAGE . "Runs_Page.php");
  165. $page = new Runs_Page();
  166. }
  167. elseif (strtoupper($this->params[0]) == "STATS"){
  168. require_once(PATH::PAGE . "Stats_Page.php");
  169. $page = new Stats_Page();
  170. }
  171. elseif (strtoupper($this->params[0]) == "TEAMS"){
  172. require_once(PATH::PAGE . "Teams_Page.php");
  173. $page = new Teams_Page();
  174. }
  175. elseif (strtoupper($this->params[0]) == "PROFILE"){
  176. require_once(PATH::PAGE . "Profile_Page.php");
  177. $page = new Profile_Page();
  178. }
  179. elseif (strtoupper($this->params[0]) == "UNITS"){
  180. if (count($this->params) == 1){
  181. require_once(PATH::PAGE . "Units_Page.php");
  182. $page = new Units_Page();
  183. }
  184. else{
  185. require_once(PATH::PAGE . "Unit_Page.php");
  186. $page = new Unit_Page($this->params[1]);
  187. }
  188. }
  189. elseif (strtoupper($this->params[0]) == "MONSTERS"){
  190. if (count($this->params) == 1){
  191. require_once(PATH::PAGE . "Monsters_Page.php");
  192. $page = new Monsters_Page();
  193. }
  194. else{
  195. require_once(PATH::PAGE . "Monster_Page.php");
  196. $page = new Monster_Page($this->params[1]);
  197. }
  198. }
  199. elseif (strtoupper($this->params[0]) == "REPORT"){
  200. if (count($this->params) == 1){
  201. require_once(PATH::PAGE . "Report_Page.php");
  202. $page = new Report_Page();
  203. }
  204. elseif (strtoupper($this->params[1]) == "SKILLUP"){
  205. require_once(PATH::PAGE . "Report_Skillup_Page.php");
  206. $page = new Report_Skillup_Page($this->params[1]);
  207. }
  208. elseif (strtoupper($this->params[1]) == "RUNE_ENCHANTMENT"){
  209. require_once(PATH::PAGE . "Report_Rune_Enchantment_Page.php");
  210. $page = new Report_Rune_Enchantment_Page($this->params[1]);
  211. }
  212. }
  213. elseif (strtoupper($this->params[0]) == "OPTIMIZER"){
  214. if (count($this->params) == 1){
  215. require_once(PATH::PAGE . "Optimizer_Page.php");
  216. $page = new Optimizer_Page();
  217. }
  218. else{
  219. require_once(PATH::PAGE . "Optimizer_Unit_Page.php");
  220. $page = new Optimizer_Unit_Page($this->params[1]);
  221. }
  222. }
  223. }
  224. // Load the view, or set an error code.
  225. if (isset($page)){
  226. require_once($page->view);
  227. return 200;
  228. }
  229. else{
  230. require_once(PATH::PAGE . "Error_Page.php");
  231. $page = new Error_Page(404);
  232. http_response_code(404);
  233. return 404;
  234. }
  235. }
  236. public function get_context(){
  237. return $this->context;
  238. }
  239. /**
  240. * Constructor.
  241. *
  242. * Handles every request, creating the required models and selecting the
  243. * view.
  244. *
  245. * @param mixed[] $params POST parameters of the request.
  246. * @return int HTTP status codes 200 or 404;
  247. */
  248. public function __construct(){
  249. $this->context = new Context();
  250. session_start();
  251. $this->db = DB::start();
  252. $this->context->set_db($this->db);
  253. }
  254. /**
  255. * Constructor.
  256. *
  257. * Receives the request params and gets itself ready.
  258. *
  259. * @param mixed[] $params POST parameters of the request.
  260. * @return int HTTP status codes 200 or 404;
  261. */
  262. public function prepare($params){
  263. // Parse parameters.
  264. foreach($params as $p){
  265. if (strlen($p) > 0){
  266. array_push($this->params, $p);
  267. }
  268. }
  269. if (
  270. count($this->params) > 1 &&
  271. (
  272. strtoupper($this->params[0]) == "ACTION"
  273. ) ||
  274. strtoupper($this->params[0]) == "API"
  275. ){
  276. // For API calls, or login action calls, skip authentication
  277. return;
  278. }
  279. // Authentication
  280. if (array_key_exists("user_token", $_COOKIE) && array_key_exists("user_id", $_COOKIE)){
  281. // Authenticated user, check token.
  282. $statement = $this->db->prepare("
  283. SELECT count(token) AS c
  284. FROM token
  285. WHERE
  286. user = :user AND
  287. token = :token AND
  288. strftime('%s', datetime(expiry, 'unixepoch', 'localtime')) > strftime('%s','now')
  289. ");
  290. $statement->bindValue(":user", $_COOKIE["user_id"], SQLITE3_INTEGER);
  291. $statement->bindValue(":token", hash('sha256', $_COOKIE["user_token"]), SQLITE3_TEXT);
  292. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  293. if ($r["c"] == 0){
  294. // Token is invalid, expired, clear cookies, session, and logout.
  295. require_once(PATH::ACTION . "logout.php");
  296. action();
  297. return;
  298. }
  299. else{
  300. // Token is valid, renew session, and assign user.
  301. $_SESSION["user_id"] = $_COOKIE["user_id"];
  302. $_SESSION["session"] = true;
  303. $this->user = new User($_COOKIE["user_id"]);
  304. $this->context->set_user($this->user);
  305. }
  306. }
  307. else{
  308. // Unauthenticated user. Continue
  309. }
  310. // Validate URL (check if it has the player ID).
  311. $this->player = null;
  312. if (sizeof($this->params) > 0 && preg_match("/^[0-9]{6,12}$/", $this->params[0]) == 1){
  313. // Player ID passed in URL. Check it in database
  314. $statement = $this->db->prepare("
  315. SELECT
  316. id,
  317. user,
  318. public
  319. FROM player
  320. WHERE id = :id
  321. ");
  322. $statement->bindValue(":id", $this->params[0], SQLITE3_TEXT);
  323. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  324. if ($r){
  325. // The player exists...
  326. if (null != $this->user && $r["user"] == $this->user->id){
  327. // ... and it belongs to the user. Proceed.
  328. $this->player = new Player($r["id"]);
  329. $this->context->set_player($this->player);
  330. }
  331. elseif (null == $this->user || $r["user"] != $this->user->id){
  332. // ... and it doesn't belong to the user...
  333. if ($r["public"] == 1){
  334. // ... and it belongs to a public profile. Proceed.
  335. $this->player = new Player($r["id"]);
  336. $this->context->set_player($this->player);
  337. }
  338. else{
  339. // ... and it belongs to a private profile. Deny access.
  340. // TODO
  341. }
  342. }
  343. }
  344. }
  345. else{
  346. // Player ID is not passed as URL...
  347. if (null == $this->user){
  348. // ... and no user logged in. Go to the landing page.
  349. require_once(PATH::PAGE . "Landing_Page.php");
  350. $page = new Landing_Page();
  351. require_once($page->view);
  352. return;
  353. }
  354. else{
  355. // ... and the user is logged in. Get last accessed account.
  356. $statement = $this->db->prepare("
  357. SELECT id
  358. FROM player
  359. WHERE user = :user
  360. ORDER BY last_access DESC
  361. ");
  362. $statement->bindValue(":user", $this->user->id, SQLITE3_INTEGER);
  363. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  364. if ($r){
  365. header("Location: /" . $r["id"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH));
  366. return;
  367. }
  368. else{
  369. require_once(PATH::PAGE . "Landing_Page.php");
  370. $page = new Landing_Page();
  371. require_once($page->view);
  372. return;
  373. }
  374. }
  375. }
  376. // Get game mode
  377. $statement = $this->db->prepare("SELECT mode FROM player WHERE id = :id;");
  378. $statement->bindValue(":id", $this->player->get_id(), SQLITE3_INTEGER);
  379. $r = $statement->execute()->fetchArray(SQLITE3_ASSOC);
  380. if ($r && $r["mode"] == GAME_MODE_ID::RTA){
  381. $this->mode = GAME_MODE_ID::RTA;
  382. }
  383. else{
  384. $this->mode = GAME_MODE_ID::NORMAL;
  385. }
  386. $this->context->set_game_mode($this->mode);
  387. }
  388. }
  389. ?>