379 lines
7.6 KiB
PHP
379 lines
7.6 KiB
PHP
<?php
|
|
/*
|
|
define('DEV_MODE', $_SERVER['REMOTE_ADDR'] === '51.159.28.165');
|
|
|
|
if (!DEV_MODE) {
|
|
http_response_code(404);
|
|
echo('File not found.');
|
|
die();
|
|
}
|
|
else {
|
|
ini_set('display_errors', 1);
|
|
error_reporting(E_ALL & ~E_NOTICE);
|
|
$mysql_suppress_err = false;
|
|
}
|
|
*/
|
|
require_once 'lib/db.php';
|
|
require_once 'lib/userpwd.php';
|
|
|
|
define('CURRENCY_CODE', '_');
|
|
define('STARTING_AMOUNT', 1000);
|
|
define('MAX_BUY_SELL_SIZE', 1000);
|
|
|
|
const STOCK_LIST = [
|
|
'PEPE', 'WOJK', 'ANIME', 'CHAD', 'CLOWN', 'LOL', 'SICP', 'AUTSM', 'BANE',
|
|
'CIA', 'BOOB', 'RDDT', 'DESU', 'JANNY', 'GME', 'CHUCK', 'YTSB', 'GACHI'
|
|
];
|
|
|
|
function output_json($data) {
|
|
header('Content-Type: application/json');
|
|
echo json_encode($data);
|
|
}
|
|
|
|
function output_error($msg) {
|
|
output_json(['error' => $msg]);
|
|
die();
|
|
}
|
|
|
|
function create_account() {
|
|
$user_ip = $_SERVER['REMOTE_ADDR'];
|
|
|
|
if (isset($_COOKIE['4chan_pass'])) {
|
|
$userpwd = new UserPwd($user_ip, '4chan.org', $_COOKIE['4chan_pass']);
|
|
}
|
|
else {
|
|
$userpwd = new UserPwd($user_ip, '4chan.org');
|
|
}
|
|
|
|
$user_id = $userpwd->getPwd();
|
|
|
|
$sql = "SELECT id FROM april_stock_users WHERE user_id = '%s' LIMIT 1";
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (frac1)');
|
|
}
|
|
|
|
if (mysql_num_rows($res)) {
|
|
$account = get_account_balance($user_id);
|
|
output_json($account);
|
|
die();
|
|
}
|
|
|
|
$cur_code = CURRENCY_CODE;
|
|
$cur_amount = (int)STARTING_AMOUNT;
|
|
|
|
$sql =<<<SQL
|
|
INSERT INTO april_stock_users (user_id, stock, amount)
|
|
VALUES ('%s', '$cur_code', $cur_amount)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (frac0)');
|
|
}
|
|
|
|
$userpwd->setCookie('.4chan.org');
|
|
|
|
output_json([
|
|
'balance' => $cur_amount
|
|
]);
|
|
}
|
|
|
|
function get_account_balance($user_id) {
|
|
$sql = "SELECT stock, SUM(amount) as amount FROM april_stock_users WHERE user_id = '%s' GROUP BY stock";
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
$data = [];
|
|
|
|
while ($row = mysql_fetch_assoc($res)) {
|
|
if ($row['stock'] == CURRENCY_CODE) {
|
|
$amount = (int)$row['amount'];
|
|
|
|
if ($amount < 0) {
|
|
$amount = 0;
|
|
}
|
|
|
|
$data['balance'] = $amount;
|
|
}
|
|
else if (in_array($row['stock'], STOCK_LIST)) {
|
|
$amount = (int)$row['amount'];
|
|
|
|
if ($amount <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$data[$row['stock']] = $amount;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
function get_account() {
|
|
$user_ip = $_SERVER['REMOTE_ADDR'];
|
|
|
|
if (!isset($_COOKIE['4chan_pass'])) {
|
|
output_error('Account not found');
|
|
}
|
|
|
|
$userpwd = new UserPwd($user_ip, '4chan.org', $_COOKIE['4chan_pass']);
|
|
|
|
if ($userpwd->isNew()) {
|
|
output_error('Account not found');
|
|
}
|
|
|
|
$user_id = $userpwd->getPwd();
|
|
|
|
$data = get_account_balance($user_id);
|
|
|
|
return [$user_id, $data];
|
|
}
|
|
|
|
function get_stock_price($stock) {
|
|
if ($stock == CURRENCY_CODE) {
|
|
output_error('Stock not found');
|
|
}
|
|
|
|
$sql = "SELECT price FROM april_stock_prices WHERE stock = '%s' ORDER BY id DESC LIMIT 1";
|
|
|
|
$res = mysql_global_call($sql, $stock);
|
|
|
|
if (!$res) {
|
|
return false;
|
|
}
|
|
|
|
$price = (int)mysql_fetch_row($res)[0];
|
|
|
|
if ($price <= 0) {
|
|
return false;
|
|
}
|
|
|
|
return $price;
|
|
}
|
|
|
|
function get_stock_http_param() {
|
|
if (!isset($_POST['stock']) || !$_POST['stock'] || $_POST['stock'] == CURRENCY_CODE) {
|
|
return false;
|
|
}
|
|
|
|
return $_POST['stock'];
|
|
}
|
|
|
|
function get_amount_http_param() {
|
|
if (!isset($_POST['amount']) || !$_POST['amount']) {
|
|
return false;
|
|
}
|
|
|
|
$amount = (int)$_POST['amount'];
|
|
|
|
if ($amount < 1 || $amount > MAX_BUY_SELL_SIZE) {
|
|
return false;
|
|
}
|
|
|
|
return $amount;
|
|
}
|
|
|
|
function get_price_http_param() {
|
|
if (!isset($_POST['price']) || !$_POST['price']) {
|
|
return false;
|
|
}
|
|
|
|
$price = (int)$_POST['price'];
|
|
|
|
if ($price < 1) {
|
|
return false;
|
|
}
|
|
|
|
return $price;
|
|
}
|
|
|
|
function enforce_cooldown($user_id) {
|
|
$sql =<<<SQL
|
|
SELECT id FROM april_stock_users WHERE user_id = '%s'
|
|
AND created_on > DATE_SUB(NOW(), INTERVAL 10 SECOND)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
if (!$res) {
|
|
return true;
|
|
}
|
|
|
|
if (mysql_num_rows($res)) {
|
|
output_error('You can only make an order once every 10 seconds');
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* BUY
|
|
*/
|
|
|
|
function buy_stock() {
|
|
$stock = get_stock_http_param();
|
|
|
|
if (!$stock) {
|
|
output_error('Stock not found');
|
|
}
|
|
|
|
$amount = get_amount_http_param();
|
|
|
|
if (!$amount) {
|
|
output_error('Invalid amount');
|
|
}
|
|
|
|
$user_price = get_price_http_param();
|
|
|
|
if (!$user_price) {
|
|
output_error('Invalid price');
|
|
}
|
|
|
|
$price = get_stock_price($stock);
|
|
|
|
if (!$price) {
|
|
output_error('Invalid price');
|
|
}
|
|
|
|
if ($user_price != $price) {
|
|
output_error('The price has changed.');
|
|
}
|
|
|
|
$total_price = $amount * $price;
|
|
|
|
list($user_id, $account) = get_account();
|
|
|
|
if ($total_price > $account['balance']) {
|
|
output_error('Your account balance is too low');
|
|
}
|
|
|
|
enforce_cooldown($user_id);
|
|
|
|
// Decrement balance
|
|
$cur_code = CURRENCY_CODE;
|
|
|
|
$sql =<<<SQL
|
|
INSERT INTO april_stock_users (user_id, stock, amount)
|
|
VALUES ('%s', '$cur_code', -$total_price)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (bi05-2)');
|
|
}
|
|
|
|
// Increment the stock amount
|
|
$sql =<<<SQL
|
|
INSERT INTO april_stock_users (user_id, stock, amount)
|
|
VALUES ('%s', '%s', $amount)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id, $stock);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (bi05-2)');
|
|
}
|
|
|
|
$account = get_account_balance($user_id);
|
|
|
|
output_json($account);
|
|
}
|
|
|
|
/**
|
|
* SELL
|
|
*/
|
|
function sell_stock() {
|
|
$stock = get_stock_http_param();
|
|
|
|
if (!$stock) {
|
|
output_error('Stock not found');
|
|
}
|
|
|
|
$amount = get_amount_http_param();
|
|
|
|
if (!$amount) {
|
|
output_error('Invalid amount');
|
|
}
|
|
|
|
$user_price = get_price_http_param();
|
|
|
|
if (!$user_price) {
|
|
output_error('Invalid price');
|
|
}
|
|
|
|
$price = get_stock_price($stock);
|
|
|
|
if (!$price) {
|
|
output_error('Invalid price');
|
|
}
|
|
|
|
if ($user_price != $price) {
|
|
output_error('The price has changed.');
|
|
}
|
|
|
|
$total_price = $amount * $price;
|
|
|
|
list($user_id, $account) = get_account();
|
|
|
|
if ($amount > $account[$stock]) {
|
|
output_error('Your account balance is too low');
|
|
}
|
|
|
|
// Cooldown
|
|
enforce_cooldown($user_id);
|
|
|
|
// Decrement the stock amount
|
|
$sql =<<<SQL
|
|
INSERT INTO april_stock_users (user_id, stock, amount)
|
|
VALUES ('%s', '%s', -$amount)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id, $stock);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (bi05-2)');
|
|
}
|
|
|
|
// Increment balance
|
|
$cur_code = CURRENCY_CODE;
|
|
|
|
$sql =<<<SQL
|
|
INSERT INTO april_stock_users (user_id, stock, amount)
|
|
VALUES ('%s', '$cur_code', $total_price)
|
|
SQL;
|
|
|
|
$res = mysql_global_call($sql, $user_id);
|
|
|
|
if (!$res) {
|
|
output_error('Internal Server Error (bi05-2)');
|
|
}
|
|
|
|
$account_balance = get_account_balance($user_id);
|
|
|
|
output_json($account_balance);
|
|
}
|
|
|
|
output_error('The market is closed');
|
|
|
|
if (isset($_POST['create'])) {
|
|
create_account();
|
|
}
|
|
else if (isset($_POST['mode'])) {
|
|
if ($_POST['mode'] === 'buy') {
|
|
buy_stock();
|
|
}
|
|
else if ($_POST['mode'] === 'sell') {
|
|
sell_stock();
|
|
}
|
|
else {
|
|
output_error('Bad request');
|
|
}
|
|
}
|
|
else {
|
|
output_error('Bad request');
|
|
}
|