/ xa24tb.php
xa24tb.php
1 <?php 2 /* 3 define('DEV_MODE', $_SERVER['REMOTE_ADDR'] === '51.159.28.165'); 4 5 if (!DEV_MODE) { 6 http_response_code(404); 7 echo('File not found.'); 8 die(); 9 } 10 else { 11 ini_set('display_errors', 1); 12 error_reporting(E_ALL & ~E_NOTICE); 13 $mysql_suppress_err = false; 14 } 15 */ 16 require_once 'lib/db.php'; 17 require_once 'lib/userpwd.php'; 18 19 define('CURRENCY_CODE', '_'); 20 define('STARTING_AMOUNT', 1000); 21 define('MAX_BUY_SELL_SIZE', 1000); 22 23 const STOCK_LIST = [ 24 'PEPE', 'WOJK', 'ANIME', 'CHAD', 'CLOWN', 'LOL', 'SICP', 'AUTSM', 'BANE', 25 'CIA', 'BOOB', 'RDDT', 'DESU', 'JANNY', 'GME', 'CHUCK', 'YTSB', 'GACHI' 26 ]; 27 28 function output_json($data) { 29 header('Content-Type: application/json'); 30 echo json_encode($data); 31 } 32 33 function output_error($msg) { 34 output_json(['error' => $msg]); 35 die(); 36 } 37 38 function create_account() { 39 $user_ip = $_SERVER['REMOTE_ADDR']; 40 41 if (isset($_COOKIE['4chan_pass'])) { 42 $userpwd = new UserPwd($user_ip, '4chan.org', $_COOKIE['4chan_pass']); 43 } 44 else { 45 $userpwd = new UserPwd($user_ip, '4chan.org'); 46 } 47 48 $user_id = $userpwd->getPwd(); 49 50 $sql = "SELECT id FROM april_stock_users WHERE user_id = '%s' LIMIT 1"; 51 52 $res = mysql_global_call($sql, $user_id); 53 54 if (!$res) { 55 output_error('Internal Server Error (frac1)'); 56 } 57 58 if (mysql_num_rows($res)) { 59 $account = get_account_balance($user_id); 60 output_json($account); 61 die(); 62 } 63 64 $cur_code = CURRENCY_CODE; 65 $cur_amount = (int)STARTING_AMOUNT; 66 67 $sql =<<<SQL 68 INSERT INTO april_stock_users (user_id, stock, amount) 69 VALUES ('%s', '$cur_code', $cur_amount) 70 SQL; 71 72 $res = mysql_global_call($sql, $user_id); 73 74 if (!$res) { 75 output_error('Internal Server Error (frac0)'); 76 } 77 78 $userpwd->setCookie('.4chan.org'); 79 80 output_json([ 81 'balance' => $cur_amount 82 ]); 83 } 84 85 function get_account_balance($user_id) { 86 $sql = "SELECT stock, SUM(amount) as amount FROM april_stock_users WHERE user_id = '%s' GROUP BY stock"; 87 88 $res = mysql_global_call($sql, $user_id); 89 90 $data = []; 91 92 while ($row = mysql_fetch_assoc($res)) { 93 if ($row['stock'] == CURRENCY_CODE) { 94 $amount = (int)$row['amount']; 95 96 if ($amount < 0) { 97 $amount = 0; 98 } 99 100 $data['balance'] = $amount; 101 } 102 else if (in_array($row['stock'], STOCK_LIST)) { 103 $amount = (int)$row['amount']; 104 105 if ($amount <= 0) { 106 continue; 107 } 108 109 $data[$row['stock']] = $amount; 110 } 111 } 112 113 return $data; 114 } 115 116 function get_account() { 117 $user_ip = $_SERVER['REMOTE_ADDR']; 118 119 if (!isset($_COOKIE['4chan_pass'])) { 120 output_error('Account not found'); 121 } 122 123 $userpwd = new UserPwd($user_ip, '4chan.org', $_COOKIE['4chan_pass']); 124 125 if ($userpwd->isNew()) { 126 output_error('Account not found'); 127 } 128 129 $user_id = $userpwd->getPwd(); 130 131 $data = get_account_balance($user_id); 132 133 return [$user_id, $data]; 134 } 135 136 function get_stock_price($stock) { 137 if ($stock == CURRENCY_CODE) { 138 output_error('Stock not found'); 139 } 140 141 $sql = "SELECT price FROM april_stock_prices WHERE stock = '%s' ORDER BY id DESC LIMIT 1"; 142 143 $res = mysql_global_call($sql, $stock); 144 145 if (!$res) { 146 return false; 147 } 148 149 $price = (int)mysql_fetch_row($res)[0]; 150 151 if ($price <= 0) { 152 return false; 153 } 154 155 return $price; 156 } 157 158 function get_stock_http_param() { 159 if (!isset($_POST['stock']) || !$_POST['stock'] || $_POST['stock'] == CURRENCY_CODE) { 160 return false; 161 } 162 163 return $_POST['stock']; 164 } 165 166 function get_amount_http_param() { 167 if (!isset($_POST['amount']) || !$_POST['amount']) { 168 return false; 169 } 170 171 $amount = (int)$_POST['amount']; 172 173 if ($amount < 1 || $amount > MAX_BUY_SELL_SIZE) { 174 return false; 175 } 176 177 return $amount; 178 } 179 180 function get_price_http_param() { 181 if (!isset($_POST['price']) || !$_POST['price']) { 182 return false; 183 } 184 185 $price = (int)$_POST['price']; 186 187 if ($price < 1) { 188 return false; 189 } 190 191 return $price; 192 } 193 194 function enforce_cooldown($user_id) { 195 $sql =<<<SQL 196 SELECT id FROM april_stock_users WHERE user_id = '%s' 197 AND created_on > DATE_SUB(NOW(), INTERVAL 10 SECOND) 198 SQL; 199 200 $res = mysql_global_call($sql, $user_id); 201 202 if (!$res) { 203 return true; 204 } 205 206 if (mysql_num_rows($res)) { 207 output_error('You can only make an order once every 10 seconds'); 208 } 209 210 return false; 211 } 212 213 /** 214 * BUY 215 */ 216 217 function buy_stock() { 218 $stock = get_stock_http_param(); 219 220 if (!$stock) { 221 output_error('Stock not found'); 222 } 223 224 $amount = get_amount_http_param(); 225 226 if (!$amount) { 227 output_error('Invalid amount'); 228 } 229 230 $user_price = get_price_http_param(); 231 232 if (!$user_price) { 233 output_error('Invalid price'); 234 } 235 236 $price = get_stock_price($stock); 237 238 if (!$price) { 239 output_error('Invalid price'); 240 } 241 242 if ($user_price != $price) { 243 output_error('The price has changed.'); 244 } 245 246 $total_price = $amount * $price; 247 248 list($user_id, $account) = get_account(); 249 250 if ($total_price > $account['balance']) { 251 output_error('Your account balance is too low'); 252 } 253 254 enforce_cooldown($user_id); 255 256 // Decrement balance 257 $cur_code = CURRENCY_CODE; 258 259 $sql =<<<SQL 260 INSERT INTO april_stock_users (user_id, stock, amount) 261 VALUES ('%s', '$cur_code', -$total_price) 262 SQL; 263 264 $res = mysql_global_call($sql, $user_id); 265 266 if (!$res) { 267 output_error('Internal Server Error (bi05-2)'); 268 } 269 270 // Increment the stock amount 271 $sql =<<<SQL 272 INSERT INTO april_stock_users (user_id, stock, amount) 273 VALUES ('%s', '%s', $amount) 274 SQL; 275 276 $res = mysql_global_call($sql, $user_id, $stock); 277 278 if (!$res) { 279 output_error('Internal Server Error (bi05-2)'); 280 } 281 282 $account = get_account_balance($user_id); 283 284 output_json($account); 285 } 286 287 /** 288 * SELL 289 */ 290 function sell_stock() { 291 $stock = get_stock_http_param(); 292 293 if (!$stock) { 294 output_error('Stock not found'); 295 } 296 297 $amount = get_amount_http_param(); 298 299 if (!$amount) { 300 output_error('Invalid amount'); 301 } 302 303 $user_price = get_price_http_param(); 304 305 if (!$user_price) { 306 output_error('Invalid price'); 307 } 308 309 $price = get_stock_price($stock); 310 311 if (!$price) { 312 output_error('Invalid price'); 313 } 314 315 if ($user_price != $price) { 316 output_error('The price has changed.'); 317 } 318 319 $total_price = $amount * $price; 320 321 list($user_id, $account) = get_account(); 322 323 if ($amount > $account[$stock]) { 324 output_error('Your account balance is too low'); 325 } 326 327 // Cooldown 328 enforce_cooldown($user_id); 329 330 // Decrement the stock amount 331 $sql =<<<SQL 332 INSERT INTO april_stock_users (user_id, stock, amount) 333 VALUES ('%s', '%s', -$amount) 334 SQL; 335 336 $res = mysql_global_call($sql, $user_id, $stock); 337 338 if (!$res) { 339 output_error('Internal Server Error (bi05-2)'); 340 } 341 342 // Increment balance 343 $cur_code = CURRENCY_CODE; 344 345 $sql =<<<SQL 346 INSERT INTO april_stock_users (user_id, stock, amount) 347 VALUES ('%s', '$cur_code', $total_price) 348 SQL; 349 350 $res = mysql_global_call($sql, $user_id); 351 352 if (!$res) { 353 output_error('Internal Server Error (bi05-2)'); 354 } 355 356 $account_balance = get_account_balance($user_id); 357 358 output_json($account_balance); 359 } 360 361 output_error('The market is closed'); 362 363 if (isset($_POST['create'])) { 364 create_account(); 365 } 366 else if (isset($_POST['mode'])) { 367 if ($_POST['mode'] === 'buy') { 368 buy_stock(); 369 } 370 else if ($_POST['mode'] === 'sell') { 371 sell_stock(); 372 } 373 else { 374 output_error('Bad request'); 375 } 376 } 377 else { 378 output_error('Bad request'); 379 }