Ответ 1
Вы можете подумать об использовании драгоценного камня Shikashi, который позволяет создавать песочницы и определять белый список разрешенных вызовов метода для отдельных объектов.
В настоящее время я работаю над текстовым движком игры в Ruby, при этом приложение разделяется на Ruby-код в /lib и данные YAML в /data, который загружается, когда это требуется в игре. Я хочу, чтобы файлы данных содержали базовые сценарии, в основном в модели event/observer. Тем не менее, я также хочу, чтобы пользователи могли создавать и совместно использовать пользовательские сценарии, не беспокоясь о вредоносном коде, встроенном в script.
Приложение: Мой первоначальный план состоял в том, чтобы разделить содержимое пользователя на два типа, "модули", которые были только для данных (и, следовательно, безопасны) и плагины, которые добавили дополнительные функции (но, очевидно, были небезопасными). Чтобы сделать аналогию с настольными играми, модули будут похожи на опубликованные сценарии приключения и контент, а плагины - это правила, содержащие дополнительные правила и системы.
Пример script (синтаксис, конечно, может быть изменен на основе решения):
---
Location:
observers:
on_door_open: |
monster = spawn_monster(:goblin);
monster.add_item(random_item());
monster.hostile = true;
С точки зрения безопасности было бы идеально, если бы скриптинг был строго выбран, возможно, через включенный mixin с небольшим 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
Я рассмотрел четыре параметра three, но я не уверен, какой из них лучше всего подходит:
Используйте Ruby-скрипты, но в виде песочницы.
Плюсы: Очень знакомы с Ruby, нет необходимости в коде "клей" или проблемах интеграции объектов между языками.
Минусы: Не очень знакомы с проблемами безопасности или песочницей, не нашли никаких готовых решений, которые кажутся подходящими.
Внедрить Вставить другой язык сценариев, например. Lua.
Плюсы: Ruby и Lua основаны на C, поэтому привязки должны быть достаточно простыми. Lua - достаточно популярный язык, поэтому помощь доступна, если я буду сталкиваться с проблемами позже. Безопасно, поскольку любая функциональность, которую я не связываю напрямую, будет недоступна из сценариев.
Минусы: Существующие привязки Ruby-Lua кажутся односторонними, старыми и плохо поддерживаемыми, или и тем, и другим. Кажется, это хитрость, чтобы внедрить язык сценариев в другой язык сценариев.
Внедрение пользовательского языка сценариев с помощью Ruby-интерпретатора. Я экспериментировал с Treetop, и не должно быть слишком сложно сделать простую грамматику, достаточную для скриптов.
Плюсы: Не нужно внедрять другой язык. Только функциональность, которую я специально реализовал, будет доступна для скриптов.
Минусы: Overkill. "Не построен здесь" синдром. Вероятно, ужасное гнездо жуков, ожидающих того, что произойдет.
Реализовать файлы данных полностью в Ruby, используя язык, специфичный для домена.
Плюсы: Простой и легкий.
Минусы:. Пользовательские данные не являются надежными.
Я также открыт для других предложений, не включенных в этот список, о которых я, возможно, и не подумал. Какое лучшее решение для безопасного внедрения скриптов, встроенных в файлы данных?
Изменить 2011 年 12 月 23 日: Добавлен четвертый вариант с DSL, добавлен "добавление" наверх с дополнительными мыслями/контекстом.
Вы можете подумать об использовании драгоценного камня Shikashi, который позволяет создавать песочницы и определять белый список разрешенных вызовов метода для отдельных объектов.
Рассмотрите возможность использования jRuby вместо Ruby. Первоначально Java была реализована для поддержки мобильного кода (еще в установленные дни) и имеет хорошо протестированную модель/реализацию безопасности, которая могла бы, я подозрительный, обернуть достаточно jRuby, чтобы пользовательские скрипты/классы не создавали хаос с остальной частью игровой системы. jRuby поддерживает внедрение, что может помочь отделить ядро игры от пользовательских приложений, хотя я не знаю, насколько он прочен в это время.
И, конечно же, jRuby - это Ruby!