Ruby песочница против интеграции языка сценариев - PullRequest
15 голосов
/ 23 декабря 2011

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

Приложение: Первоначально планировалось создать пользователяконтент разделен на два типа: «модули», которые были предназначены только для данных (и, следовательно, безопасны), и плагины, которые добавляли дополнительную функциональность (но, очевидно, были небезопасны).Чтобы провести аналогию с настольными играми, модули были бы похожи на опубликованные сценарии приключений и контент, а плагины - это книги правил, содержащие дополнительные правила и системы.

Пример сценария (синтаксис, конечно, может изменяться в зависимости от решения):

---
Location:
  observers:
    on_door_open: |
      monster = spawn_monster(:goblin);
      monster.add_item(random_item());
      monster.hostile = true;

С точки зрения безопасности было бы идеально, если бы сценарий был строго включен, возможно, через встроенный миксин с небольшим количеством DSL, например:

class Frog
  include Scriptable

  def jump; ... ; end # this can be called from a script
  allow_scripting :jump

  def ribbit; ... ; end # this cannot be called from a script
end

Я посмотрелна три четыре варианта, но я не уверен, какой из подходов лучше всего использовать:

  1. Использовать сценарии Ruby, но в какой-то песочнице.

    Плюсы: Очень хорошо знаком с Ruby, нет необходимости в "склеивании" кода или проблем с интеграцией объектов между языками.

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

  2. Реализация Внедрение другого языка сценариев, например Lua.

    Плюсы: Ruby и Lua основаны на C, поэтому привязки должны быть достаточно простыми.Lua - достаточно популярный язык, поэтому помощь можно получить, если я столкнусь с проблемами позже.Безопасный, так как любые функции, которые я специально не связываю, будут недоступны из сценариев.

    Минусы: Существующие привязки Ruby-Lua кажутся односторонними, старыми и плохо обслуживаемыми, или оба,Кажется бесполезным встраивать язык сценариев в другой язык сценариев.

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

    Плюсы: Нет необходимостивставлять другой язык.Только функции, которые я специально реализовал, будут доступны для сценариев.

    Минусы: Overkill.Синдром «не построен здесь».Вероятно, ужасное гнездо ошибок, ожидающих появления.

  4. Реализация файлов данных полностью на Ruby с использованием языка, специфичного для домена.

    Плюсы: Просто и легко.

    Минусы: Нет данных, созданных пользователем, можно доверять.

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

Edit 2011 年 12 月 23 日: Добавлен четвертый вариант с DSL, добавлено "addendum" вверху с дополнительными мыслями /контекст.

Ответы [ 2 ]

5 голосов
/ 02 января 2012

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

1 голос
/ 24 декабря 2011

Подумайте об использовании jRuby вместо Ruby. Изначально Java была реализована для поддержки мобильного кода (еще в дни приставок) и имеет хорошо протестированную модель / реализацию безопасности , которая, как я подозреваю, могла бы обернуть достаточно jRuby, чтобы не допустить пользовательских скриптов / классов создавая хаос с остальной игровой системой. jRuby также поддерживает встраивание , что может помочь отделить игровое ядро ​​от пользовательских приложений, хотя я не знаю, насколько оно устойчиво в настоящее время.

И, конечно же, jRuby - это Ruby!

...