4chan/emotes_xa22.php
2025-04-17 14:46:47 -05:00

665 lines
18 KiB
PHP

<?php
http_response_code(404);
echo('File not found.');
die();
//define('DEV_MODE', $_SERVER['REMOTE_ADDR'] === '51.159.28.165');
//define('DEV_MODE', false);
/*
if (!DEV_MODE) {
http_response_code(404);
echo('File not found.');
die();
}
else {
ini_set('display_errors', 1);
error_reporting(E_ALL & ~E_NOTICE);
}
*/
header('Content-Type: application/json');
require_once 'lib/db.php';
require_once 'lib/userpwd.php';
define('XA_DOMAIN', ($_SERVER['HTTP_HOST'] === 'sys.4chan.org') ? '4chan.org' : '4channel.org');
define('XA_PWD_TTL', 3600); // 1h
define('XA_COOKIE_TTL', 172800); // 48h
define('HMAC_SECRET', '58c7716fe310556e782b45610b4c1202f56df9f6de2bad92f7df17a7ae80a288');
define('ERR_BAD_REQ', 'Bad Request');
define('ERR_BAD_TKN', 'Cookies need to be enabled');
define('ERR_NO_PTS', 'Not enough points');
define('ERR_ALREADY_OWNED', 'You already have that emote');
define('ERR_GENERIC', 'Internal Server Error');
define('XA_ROLL_PRICE', 10);
define('XA_TICK_POINTS', 20);
define('XA_TICK_INTERVAL', 300);
// ------------
$emotes = [
// Image emotes (type 2, 3): [ type, filename prefix, width, height ]
// 81 emotes
'AngryWojak' => [ 2, '03d18964', 27, 32 ],
'Aquacry' => [ 2, '83cf2699', 30, 30 ],
'AWOOOO' => [ 2, 'e2ad2cb7', 28, 32 ],
'AYAYA' => [ 2, 'f93f9e5a', 32, 31 ],
'AYAYAHyper' => [ 2, 'bc1ff2b8', 32, 32 ],
'BOOBA' => [ 2, 'fb56168f', 32, 32 ],
'BOOMER' => [ 2, '51ca59c2', 32, 32 ],
'Bruh' => [ 2, '67905c4f', 32, 32 ],
'Catcry' => [ 2, '967f06c9', 28, 28 ],
'ChadYes' => [ 2, 'c7375c9d', 31, 32 ],
'COPIUM' => [ 2, '4dfb5c71', 32, 31 ],
'DontBully' => [ 2, '199f7d0e', 31, 32 ],
'EZY' => [ 2, 'adf2d2f0', 28, 26 ],
'FeelsBadMan' => [ 2, '59b6bba6', 30, 29 ],
'FeelsGoodMan' => [ 2, 'cda7b2fb', 32, 24 ],
'FeelsOkayMan' => [ 2, '08b66b75', 28, 27 ],
'FeelsSpecialMan' => [ 2, '25086889', 28, 25 ],
'FeelsStrongMan' => [ 2, '0ee6ba1c', 32, 31 ],
'FeelsWeirdMan' => [ 2, 'ad2977e6', 28, 27 ],
'gachiGASM' => [ 2, 'c291d202', 24, 28 ],
'gachiHYPER' => [ 2, '634a21ba', 24, 28 ],
'Gigachad' => [ 2, '7a95728b', 29, 32 ],
'GoodNight' => [ 2, 'a6d16707', 31, 32 ],
'Hahaa' => [ 2, 'af528e56', 28, 28 ],
'HeavyBreathing' => [ 2, '4623886c', 32, 32 ],
'KannaNom' => [ 2, '5de4addd', 32, 32 ],
'KannaPolice' => [ 2, '98cf0be7', 32, 32 ],
'KEKW' => [ 2, 'e54792d7', 32, 32 ],
'KEKWait' => [ 2, 'c2cfb2e3', 32, 32 ],
'MarisaFace' => [ 2, '857a9ea0', 24, 24 ],
'MeguminHappy' => [ 2, 'a19762fc', 32, 32 ],
'MikuStare' => [ 2, 'b674048b', 32, 32 ],
'monkaChrist' => [ 2, '48c107b3', 28, 28 ],
'monkaGIGA' => [ 2, 'de27847b', 28, 28 ],
'monkaH' => [ 2, 'acb11630', 28, 28 ],
'monkaHmm' => [ 2, 'd3c674ba', 32, 32 ],
'monkaMEGA' => [ 2, '0b3318e4', 28, 28 ],
'monkaOMEGA' => [ 2, 'bb299b4d', 32, 32 ],
'monkaS' => [ 2, 'ed1cc57f', 28, 28 ],
'monkaSpeed' => [ 2, '87c89650', 32, 30 ],
'monkaW' => [ 2, 'b05923f5', 32, 32 ],
'nepSmug' => [ 2, '57b01648', 32, 32 ],
'OMEGALUL' => [ 2, 'c4035570', 31, 32 ],
'peepoBlanket' => [ 2, '099390a2', 31, 32 ],
'peepoClown' => [ 2, '8ea2d160', 32, 32 ],
'peepoHappy' => [ 2, '68104e2a', 28, 20 ],
'peepoWTF' => [ 2, '3d8675e9', 28, 19 ],
'Pepega' => [ 2, '1ee7c5a1', 32, 25 ],
'PepeHands' => [ 2, 'f2ecf801', 32, 32 ],
'PepeLaugh' => [ 2, '51cbf903', 30, 29 ],
'PepeLmao' => [ 2, '25908e08', 28, 28 ],
'pepePoint' => [ 2, '90786369', 32, 32 ],
'PepoG' => [ 2, '4459d60b', 32, 26 ],
'pepoRope' => [ 2, '6ec0dd2c', 32, 31 ],
'PepoThink' => [ 2, '9ecd704b', 32, 31 ],
'pikachuS' => [ 2, '42faedcc', 32, 32 ],
'PillowNo' => [ 2, '1e4d8dfa', 32, 32 ],
'PillowYes' => [ 2, '6f5bc7e5', 32, 32 ],
'Pog' => [ 2, 'fad6951c', 28, 28 ],
'POGGERS' => [ 2, '6f0d4e37', 32, 32 ],
'PressF' => [ 2, 'f0a256b9', 32, 30 ],
'REEeee' => [ 2, 'b06b1566', 32, 32 ],
'REEEEE' => [ 2, 'ba70c4d9', 32, 28 ],
'ReimuGlare' => [ 2, 'bdf28159', 32, 32 ],
'ReimuPalm' => [ 2, '41a37aa0', 32, 32 ],
'SadCatW' => [ 2, 'd8f61d71', 32, 32 ],
'Sadge' => [ 2, 'e024965e', 28, 22 ],
'SeetheWojak' => [ 2, 'a9f848d3', 28, 32 ],
'Stonks' => [ 2, '53478ca5', 31, 32 ],
'ThisIsFine' => [ 2, 'd9bf8456', 28, 31 ],
'Thonk' => [ 2, 'ec538b5c', 32, 27 ],
'TooLewd' => [ 2, 'ddc55766', 32, 32 ],
'Tuturu' => [ 2, 'c72e8e84', 32, 32 ],
'umaruCry' => [ 2, '7242c342', 28, 28 ],
'WanWan' => [ 2, '8a527ac8', 32, 31 ],
'WeirdChamp' => [ 2, '3021a426', 31, 32 ],
'weSmart' => [ 2, '6476e57d', 27, 28 ],
'wojakNPC' => [ 2, '24edafcc', 32, 32 ],
'wojakWithered' => [ 2, 'ed7d4c3a', 32, 30 ],
'WTFF' => [ 2, '8b7cc3e0', 32, 32 ],
'YEP' => [ 2, 'e1899bbe', 32, 31 ],
'YesHoney' => [ 2, '2b414cf1', 31, 25 ],
// 28 emotes
'bane' => [ 3, 'c458ef22', 32, 32 ],
'bog' => [ 3, 'c2e2602a', 32, 32 ],
'cia' => [ 3, 'c69a1ef1', 32, 32 ],
'cockmongler' => [ 3, 'eda6f332', 22, 32 ],
'desu' => [ 3, '80692b94', 28, 32 ],
'desusmirk' => [ 3, '72694e0e', 41, 32 ],
'frodo' => [ 3, 'e9d526e8', 32, 32 ],
'goldface' => [ 3, '7081142e', 32, 32 ],
'happycat' => [ 3, '1d3f2a13', 27, 32 ],
'happyn' => [ 3, 'afd49202', 25, 32 ],
'jannydog' => [ 3, 'f0dcbf8a', 35, 32 ],
'koiwai' => [ 3, '1d7e369a', 44, 32 ],
'koiwaiwave' => [ 3, '0e313986', 31, 32 ],
'konata' => [ 3, 'eb07a2c8', 32, 32 ],
'laughingw' => [ 3, '6e6217c7', 32, 32 ],
'longcat' => [ 3, '0ee48fb4', 37, 32 ],
'longcata' => [ 3, '95c37417', 37, 30 ],
'longcatb' => [ 3, 'e77bc341', 37, 32 ],
'moetron' => [ 3, 'cf1d4b8d', 32, 32 ],
'mudkip' => [ 3, 'a4b23eff', 31, 32 ],
'shoopdw' => [ 3, '11339e7b', 23, 32 ],
'shoopdw2' => [ 3, '49bde730', 100, 32 ],
'troll' => [ 3, 'd89a0070', 37, 32 ],
'trollface' => [ 3, '7b4acfbf', 32, 26 ],
'yaranaika' => [ 3, 'a6955123', 32, 32 ],
'yaranaika2' => [ 3, '4d00227b', 32, 32 ],
// Unicode emojis (type 1): [ type, html entity ]
// 58 emojis
'happy' => [ 1, '&#x1F600;' ],
'grin' => [ 1, '&#x1F604;' ],
'xd' => [ 1, '&#x1F606;' ],
'grinsweat' => [ 1, '&#x1F605;' ],
'rofl' => [ 1, '&#x1F923;' ],
'lmao' => [ 1, '&#x1F602;' ],
'smile' => [ 1, '&#x1F642;' ],
'wink' => [ 1, '&#x1F609;' ],
'glad' => [ 1, '&#x1F60A;' ],
'kiss' => [ 1, '&#x1F619;' ],
'crazy' => [ 1, '&#x1F92A;' ],
'think' => [ 1, '&#x1F914;' ],
'wot' => [ 1, '&#x1F928;' ],
'kay' => [ 1, '&#x1F610;' ],
'yikes' => [ 1, '&#x1F612;' ],
'eyeroll' => [ 1, '&#x1F644;' ],
'confused' => [ 1, '&#x1F615;' ],
'pensive' => [ 1, '&#x1F614;' ],
'disgust' => [ 1, '&#x1F922;' ],
'vomit' => [ 1, '&#x1F92E;' ],
'dizzy' => [ 1, '&#x1F635;' ],
'nerd' => [ 1, '&#x1F913;' ],
'worry' => [ 1, '&#x1F61F;' ],
'sad' => [ 1, '&#x1F641;' ],
'frown' => [ 1, '&#x2639;&#xFE0F;' ],
'wow' => [ 1, '&#x1F632;' ],
'blush' => [ 1, '&#x1F633;' ],
'cry' => [ 1, '&#x1F622;' ],
'plead' => [ 1, '&#x1F97A;' ],
'baw' => [ 1, '&#x1F62D;' ],
'shock' => [ 1, '&#x1F631;' ],
'anguish' => [ 1, '&#x1F627;' ],
'devil' => [ 1, '&#x1F608;' ],
'angry' => [ 1, '&#x1F620;' ],
'struggle' => [ 1, '&#x1F623;' ],
'proud' => [ 1, '&#x1F624;' ],
'smirk' => [ 1, '&#x1F60F;' ],
'drool' => [ 1, '&#x1F924;' ],
'love' => [ 1, '&#x1F60D;' ],
'skull' => [ 1, '&#x1F480;' ],
'clown' => [ 1, '&#x1F921;' ],
'alien' => [ 1, '&#x1F47D;' ],
'robot' => [ 1, '&#x1F916;' ],
'ok' => [ 1, '&#x1F44C;' ],
'fu' => [ 1, '&#x1F595;' ],
'thup' => [ 1, '&#x1F44D;' ],
'thdown' => [ 1, '&#x1F44E;' ],
'punch' => [ 1, '&#x1F44A;' ],
'pray' => [ 1, '&#x1F64F;' ],
'flex' => [ 1, '&#x1F4AA;' ],
'eyes' => [ 1, '&#x1F440;' ],
'drip' => [ 1, '&#x1F4A6;' ],
'wind' => [ 1, '&#x1F4A8;' ],
'fire' => [ 1, '&#x1F525;' ],
'clover' => [ 1, '&#x1F340;' ],
'anger' => [ 1, '&#x1F4A2;' ],
'perfect' => [ 1, '&#x1F4AF;' ],
'zzz' => [ 1, '&#x1F4A4;' ]
];
$emote_pools = [
// 58
['happy','grin','xd','grinsweat','rofl','lmao','smile','wink','glad','kiss',
'crazy','think','wot','kay','yikes','eyeroll','confused','pensive','disgust',
'vomit','dizzy','nerd','worry','sad','frown','wow','blush','cry','plead','baw',
'shock','anguish','devil','angry','struggle','proud','smirk','drool','love',
'skull','clown','alien','robot','ok','fu','thup','thdown','punch','pray',
'flex','eyes','drip','wind','fire','clover','anger','perfect','zzz'],
// 81
['03d18964','83cf2699','e2ad2cb7','f93f9e5a','bc1ff2b8','fb56168f','51ca59c2',
'67905c4f','967f06c9','c7375c9d','4dfb5c71','199f7d0e','adf2d2f0','59b6bba6',
'cda7b2fb','08b66b75','25086889','0ee6ba1c','ad2977e6','c291d202','634a21ba',
'7a95728b','a6d16707','af528e56','4623886c','5de4addd','98cf0be7','e54792d7',
'c2cfb2e3','857a9ea0','a19762fc','b674048b','48c107b3','de27847b','acb11630',
'd3c674ba','0b3318e4','bb299b4d','ed1cc57f','87c89650','b05923f5','57b01648',
'c4035570','099390a2','8ea2d160','68104e2a','3d8675e9','1ee7c5a1','f2ecf801',
'51cbf903','25908e08','90786369','4459d60b','6ec0dd2c','9ecd704b','42faedcc',
'1e4d8dfa','6f5bc7e5','fad6951c','6f0d4e37','f0a256b9','b06b1566','ba70c4d9',
'bdf28159','41a37aa0','d8f61d71','e024965e','a9f848d3','53478ca5','d9bf8456',
'ec538b5c','ddc55766','c72e8e84','7242c342','8a527ac8','3021a426','6476e57d',
'24edafcc','ed7d4c3a','8b7cc3e0','e1899bbe','2b414cf1'],
// 28
['c458ef22','c2e2602a','c69a1ef1','eda6f332','80692b94','72694e0e','e9d526e8',
'7081142e','1d3f2a13','afd49202','f0dcbf8a','1d7e369a','0e313986','eb07a2c8',
'6e6217c7','0ee48fb4','95c37417','e77bc341','cf1d4b8d','a4b23eff','11339e7b',
'49bde730','d89a0070','7b4acfbf','a6955123','4d00227b']
];
// ------------
function xa_error($msg, $extra = null) {
$data = array('status' => 'error', 'msg' => $msg);
if ($extra) {
$data = array_merge($data, $extra);
}
echo json_encode($data);
die();
}
function xa_success($data = null) {
$ret = array('status' => 'success');
if ($data) {
$ret['data'] = $data;
}
echo json_encode($ret);
die();
}
/**
* Sessions
*/
function xa_start_session() {
// Recover previous session by sid
if (isset($_COOKIE['xa_sid']) && $_COOKIE['xa_sid']) {
$data = xa_recover_session_by_sid($_COOKIE['xa_sid']);
if ($data) {
xa_success($data);
}
}
$ip = $_SERVER['REMOTE_ADDR'];
// Recover previous session by IP
$sid = hash_hmac('sha1', $ip, HMAC_SECRET);
if (!$sid) {
xa_error(ERR_GENERIC . ' (ssx9)');
}
$data = xa_recover_session_by_sid($sid);
if ($data) {
xa_set_sid_cookie($sid);
xa_success($data);
}
// Create new session
$data = [];
if (isset($_COOKIE['4chan_pass'])) {
$userpwd = new UserPwd($ip, XA_DOMAIN, $_COOKIE['4chan_pass']);
if ($userpwd->maskLifetime() >= XA_PWD_TTL) {
$balance = 100;
}
}
else {
$balance = 0;
}
$data['start_ts'] = $_SERVER['REQUEST_TIME'];
$data['balance'] = $balance;
$data['owned'] = [];
$ret = xa_save_session($sid, $ip, $data);
if (!$ret) {
xa_error(ERR_GENERIC . ' (ssx5)');
}
xa_set_sid_cookie($sid);
xa_success($data);
}
function xa_set_sid_cookie($sid) {
setcookie('xa_sid', $sid, $_SERVER['REQUEST_TIME'] + XA_COOKIE_TTL, '/', '.' . XA_DOMAIN, true);
}
function xa_save_session($sid, $ip, $data) {
$sql = "INSERT INTO april_emotes (session_id, ip, data) VALUES('%s', '%s', '%s')";
$data = json_encode($data);
if (!$data) {
return false;
}
return mysql_global_call($sql, $sid, $ip, $data);
}
function xa_rebuild_owned_emotes($data) {
global $emotes;
$owned_meta = [];
if (!isset($data['owned'])) {
return $owned_meta;
}
foreach ($data['owned'] as $key) {
$_e = $emotes[$key];
if ($_e) {
$owned_meta[] = [$key, $_e[0], $_e[1]];
}
}
return $owned_meta;
}
function xa_recover_session_by_sid($sid) {
$sql = "SELECT data FROM april_emotes WHERE session_id = '%s' LIMIT 1";
$res = mysql_global_call($sql, $sid);
if (!$res) {
xa_error(ERR_GENERIC . ' (gsbs5)');
}
$data = mysql_fetch_assoc($res)['data'];
if (!$data) {
return null;
}
$data = json_decode($data, true);
if (!$data) {
xa_error(ERR_GENERIC . ' (gsbs4)');
}
$data['owned'] = xa_rebuild_owned_emotes($data);
return $data;
}
/**
* Rolling
*/
function xa_roll($size) {
global $emotes, $emote_pools;
if (!isset($_COOKIE['xa_sid']) || !$_COOKIE['xa_sid']) {
xa_error(ERR_BAD_REQ);
}
$sid = $_COOKIE['xa_sid'];
$rolled_eids = [];
for ($i = 0; $i < $size; $i++) {
$_r = mt_rand(0, 99);
if ($_r >= 90) {
// 28 emotes in pool 3
$rolled_eids[] = $emote_pools[2][mt_rand(0, count($emote_pools[2]) - 1)];
}
else if ($_r >= 50) {
// 81 emotes in pool 2
$rolled_eids[] = $emote_pools[1][mt_rand(0, count($emote_pools[1]) - 1)];
}
else {
// 58 emojis in pool 1
$rolled_eids[] = $emote_pools[0][mt_rand(0, count($emote_pools[0]) - 1)];
}
}
mysql_global_call('START TRANSACTION');
$sql = "SELECT data FROM april_emotes WHERE session_id = '%s' FOR UPDATE";
$res = mysql_global_call($sql, $sid);
if (!$res) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (lbr8)');
}
$data = mysql_fetch_assoc($res)['data'];
if (!$data) {
mysql_global_call('COMMIT');
xa_error(ERR_BAD_REQ);
}
$data = json_decode($data, true);
if (!$data) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (lbr9)');
}
// Check if enough points
$full_balance = xa_get_full_balance($data);
$total_cost = $size * XA_ROLL_PRICE;
if ($full_balance < $total_cost) {
mysql_global_call('COMMIT');
xa_error(ERR_NO_PTS, [ 'pts' => $data['balance'] ]);
}
// Roll results to return to the client for visual purposes
$obtained = [];
$recycled_points = 0;
if (!isset($data['owned'])) {
$data['owned'] = [];
}
foreach ($rolled_eids as $eid) {
$_e_meta = xa_get_emote_by_id($eid);
list($key, $kind, $arg) = $_e_meta;
// Emote already owned, recycle it
if (in_array($key, $data['owned'])) {
if ($kind === 3) {
$recycled_points += 10;
}
else {
$recycled_points += 5;
}
}
// New emote, add it to the owned list
else {
$data['owned'][] = $key;
}
$obtained[] = $_e_meta;
}
$data['balance'] += $recycled_points;
$data['balance'] -= $total_cost;
$balance = $data['balance'];
$data = json_encode($data);
$sql = "UPDATE april_emotes SET data = '%s' WHERE session_id = '%s' LIMIT 1";
$res = mysql_global_call($sql, $data, $sid);
if (!$res) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (lbr6)');
}
mysql_global_call('COMMIT');
xa_success(['obtained' => $obtained, 'balance' => $balance]);
}
function xa_get_full_balance($data) {
$now = $_SERVER['REQUEST_TIME'];
$start_ts = (int)$data['start_ts'];
$tick_balance = floor(($now - $start_ts) / XA_TICK_INTERVAL) * XA_TICK_POINTS;
return $tick_balance + $data['balance'];
}
function xa_get_emote_by_id($id) {
global $emotes;
foreach ($emotes as $key => $meta) {
$_kind = $meta[0];
$_arg = $meta[1];
// Emoji (type 1)
if ($_kind === 1) {
if ($key === $id) {
return [$key, $_kind, $_arg];
}
}
// Image emotes
else {
if ($_arg === $id) {
return [$key, $_kind, $_arg];
}
}
}
return null;
}
/**
* Buying
*/
function xa_buy() {
global $emotes, $emote_pools;
if (!isset($_COOKIE['xa_sid']) || !$_COOKIE['xa_sid']) {
xa_error(ERR_BAD_REQ);
}
if (!isset($_POST['eid']) || !$_POST['eid']) {
xa_error(ERR_BAD_REQ);
}
$obtained = xa_get_emote_by_id($_POST['eid']);
if (!$obtained) {
xa_error(ERR_BAD_REQ);
}
list($key, $kind, $arg) = $obtained;
// Pool 1
if ($kind === 1) {
$total_cost = 50;
}
// Pool 2
else if ($kind === 2) {
$total_cost = 150;
}
// Pool 3
else {
$total_cost = 300;
}
$sid = $_COOKIE['xa_sid'];
mysql_global_call('START TRANSACTION');
$sql = "SELECT data FROM april_emotes WHERE session_id = '%s' FOR UPDATE";
$res = mysql_global_call($sql, $sid);
if (!$res) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (be0)');
}
$data = mysql_fetch_assoc($res)['data'];
if (!$data) {
mysql_global_call('COMMIT');
xa_error(ERR_BAD_REQ);
}
$data = json_decode($data, true);
if (!$data) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (be1)');
}
// Check if already owned
if (in_array($key, $data['owned'])) {
mysql_global_call('COMMIT');
xa_error(ERR_ALREADY_OWNED);
}
// Check if enough points
$full_balance = xa_get_full_balance($data);
if ($full_balance < $total_cost) {
mysql_global_call('COMMIT');
xa_error(ERR_NO_PTS, [ 'pts' => $data['balance'] ]);
}
$data['owned'][] = $key;
$data['balance'] -= $total_cost;
$balance = $data['balance'];
$data = json_encode($data);
$sql = "UPDATE april_emotes SET data = '%s' WHERE session_id = '%s' LIMIT 1";
$res = mysql_global_call($sql, $data, $sid);
if (!$res) {
mysql_global_call('COMMIT');
xa_error(ERR_GENERIC . ' (lbr6)');
}
mysql_global_call('COMMIT');
xa_success(['obtained' => $obtained, 'balance' => $balance]);
}
// --------------
if (!isset($_POST['action'])) {
xa_error(ERR_BAD_REQ);
}
if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != ''
&& !preg_match('/^https?:\/\/([_a-z0-9]+)\.(4chan|4channel)\.org(\/|$)/', $_SERVER['HTTP_REFERER'])) {
xa_error(ERR_BAD_REQ . '(xr1)');
}
// -------------
$_action = $_POST['action'];
if ($_action === 'start') {
xa_start_session();
}
else if ($_action === 'roll3') {
xa_roll(3);
}
else if ($_action === 'roll10') {
xa_roll(10);
}
else if ($_action === 'buy') {
xa_buy();
}
else {
xa_error(ERR_BAD_REQ);
}