...

суббота, 16 мая 2015 г.

[Из песочницы] Обход CloudFlare ScrapeShield в Java (Android)

В некоторый момент времени мне пришлось решить проблему, описанную в заголовке. Долго размышлял, писать ли очевидное, в итоге решил, что кому-то это может пригодиться.

Причина достаточно тривиальна — являясь автором Android-клиента к весьма нишевому сайту, я в то же время не вхожу ни в число его администраторов, ни в число соучредителей. Таки образом ни о каких решениях руководства сайта я не осведомлён до момента их фактического вступления в силу.

Не так давно на этот сайт началась DDoS-атака, и администрация включила DDoS-защиту от CloudFlare. Соответственно, приложение-клиент, использовавшее до этого стандартные механизмы авторизации через POST+Cookie, перестало авторизовывать пользователей. Общение с администрацией ни к чему не привело — «что мы можем сделать, лучше уж без мобильных клиентов, чем вообще никак».

Естественно, всё это начало отражаться на рейтингах и породило весьма нелестные отзывы.

Решением стал обход защиты от CloudFlare путём имитации поведения браузера на их странице. CloudFlare в конкретно этом случае использует хэш, ключ и случайный javascript-код, который браузер исполняет (вычисление нескольких арифметических действий, с виду выглядящих как обфусцированный мусор) и позже отсылает получившееся число вместе с хэшем и ключом на страницу проверки. Наша задача, таким образом — перехватить javascript-задание, решить его любым способом и спросить, правильна ли наша отгадка. Если да — получаем плюшку (куки cf_clearance). Если нет — получаем 503.

Покопавшись в поисковике, нашлась ровно одна ссылка, ведущая на проект, делающий нечто весьма похожее. Написанный на Python с использованием node.js или другого совместимого провайдера для PyExecJS. При всём моём уважении к Python, его использование в легковесном нишевом приложении было неоправданной роскошью, на интеграцию которой пришлось бы потратить много часов. Было принято стратегическое решение переписать код решателя на Java.

Некоторые примечания/неочевидности, возникшие во время написания кода:

  • В качестве JS-провайдера был выбран Mozilla Rhino, предоставляющий при отключённых оптимизациях совместимый с Dalvik-bytecode интерфейс.
  • UserAgent'ы, присущие автоматическим запросам, отклоняются с Error 503. Любые «Java/1.5.0_08», «libcurl-agent/1.0» и им подобные строки мгновенно отвергаются. Прежде чем хоть что-то пробовать, замаскируйтесь под UserAgent современного браузера.
  • В качестве Http-клиента использовалась реализация от Apache. Ей я больше доверяю, чем HttpURLConnection, которую продвигают разработчики Android, но это дело вкусов. Можете использовать любую совместимую реализацию, например, OkHttpClient
  • Важно: если вы хотите позже отображать какие-то данные c сайта в WebView, нужно учесть две вещи:
    1. У http-клиента должен быть в точности такой же UserAgent, что и у WebView (используйте settings.userAgentString у WebView)
    2. После получения cf_clearance-куки необходимо синхронизировать её с WebView (пример кода ниже)

Итоговый вариант ниже. Сколочен на скорую руку, но базовое представление о том, как всё работает, даёт.

    private final static Pattern OPERATION_PATTERN = Pattern.compile("setTimeout\\(function\\(\\)\\{\\s+(var t,r,a,f.+?\\r?\\n[\\s\\S]+?a\\.value =.+?)\\r?\\n");
    private final static Pattern PASS_PATTERN = Pattern.compile("name=\"pass\" value=\"(.+?)\"");
    private final static Pattern CHALLENGE_PATTERN = Pattern.compile("name=\"jschl_vc\" value=\"(\\w+)\"");

    abstract public HttpResponse getPage(URI url, HashMap<String, String> headers) throws IOException;
    abstract public CookieStore getCookieStore();

    public boolean cloudFlareSolve(String responseString) {
        // инициализируем Rhino
        Context rhino = Context.enter();
        try {
            String domain = "www.example.com";
            
            // CF ожидает ответа после некоторой задержки
            Thread.sleep(5000);
            
            // вытаскиваем арифметику
            Matcher operationSearch = OPERATION_PATTERN.matcher(responseString);
            Matcher challengeSearch = CHALLENGE_PATTERN.matcher(responseString);
            Matcher passSearch = PASS_PATTERN.matcher(responseString);
            if(!operationSearch.find() || !passSearch.find() || !challengeSearch.find())
                return false;
            
            String rawOperation = operationSearch.group(1); // операция
            String challengePass = passSearch.group(1); // ключ
            String challenge = challengeSearch.group(1); // хэш
            
            // вырезаем присвоение переменной
            String operation = rawOperation
                    .replaceAll("a\\.value =(.+?) \\+ .+?;", "$1")
                    .replaceAll("\\s{3,}[a-z](?: = |\\.).+", "");
            String js = operation.replace("\n", "");
            
            rhino.setOptimizationLevel(-1); // без этой строки rhino не запустится под Android
            Scriptable scope = rhino.initStandardObjects(); // инициализируем пространство исполнения

            // either do or die trying
            int result = ((Double) rhino.evaluateString(scope, js, "CloudFlare JS Challenge", 1, null)).intValue();
            String answer = String.valueOf(result + domain.length()); // ответ на javascript challenge

            final List<NameValuePair> params = new ArrayList<>(3);
            params.add(new BasicNameValuePair("jschl_vc", challenge));
            params.add(new BasicNameValuePair("pass", challengePass));
            params.add(new BasicNameValuePair("jschl_answer", answer));
            
            HashMap<String, String> headers = new HashMap<>(1);
            headers.put("Referer", "http://" + domain + "/"); // url страницы, с которой было произведено перенаправление
            
            String url = "http://" + domain + "/cdn-cgi/l/chk_jschl?" + URLEncodedUtils.format(params, "windows-1251");
            
            HttpResponse response = getPage(URI.create(url), headers);
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // в ответе придёт страница, указанная в Referer
                response.getEntity().consumeContent(); // с контентом можно делать что угодно
                return true;
            }
        } catch (Exception e) {
            return false;
        } finally {
            Context.exit(); // выключаем Rhino
        }
        return false;
    }

    private void syncCookiesWithWebViews() {
        List<Cookie> cookies = getCookieStore().getCookies();
        CookieManager cookieManager = CookieManager.getInstance(); // CookieManager служит для синхронизации cookies между WebView
        for (Cookie cookie : cookies) {
            String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
            cookieManager.setCookie("diary.ru", cookieString);
        }
    }

Код клиента опубликован под GPLv3, так что, скорее всего, о нём скоро прознает и CloudFlare, что приведёт к смене алгоритма. Тем не менее, я не приверженец принципа security by obscurity и задачу пускать мобильных пользователей до спада DDoS удалось решить.

Спасибо за внимание. Вопросы/замечания в комментарии.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Moscow Python Meetup «Async: Why and When»

Привет, хочу пригласить вас на втору встречу нашего сообщества Moscow Python Meetup, она пройдёт 28 мая (начало в 19:00) в офисе компании Rambler&Co. Тема встречи — «Async: why and when?».

Программа и гости ожидаются невероятно интересные.

  • Обзор положения дел в asyncio
    Андрей Светлов, LevelUp, Python Core Developer
  • Async: why and when? Cравнительный анализ данных фреймворков: asyncio, gevent, twisted, tornado
    Алексей Гречишкин, Rambler&Co, Тимлид
    Злата Обуховская, Rambler&Co, Тимлид «Рамблер-Новости»

  • Мертв ли R? Или статистический анализ данных с помощью Python
    Павел Клеменков, Rambler&Co, Руководитель отдела машинного обучения
  • Let it crash: what Python can learn from Erlang
    Benoit Chesneau, Enki Multimedia, Web Craftsman


Для участия необходима обязательная регистрация на Timepad.

И, до встречи, друзья.

P.S. Отдельное спасибо компании Rambler&Co за помощь в организации. Саше Шорину ( доклад на первой встрече ) и Александру Зеленяку за то, что они всё-всё сделали, чтобы это мероприятие состоялось.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Социальная сеть на Android за несколько выходных — часть I (клиент)

Введение


Несмотря на обилие социальных сетей, за последние несколько лет появился целый ряд новых, оригинальных и необычных социальных приложений, таких как just yo, snapchat, secret, и пр. Успех приложения just yo, ограниченного единственной функцией – отправкой сообщения фиксированного содержания, меня заинтересовал и мы с друзьями тоже решили попробовать написать очередную социальную сеть на Android. Нашей целью было очертить круг задач общий для большинства подобных приложений, предложить их решения и подготовить скелет, из которого каждый сможет сделать что-то своё и оригинальное, не тратя время на решение рутинных вопросов. С результатами работы можно сразу ознакомиться на githubandroid клиент и сервер на ruby on rails.

Содержание


Концепция и функционал
Интерфейс
Ускорение загрузки фотографий
Граф друзей
Сетевые запросы
Авторизация
SQLite для БД контактов, изображений
Продолжение следует

Концепция и функционал


Для начала мы определились с концепцией нового сервиса и выбрали модель – гибрид instagram и whatsapp. От инстаграма мы взяли главный сценарий использования – загрузку фотографий в ленту друзей с комментариями и лайками. А от вотсапа принцип организации графа друзей – через записную книжку по телефонным номерам друзей в автоматическом режиме.
Особенности выбранной модели

Выбранная модель графа подразумевает среднюю скорость роста сети, т.к. каждый новый пользователь может вовлечь в приложение максимум несколько десятков/сотен человек из записной книжки. С другой стороны, такой подходит исключает необходимость модерации и фильтрации контента на начальном этапе развития, т.к. доступность контента определяется личными контактами пользователя и предотвращает массовые спам-рассылки и прочие пагубные явления. В итоге имеем простой сервис, готовый для использования в кругу друзей и не требующий больших затрат на операционную поддержку с технической и организационной точки зрения.


Далее мы очертили функциональный минимум нашего приложения:
  • Загрузка фотографий и их просмотр в галерее
  • Управление списком друзей на основе записной книжки
  • Лента фотографий, загруженных друзьями


Интерфейс


Очертив круг базовых функций, мы перешли к дизайну интерфейса. Каждая функция хорошо ложится на отдельный фрагмент и равновероятность их использования подсказывает использование горизонтального swipe-перехода с помощью ViewPager (Туториалы по swipe и ViewPager туториал 1 туториал 2). На первом этапе у нас получилась следующая диаграмма переходов:
Рис. 1. Диаграмма переходов
image

Рассмотрим каждый из фрагментов более детально.
Контакт лист

Рис. 2. Контакт лист - wireframe и скриншот
image

Контакт лист отображает список друзей по записной книжке, зарегистрированных в сервисе, позволяет подписаться, а также открывает подробный профиль пользователя при нажатии. Он реализован обычным ListView (туториал).
Галерея

Рис. 3. Галерея - wireframe и скриншот
image

Галерея отображает локальные и загруженные на сервер фотографии пользователя с кратким описанием в заголовке.
Т.к. размер фотографий с учётом заголовка и соотношение сторон может различаться, мы решили использовать асимметричный GridView от Etsy AndroidStaggeredGrid. Алгоритм позиционирования отображений в таком случае требует особого подхода, в частности в AndroidStaggeredGrid вместо ImageView используется DynamicHeightImageView с заранее предопределяемым соотношением. В результате получается довольно красивая и плавно прокручиваемая плиточная галерея.
Лента

Лента отображает фотографии, загруженные друзьями, на которых подписан пользователь. Здесь мы также применили обычный ListView, т.к. каждая фотография может занимать большую часть экрана для удобства просмотра и масштабирование может проходить по ширине экрана. При нажатии на изображение открывается подробное описание фотографии с комментариями.
Рис. 4. Лента - wireframe и скриншот
image

Подробное описание фотографии

Подробное описание фотографии содержит метаданные выбранного изображения (имя автора, описание, кол-во лайков и т.д.), а также список комментариев.
Рис. 5. Описание фотографии - wireframe и скриншот
image

Профиль пользователя

Профиль пользователя содержит метаданные пользователя и галерею загруженных фотографий пользователя.
Рис. 6. Профиль пользователя - wireframe и скриншот
image


Ускорение загрузки фотографий


L1/L2 кэш

Подгрузка фотографий является ключевым и достаточно ресурсоёмким процессом. Фотографии загружаются как из локальной галереи на устройстве, так и с удаленного хранилища. Скорость подгрузки влияет на плавность прокрутки галереи и общее удобство интерфейса, поэтому мы решили использовать двухуровневый кэш – L1 cache в оперативной памяти и L2 cache на дисковом носителе устройства.
В качестве дискового L2 кэша мы выбрали популярный плагин от Jake Wharton, он поддерживает журналирование и предоставляет удобную обёртку над стандартным DiskLruCache из Андроид SDK. L1 cache реализован стандартным андроидовским LruCache (см. com.freecoders.photobook.utils.DiskLruBitmapCache и com.freecoders.photobook.utils.MemoryLruCache).
Упреждающее масштабирование

В случае с лентой новостей возможен вариант, когда лента уже загружена, а фотографии продолжают загружаться с удаленного хранилища. Тогда при прокрутке возможен скачкообразный эффект при завершении подгрузки, если пользователь уже прокрутил список вниз. Чтобы его избежать мы применили упреждающее масштабирование отображений в ленте – т.е. размеры рамки для фотографии высчитываются на основе соотношения сторон и задаются еще до того, как фотография загрузилась с сервера. Таким образом позиция элементов в списке ListView не изменяется после подгрузки новых фотографий.
Код 1. Пример упреждающего масштабирования в DynamicHeightImageView
class FeedAdapter
public View getView(int position, View convertView, ViewGroup parent) {
  ...
  holder.imgView.setHeightRatio(feedEntry.image.ratio);
  holder.imgView.setTag(pos);
  mImageLoader.get(feedEntry.image.url_medium, new ImageListener(pos, holder.imgView, null));
  ...
}



Даунсэмплинг

Кроме того, в Android существуют ограничения на максимальный размер и разрешение фотографии, отображаемой на экране. Это предусмотрено для предотвращения переполнения памяти. Поэтому перед загрузкой bitmap необходимо произвести downsampling.
Код 2. Пример даунсэмплинга изображений
class ImageUtils
public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            while (((halfHeight / inSampleSize) > reqHeight)
                    || ((halfWidth / inSampleSize) > reqWidth)) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmap(String imgPath, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imgPath, options);

        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(imgPath, options);
    }



Миниатюры

Также если media scanner успел обработать все фотографии, то для них уже могут быть созданы миниатюры в памяти устройства. Это правило выполняется не всегда, но если миниатюра есть, то это значительно ускоряет процесс загрузки и позволяет избежать downsampling.
Код 3. Пример загрузки миниатюр из MediaStore
class ImagesDataSource
    public String getThumbURI(String strMediaStoreID) {
        ContentResolver cr = mContext.getContentResolver();
        String strThumbUri = "";
        Cursor cursorThumb = cr.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Images.Thumbnails.DATA},
                MediaStore.Images.Thumbnails.IMAGE_ID + "= ?",
                new String[]{strMediaStoreID}, null);
        if( cursorThumb != null && cursorThumb.getCount() > 0 ) {
            cursorThumb.moveToFirst();
            strThumbUri = cursorThumb.getString(
                    cursorThumb.getColumnIndex( MediaStore.Images.Thumbnails.DATA ));
        }
        cursorThumb.close();
        return strThumbUri;
    }




Граф друзей


Следующим шагом, определяющим интерфейс и логику сервиса была детализация графа друзей. Мы рассматривали два подхода – принцип друзей (как вконтакте) и принцип подписчиков (как в твиттере). Принцип друзей подразумевает взаимное согласие на доступ к галерее и личному профилю, а также требует подтверждения знакомства с противоположной стороны. В случае с подписчиками не требуется запрашивать подтверждение с противоположной стороны и позволяет каждой из сторон независимо определять источники наполнения своей фотоленты.
Данный выбор подразумевает направленный граф, который будет реализован в виде строк (ID подписчика, ID автора) реляционной БД на сервере.
image

Сетевые запросы


Все сетевые запросы выполняются асинхронно, а результат операции с помощью callback-интерфейса передаются в запрашивающий модуль. В 2013 году Google представила собственный плагин Volley как замену Apache HTTPClient. Её преимуществами является поддержка очереди запросов, приоритизация, стандартные обёртки для string и json запросов, keepalive, повторная отправка при неудаче, и пр. Мы решили использовать её в качестве основы для большинства сетевых запросов.
Что не понравилось в Volley

Забегая вперед скажу, что Volley действительно упрощает разработку сетевых интерфейсов по сравнению с HTTPClient, но на момент разработки стандартные обёртки для String и Json запросов от Volley еще были довольно сырыми, например не позволяли настроить ContentType или HttpHeaders, отсутствовала поддержка MultiPart запросов, поэтому нам пришлось их немного переписать (см. com.freecoders.photobook.network.MultiPartRequest и com.freecoders.photobook.network.StringRequest)


Код 4. Пример сетевого запроса (Запрос профиля пользователя)
class ServerInterface
    public static final void getUserProfileRequest (Context context, String[] userIds,
            final Response.Listener<HashMap<String, UserProfile>> responseListener,
            final Response.ErrorListener errorListener) {
        HashMap<String, String> headers = makeHTTPHeaders();
        String strIdHeader = userIds.length > 0 ? userIds[0] : "";
        for (int i = 1; i < userIds.length; i++) strIdHeader = strIdHeader + "," + userIds[i];
        headers.put(Constants.KEY_ID, strIdHeader);
        Log.d(LOG_TAG, "Get user profile request");
        StringRequest request = new StringRequest(Request.Method.GET,
            Constants.SERVER_URL + Constants.SERVER_PATH_USER, "", headers,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.d(LOG_TAG, response);
                    Type type = new TypeToken<ServerResponse
                            <HashMap<String, UserProfile>>>(){}.getType();
                    try {
                        ServerResponse<HashMap<String, UserProfile>> res =
                                gson.fromJson(response, type);
                        if (res != null && res.isSuccess() && res.data != null
                                && responseListener != null)
                            responseListener.onResponse(res.data);
                        else if (responseListener != null)
                            responseListener.onResponse(new HashMap<String, UserProfile>());
                    } catch (Exception e) {
                        if (responseListener != null)
                            responseListener.onResponse(new HashMap<String, UserProfile>());
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    if ((error != null) && (error.networkResponse != null)
                            && (error.networkResponse.data != null))
                        Log.d(LOG_TAG, "Error: " +
                                new String(error.networkResponse.data));
                    if (errorListener != null) errorListener.onErrorResponse(error);
                }
            }
        );
        VolleySingleton.getInstance(context).addToRequestQueue(request);
    }



Код 5. VolleySingleton
class VolleySingleton
public class VolleySingleton {
...
    public <T> void addToRequestQueue(Request<T> req) {
        int socketTimeout = 90000;
        RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        req.setRetryPolicy(policy);
        getRequestQueue().add(req);
    }
...
}




Авторизация


Для авторизации мы решили использовать пару публичный/приватный id. При регистрации клиенту высылается эта пара, причём приватный id доступен только этому пользователю и отправляется в заголовке HTTP с каждым запросом к серверу. А публичный id доступен всем пользователям и используется другими клиентами при запросах на добавление в друзья или просмотре профиля.

SQLite для БД контактов, изображений


Локальная БД клиента содержит необходимый минимум информации для облегчения нагрузки на сервер:
  • Список друзей
  • Список загруженных фотографий

Список друзей из адресной книги, зарегистрированных в сервисе, их метаданные (аватар, имя и пр.) запрашивается на сервере при каждом запуске приложения и сохраняется в локальной БД для наполения первого фрагмента (список контактов). Список загруженных фотографий содержит метаданные фотографий, загруженных на сервер. Оба списка синхронизируются с сервером на случай переустановки приложения.
Код 6. Пример работы в SQLite
class FriendsDataSource
public class FriendsDataSource {
    private SQLiteDatabase database;
    private SQLiteHelper dbHelper;
    private String[] allColumns = { SQLiteHelper.COLUMN_ID,SQLiteHelper.COLUMN_NAME,
            SQLiteHelper.COLUMN_CONTACT_KEY, SQLiteHelper.COLUMN_USER_ID,
            SQLiteHelper.COLUMN_AVATAR, SQLiteHelper.COLUMN_STATUS};
...
    public FriendEntry createFriend(String Name, String ContactKey, String UserId,
                String Avatar, int Status) {
        //Add new FriendEntry
        ContentValues cv = new ContentValues();
        cv.put(dbHelper.COLUMN_CONTACT_KEY,ContactKey);
        cv.put(dbHelper.COLUMN_NAME,Name);
        cv.put(dbHelper.COLUMN_USER_ID,UserId);
        cv.put(dbHelper.COLUMN_AVATAR,Avatar);
        cv.put(dbHelper.COLUMN_STATUS,Status);
        cv.put(dbHelper.COLUMN_TYPE,FriendEntry.INT_TYPE_PERSON);

        database.insert(dbHelper.TABLE_FRIENDS, null, cv);
        return null;
    }

    public ArrayList<FriendEntry> getFriendsByStatus(int StatusSet[]) {
        String selection = dbHelper.COLUMN_STATUS + " IN (?";
        String values[] = new String[StatusSet.length];
        values[0] = String.valueOf(StatusSet[0]);
        for (int i = 1; i < StatusSet.length; i++) {
            selection = selection + ",?";
            values[i] = String.valueOf(StatusSet[i]);
        }
        selection = selection + ") ";

        selection = selection + " AND "
                + SQLiteHelper.COLUMN_TYPE + " = " + FriendEntry.INT_TYPE_PERSON;

        String orderBy =  SQLiteHelper.COLUMN_NAME + " ASC";

        Cursor cursor = database.query(dbHelper.TABLE_FRIENDS,
                null, selection, values, null, null, orderBy);

        ArrayList<FriendEntry> listFriends = new ArrayList<FriendEntry>();

        if (cursor == null) {
            return listFriends;
        } else if (!cursor.moveToFirst()) {
            cursor.close();
            return listFriends;
        }

        do{
            listFriends.add(cursorToFriendEntry(cursor));
        }while (cursor.moveToNext());

        cursor.close();
        return listFriends;
    }

    private FriendEntry cursorToFriendEntry(Cursor cursor) {

        FriendEntry friend = new FriendEntry();
        friend.setId(cursor.getInt(idColIndex));
        friend.setName(cursor.getString(nameColIndex));
        friend.setUserId(cursor.getString(userIdColIndex));
        friend.setAvatar(cursor.getString(avatarColIndex));
        friend.setStatus(cursor.getInt(statusColIndex));
        friend.setType(cursor.getInt(typeColIndex));
        friend.setContactKey(cursor.getString(ContactKeyColIndex));

        return friend;
    }
...
}




Продолжение следует


В этой части статьи мы попытались рассмотреть только основные вопросы и проблемы, с которыми мы столкнулись при разработке Android-клиента. Проект разрабатывался в стиле хакатона выходного дня и без каких-либо коммерческих целей, поэтому мы не претендуем на оригинальность подходов, не можем похвастаться целостной стилистикой кода. Если у вас есть другие советы, решения или идеи по разработке мобильных социальных приложений, то будем рады услышать их в комментариях. Также если вам понравилось или пригодилось наше пособие, то можете свободно использовать его в своих проектах, улучшать или даже присылать pull-request'ы, за что будем особенно благодарны.
Во второй части мы рассмотрим более подробно серверную часть сервиса, особенности загрузки изображений на облачное хранилище AWS S3, постобработки изображений, доставки Push-уведомлений, и пр.

Всем хороших выходных и до новых встреч!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Отменено решение Невьянского суда о блокировке Bitcoin сайтов

В Свердловском областном суде состоялось второе, оно же последнее, заседание по поводу решения Невьянского суда о признании информации на сайтах криптовалютной тематики запрещенной к распространению на территории Российской федерации. Суд отменил решение о блокировках.

Напомним, что с 13 января семь сайтов, связанных с тематикой Bitcoin, были заблокированы Роскомнадзором по решению Невьянского городского суда. В свою очередь суд принял его после обращения Невьянского городского прокурора с заявлением в защиту неопределенного круга лиц. Кому интересно, вот более подробный таймлайн событий.

Из этих семи сайтов btcsec.com и bitcoinconf.ru решили в судебном порядке добиваться отмены данного решения. Ситуация осложнялась также тем, что все сроки на подачу апелляций уже прошли. Несколько месяцев потребовалось на восстановление сроков и два судебных заседания. Материалы по этому делу и содержимое апеляционной жалобы btcsec.com выложены тут.

Если вкратце, то сроки были восстановлены по причине того, что заинтересованные стороны к участию в деле привлечены не были, и копии судебного решения им не высылались.

На первом заседании прокуратурой было заявлено ходатайство о прекращении производства по нашей апелляционной жалобе на том основании, что прокуратура не требовала блокировки доступа к ресурсам, а требовала лишь признать информацию не подлежащей распространению. Представитель btcsec.com заявил, что блокировка сайта является прямым следствием признания информации, размещенной на сайте, не подлежащей распространению, соответственно, и btcsec.com является заинтересованным лицом и может оспаривать решение суда. В результате обсуждения суд отказал представителю прокуратуры в прекращении производства по жалобе и принял решение рассматривать дело по правилам суда первой инстанции.

На втором заседании прокуратура заявила ходатайство об отказе от своих требований к тем ресурсам, которые обжаловали решение. При этом оставшиеся ресурсы, по мнению прокуратуры, должны были остаться заблокированы. Представители ресурсов btcsec.com и bitcoinconf.ru озвучили доводы апелляционной жалобы и настаивали на отмене решения в полном объеме. В результате рассмотрения дела, судебная коллегия постановила отменить решение Невьянского городского суда. Таким образом, блокировка ресурсов о криптовалютах в январе 2015 года признана незаконной.

Помимо исключения всех сайтов по делу из списка блокировки Роскомнадзора, это еще означает и отмену решения, что информация о криптовалютах, и в частности Bitcoin, является информацией, распространение которой на территории Российской федерации запрещено.

И напоследок стоит отметить, что благодаря этому судебному процессу удалось добиться не только разблокировки сайтов непосредственных участников процесса, но и международного сайта разработчиков bitcoin.org и Bitcoin-википедии bitcoin.it, которые скоро вновь станут доступными для пользователей из России.

Администрация сайта Bitcoin Security выражает благодарность:

  • Юридической компании «Толкачев и Партнеры» и лично Артему Толкачеву за представление интересов в суде.
  • Компании Smile Expo за решение не оставаться в стороне и в судебном порядке добиваться отмены незаконного решения.
  • Bitcoin Сообществу за всестороннюю поддержку, это наша общая победа!
  • Информационным ресурсам и СМИ, которые освещали ход этого судебного дела.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Язык программирования Crystal

Читая статью Интервью с Эриком Михаельс-Обером, RubyHero-2014 наткнулся на упоминание ЯП Crystal.
«Что за зверь?» — подумал я и полез искать информацию. То, что я нашел, меня, признаюсь, впечатлило.

Знакомьтесь — Crystal


Создавая язык, авторы задавались следующими целями:
  • иметь максимально похожий на Ruby синтаксис
  • иметь вывод типов
  • вызывать код на C с помощью написания байндингов
  • иметь возможность выполнения кода и кодогенерации на стадии компиляции
  • компилировать все это в нативный код

Лаконичность синтаксиса Ruby + скорость C? Как по мне — звучит неплохо.

Первый коммит в репозиторий на гитхабе был сделан 2-го сентябра 2012 года. На данный момент разработка языка находится на стадии альфы версии 0.7.1 — синтаксис и стандартная библиотека могут подвергаться изменениям.

Интересно, что в версии 0.7.0 весь IO по-умолчанию стал асинхронным. В Crystal, как и в Go, для укрощения многопоточности можно использовать каналы. Вот как выглядит использование каналов на примере вычисления простых чисел (пример из репозитория, портирован с Go):

def generate(chan)
  i = 2
  loop do
    chan.send(i)
    i += 1
  end
end

def filter(in_chan, out_chan, prime)
  loop do
    i = in_chan.receive
    if i % prime != 0
      out_chan.send(i)
    end
  end
end

def run_filter(in_chan, out_chan, prime)
  spawn { filter(in_chan, out_chan, prime) }
end

ch = Channel(Int32).new
spawn { generate(ch) }

100.times do
  prime = ch.receive
  puts prime
  ch1 = Channel(Int32).new
  run_filter(ch, ch1, prime)
  ch = ch1
end

В репозитории можно найти внушительное количество примеров использования языка для решения самых разных задач, в их числе реализация красно-черных деревьев, трассировка лучей, решение задачи N тел, нейронная сеть, интерпретатор brainfuck. Также есть пример простого http-сервера.

6-го июля разработчики выступают с докладом о языке на конференции Curry On в Праге.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

пятница, 15 мая 2015 г.

Сколько тратят корпорации на продвижение своих облачных продуктов?

Крупные игроки рынка облачных сервисов стараются занять доминирующее положение. При этом такие компании тратят миллиарды долларов в год на расширение мощностей своих дата-центров, с тем, чтобы поддерживать работоспособность собственных сервисов на высоком уровне. При этом бюджет таких проектов увеличивается год от года.

Лучше всего такая тенденция прослеживается на примере Amazon с их Amazon Web Services. Здесь все хорошо и с точки зрения затрат, и с точки зрения получаемого дохода. Так, в 2015 году выручка за первый квартал составила около $1,57 млрд. Это на 50% больше, чем за аналогичный период времени в прошлом году. Чистая прибыль — $265 млн. Доход компании за год, показанный в первом квартале 2015, составил $5,16 млрд.

При этом AWS увеличивает доходность, так что $5 млрд — не предел. Тем не менее, AWS требует постоянных затрат на приобретение дополнительного оборудования, обновления инфраструктуры дата-центров и другие статьи расходов. На конец 2014 года стоимость оборудования, зданий и сооружений, земли, на которой расположены ДЦ AWS составила $7 млрд. Годом прежде стоимость всего этого составляла только $3,8 млрд.

Не Amazon-ом единым

Конкуренты Amazon по облачным сервисам тратят не намного меньше. Ежегодные затраты таких корпораций как Microsoft и Google на свои облачные сервисы составляют миллиарды долларов США. На свою облачную инфраструктуру «корпорация добра» тратит не намного меньше, чем конкуренты.

Google

Так, капитальные затраты Google только за первый квартал 2015 года составили около $2,93 млрд. Здесь, в основном, затраты на оборудование, создание дата-центров и прочих объектов. По словам представителей корпорации, расходы на все эти затратные статьи будут только расти.

К примеру, в этом месяце руководство Google заявило о планах вложить еще $1 млрд на расширение возможностей дата-центра в Айове. К этому стоит прибавить еще полтора миллиарда долларов, которые уже были вложены в этот объект.

Microsoft

Корпорация Microsoft уже является прямым конкурентом Amazon в сфере предоставления доступа к облачным сервисам. К сожалению, редмондская компания не сообщает свои затраты на собственные «облака», но известно, что операционные затраты на эти нужды только в первом квартале этого года выросли на $190, или на 13% по отношению к аналогичным затратам первого квартала прошлого года. Деньги компания тратит, в основном, на увеличение производительности своих ДЦ и расширение их возможностей.

Ранее руководство Microsoft заявляло о намерении вкладывать еще больше в строительство дата-центров и расширения соответствующей инфраструктуры. Только один из недавно анонсированных ДЦ стоил компании $1,1 млрд, кстати, дата-центр тоже построен в Айове. И еще $1 млрд будет вложен в дата-центр из Ирландии.

По мнению некоторых аналитиков, увеличение затрат вызвано тем, что компании конкурируют друг с другом, стремясь снизить цены на свои услуги и улучшить качество сервиса, привлекая тем самым клиентов.

Так, за последние 10 лет стоимость услуг AWS снизилась в 48 раз.

Доходы компаний также возрастают, при этом неплохо получается конкурировать с уже названными компаниями и корпорации IBM:

Заинтересованность компаний в облачном сегменте рынка телекоммуникационных услуг понятна: облака все более востребованы, а по оценке аналитической компании Statista общий объем этого рынка к 2016 году вырастет вплоть до $24,22 млрд.

Желтая майка лидера

По-прежнему принадлежит Amazon с ее AWS. В прошлом году емкость облачного сервиса компании примерно в 5 раз превышала мощности сервисов 14 ближайших конкурентов компании. Стоимость же оборудования компании, используемое для предоставления услуг AWS, составляет уже около трети стоимости активов самой компании.

Насколько можно понять, Amazon сдавать свое первое место не собирается, и в будущем компания будет тратить миллиарды и миллиарды, а конкуренты будут догонять лидера.

Рынок нагревается, гонка гигантов продолжается. Главное, чтобы потребители в результате такой активной конкуренции компаний только выигрывали.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Безопасность сетевой инфраструктуры. Расширенные методы взлома и защиты. Видео

Мы решили продолжить нашу традицию публиковать записи наших предыдущих вебинаров для всех желающих с целью повышения уровня осведомленности в ИБ. Не лишним будет отметить, что вебинары составляют примерно 20% от нашей программы обучения, основной упор делается на практику. Проверить свои знания вы всегда можете в наших лабораториях тестирования на проникновение, например сейчас для всех желающих открыта бесплатная лаборатория тестирования на проникновение Test lab v.7.

Программа курса:

Первое занятие — «Инструментарий пентестера»
Это занятие представляет из себя небольшой обзор истории появления и развития дистрибутива BackTrack и превращением его в Kali Linux.



Второе занятие — «L2 под прицелом»
Этот вебинар демонстрирует различные уязвимости и ошибки часто допускаемые в конфигурациях канального уровня на примере оборудования компании Cisco Systems.

Третье занятие — «Крафтинг сетевых пакетов»
Этот вебинар целиком и полностью посвящен утилите Scapy и сборке сетевых пакетов вручную.

Четвертое занятие — «Анализ сети»
Состоит из известной утилиты netcat и различных его последователей.

Пятое занятие — «Пост эксплуатация»
Демонстрирует туннелирование и скрытие сетевого трафика в различных протоколах (от icmp до dns).

Инструктор Александр sinist3r Дмитренко, автор нескольких публикаций на Хабре, в журнале Хакер и многих других.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Анонс Rust 1.0

Сегодня мы с гордостью представляем релиз Rust версии 1.0, нового языка программирования для создания более надёжных и эффективных систем. Раст объединяет в себе низкоуровневый контроль над производительностью с удобством и гарантиями безопасности языков высокого уровня. Лучше того, он при этом не требует сборщика мусора или среду выполнения, так что библиотеками на Расте можно безболезненно заменять библиотеки на C (англ.). Если вы хотите поэкспериментировать с Растом, лучше всего начать с раздела «Getting Started» книги Rust Book (если вы предпочитаете читать с электронных книг, Паскаль Хертлиф (Pascal Hertleif) поддерживает неофициальные версии этой книги в электронном виде).

Что отличает Раст от других языков, так это его система типов, основанная на улучшенном и кодифицированном своде лучших практик, отработанных поколениями программистов на C и C++. Так что Расту есть что предложить как опытным системных программистам, так и новичкам: опытные разработчики оценят сэкономленное на отладке время, а новичкам придётся по вкусу возможность писать низкоуровневый код, не беспокоясь о мелких ошибках, которые приводят к необъяснимым падениям их программ.

Что значит для Раста релиз 1.0?


Текущая версия Раста — результат множества итераций и экспериментов. Такой процесс разработки прекрасно нам послужил: Раст сейчас намного проще и мощнее, чем мы изначально представляли. Но из-за всех этих экспериментов поддерживать проекты, написанные на Расте, было очень сложно, так как язык и стандартная библиотека постоянно менялись.

Релиз версии 1.0 означает, что этому беспорядку пришёл конец. Этот релиз — официальное начало нашему пути к поддержанию стабильности (англ.). Начиная с этого момента изменения, ломающие совместимость, будут за пределами стабильной версии (за исключением некоторых вещей, вроде багов в компиляторе).

Учитывая сказанное, релиз 1.0 не означает, что язык Раст «завершён». У нас в запасе множество улучшений. На самом деле, ночные сборки уже содержат улучшения в скорости компиляции (а их будет ещё больше) и включают новые API и фичи языка, такие, как std::fs и ассоциированные константы.

Чтобы быть уверенными, что улучшения в компиляторе и языке входят в экосистему как можно более полно и быстро, мы решили использовать train-based модель релизов. Это означает, что мы будем выпускать регулярные релизы каждые шесть недель, как это делают команды Firefox и Chrome. Чтобы начать этот процесс, мы также выпускаем бета-релиз Раста 1.1 — одновременно со стабильным релизом 1.0.

Cargo и crates.io


Создание настоящего проекта — это не только написание кода, это ещё и управление зависимостями. Cargo — пакетный менеджер и система сборки Раста — создан, чтобы облегчить эту задачу. С использованием Cargo скачивание и установка новых библиотек проста настолько же, насколько просто добавить новую строчку в файл манифеста.

Конечно, чтобы использовать зависимость, её нужно сначала найти. Здесь появляется crates.io — центральный репозиторий пакетов Раста. С его помощью очень просто и искать чужие пакеты, и публиковать свои.

С момента анонсирования cargo и crates.io ­— месяцев шесть назад — число пакетов стабильно растёт. Однако сейчас мы в самом начале пути, так что есть ещё много замечательных пакетов, которые нужно написать. Если вам интересно создавать новые библиотеки, которые потрясут мир Раста — сейчас самое время!

Открытые и исходники, и управление


Раст был open-source проектом с самого начала. Последние несколько лет мы постоянно искали способы сделать наше руководство более открытым и управляемым сообществом. С тех пор, как мы ввели процесс RFC, чуть больше года назад, все основные решения по поводу Раста записываются и обсуждаются открыто. Недавно мы приняли новую модель управления, которая состоит в разделении на подкоманды, каждая из которых будет отвечать за RFC в своей определённой области. Если вы хотите помочь определить будущее Раста, мы будем рады любому вашему участию: загружайте библиотеки на crates.io, комментируйте RFC, или пишите сам код Раста.

Мы бы хотели выразить особую благодарность следующим людям, каждый из которых привнёс свой вклад с момента нашего предыдущего релиза (полный список контрибуторов здесь):

  • Aaron Gallagher <_@habnab.it>
  • Aaron Turon <aturon@mozilla.com>
  • Abhishek Chanda <abhishek@cloudscaling.com>
  • Adolfo Ochagavía <aochagavia92@gmail.com>
  • Alex Burka <durka42+github@gmail.com>
  • Alex Crichton <alex@alexcrichton.com>
  • Alex Quach <alex@clinkle.com>
  • Alexander Polakov <plhk@sdf.org>
  • Andrea Canciani <ranma42@gmail.com>
  • Andreas Martens <andreasm@fastmail.fm>
  • Andreas Tolfsen <ato@mozilla.com>
  • Andrei Oprea <andrei.br92@gmail.com>
  • Andrew Paseltiner <apaseltiner@gmail.com>
  • Andrew Seidl <dev@aas.io>
  • Andrew Straw <strawman@astraw.com>
  • Andrzej Janik <vosen@vosen.pl>
  • Aram Visser <aramvisser@gmail.com>
  • Ariel Ben-Yehuda <arielb1@mail.tau.ac.il>
  • Augusto Hack <hack.augusto@gmail.com>
  • Avdi Grimm <avdi@avdi.org>
  • Barosl Lee <vcs@barosl.com>
  • Ben Ashford <ben@bcash.org>
  • Ben Gesoff <ben.gesoff@gmail.com>
  • Björn Steinbrink <bsteinbr@gmail.com>
  • Brad King <brad.king@kitware.com>
  • Brendan Graetz <github@bguiz.com>
  • Brett Cannon <brettcannon@users.noreply.github.com>
  • Brian Anderson <banderson@mozilla.com>
  • Brian Campbell <lambda@continuation.org>
  • Carlos Galarza <carloslfu@gmail.com>
  • Carol (Nichols || Goulding) <carol.nichols@gmail.com>
  • Carol Nichols <carol.nichols@gmail.com>
  • Chris Morgan <me@chrismorgan.info>
  • Chris Wong <lambda.fairy@gmail.com>
  • Christopher Chambers <chris.chambers@peanutcode.com>
  • Clark Gaebel <cg.wowus.cg@gmail.com>
  • Cole Reynolds <cpjreynolds@gmail.com>
  • Colin Walters <walters@verbum.org>
  • Conrad Kleinespel <conradk@conradk.com>
  • Corey Farwell <coreyf@rwell.org>
  • Dan Callahan <dan.callahan@gmail.com>
  • Dave Huseby <dhuseby@mozilla.com>
  • David Reid <dreid@dreid.org>
  • Diggory Hardy <github@dhardy.name>
  • Dominic van Berkel <dominic@baudvine.net>
  • Dominick Allen <dominick.allen1989@gmail.com>
  • Don Petersen <don@donpetersen.net>
  • Dzmitry Malyshau <kvarkus@gmail.com>
  • Earl St Sauver <estsauver@gmail.com>
  • Eduard Burtescu <edy.burt@gmail.com>
  • Erick Tryzelaar <erick.tryzelaar@gmail.com>
  • Felix S. Klock II <pnkfelix@pnkfx.org>
  • Florian Hahn <flo@fhahn.com>
  • Florian Hartwig <florian.j.hartwig@gmail.com>
  • Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
  • FuGangqiang <fu_gangqiang@163.com>
  • Garming Sam <garming_sam@outlook.com>
  • Geoffrey Thomas <geofft@ldpreload.com>
  • Geoffry Song <goffrie@gmail.com>
  • Gleb Kozyrev <gleb@gkoz.com>
  • Graydon Hoare <graydon@mozilla.com>
  • Guillaume Gomez <guillaume1.gomez@gmail.com>
  • Hajime Morrita <omo@dodgson.org>
  • Hech <tryctor@gmail.com>
  • Heejong Ahn <heejongahn@gmail.com>
  • Hika Hibariya <hibariya@gmail.com>
  • Huon Wilson <dbau.pp+github@gmail.com>
  • Igor Strebezhev <xamgore@ya.ru>
  • Isaac Ge <acgtyrant@gmail.com>
  • J Bailey <jj2baile@uwaterloo.ca>
  • Jake Goulding <jake.goulding@gmail.com>
  • James Miller <bladeon@gmail.com>
  • James Perry <james.austin.perry@gmail.com>
  • Jan Andersson <jan.andersson@gmail.com>
  • Jan Bujak <j@exia.io>
  • Jan-Erik Rediger <janerik@fnordig.de>
  • Jannis Redmann <mail@jannisr.de>
  • Jason Yeo <jasonyeo88@gmail.com>
  • Johann <git@johann-hofmann.com>
  • Johann Hofmann <git@johann-hofmann.com>
  • Johannes Oertel <johannes.oertel@uni-due.de>
  • John Gallagher <jgallagher@bignerdranch.com>
  • John Van Enk <vanenkj@gmail.com>
  • Jonathan S <gereeter+code@gmail.com>
  • Jordan Humphreys <mrsweaters@users.noreply.github.com>
  • Joseph Crail <jbcrail@gmail.com>
  • Josh Triplett <josh@joshtriplett.org>
  • Kang Seonghoon <kang.seonghoon@mearie.org>
  • Keegan McAllister <kmcallister@mozilla.com>
  • Kelvin Ly <kelvin.ly1618@gmail.com>
  • Kevin Ballard <kevin@sb.org>
  • Kevin Butler <haqkrs@gmail.com>
  • Kevin Mehall <km@kevinmehall.net>
  • Krzysztof Drewniak <krzysdrewniak@gmail.com>
  • Lee Aronson <lee@libertad.ucsd.edu>
  • Lee Jeffery <leejeffery@gmail.com>
  • Liam Monahan <liam@monahan.io>
  • Liigo Zhuang <com.liigo@gmail.com>
  • Luke Gallagher <luke@hypergeometric.net>
  • Luqman Aden <me@luqman.ca>
  • Manish Goregaokar <manishsmail@gmail.com>
  • Manuel Hoffmann <manuel@polythematik.de>
  • Marin Atanasov Nikolov <dnaeon@gmail.com>
  • Mark Mossberg <mark.mossberg@gmail.com>
  • Marvin Löbel <loebel.marvin@gmail.com>
  • Mathieu Rochette <mathieu@rochette.cc>
  • Mathijs van de Nes <git@mathijs.vd-nes.nl>
  • Matt Brubeck <mbrubeck@limpet.net>
  • Michael Alexander <beefsack@gmail.com>
  • Michael Macias <zaeleus@gmail.com>
  • Michael Park <mcypark@gmail.com>
  • Michael Rosenberg <42micro@gmail.com>
  • Michael Sproul <micsproul@gmail.com>
  • Michael Woerister <michaelwoerister@gmail>
  • Michael Wu <mwu@mozilla.com>
  • Michał Czardybon <mczard@poczta.onet.pl>
  • Mickaël Salaün <mic@digikod.net>
  • Mike Boutin <mike.boutin@gmail.com>
  • Mike Sampson <mike@sambodata.com>
  • Ms2ger <ms2ger@gmail.com>
  • Nelo Onyiah <nelo.onyiah@gmail.com>
  • Nicholas <npmazzuca@gmail.com>
  • Nicholas Mazzuca <npmazzuca@gmail.com>
  • Nick Cameron <ncameron@mozilla.com>
  • Nick Hamann <nick@wabbo.org>
  • Nick Platt <platt.nicholas@gmail.com>
  • Niko Matsakis <niko@alum.mit.edu>
  • Oak <White-Oak@users.noreply.github.com>
  • Oliver Schneider <github6541940@oli-obk.de>
  • P1start <rewi-github@whanau.org>
  • Pascal Hertleif <killercup@gmail.com>
  • Paul Banks <banks@banksdesigns.co.uk>
  • Paul Faria <paul_faria@ultimatesoftware.com>
  • Paul Quint <DrKwint@gmail.com>
  • Pete Hunt <petehunt@users.noreply.github.com>
  • Peter Marheine <peter@taricorp.net>
  • Phil Dawes <phil@phildawes.net>
  • Philip Munksgaard <pmunksgaard@gmail.com>
  • Piotr Czarnecki <pioczarn@gmail.com>
  • Piotr Szotkowski <chastell@chastell.net>
  • Poga Po <poga.bahamut@gmail.com>
  • Przemysław Wesołek <jest@go.art.pl>
  • Ralph Giles <giles@mozilla.com>
  • Raphael Speyer <rspeyer@gmail.com>
  • Remi Rampin <remirampin@gmail.com>
  • Ricardo Martins <ricardo@scarybox.net>
  • Richo Healey <richo@psych0tik.net>
  • Rob Young <rob.young@digital.cabinet-office.gov.uk>
  • Robin Kruppe <robin.kruppe@gmail.com>
  • Robin Stocker <robin@nibor.org>
  • Rory O’Kane <rory@roryokane.com>
  • Ruud van Asseldonk <dev@veniogames.com>
  • Ryan Prichard <ryan.prichard@gmail.com>
  • Scott Olson <scott@scott-olson.org>
  • Sean Bowe <ewillbefull@gmail.com>
  • Sean McArthur <sean.monstar@gmail.com>
  • Sean Patrick Santos <SeanPatrickSantos@gmail.com>
  • Seo Sanghyeon <sanxiyn@gmail.com>
  • Shmuale Mark <shm.mark@gmail.com>
  • Simon Kern <simon.kern@rwth-aachen.de>
  • Simon Sapin <simon@exyr.org>
  • Simonas Kazlauskas <git@kazlauskas.me>
  • Sindre Johansen <sindre@sindrejohansen.no>
  • Skyler <skyler.lipthay@gmail.com>
  • Steve Klabnik <steve@steveklabnik.com>
  • Steven Allen <steven@stebalien.com>
  • Swaroop C H <swaroop@swaroopch.com>
  • Sébastien Marie <semarie@users.noreply.github.com>
  • Tamir Duberstein <tamird@gmail.com>
  • Tero Hänninen <tejohann@kapsi.fi>
  • Theo Belaire <theo.belaire@gmail.com>
  • Theo Belaire <tyr.god.of.war.42@gmail.com>
  • Thiago Carvalho <thiago.carvalho@westwing.de>
  • Thomas Jespersen <laumann.thomas@gmail.com>
  • Tibor Benke <ihrwein@gmail.com>
  • Tim Cuthbertson <tim@gfxmonk.net>
  • Tincan <tincann@users.noreply.github.com>
  • Ting-Yu Lin <aethanyc@gmail.com>
  • Tobias Bucher <tobiasbucher5991@gmail.com>
  • Toni Cárdenas <toni@tcardenas.me>
  • Tshepang Lekhonkhobe <tshepang@gmail.com>
  • Ulrik Sverdrup <root@localhost>
  • Vadim Chugunov <vadimcn@gmail.com>
  • Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
  • Valerii Hiora <valerii.hiora@gmail.com>
  • Wangshan Lu <wisagan@gmail.com>
  • Wei-Ming Yang <rick68@users.noreply.github.com>
  • Will <will@glozer.net>
  • Will Hipschman <whipsch@gmail.com>
  • Wojciech Ogrodowczyk <github@haikuco.de>
  • Xue Fuqiao <xfq.free@gmail.com>
  • Xuefeng Wu <xfwu@thoughtworks.com>
  • York Xiang <bombless@126.com>
  • Young Wu <doomsplayer@gmail.com>
  • bcoopers <coopersmithbrian@gmail.com>
  • critiqjo <john.ch.fr@gmail.com>
  • diwic <diwic@users.noreply.github.com>
  • fenduru <fenduru@users.noreply.github.com>
  • gareins <ozbolt.menegatti@gmail.com>
  • github-monoculture <eocene@gmx.com>
  • inrustwetrust <inrustwetrust@users.noreply.github.com>
  • jooert <jooert@users.noreply.github.com>
  • kgv <mail@kgv.name>
  • klutzy <klutzytheklutzy@gmail.com>
  • kwantam <kwantam@gmail.com>
  • leunggamciu <gamciuleung@gmail.com>
  • mdinger <mdinger.bugzilla@gmail.com>
  • nwin <nwin@users.noreply.github.com>
  • pez <james.austin.perry@gmail.com>
  • robertfoss <dev@robertfoss.se>
  • rundrop1 <rundrop1@zoho.com>
  • sinkuu <sinkuupump@gmail.com>
  • tynopex <tynopex@users.noreply.github.com>
  • Łukasz Niemier <lukasz@niemier.pl>
  • らいどっと <ryogo.yoshimura@gmail.com>

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Из песочницы] Sublime Text 3 — пользовательская подсветка синтаксиса

Расширяемость Sublime Text не знает границ. Для тех, кому мало стандартных функций, на Хабре уже рассказывали о том, как создать сниппет, как написать простой плагин, как написать сложный плагин и еще много много чего. Про ручную настройку подсветки синтаксиса толком ничего не смог найти: для кого-то слишком очевидно, кому-то просто не нужна, а кому-то и наверняка же пригодится.

Итак, задача: имея какие-нибудь абстрактные логи доступа в wonder-net:

!->14/02 16:44:22 [134.249.51.251:39951>80] (t1 19) >HTTP  in:504 out:34  Time:156
GET /5168742330521893/ HTTP/1.1 SCOD=00
!->14/02 16:44:24 [134.249.51.251:49507>80] (t1 20) 
GET /4405885823409377/ HTTP/1.1 SCOD=00
!->14/02 16:54:11 [195.18.13.107:1721>80] (t2 22) 
GET /4149437701562173/ HTTP/1.1 SCOD=00
!->14/02 16:54:11 [195.18.13.107:1721>80] (t2 23) >HTTP  in:385 out:10138  Time:156
GET /5211537451172048/ HTTP/1.1 SCOD=00
!->14/02 16:54:24 [195.18.13.107:1727>80] (t1 30) >HTTP  in:423 out:1220  Time:187
GET /5211537446447554/ HTTP/1.1 SCOD=23
!->14/02 18:07:24 [82.145.208.159:43634>80] (t2 52) 
GET /4149437838265377/ HTTP/1.1 SCOD=00
!->14/02 18:09:41 [82.145.208.174:41708>80] (t2 61) 
GET /4149497815750155 / HTTP/1.1 SCOD=00
!->14/02 18:51:39 [82.145.210.33:55210>80] (t1 66) >HTTP  in:543 out:34  Time:0
GET /5168757259478487/ HTTP/1.1 SCOD=00
!->14/02 18:51:40 [82.145.210.33:55332>80] (t1 68) >HTTP  in:544 out:1243  Time:141
GET /4149497800456701 / HTTP/1.1 SCOD=00
!->14/02 18:51:46 [82.145.210.33:57345>80] (t1 73) >HTTP  in:544 out:1243  Time:125
GET /5168742330521893/ HTTP/1.1 SCOD=00


выделить:
Дату-время — фиолетовым курсивом;
Номер карты — желтым курсивом, если не в черном списке или красным, если иначе;
ip-адрес — темно-зеленым, если не в черном списке или красным, если иначе;
scod=хх — темно-зеленым если 00 или красным, если иначе.

В нашу цветовую схему нужно добавить стили, которыми мы собираемся подсвечивать текст. Насколько я понял, все цветовые схемы аккуратно собраны в файле c:\Program Files\Sublime Text 3\Packages\Color Scheme — Default.sublime-package.

Файл представляет собой zip архив без сжатия. Распаковываем, выбираем любимую схему (по умолчанию Monokai.tmTheme) и копируем ее в…(запускаем Sublime Text: меню Preferences — Browse Packages) папку User.

Открываем свежескопированный Monokai.tmTheme для редактирования. В самом низу перед закрывающимся </array> добавляем блоки стилей. Стиль может содержать три параметра: background, foreground и fontStyle. fontStyle в свою очередь bold, italic и underline.

фиолетовый курсив будет выглядеть так:

<dict>
        <key>scope</key>
        <string>violet</string> <!-- По этому имени будем обращаться к стилю --> 
        <key>settings</key>
        <dict>
                <key>foreground</key>
                <string>#EE82EE</string>
                <key>fontStyle</key>
                <string>italic</string>
        </dict>
</dict>


жирный желтый(ЖЖ):
<dict>
        <key>scope</key>
        <string>yellow</string>
        <key>settings</key>
        <dict>
                <key>foreground</key>
                <string>#FFD700</string>
                <key>fontStyle</key>
                <string>bold</string>
        </dict>
</dict>

темно-зеленый:

<dict>
        <key>scope</key>
        <string>green</string>
        <key>settings</key>
        <dict>
                <key>foreground</key>
                <string>#006400</string>
        </dict>
</dict>

красный:

<dict>
        <key>scope</key>
        <string>red</string>
        <key>settings</key>
        <dict>
                <key>foreground</key>
                <string>#FF0000</string>
        </dict>
</dict>


2. В той же папке User создаем файл синтаксиса: wonderLog.tmLanguage с содержимым:
<?xml version="1.0" encoding="UTF-8" ?>
<plist version="1.0">
    <dict>
        <key>patterns</key>
        <array>
            <dict>
                <key>name</key>
                <string>red</string> <!-- Имя стиля --> 
                <key>match</key>
                <string>\b(?i)(?:5168742330521893|4149437701562173|4149497815750155)\b</string> <!-- Регулярное выражение к-рое надо выделить (номера из черного списка) --> 
            </dict>

            <dict>
                <key>name</key>
                <string>red</string> 
                <key>match</key>
                <string>\b(?i)(?:134\.249\.51\.251|82\.145\.208\.174)\b</string> <!-- ip из черного списка (точки экранируем) --> 
            </dict>

            <dict>
                <key>name</key>
                <string>green</string> 
                <key>match</key>
                <string>\b(?i)scod=00\b</string> <!-- scod=00 --> 
            </dict>

            <dict>
                <key>name</key>
                <string>red</string> 
                <key>match</key>
                <string>\b(?i)scod=\d+\b</string> <!-- scod!=00 --> 
            </dict>

            <dict>
                <key>name</key>
                <string>green</string> 
                <key>match</key>
                <string>\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b</string> <!-- остальные ip (конечно, надо не так, но...) --> 
            </dict>

            <dict>
                <key>name</key>
                <string>yellow</string> 
                <key>match</key>
                <string>\b\d{16}\b</string> <!-- остальные номера --> 
            </dict>

            <dict>
                <key>name</key>
                <string>violet</string> 
                <key>match</key>
                <string>\d{1,2}/\d{1,2}\s\d{2}:\d{2}:\d{2}</string> <!-- дата, время --> 
            </dict>

        </array>
        <key>name</key>
        <string>wonderLog</string> 
        <key>scopeName</key>
        <string>wonderLog</string>
        <key>fileTypes</key>
        <array>
            <string>log</string> <!-- К этому расширению файла будет автоматически применяться данный синтаксис -->
        </array>
    </dict>
</plist>


На примере видно, что если несколько регулярных выражений претендуют закрасить цвет по-разному, то приоритет будет у того, которое описано выше (первее).

Сохраняем все.

Выбираем пользовательскую цветовую схему: Preferences — Color Scheme — User — Monokai.

Открываем наш чудо-лог (если расширение файла не совпадает с шаблонным, делаем View — Syntax — wonderLog) и наслаждаемся результатом:

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Windows 10 на Raspberry Pi 2, первые впечатление

29 апреля, мне пришло письмо от Микрософт, о том, что наконец то, вышла первая бета адаптация Windows 10 для raspberry pi2. События этого ждали вероятно многие, в том числе и я. Как это будет выглядеть? Как будет работать? Быстро — не быстро. Да в целом, это чертовски интригующе!



К 29 апреля, у меня на столе уже стояла коробка с китайским монитором на 7 дюймов, контролером к нему и собственно само устройство размерами с кредитную карту. Какие я цели приследовал все это объединив? Я работал, и продолжаю работать, над собственным проектом CarPC. Но об этом я напишу позже, когда будет готово и будет что показать, сейчас про другое, сейчас про Windows 10

Итак. Первые попытки установить 10-ку не увенчались успехом. Первой моей ошибкой, была попытка установить 10-ку только на устройство, без установки на основной компьютер — донор. Утилита dism ни в какую этого делать не хотела, чтобы я не предпринимал, как бы я ни колдавал. Надо кстати отметить, что подобные попытки сделать это были ни только у меня. У кого-то даже получилось. Вот веточка на официальном форуме. http://ift.tt/1Fd5FXI

Чем все закончилось? Да как в анекдоте про Петьку и Чапаева. В нем Чапаев отправляет Петьку в Японию учиться гипнозу. Тест был один. Сделай так, чтобы наш сантехник играл на баяне. И у Петьки ни как не получалось. После пятой попытки и пятого года обучения сантехник заиграл. Он держал в руках батарею и управлялся с ней как с баяном, при этом говоря — «Ну не умею я играть на баяне». Так и Windows 10, не умел устанавливаться без компьютера донора, похожего на него, в итоге, я его замучил и он поставился, на диск С. dism снес мне «партишен» начисто

Ну чтож. Ставим Windows 10 и на основной компьютер. Система как система. Пуск вернули. А еще есть броузер «Спартанец». Он зараза, как только запускается, все время себя ставит «главным» хочешь ты этого или не хочешь. И зараза именно его операционная система запускает, а ни мой ненаглядный Хром, который, кстати, стоит «по умолчанию»

Но вернемся к нашим «баранам». Утилита dism прекрасно отработала. ОС стоит. И вот — вуаля, я вижу заставку. На ней нарисован «Расбери» и дана общая информация. IP адрес, имя компьютера и т.д. Изучаем дальше. Что же это? И вот тут меня ждал первое разочарование. Я ждал другого. Если raspberry OS, это Linux, это полноценная, многозадачная операционная система. То тут нет. Я действительно рассчитывал увидеть что то типа экрана заставки с плитками как на «Мобильной Виндовс», но тут нет ничего.

Управление «операционной системой» осуществляется по средствам веб-интерфейса. Набираем в броузере, скажем 192.168.1.14 и видим это. На самом же устройство ничего этого лицезреть нельзя.

Ну чтож. Давайте напишем HelloWord! Что нам для этого надо?

1. Установить Microsoft Visual Studio. Microsoft предлагает 15 версию. Ставим.
http://ift.tt/1A6KJCE

2. Включить режим разработки
http://ift.tt/1A6KJCI

3. Установить пакет модулей MVS для разработки под Расбери
http://ift.tt/1pktl6g
(Не забудьте зарегистрироваться в Microsoft Connect, иначе скачать *.MSI не получится)

4. А теперь нам нужно уставить соединение с Расбери. Грубо говоря соединить компьютер донор, с устройством. Делается это в PowerShell
Вот тут инструкция
http://ift.tt/1GJzsL3

Далее. Открываем MVS. И следуем этой инструкции
http://ift.tt/1dJsJEo
С небольшими изменениями. Если следовать инструкции слово в слово, то запустить приложение на устройстве не получится. По крайне мере у меня так не вышла. Не понятно почему у них в настройках стоит x86

А вот так — запускается :-)
И еще. С момента, когда я нажал на кнопку Remote Mashine и мое приложение появилось на устройстве, прошло… всего 2 минуты.

И в заключении. Для чего все таки Windows 10? Да для того же, что и Arduino. То же самое. Те же светодиоды. Приводы. Датчики. Ни более. Назвать все таки это Операционной Системой, я не могу. Нужна ли она для одного приложения? Даже MS DOS умел больше. А надо ли это?

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Из песочницы] Исследование чужого чита для FarCry 4

Не так давно приобрел игру FarCry 4 и она мне сразу очень понравилась. Со временем захотелось немного поковыряться во внутренностях этой игры и написать для нее чит.

Немного поковырявшись в игре при помощи отладчика, мне удалось без особого труда узнать, как сделать следующие функции: бесконечные патроны, стрельба без перезарядки, телепортация игрока, скорострельность, убрать отдачу. Так же узнал, как увеличить высоту прыжка игрока. Но вот когда я принялся искать, как сделать игрока бессмертным (мне казалось, что в этом ничего сложного не будет), возникли трудности.

Для начала при помощи Cheat Engine нашел адрес здоровья персонажа и поставив брекпоинт на запись. Нашел инструкцию, которая изменяет здоровье. Естественно, как и в большинстве игр, эта инструкция отвечает за изменение здоровья всех персонажей в игре, будь то враги, или свои, или даже транспорт (автомобили, самолеты). Такие задачи мне решать не впервой и я знаю, что нужно найти, чем игрок отличается, допустим, от автомобиля или от врага, произвести инъекцию кода и перед изменяющей инструкцией добавить проверку. В результате чего эта инструкция будет выполнятся для всех объектов — кроме игрока.

Но в поисках этого отличия я просидел несколько дней — и все напрасно. Мне не удалось найти ни одной зацепки на то, как отличить что-либо в игре от игрока. Впрочем, не стал отчаиваться и решил пойти не совсем честным путем — просто «посмотреть», как это делают другие читы, в которых есть функция бессмертия.

Я приступил к поискам читов для FarCry 4 в интернете и нашел чит для последней версии игры 1.9. Скачал, антивирус забил тревогу. Следующий чит, который скачал, не работал, но антивирус он не разозлил. 3-й скачанный чит вроде оказался без вирусов и рабочий.

Первым делом я решил проверить исполняемый файл чита при помощи PEiD.

Как можно догадаться, ничего хорошего надпись «Not a valid PE file» не предвещает. Это означает, что над ним издевались упаковщики, протекторы и прочая нечисть. Но не все так плохо, ведь мы же не хотим модифицировать данный файл, он и так полностью бесплатный и распространяется свободно. Все, что нам нужно это узнать — откуда данный чит, что читает и куда записывает.

Для записи данных в чужой процесс есть WinApi функций WriteProcessMemory, а для чтения ReadProcessMemory. Теперь проверим, устоит ли великая и могучая защита данного чита перед API монитором. Перед OllyDBG она устояла; после того, как я попробовал открыть его в этом отладчике, он написал, что не хочет работать с невалидными файлами.

Запускаем игру и под контролем API монитора запускаем чит. API монитор к этому файлу, как оказалось, никаких претензий не имеет. Теперь проверим, перехватит ли он вызовы двух нужных нам функций. Для этого активируем в чите бессмертие и смотрим на результат.

Сначала чит прочитал один байт из памяти игры, а затем еще 3 раза произвел запись. При первом вызове он записал 5 байт, при втором — 21 байт, и при третьем вызове снова 5 байт. Если немного подумать, то можно догадаться, что к чему. Сначала производится замена оригинальной инструкции на безусловный переход, затем по адресу, куда будет совершаться прыжок, записывается код размером 21 байт и напоследок в конец этого кода добавляется безусловный переход на следующую инструкцию, которая находится за оригинальной (которая изменяет здоровье).

Однако на самом деле я угадал только со вторым и третьим вызовом, при первом вызове по адресу FC64.FCE_Engine_GetCloudTypeCount+21F923 записывается следующая инструкция:

comiss xmm9,[rbx+0C]

.
Ниже находится изображение основного кода, который записывается при втором вызове функции WriteProcessMemor.

Детально я не стал разбираться, как этот чит делает игрока бессмертным. Решил просто скопировать этот алгоритм и добавить в свой чит.

Также хочу добавить лично мое мнение по поводу читов типа «Трейнер». Я считаю, что защитить такие читы от взлома практически невозможно, поскольку известно их слабое место, которое заключается в том, что они в любом случае должны вызывать WinApi функции WriteProcessMemory и ReadProcessMemory и как бы там не шифровались данные, в эти функции они поступают в чистом виде. Также я хочу сказать, что если вы собрались писать серьезные читы с уникальным функционалом, то лучше это реализовать в виде DLL, которую при запуске игры инжектировать в процесс — там уже не так просто будет адресочки узнать.

Если трейнер скомпилирован под .NET, то API монитор откажется с ним работать. В этом случае можно в отладчике установить брекпоинт на функции WriteProcessMemory и ReadProcessMemory, а когда он сработает — посмотреть содержимое стека и извлечь оттуда адрес, по которому будут записаны данные.

То, что я написал выше — это мое личное мнение, и кто-то может с этим согласится, а кто-то нет. Надеюсь, данная статья вам понравилась.

Не советую вам «копипастить» функционал чужих читов, поскольку вы при этом не набираетесь опыта. Также создание читов таким способом не будет приносить удовольствие.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Из песочницы] Разработка и встраивание расширений .vsix в Visual Studio на C# для чайников

Для кого эта статья


Странно говорить о таких понятиях, как расширение функционала такого продукта, как Visual Studio в контексте «для чайников», но есть люди, которые и журналы смотрят с последней страницы. Эта статья для тех, кто уже имеет представление как обращаться со студией, но пока мало знает, чем она может помочь, и уже очень хочется добавить свою фичу.

Ожидаемые результаты


Научиться создавать и встраивать VSPackage расширения в VS 2012, на примере расширения для запуска калькулятора прямо из студии.

Что потребуется


Для разработки расширения потребуется сама студия, я воспользуюсь VS 2012, а также необходимо установить VS SDK 2012. Отмечу, что для разработки в VS 2010 есть VSPackage Builder , и этот инструмент помогает создавать расширения в дизайнере. Мы же обойдемся только шаблоном проекта предоставляемого SDK.

Шаг 1. Создаем проект


Файл->Создать->Проект->Шаблоны->Другие типы проектов-Расширение среды->Visual Studio Package и задаем имя проекта VSPackageCalc.
Далее следуем указаниям мастера, обратив внимание на следующие окна

Шаг 2. Редактируем способ запуска и отображение кнопки в студии


Искомый файл: VSPackageCalc.vsct — файл с расширением .vsct

Определимся где отобразить кнопку и как запускать расширение, Отмечу два варианта отображения:
— добавление пункта меню в меню «Сервис»
— добавление панели кнопок в тулбар

Группа команд для меню «Сервис» задается так (код уже сгенерирован):

<Group guid="guidVSPackageCalcCmdSet" id="MyMenuGroup" priority="0x0600">
        <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
      </Group>


Как будет назваться панель инструментов в меню панелей инструментов (оставим имя по умолчанию VSPackageCalc Toolbar):
<Menu guid="guidVSPackageCalcCmdSet" id="IDM_TLB_RTF" priority="0x0000" type="Toolbar">
        <Parent guid="guidVSPackageCalcCmdSet" id="0"/>
        <Strings>
          <ButtonText>VSPackageCalc Toolbar</ButtonText>
        </Strings>
      </Menu>


Честно говоря идентификаторов типа IDM_VS_MENU_TOOLS, указывающих в какой раздел меню можно поместить вывоз функции расширения, много, и разбираться со всеми не входит в рамки статьи, но кое-что можно почерпнуть в MSDN

Далее определимся с видом кнопки тулбара. Сначала удалим лишнее кнопки из нашего тулбара (по умолчанию создаются инструменты для редактирования), заменив код с описанием группы кнопок тулбара расширения:

<!-- Toolbar groups -->
      <Group guid="guidVSPackageCalcCmdSet" id="IDG_RTF_TLB_FONT1" priority="0x0100">
        <Parent guid="guidVSPackageCalcCmdSet" id="IDM_TLB_RTF"/>
      </Group>
      ...


на код одного элемента тулбара:
<!-- Toolbar groups -->
      <Group guid="guidVSPackageCalcCmdSet" id="MyMenuGroup" priority="0x0100">
        <Parent guid="guidVSPackageCalcCmdSet" id="IDM_TLB_RTF"/>
      </Group>


Далее можно редактировать текст и отображения самого пункта меню:
<Button guid="guidVSPackageCalcCmdSet" id="cmdidCalcStart" priority="0x0100" type="Button">
        <Parent guid="guidVSPackageCalcCmdSet" id="MyMenuGroup" />
        <Icon guid="guidImages" id="bmpPic1" />
        <Strings>
          <ButtonText>Калькулятор</ButtonText>
        </Strings>
      </Button>


Можно удалить элемент Icon (иконку), и тогда будет отображаться только текст. Иначе при отображении в тулбаре будет иконка, а чтобы показать и текст к ней, придется настраивать отдельно через инструмент настройки отображения кнопок тулбара в самой студии.

Шаг 3. Описание функционала расширения


Для задания функционала нашего расширения, его нужно описать в файле VSPackageCalcPackage.cs, отредактировав метод обработки нажатия на кнопку меню, который также был уже сгенерирован при создании проекта. Удалим все, что внутри метода и заменим на запуск приложения — стандартного калькулятора:
private void MenuItemCallback(object sender, EventArgs e)
        {
            // Запуск процесса:
            Process.Start("Calc.exe");
        }

Шаг 4. Встраивание расширения


Ну вот почти и готово, осталось только собрать проект и в папке построения запустить VSPackageCalc.vsix.
Процесс установки


После установки необходимо перезапустить студию.

Шаг 5. Использование встроенной фичи


Запуск из меню Сервис


Запуск из тулбара
Сначала нужно добавить панель инструментов VSPackageCalc Toolbar средствами VS — правая мышь по тулбару и отметить галочкой. Тула появилась на панели:


Заключение


Пусть фича не очень полезная и не сложная получилась, но, надеюсь, полученные знания подтолкнут к более глубокому изучению вопроса разработки расширений для Visual Studio.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Вебинары НР Software

сегодня в 16:13

Привет, Хабр! Компания НР приглашает вас принять участие в новой серии пятничных семинаров и вебинаров HP Software.

В этом году технические специалисты и консультанты HP продемонстрируют последние обновления портфеля НР Software, приведут примеры решений для автоматизации, мониторинга и построения гибридной инфраструктуры, продемонстрируют новые возможности продуктов-лидеров ИТ-рынка.

На семинарах будет предоставлена возможность не только услышать презентации, но и обсудить интересующие вас вопросы со спикерами и коллегами, получить консультацию специалистов НP Software.

Для участия необходимо зарегистрироваться на интересующий Вас семинар/вебинар. Подключиться к вебинару можно через виртуальную комнату НР. Ссылка на комнату и инструкция придет в письме с подтверждением Вашей регистрации. Узнать больше.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Интервью с Эриком Михаельс-Обером, RubyHero-2014

Эрик — Ruby-герой 2014 года, популярный ментор среди разных Ruby-сообществ (Ruby Summer of Code, Google Summer of Code и Rails Girls Summer of Code) и просто интересный человек. Изначально интервью должно было выглядеть в стиле «коротко продолжи фразу», но Эрик подошел к делу творчески, поэтому публикую его полностью.

  • Расскажи, пожалуйста, о своем опыте работы на Ruby. Когда начал и с чего?

Я начал полноценно работать на Ruby в 2006 году, когда моя команда решила перевести наше веб-приложение с PHP на Rails. Rails на тот момент был на уровне версии 1.0. Кажется, мы использовали Ruby версию 1.8.4 и веб-сервер Mongrel. Это было еще до Rack, Bundler, RubyGems.org или GitHub. Оглядываясь назад, трудно себе представить работу на Ruby без этих инструментов, которые я сейчас использую каждый день.
  • Ruby помог мне...

Ruby помог мне осознать, что люди ценнее компьютеров. Большинство языков программирования оптимизированы для быстрого выполнения кода. Ruby оптимизирован так, чтобы можно было быстро читать и писать код. Это изменило мое понимание кода, теперь я пишу для людей, а не для компьютеров.
  • Я люблю Ruby за...

Ruby, как язык, очень классный, но намного больше мне нравится Ruby-сообщество. Будучи его частью, я общаюсь с замечательными людьми по всему миру. Мне нравится встречать новых Ruby-программистов на Meetup’ах и конференциях. Я очень много узнал от тех, кто открыто делится своими знаниями в своих блогах, подкастах, видеороликах и т.д. Я люблю Rails Girls, RailsBridge и другие ИТ-сообщества, которые делают программирование более разнообразным и содержательным. Мне по душе творческий дух Ruby-сообщества, который вдохновляет на создание таких проектов как Artoo, Kids Ruby, Shoes, Gosu, Sonic Pi и т.д.
  • Я не люблю Ruby за...

Я думаю, что Ruby будет лучше, если его синтаксис будет более последовательным. Например, в Ruby есть 2 различных способа сделать хэш и 7 различных способов сделать функцию (def, proc, Proc.new, lambda, ->, {}, do…end) по сравнению с JavaScript, который имеет единый синтаксис хэша/объекта и один способ определить функции, независимо от того, именованная ли это функция или анонимная. Ruby также имеет слишком много псевдонимов по сравнению с философией Python, которая говорит, что должен быть только один очевидный способ сделать что-то. Дизайн – это искусство принятия решений. При наличии нескольких имен для одного метода (например, map/collect, reduce/inject, find/detect, find_all/select и т.д.), создатели Ruby избегали жесткого решения, передав этот выбор пользователю. Ruby также имеет много похожих имен для методов, которые несколько отличаются (например ==, ===, eql?, equal?). Я использую Ruby ежедневно в течении почти 10 лет, и я до сих пор не могу вспомнить разницу между eql? и equal?, не посмотрев подсказку. Мне бы хотелось, чтобы эти методы имели более описательные имена.

Другим примером являются тонкие различия между alias и alias_method, или private и protected. Думаю, Symbol можно заменить на frozen String и удалить из пользовательской части языка. Есть несколько других языковых «особенностей», которые я хотел бы исключить из Ruby, если бы мог, например глобальные переменные, пришедшие из Perl. На мой взгляд, это не связано с остальной частью языка. Есть также много плохо поддерживающегося и устаревшего кода в стандартной библиотеке Ruby. Хотелось бы чтобы стандартные библиотеки обновлялись, для использования новых возможностей языка, например keyword arguments. Если подобные функции не используются для основных/стандартных библиотек, их нужно исключить, так как они создают ненужные сложности. Было бы замечательно, если бы в Ruby была возможность находить некоторые виды ошибок на начальной стадии (во время запуска).

И еще не помешал бы динамический компилятор, способный генерировать бинарные файлы. И лучшую производительность выполнения. Я начал использовать вместо Ruby Crystal, которому и будет посвящен мой доклад, так как в нем есть большинство функций, которые мне нравятся в Ruby и отсутствуют те, которые мне не нравятся.

  • Самое ужасное архитектурное решение/ код, которое ты когда-либо встречал...

Первое, что приходит на ум, это то, как Rails выполняет проверку уникальности. Для тех, кто не знает, он просто делает SELECT, чтобы увидеть, существует ли поле, прежде чем делать INSERT. Первая проблема заключается в том, что эти две операции не делаются в транзакции, так что возникают условия для появления гонок сигналов, которые позволяют вставлять неуникальные записи. Тем не менее, транзакции, в принципе, не очень хорошее решение, так как они вызывают слишком много блокировок таблиц. Лучшим решением является просто создание уникального индекса на этом поле в базе данных, что гарантирует правильность и оптимальную производительность. Подход Rails к валидации уникальности – это слабая защита, которая дает пользователю ложное ощущение безопасности.
  • Самая впечатляющая новость о Ruby в 2014 году...

Это новость о создании RubyBench.org Аланом Го Сян Таном (Alan Guo Xiang Tan). Это невероятно ценный (и давно ожидаемый) вклад в сообщество Ruby. Этот проект будет гарантировать рост производительности Ruby, и с каждым релизом он будет становится все быстрее. Если бы RubyBench существовал раньше, он мог бы предотвратить потерю производительности в Ruby 1.9.
  • Жизнь после Ruby – это...

Crystal! Чтобы узнать больше – приходите на мой доклад :) (В конце мая Эрик будет выступать на Ruby-конференции в Киеве с темой доклада о Crystal).
  • Над чем работаешь сейчас?

В данным момент я работаю над переписыванием Twitter CLI под Crystal а также обучаю студентов на Rails Girls Summer of Code
  • В процессе разработки я обязательно использую...

Особое место в моей среде разработки занимает Fish shell, который я рекомендую всем, кто проводит много времени в командной строке. Попробуйте пользоваться им неделю, и вы уже не сможете без него обходиться!
  • Твои любимые Ruby блоги/сообщества/сайты

Ruby-Talk, Ruby Weekly, и This week in Rails рассылки. Блоги Aaron Patterson, Aman Gupta, Sam Saffron, James Edward Gray II, Thomas Reynolds, Sandi Metz, Tom Stuart, Avdi Grimm, Jessica Kerr и Pat Shaughnessy. Также я читаю много блогов, не имеющих отношения к Ruby.
  • Я рекомендую книгу...

“Ruby Under a Microscope”, Pat Shaughnessy, поскольку это захватывающий взгляд на то, как работает Ruby изнутри. Я также рекомендовал бы Practical Object-Oriented Design in Ruby, Sandi Metz каждому Ruby-программисту, который еще ее не читал. Для лучшего понимания IT, как области знаний, я рекомендую Understanding Computation, Tom Stuart. А для совсем начинающих, я рекомендую Learn to Program by Chris Pine. Ну и наконец, книга Why's (Poignant) Guide to Ruby, занимает особое место в моем сердце.
  • Твой личный лайфхак:

Добавь такую строку в свой crontab: */30 9-17 * * 1-5 say «Stand up and walk around».

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

IO.js объединяется с NodeJS

+

Несколько дней назад состоялось заседание технического комитета проекта io.js, на котором принято решение о воссоединении с Node.js и дальнейшем совместном развитии под эгидой организации Node Foundation.

Всего полгода назад 5 из 7 ключевых разработчиков Node.js недовольные консервативной политикой компании Joyent, курирующей разработку проекта Node.js подключились к разработке форка IO.js.

IO.js оказался более конкурентным по производительности и по скорости разработки. Это заставило Joyent «взбодриться» и перестать игнорировать мнение сообщества.

В ответ на призыв компании Joyent вернуться к совместной работе, участники io.js приняли предложение и выразили готовность развивать совместный продукт под брендом Node.js.

Новость бурно обсуждают здесь: http://ift.tt/1ROKFx3

Будем ждать NodeJS 3.0. Ура товарищи :)!!!

PS: Когда там уже Oracle с MySQL образумиться.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Сессии вопросов и ответов для зрителей в online на DevCon

Уже на следующей неделе состоится наша ежегодная и уже пятая конференция для разработчиков — DevCon 2015. По традиции для тех, кто не смог приехать лично, мы организуем online-трансляцию всех треков.

В этом году мы решили расширить взамодействие с теми, кто нас смотрит по эту сторону экранов, чтобы вы также могли «пообщаться» с экспертами, приехавшими на конференцию. Участник на площадке может подойти к докладчику и задать вопрос напрямую, а для зрителей в online была доступна только возможность спросить что-нибудь в чатике и надеяться, что ему что-то вменяемое ответят. Мы подумали, что это плохо, и поэтому добавили в конференцию новый для формат.

Новый формат


Итак, специально для тех, кто будет смотреть нас в трансляции мы добавили 6 QA-сессий с экспертами конференции: одну с участниками открытия и пять сессий в соответствии с тематиками конфереции:


(список участников может измениться ближе к конференции)

Сессии вопросов и ответов будут проходить в перерывах между докладами, поэтому вы можете не опасаться, что пропустите что-то идущее параллельно. Задача участников дискуссии: ответить на те вопросы, которые волнуют вас.

Как задать вопрос?


Если вы хотите, чтобы мы задали ваш вопрос экспертам, у вас есть несколько вариантов, как его задать:
1. На сайте конференции через специальную форму (требуется регистрация). Там же можно проголосовать за понравившийся вопрос.
2. В комментариях к этому посту
3. В твиттере с хештегом #msdevcon
4. В чате во время конференции

Как отбирают вопросы?


Во-первых, кто это делает. Это делаю я, поэтому все претензии можно высказывать мне :)
Во-вторых, как: я учитываю, прежде всего, два параметра:
  • релевантность вопроса по тематике (клиентская разработка, облачная разработка, языки и инструменты, разработка игр, корпоративная разработка) и экспертизе докладчиков
  • интерес к ответу на вопрос у целевой аудитории (плюсы на хабре, ретвиты и добавление в избранное в твиттере, голоса на сайте).

Из-за ограничений по времени, скорее всего, мы не успеем задать все вопросы, но после конференции мы сделаем отдельный пост с ответами.

Ждем ваших вопросов и приятного DevCon'а!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Об альтернативном образовании вообще и про C# в частности

Сейчас очень часто говорят о том, что нынешняя система образования никуда не годится, она лишает детей творческих способностей, у неё низкая эффективность и нужно что-то срочно менять.

Только вот конкретных решений этой проблемы почти не видно — что именно нужно поменять и как следует строить современную систему образования, чтобы она отвечала духу нового времени, помогала развиваться творческим способностям и была при этом эффективной.

У меня есть некоторые свои собственные соображения и наработки для решения этой проблемы в рамках своей специальности — способа изучения языка программирования C#.

Издавна изучение профессии происходило через банальное повторение. Просто повторяя за мастером те или иные действия можно получить более менее приемлимый результат. После многократного повторения количество переходит в качество и происходит обретение навыка, который уже «не пропьёшь», потому что «руки помнят».

Мне 37 лет, я программист, пишу программы с 16 лет (начинал с МК-52), меня просто прёт от процесса создания программ. А ещё мне нравится обучать других тому, что сам умею. Поэтому я и занялся созданием своей методики изучения программирования по которой изучать язык интересно, навыки программирования прокачиваются незаметно, всё получается «само собой».

И методика моя не нова, она использует принцип повторения действий для получения быстрого результата. На вебинарах мы с нуля пишем на C# несложные игровые программы. Ученикам это очень нравится, они с удовольствием повторяют все действия и… получают готовую игру, хотя ещё не очень понимают, чем отличается base от case. Но писать программы уже не страшно, уроков очень много, можно идти дальше и создавать новые игровые программки, удивляя себя и своих друзей. Ох, как это… мотивирует! Один из учеников после такого урока написал мне: «Наконец-таки я написал хоть что-то полезное!»

Впрочем, эйфория быстро проходит, и ученикам уже мало просто повторить действия по видеоуроку, хочется добавить что-то от себя. И вот тут начинается самое интересное! «Обломатор», как сказал один из участников. Ничего не выходит, программа не работает, выскакивают странные ошибки, которые непонятно, как исправлять.

И тут наш герой самостоятельно начинает читать книжки, ищет информацию, читает форумы. Только теперь он чётко представляет, зачем ему это надо, у него есть цель: доделать программу! Это его мотивирует к самостоятельному обучению, читать книги уже становится интересно, потому что этим знаниям теперь есть за что зацепиться, так как кое-какой опыт уже наработан, есть что вспомнить и быстро понять.

Вот и весь «секрет». Не вдалбливать знания, а прививать навыки. Знания сейчас легко найти самостоятельно, а вот приобрести навыки можно только в результате продолжительной практики.

Я ни в коем случае не отвергаю классические способы изучения программирования, но чтобы ими эффективно пользоваться — нужен разгон, трамплин, подготовка, Саначала нужно «написать свой миллион плохих строчек», а потом уже пойдёт красноречие.

Моя миссия — сделать всё, чтобы ученикам прокачивать навыки программирования было интересно: показывать пример, мотивировать их к практическим действиям, предоставлять последовательный доступ к урокам, дать возможность решать самостоятельные задачи в разделе Консоль, зажигать огонёк интереса на вебинарах и всячески подталкивать к самостоятельному творчеству при создании программ на языке C#.

Для достижения этой цели я использую следующие принципы:
1. На каждом уроке создаётся с нуля готовая программа.
2. За каждый урок необходимо отчитаться — прислать отчёт с картинками и комментариями.
3. Корректность отчётов проверяют сами ученики друг у друга: хорошо или плохо.
4. Доступ к следующему уроку только после выполнения предыдущего.
5. Несколько сотен самостоятельных заданий с интерактивной проверкой.
6. Для каждой задачи есть видеорешение и возможность посмотреть чужие решения.
7. Регулярные вебинары не дают «засохнуть» и добавляют мотивации для продолжения.

На сегодняшний момет на проекте около 2500 участников, которые отправили 5800 отчётов по видеоурокам и решили 35000 задач. Судя по отзывам учеников, мне удалось создать неплохую систему альтернативного обучения языку программирования C#. Лучше всего она подходит для начинающих программистов, которые делают в изучении языка первые шаги, но постепенно я записываю и более сложные курсы по другим направлениям.

Вот если бы можно было бы найти подобные варианты для всех предметов, чтобы заменить школьное образование!

У меня растёт ребёнок, ему уже 4 года, я постоянно задумываюсь об альтернативе обычной школе, но пока ничего толком придумать не могу, кроме как отдать его в разные кружки и приглашать разных репетиторов. А мне бы хотелось решить эту задачу комплексно. Однако, когда я высказываю эти мысли родным и знакомым, которые сами только что пересказывали первый абзац этой статьи, вижу удивлённые лица и дикий страх от идеи не отдавать ребёнка в школу.

Я вижу успех описанной идеи, но пока не могу придумать, как её развить на школьные предметы. Нужны единомышленники. Поэтому я и решил обратиться к интеллектуальному сообществу Хабра, чтобы услышать мнения и рекомендации от умных опытных и просвещённых в разных областях людей.

Спасибо за внимание.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.