Статьи

Разработка кроссплатформенной игры HTML5: часть 3


Это заключительная часть серии из трех статей о советах по разработке игр на HTML5.
Часть 1 была
посвящена визуальным советам и советам по производительности,
часть 2
была посвящена методам ввода, и теперь я собираюсь завершить ее некоторыми советами по обеспечению безопасности вашей игры.

Часть 1. Создание великолепного внешнего вида игры на всех платформах.

Часть 2. Работа с различными типами ввода для каждой платформы.

Часть 3. Обеспечение безопасности вашей игры.

Часть 3 охватывает:

  • затемнение
  • Анонимная функция-обертка
  • Бэкэнд для вашей игры
  • Это действительно необходимо?

Поскольку ваш исходный код JavaScript может просматривать любой пользователь,
вы никогда не будете на 100% защищены только с помощью клиентского решения
. С учетом вышесказанного, есть несколько вещей, которые вы можете сделать, чтобы сделать хакерскую игру немного сложнее.

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

Вот несколько способов борьбы с хакерами:

затемнение

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

Как пример, это:

(function() {

var text = 'Hello World!';

console.log( text );
})();



становится:

(function(){var a="Hello World!";console.log(a)})()

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

К сожалению, этот процесс можно повернуть вспять, и результат выглядит примерно так:

(function() {

var a = "Hello World!";

console.log(a);
})();


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

Процесс обфускации вашего кода довольно прост. Мы используем
UglifyJS
и rake-файл Ruby, чтобы и скомпилировать все наши файлы JavaScript вместе, и сжать / запутать их.

Если вы заинтересованы в использовании
имеющейся
у нас системы, используйте Ruby и этот rakefile (вот
версия компиляции coffeescript
).

Вам понадобится Ruby, а также RubyGems и гемы: rake, uglifier и fssm. Rake использует файл манифеста, отформатированный примерно так (просто измените его на все имена файлов, которые вам нужны):

//= require 'md5.js'
//= require 'core.js'
//= require 'tiles.js'
//= require 'input.js'
//= require 'main.js'
//= require 'timer.js'

После того, как все это настроено, вы можете просто использовать команду rake watch, находясь в главном каталоге вашей игры, и каждый раз, когда исходный файл сохраняется, он будет перекомпилировать уменьшенный / запутанный файл JavaScript для вас.

Взгляните на наш
исходный код Slime Volley
(где он используется), если вы все еще в замешательстве.

Есть много других способов сделать это. Вот способ использовать
UglifyJS онлайн
, и вы можете альтернативно использовать
YUI Compressor
или
Google Closure Compiler
.

Анонимные функции оболочки

Самый простой способ манипулировать HTML5-игрой — запустить некоторый код JavaScript, добавив javascript: doSomething (); в адресной строке или запуска JavaScript из консоли. Если у вас есть глобальная переменная на стороне клиента, которая отслеживает оценку пользователя, все, что мне нужно сделать, — это ввести значение Score = 10000000; и я настроен …

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


(function() {
    // Your code goes here...
})();


Фактически, это хорошая практика, независимо от того, заботитесь ли вы о редактируемых переменных (CoffeeScript компилируется так по умолчанию). Это хороший способ предотвратить взаимодействие вашего кода с кодом из других библиотек.

Если вам нужен доступ к глобальным переменным из анонимной функции, просто используйте window.variableName .

Бэкэнд для вашей игры

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

Для наших игр мы используем комбинацию
node.js
и
Socket.IO
.
nowjs
— еще один хороший вариант (это уровень абстракции над Socket.IO). Вы можете использовать другие языки, такие как PHP или Ruby, но имеет смысл использовать JavaScript.

Целью бэкэнда является обработка логики для игры. Как правило, это включает в себя симуляцию игры (которая снова делает node.js лучшим выбором) и использование результатов, полученных сервером, а не клиентом.

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

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

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

В действии

Слово Войны

Word Wars изначально назывался Worldle и был разработан за 24 часа для хакатона в Техасском университете несколькими другими студентами. Из-за нехватки времени на разработку, это было совершенно не безопасно.

В игре появилось немного шума на HackerNews, и почти сразу же
появился скрипт greasemonkey
для взлома игры (в дополнение к некоторым сумасшедшим инъекциям HTML и CSS, поскольку они не избежали высоких результатов).

Их создатели — наши друзья, поэтому мы предложили усовершенствовать игру для них, а также сделать ее более безопасной. С тех пор у нас не было проблем с мошенничеством (хотя игра похожа на Boggle, она не застрахована от Boggle-cheater, когда вы входите в сетку и генерирует все возможные слова)

На Clay.io

Когда мы впервые разработали Clay.io (API, который заботится о различных игровых функциях, таких как списки лидеров и достижения), мы столкнулись с некоторыми интересными проблемами: «Как лучше всего обеспечить безопасную передачу данных, таких как игровые результаты и достижения?»

Наше решение состояло в том, чтобы использовать подход, аналогичный тому, который Google использует для Google Wallet. Разработчики могут сгенерировать
JSON Web Token
(JWT) на своем сервере и отправить его нам со стороны клиента. По сути, JWT — это объект JavaScript, зашифрованный уникальной солью (в нашем случае, секретным ключом разработчика).

Этот подход позволил нам сохранить формат публикации рекордов и достижений относительно одинаковым для игр, независимо от того, есть ли у них бэкэнд. Вместо использования (новый Clay.Leaderboard ({id: 1}) .post ({счет: 50}); можно использовать (новый Clay.Leaderboard ({id: 1}) .post ({jwt: jwt}) ;

Вы можете прочитать нашу полную документацию по шифрованию
здесь
, и пример нашей реализации в Slime Volley
здесь
.

Это все действительно необходимо?

Не совсем, но рано или поздно это понадобится. Менее чем через час после выхода версии Angry Birds для HTML5 уже
был взломан для получения всех уровней
.

С другой стороны, если вы спешите завершить игру, вы * можете * на время ее опустить. Например, я вообще не реализовывал бэкэнд для игры, которую выпустил чуть более недели назад. Игра получила довольно хороший отклик (в том числе более 30 000 уникальных посетителей и даже пост на Kotaku), но до сих пор не было сфальсифицированных результатов, поданных кем-либо.

Вот и все для этой серии советов по разработке игр на HTML5, надеюсь, это было полезно! Вы можете следить за тем, что мы делаем на Clay.io в нашем
блоге
, есть большая вероятность, что у нас будет еще несколько уроков и советов по разработке игр. Если вы разрабатываете игру и не хотите создавать такие функции, как достижения, списки лидеров и обработка платежей, взгляните на наш
API
. Даже если вы предпочитаете делать это самостоятельно, рассмотрите возможность добавления своей игры на
наш кроссплатформенный рынок
, она бесплатна и чрезвычайно проста! Наша главная цель — помочь разработчикам, поэтому, если у вас есть идеи о том, как мы можем улучшить, дайте нам знать!