Exemple #1
0
function GetBattleNetURL($region, $path)
{
    $region = trim(strtolower($region));
    if (substr($path, 0, 1) == '/') {
        $path = substr($path, 1);
    }
    $start = microtime(true);
    $finalUrl = '';
    while (!$finalUrl && $start + 5 > microtime(true)) {
        $cacheKey = 'BattleNetKeyUsage';
        if (!MCAdd($cacheKey . '_critical', 1, 5 * BATTLE_NET_REQUEST_PERIOD)) {
            usleep(50000);
            continue;
        }
        $apiHits = MCGet($cacheKey);
        if ($apiHits === false) {
            $apiHits = [];
        }
        $hitCount = count($apiHits);
        if ($hitCount >= BATTLE_NET_REQUEST_LIMIT) {
            $now = microtime(true);
            while ($apiHits[0] < $now && $now < $apiHits[0] + BATTLE_NET_REQUEST_PERIOD) {
                usleep(50000);
                $now = microtime(true);
            }
        }
        $apiHits[] = microtime(true);
        $hitCount++;
        if ($hitCount > BATTLE_NET_REQUEST_LIMIT) {
            array_splice($apiHits, 0, $hitCount - BATTLE_NET_REQUEST_LIMIT);
        }
        MCSet($cacheKey, $apiHits, 10 * BATTLE_NET_REQUEST_PERIOD);
        MCDelete($cacheKey . '_critical');
        $pattern = $region == 'cn' ? 'https://api.battlenet.com.%s/%s%sapikey=%s' : 'https://%s.api.battle.net/%s%sapikey=%s';
        $finalUrl = sprintf($pattern, $region, $path, strpos($path, '?') !== false ? '&' : '?', BATTLE_NET_KEY);
    }
    return $finalUrl ? $finalUrl : false;
}
Exemple #2
0
function MCHouseLock($house, $waitSeconds = 30)
{
    global $MCHousesLocked;
    static $registeredShutdown = false;
    if (isset($MCHousesLocked[$house])) {
        return true;
    }
    $giveUpAt = microtime(true) + $waitSeconds;
    $me = ['pid' => getmypid(), 'script' => $_SERVER["SCRIPT_FILENAME"], 'when' => time()];
    do {
        if (MCAdd('mchouselock_' . $house, $me, 30 * 60)) {
            $MCHousesLocked[$house] = true;
            if (!$registeredShutdown) {
                $registeredShutdown = true;
                register_shutdown_function('MCHouseUnlock');
            }
            return true;
        }
        usleep(500000);
    } while ($giveUpAt > microtime(true));
    $currentLock = MCGet('mchouselock_' . $house);
    DebugMessage("Could not get house lock for {$house}, owned by " . $currentLock['pid'] . ' ' . $currentLock['script'] . ' ' . TimeDiff($currentLock['when']));
    return false;
}
Exemple #3
0
function SetWatch($loginState, $type, $item, $bonusSet, $region, $house, $direction, $quantity, $price)
{
    $userId = $loginState['id'];
    $type = $type == 'species' ? 'species' : 'item';
    $subType = $type == 'species' ? 'breed' : 'bonusset';
    $item = intval($item, 10);
    if (!$item) {
        return false;
    }
    $bonusSet = intval($bonusSet, 10);
    if ($bonusSet < 0) {
        $bonusSet = null;
    }
    $house = intval($house, 10);
    if ($house <= 0) {
        if (!in_array($region, ['US', 'EU'])) {
            return false;
        }
        $house = null;
    } else {
        $region = null;
    }
    if (!in_array($direction, ['Under', 'Over'])) {
        return false;
    }
    $quantity = intval($quantity, 10);
    if ($quantity < 0) {
        $quantity = null;
    }
    $price = intval($price, 10);
    if ($price < 0) {
        $price = null;
    }
    if (!is_null($quantity)) {
        if (is_null($price)) {
            // qty available query
            if ($quantity == 0 && $direction == 'Under') {
                // qty never under 0
                return false;
            }
        } else {
            // cost to buy $quantity is $direction $price
            if ($quantity == 0) {
                // must buy at least 1
                return false;
            }
            if ($price == 0 && $direction == 'Under') {
                // price never under 0
                return false;
            }
        }
    } else {
        // market price queries
        if (is_null($price)) {
            // both qty and price null
            return false;
        }
        if ($price <= 0) {
            // price never under 0
            return false;
        }
    }
    $loops = 0;
    while (!MCAdd(SUBSCRIPTION_WATCH_LOCK_CACHEKEY . $userId, 1, 15)) {
        usleep(250000);
        if ($loops++ >= 120) {
            // 30 seconds
            return false;
        }
    }
    $db = DBConnect();
    $db->begin_transaction();
    $stmt = $db->prepare('select seq, region, house, direction, quantity, price from tblUserWatch where user = ? and ' . $type . ' = ? and ifnull(' . $subType . ',0) = ifnull(?,0) and deleted is null for update');
    $stmt->bind_param('iii', $userId, $item, $bonusSet);
    $stmt->execute();
    $result = $stmt->get_result();
    $curWatches = DBMapArray($result);
    $stmt->close();
    $fail = false;
    $cnt = count($curWatches);
    $fail |= $cnt > SUBSCRIPTION_WATCH_LIMIT_PER;
    foreach ($curWatches as $curWatch) {
        $fail |= !is_null($curWatch['region']) && $curWatch['region'] == $region && $curWatch['direction'] == $direction && $curWatch['quantity'] == $quantity && $curWatch['price'] == $price;
        $fail |= is_null($region) && is_null($curWatch['region']) && $curWatch['house'] == $house && $curWatch['direction'] == $direction && $curWatch['quantity'] == $quantity && $curWatch['price'] == $price;
    }
    if ($fail) {
        $db->rollback();
        MCDelete(SUBSCRIPTION_WATCH_LOCK_CACHEKEY . $userId);
        return false;
    }
    if (GetWatchCount($userId, $db) >= SUBSCRIPTION_WATCH_LIMIT_TOTAL) {
        $db->rollback();
        MCDelete(SUBSCRIPTION_WATCH_LOCK_CACHEKEY . $userId);
        return false;
    }
    $stmt = $db->prepare('update tblUser set watchsequence = last_insert_id(watchsequence+1) where id = ?');
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $stmt->close();
    $seq = $db->insert_id;
    $stmt = $db->prepare('insert into tblUserWatch (user, seq, region, house, ' . $type . ', ' . $subType . ', direction, quantity, price, created) values (?,?,?,?,?,?,?,?,?,NOW())');
    $stmt->bind_param('iisiiisii', $userId, $seq, $region, $house, $item, $bonusSet, $direction, $quantity, $price);
    $stmt->execute();
    $stmt->close();
    $cnt = $db->affected_rows;
    if ($cnt == 0) {
        $db->rollback();
        MCDelete(SUBSCRIPTION_WATCH_LOCK_CACHEKEY . $userId);
        return false;
    }
    $db->commit();
    MCDelete(SUBSCRIPTION_WATCH_LOCK_CACHEKEY . $userId);
    $cacheKeyPrefix = defined('SUBSCRIPTION_' . strtoupper($type) . '_CACHEKEY') ? constant('SUBSCRIPTION_' . strtoupper($type) . '_CACHEKEY') : 'subunknown_' . substr($type, 0, 20);
    MCDelete($cacheKeyPrefix . $userId . '_' . $item);
    MCDelete($cacheKeyPrefix . $userId);
    MCDelete(SUBSCRIPTION_WATCH_COUNT_CACHEKEY . $userId);
    return true;
}
function SendUserMessage($userId, $messageType, $subject, $message)
{
    $loops = 0;
    while (!MCAdd(SUBSCRIPTION_MESSAGES_CACHEKEY . "lock_{$userId}", 1, 15)) {
        usleep(250000);
        if ($loops++ >= 120) {
            // 30 seconds
            return false;
        }
    }
    $db = DBConnect(true);
    $seq = 0;
    $cnt = 0;
    $stmt = $db->prepare('select ifnull(max(seq),0)+1, count(*) from tblUserMessages where user = ?');
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $stmt->bind_result($seq, $cnt);
    $stmt->fetch();
    $stmt->close();
    $stmt = $db->prepare('INSERT INTO tblUserMessages (user, seq, created, type, subject, message) VALUES (?, ?, NOW(), ?, ?, ?)');
    $stmt->bind_param('iisss', $userId, $seq, $messageType, $subject, $message);
    $success = $stmt->execute();
    $stmt->close();
    if ($success) {
        $cnt++;
    }
    if ($cnt > SUBSCRIPTION_MESSAGES_MAX) {
        $stmt = $db->prepare('delete from tblUserMessages where user = ? order by seq asc limit ?');
        $cnt = $cnt - SUBSCRIPTION_MESSAGES_MAX;
        $stmt->bind_param('ii', $userId, $cnt);
        $stmt->execute();
        $stmt->close();
    }
    MCDelete(SUBSCRIPTION_MESSAGES_CACHEKEY . "lock_{$userId}");
    if (!$success) {
        DebugMessage("Error adding user message: " . $db->error);
        $db->close();
        return false;
    }
    MCDelete(SUBSCRIPTION_MESSAGES_CACHEKEY . $userId);
    MCDelete(SUBSCRIPTION_MESSAGES_CACHEKEY . $userId . '_' . $seq);
    $stmt = $db->prepare('select name, email, locale from tblUser where id = ? and email is not null and emailverification is null');
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $name = $address = $locale = '';
    $stmt->bind_result($name, $address, $locale);
    if (!$stmt->fetch()) {
        $address = false;
    }
    $stmt->close();
    if ($address) {
        NewsstandMail($address, $name, $subject, $message, $locale);
    }
    UpdateUserRss($userId, $db);
    $db->close();
    return $seq;
}