function directory_init(&$a) { $a->set_pager_itemspage(60); if (x($_GET, 'ignore')) { q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ", intval(local_channel()), dbesc($_GET['ignore'])); } $observer = get_observer_hash(); $global_changed = false; $safe_changed = false; if (array_key_exists('global', $_REQUEST)) { $globaldir = intval($_REQUEST['global']); $global_changed = true; } if ($global_changed) { $_SESSION['globaldir'] = $globaldir; if ($observer) { set_xconfig($observer, 'directory', 'globaldir', $globaldir); } } if (array_key_exists('safe', $_REQUEST)) { $safemode = intval($_REQUEST['safe']); $safe_changed = true; } if ($safe_changed) { $_SESSION['safemode'] = $safemode; if ($observer) { set_xconfig($observer, 'directory', 'safe_mode', $safemode); } } }
function init() { \App::set_pager_itemspage(60); if (x($_GET, 'ignore')) { q("insert into xign ( uid, xchan ) values ( %d, '%s' ) ", intval(local_channel()), dbesc($_GET['ignore'])); goaway(z_root() . '/directory?suggest=1'); } $observer = get_observer_hash(); $global_changed = false; $safe_changed = false; $pubforums_changed = false; if (array_key_exists('global', $_REQUEST)) { $globaldir = intval($_REQUEST['global']); $global_changed = true; } if ($global_changed) { $_SESSION['globaldir'] = $globaldir; if ($observer) { set_xconfig($observer, 'directory', 'globaldir', $globaldir); } } if (array_key_exists('safe', $_REQUEST)) { $safemode = intval($_REQUEST['safe']); $safe_changed = true; } if ($safe_changed) { $_SESSION['safemode'] = $safemode; if ($observer) { set_xconfig($observer, 'directory', 'safemode', $safemode); } } if (array_key_exists('pubforums', $_REQUEST)) { $pubforums = intval($_REQUEST['pubforums']); $pubforums_changed = true; } if ($pubforums_changed) { $_SESSION['pubforums'] = $pubforums; if ($observer) { set_xconfig($observer, 'directory', 'pubforums', $pubforums); } } }
function init() { $observer = get_observer_hash(); if (!$observer) { return; } if ($observer) { $safe_mode = get_xconfig($observer, 'directory', 'safe_mode'); } if ($safe_mode == '') { set_xconfig($observer, 'directory', 'safe_mode', '0'); } elseif ($safe_mode == '0') { set_xconfig($observer, 'directory', 'safe_mode', '1'); } elseif ($safe_mode == '1') { set_xconfig($observer, 'directory', 'safe_mode', '0'); } if (isset($_GET['address'])) { $address = $_GET['address']; } else { $address = z_root() . '/directory'; } goaway($address); }
function get() { $noid = get_config('system', 'disable_openid'); if ($noid) { goaway(z_root()); } logger('mod_openid ' . print_r($_REQUEST, true), LOGGER_DATA); if (x($_REQUEST, 'openid_mode')) { $openid = new LightOpenID(z_root()); if ($openid->validate()) { logger('openid: validate'); $authid = normalise_openid($_REQUEST['openid_identity']); if (!strlen($authid)) { logger(t('OpenID protocol error. No ID returned.') . EOL); goaway(z_root()); } $x = match_openid($authid); if ($x) { $r = q("select * from channel where channel_id = %d limit 1", intval($x)); if ($r) { $y = q("select * from account where account_id = %d limit 1", intval($r[0]['channel_account_id'])); if ($y) { foreach ($y as $record) { if ($record['account_flags'] == ACCOUNT_OK || $record['account_flags'] == ACCOUNT_UNVERIFIED) { logger('mod_openid: openid success for ' . $x[0]['channel_name']); $_SESSION['uid'] = $r[0]['channel_id']; $_SESSION['account_id'] = $r[0]['channel_account_id']; $_SESSION['authenticated'] = true; authenticate_success($record, $r[0], true, true, true, true); goaway(z_root()); } } } } } // Successful OpenID login - but we can't match it to an existing account. // See if they've got an xchan $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", dbesc($authid)); if ($r) { $_SESSION['authenticated'] = 1; $_SESSION['visitor_id'] = $r[0]['xchan_hash']; $_SESSION['my_url'] = $r[0]['xchan_url']; $_SESSION['my_address'] = $r[0]['xchan_addr']; $arr = array('xchan' => $r[0], 'session' => $_SESSION); call_hooks('magic_auth_openid_success', $arr); \App::set_observer($r[0]); require_once 'include/security.php'; \App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name'])); logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); if ($_SESSION['return_url']) { goaway($_SESSION['return_url']); } goaway(z_root()); } // no xchan... // create one. // We should probably probe the openid url and figure out if they have any kind of // social presence we might be able to scrape some identifying info from. $name = $authid; $url = trim($_REQUEST['openid_identity'], '/'); if (strpos($url, 'http') === false) { $url = 'https://' . $url; } $pphoto = z_root() . '/' . get_default_profile_photo(); $parsed = @parse_url($url); if ($parsed) { $host = $parsed['host']; } $attr = $openid->getAttributes(); if (is_array($attr) && count($attr)) { foreach ($attr as $k => $v) { if ($k === 'namePerson/friendly') { $nick = notags(trim($v)); } if ($k === 'namePerson/first') { $first = notags(trim($v)); } if ($k === 'namePerson') { $name = notags(trim($v)); } if ($k === 'contact/email') { $addr = notags(trim($v)); } if ($k === 'media/image/aspect11') { $photosq = trim($v); } if ($k === 'media/image/default') { $photo_other = trim($v); } } } if (!$nick) { if ($first) { $nick = $first; } else { $nick = $name; } } require_once 'library/urlify/URLify.php'; $x = strtolower(\URLify::transliterate($nick)); if ($nick & $host) { $addr = $nick . '@' . $host; } $network = 'unknown'; if ($photosq) { $pphoto = $photosq; } elseif ($photo_other) { $pphoto = $photo_other; } $mimetype = guess_image_type($pphoto); $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,\n\t xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, \n\t\t\t\t\txchan_name_date, xchan_hidden)\n\t values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ", dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($mimetype), dbesc($pphoto), dbesc($addr), dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($name), dbesc($network), dbesc(datetime_convert()), dbesc(datetime_convert())); if ($x) { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($url)); if ($r) { $photos = import_xchan_photo($pphoto, $url); if ($photos) { $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', \n\t\t\t\t\t\t\t\txchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($url)); } set_xconfig($url, 'system', 'openid', $authid); $_SESSION['authenticated'] = 1; $_SESSION['visitor_id'] = $r[0]['xchan_hash']; $_SESSION['my_url'] = $r[0]['xchan_url']; $_SESSION['my_address'] = $r[0]['xchan_addr']; $arr = array('xchan' => $r[0], 'session' => $_SESSION); call_hooks('magic_auth_openid_success', $arr); \App::set_observer($r[0]); info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name'])); logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']); if ($_SESSION['return_url']) { goaway($_SESSION['return_url']); } goaway(z_root()); } } } } notice(t('Login failed.') . EOL); goaway(z_root()); // NOTREACHED }
function discover_by_webbie($webbie) { require_once 'library/HTML5/Parser.php'; $result = array(); $network = null; $diaspora = false; $gnusoc = false; $dfrn = false; $has_salmon = false; $salmon_key = false; $atom_feed = false; $diaspora_base = ''; $diaspora_guid = ''; $diaspora_key = ''; $webbie = strtolower($webbie); $x = webfinger_rfc7033($webbie, true); if ($x && array_key_exists('links', $x) && $x['links']) { foreach ($x['links'] as $link) { if (array_key_exists('rel', $link)) { // If we discover zot - don't search further; grab the info and get out of // here. if ($link['rel'] === PROTOCOL_ZOT) { logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG); if (array_key_exists('zot', $x) && $x['zot']['success']) { $i = import_xchan($x['zot']); } else { $z = z_fetch_url($link['href']); if ($z['success']) { $j = json_decode($z['body'], true); $i = import_xchan($j); return true; } } } if ($link['rel'] == NAMESPACE_DFRN) { $dfrn = $link['href']; } if ($link['rel'] == 'magic-public-key') { if (substr($link['href'], 0, 5) === 'data:') { $salmon_key = convert_salmon_key($link['href']); } } if ($link['rel'] == 'salmon') { $has_salmon = true; $salmon = $link['href']; } if ($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') { $atom_feed = $link['href']; } } } } logger('webfinger: ' . print_r($x, true), LOGGER_DATA, LOG_INFO); $arr = array('address' => $webbie, 'success' => false, 'webfinger' => $x); call_hooks('discover_channel_webfinger', $arr); if ($arr['success']) { return true; } $aliases = array(); // Now let's make some decisions on what we may need // to obtain further info $probe_atom = false; $probe_old = false; $probe_hcard = false; $address = ''; $location = ''; $nickname = ''; $fullname = ''; $avatar = ''; $pubkey = ''; if (is_array($x)) { if (array_key_exists('address', $x)) { $address = $x['address']; } if (array_key_exists('location', $x)) { $location = $x['location']; } if (array_key_exists('nickname', $x)) { $nickname = $x['nickname']; } } if (!$x) { $probe_old = true; } if (!$dfrn && !$has_salmon) { $probe_old = true; } if ($probe_old) { $y = old_webfinger($webbie); if ($y) { logger('old_webfinger: ' . print_r($x, true)); foreach ($y as $link) { if ($link['@attributes']['rel'] === NAMESPACE_DFRN) { $dfrn = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'salmon') { $notify = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === NAMESPACE_FEED) { $poll = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') { $hcard = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') { $profile = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') { $poco = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') { $diaspora_base = unamp($link['@attributes']['href']); $diaspora = true; } if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') { $diaspora_guid = unamp($link['@attributes']['href']); $diaspora = true; } if ($link['@attributes']['rel'] === 'diaspora-public-key') { $diaspora_key = base64_decode(unamp($link['@attributes']['href'])); if (strstr($diaspora_key, 'RSA ')) { $pubkey = rsatopem($diaspora_key); } else { $pubkey = $diaspora_key; } $diaspora = true; } if ($link['@attributes']['rel'] == 'magic-public-key') { if (substr($link['@attributes']['href'], 0, 5) === 'data:') { $salmon_key = convert_salmon_key($link['@attributes']['href']); } } if ($link['@attributes']['rel'] == 'salmon') { $has_salmon = true; $salmon = $link['@attributes']['href']; } if ($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') { $atom_feed = $link['@attributes']['href']; } if ($link['@attributes']['rel'] === 'alias') { $aliases[] = $link['@attributes']['href']; } if ($link['@attributes']['rel'] === 'subject') { $subject = $link['@attributes']['href']; } } } } if ($subject || $aliases) { if (strpos($webbie, '@')) { $rhs = substr($webbie, strpos($webbie, '@') + 1); } else { $m = parse_url($webbie); if ($m) { $rhs = $m['host'] . ($m['port'] ? ':' . $m['port'] : ''); } } $v = array('subject' => $subject, 'aliases' => $aliases); $address = find_webfinger_address($v, $rhs); $location = find_webfinger_location($v, $rhs); if ($address) { $nickname = substr($address, 0, strpos($address, '@')); } } if ($salmon_key && $has_salmon && $atom_feed && !$dfrn && !$diaspora) { $gnusoc = true; $probe_atom = true; } if (!$pubkey) { $pubkey = $salmon_key; } if (($dfrn || $diaspora) && $hcard) { $probe_hcard = true; } if (!$fullname) { $fullname = $nickname; } if ($probe_atom) { $k = z_fetch_url($atom_feed); if ($k['success']) { $feed_meta = feed_meta($k['body']); } if ($feed_meta) { // stash any discovered pubsubhubbub hubs in case we need to follow them // this will save an expensive lookup later if ($feed_meta['hubs'] && $address) { set_xconfig($address, 'system', 'push_hubs', $feed_meta['hubs']); set_xconfig($address, 'system', 'feed_url', $atom_feed); } if ($feed_meta['author']['author_name']) { $fullname = $feed_meta['author']['author_name']; } if (!$avatar) { if ($feed_meta['author']['author_photo']) { $avatar = $feed_meta['author']['author_photo']; } } // for GNU-social over-ride any url aliases we may have picked up in webfinger // The author.uri element in the feed is likely to be more accurate if ($gnusoc && $feed_meta['author']['author_uri']) { $location = $feed_meta['author']['author_uri']; } } } else { if ($probe_hcard) { $vcard = scrape_vcard($hcard); if ($vcard) { logger('vcard: ' . print_r($vcard, true), LOGGER_DATA); if ($vcard['fn']) { $fullname = $vcard['fn']; } if ($vcard['photo'] && strpos($vcard['photo'], 'http') !== 0) { $vcard['photo'] = $diaspora_base . '/' . $vcard['photo']; } if (!$avatar) { $avatar = $vcard['photo']; } } } } if ($profile && !$location) { $location = $profile; } if ($location) { $m = parse_url($location); $base = $m['scheme'] . '://' . $m['host']; $host = $m['host']; } if ($diaspora && $diaspora_base && $diaspora_guid) { if ($dfrn) { $network = 'friendica-over-diaspora'; } else { $network = 'diaspora'; } $base = trim($diaspora_base, '/'); $notify = $base . '/receive'; } else { if ($gnusoc) { $network = 'gnusoc'; $notify = $salmon; } } logger('network: ' . $network); logger('address: ' . $address); logger('fullname: ' . $fullname); logger('pubkey: ' . $pubkey); logger('location: ' . $location); // if we have everything we need, let's create the records if ($network && $address && $fullname && $pubkey && $location) { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($address)); if ($r) { $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1", dbesc($fullname), dbesc($network), dbesc(datetime_convert()), dbesc($address)); } else { $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($address), dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($pubkey), dbesc($address), dbesc($location), dbesc($fullname), dbesc($network), dbescdate(datetime_convert())); } $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($address)); if (!$r) { $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)", dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($address), dbesc($address), dbesc($network), dbesc($base), dbesc($host), dbesc($notify), dbescdate(datetime_convert())); } $photos = import_xchan_photo($avatar, $address); $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbescdate(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($address)); return true; } return false; }
function pubsubhubbub_subscribe($url, $channel, $xchan, $feed, $hubmode = 'subscribe') { $push_url = z_root() . '/pubsub/' . $channel['channel_address'] . '/' . $xchan['abook_id']; $verify = get_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'verify_token'); if (!$verify) { $verify = set_abconfig($channel['channel_id'], $xchan['xchan_hash'], 'pubsubhubbub', 'verify_token', random_string(16)); } if ($feed) { set_xconfig($xchan['xchan_hash'], 'system', 'feed_url', $feed); } else { $feed = get_xconfig($xchan['xchan_hash'], 'system', 'feed_url'); } $params = 'hub.mode=' . $hubmode . '&hub.callback=' . urlencode($push_url) . '&hub.topic=' . urlencode($feed) . '&hub.verify=async&hub.verify_token=' . $verify; logger('subscribe_to_hub: ' . $hubmode . ' ' . $xchan['xchan_name'] . ' to hub ' . $url . ' endpoint: ' . $push_url . ' with verifier ' . $verify); $x = z_post_url($url, $params); logger('subscribe_to_hub: returns: ' . $x['return_code'], LOGGER_DEBUG); return; }
function set_aconfig($account_id, $family, $key, $value) { return set_xconfig('a_' . $account_id, $family, $key, $value); }
/** * @brief This function provides the API endpoints, primarily called by the * JavaScript functions via $.post() calls. * * @return json JSON-formatted structures with a "status" indicator for success * as well as other requested data */ function chess_post(&$a) { if (argc() > 1) { switch (argv(1)) { // API: /chess/settings // Updates game settings for the observer case 'settings': $observer = App::get_observer(); $settings = x($_POST, 'settings') ? $_POST['settings'] : null; $settings = json_decode($settings, true); if (!isset($settings['notify_enabled'])) { json_return_and_die(array('errormsg' => 'Invalid settings', 'status' => false)); } $notify_enable = intval($settings['notify_enabled']); set_xconfig($observer['xchan_hash'], 'chess', 'notifications', $notify_enable); json_return_and_die(array('status' => true)); // API: /chess/resume // Resumes a game specified by "game_id" allowing further moves // API: /chess/resume // Resumes a game specified by "game_id" allowing further moves case 'resume': $observer = App::get_observer(); $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : ''; $g = chess_get_game($game_id); if (!$g['status']) { json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false)); } $success = chess_resume_game($g['game']); if (!$success) { json_return_and_die(array('errormsg' => 'Error resuming game', 'status' => false)); } else { json_return_and_die(array('status' => true)); } // API: /chess/end // Ends a game specified by "game_id" preventing further moves // API: /chess/end // Ends a game specified by "game_id" preventing further moves case 'end': $observer = App::get_observer(); $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : ''; $g = chess_get_game($game_id); if (!$g['status']) { json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false)); } $success = chess_end_game($g['game']); if (!$success) { json_return_and_die(array('errormsg' => 'Error ending game', 'status' => false)); } else { json_return_and_die(array('status' => true)); } // API: /chess/delete // Deletes a game specified by "game_id" // API: /chess/delete // Deletes a game specified by "game_id" case 'delete': if (!local_channel()) { json_return_and_die(array('errormsg' => 'Must be local channel.', 'status' => false)); } $channel = App::get_channel(); $game_id = x($_POST, 'game_id') ? $_POST['game_id'] : ''; $d = chess_delete_game($game_id, $channel); if (!$d['status']) { json_return_and_die(array('errormsg' => 'Error deleting game', 'status' => false)); } else { json_return_and_die(array('status' => true)); } // API: /chess/revert // Reverts a game specified by "game_id" to a previous board position // specified by the "mid" of the child post of the original game post // in the item table // TODO: Determine why the board position in the game item is not actually // being reverted // API: /chess/revert // Reverts a game specified by "game_id" to a previous board position // specified by the "mid" of the child post of the original game post // in the item table // TODO: Determine why the board position in the game item is not actually // being reverted case 'revert': $observer = App::get_observer(); $game_id = $_POST['game_id']; $g = chess_get_game($game_id); if (!$g['status']) { json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false)); } $active = $game['active'] === $observer['xchan_hash'] ? true : false; if (!$active) { json_return_and_die(array('errormsg' => 'It is not your turn', 'status' => false)); } $r = chess_revert_position($g['game'], $observer, $_POST['mid']); if (!$r['status']) { json_return_and_die(array('errormsg' => 'Error reverting game', 'status' => false)); } json_return_and_die(array('status' => true)); // API: /chess/history // Retrieves all the board positions for a game in order to populate the // history viewer in the control panel // API: /chess/history // Retrieves all the board positions for a game in order to populate the // history viewer in the control panel case 'history': $observer = App::get_observer(); $game_id = $_POST['game_id']; $g = chess_get_game($game_id); if (!$g['status']) { json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false)); } $player = array_search($observer['xchan_hash'], $game['players']); $h = chess_get_history($g['game']); if (!$h['status']) { json_return_and_die(array('errormsg' => 'Error retrieving game history', 'status' => false)); } json_return_and_die(array('history' => $h['history'], 'status' => true)); // API: /chess/update // Updates a game specified by "game_id" with a new board position specified // by "newPosFEN" in FEN-format // API: /chess/update // Updates a game specified by "game_id" with a new board position specified // by "newPosFEN" in FEN-format case 'update': $observer = App::get_observer(); $game_id = $_POST['game_id']; $g = chess_get_game($game_id); if (!$g['status']) { json_return_and_die(array('errormsg' => 'Invalid game', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { json_return_and_die(array('errormsg' => 'You are not a valid player', 'status' => false)); } $player = array_search($observer['xchan_hash'], $game['players']); $active = $game['active'] === $game['players'][$player] ? true : false; json_return_and_die(array('position' => $game['position'], 'myturn' => $active, 'ended' => $game['ended'], 'status' => true)); // API: /chess/move // Adds a new board position by creating a child post for the original // game item. // API: /chess/move // Adds a new board position by creating a child post for the original // game item. case 'move': $observer = App::get_observer(); $game_id = $_POST['game_id']; $newPosFEN = $_POST['newPosFEN']; $g = chess_get_game($game_id); if (!$g['status']) { notice(t('Invalid game.') . EOL); json_return_and_die(array('errormsg' => 'Invalid game ID', 'status' => false)); } // Verify that observer is a valid player $game = json_decode($g['game']['obj'], true); if (!in_array($observer['xchan_hash'], $game['players'])) { notice(t('You are not a player in this game.') . EOL); goaway('/chess'); } $player = array_search($observer['xchan_hash'], $game['players']); $color = $game['colors'][$player]; $active = $game['active'] === $observer['xchan_hash'] ? true : false; if (!$active) { json_return_and_die(array('errormsg' => 'It is not your turn', 'status' => false)); } if (x($game, 'ended') && intval($game['ended']) === 1) { json_return_and_die(array('errormsg' => 'The game is over', 'status' => false)); } $move = chess_make_move($observer, $newPosFEN, $g['game']); if ($move['status']) { $active_xchan = $game['players'][0] === $observer['xchan_hash'] ? $game['players'][1] : $game['players'][0]; if (chess_set_position(chess_get_game($game_id)['game'], $newPosFEN)) { chess_set_active(chess_get_game($game_id)['game'], $active_xchan); } json_return_and_die(array('status' => true)); } else { json_return_and_die(array('errormsg' => 'Move failed', 'status' => false)); } default: break; } } if (argc() > 2) { switch (argv(2)) { // API: /chess/[channelname]/new/ // This endpoint handles the new game form submission and creates a new // game between two channels specified by the standard ACL case 'new': if (!local_channel()) { notice(t('You must be a local channel to create a game.') . EOL); return; } // Ensure ACL specifies exactly one other channel $channel = App::get_channel(); $acl = new Zotlabs\Access\AccessList($channel); $acl->set_from_array($_REQUEST); $perms = $acl->get(); $allow_cid = expand_acl($perms['allow_cid']); $valid = 0; if (count($allow_cid) > 1) { foreach ($allow_cid as $allow) { if ($allow == $channel['channel_hash']) { continue; } $valid++; } } if ($valid != 1) { notice(t('You must select one opponent that is not yourself.') . EOL); return; } else { info(t('Creating new game...') . EOL); // Get the game owner's color choice $color = ''; if ($_POST['color'] === 'white' || $_POST['color'] === 'black') { $color = $_POST['color']; } else { notice(t('You must select white or black.') . EOL); return; } $game = chess_create_game($channel, $color, $acl); if ($game['status']) { goaway('/chess/' . $channel['channel_address'] . '/' . $game['item']['resource_id']); } else { notice(t('Error creating new game.') . EOL); } return; } default: break; } } }