Ruby沙盒与集成脚本语言

我目前正在使用Ruby中基于文本的游戏引擎,应用程序分为/ lib中的Ruby代码和/ data中的YAML数据,在游戏需要时加载。 我想允许数据文件包含基本脚本,主要是在事件/观察者模型中。 但是,我还希望用户能够生成和共享自定义方案,而无需担心脚本中嵌入的恶意代码。

附录:我最初的计划是将用户创建的内容分为两种类型,“模块”只是数据(因此是安全的)和插件,它们增加了额外的function(但显然不安全)。 为了类似于桌面游戏,模块就像发布的冒险场景和内容,插件将是包含附加规则和系统的规则手册。

示例脚本(当然语法可根据解决方案进行更改):

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

从安全角度来看,如果脚本严格选择加入,可能是通过包含一个带有一点DSL的mixin来实现的,例如:

 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是一种相当流行的语言,如果我以后遇到问题,请提供帮助。 安全,因为我没有专门绑定的任何function将无法从脚本中获取。

    缺点:现有的Ruby-Lua绑定似乎是单向的,旧的,维护不良,或两者兼而有之。 似乎有点狡猾,将脚本语言嵌入到另一种脚本语言中。

  3. 使用Ruby解释器实现自定义脚本语言。 我一直在试验Treetop ,制作一个足以满足脚本的简单语法应该不会太难。

    优点:无需嵌入其他语言。 只有我专门实现的function才可用于脚本。

    缺点:矫枉过正。 “没有建在这里”的综合症。 可能是可怕的虫巢等待发生。

  4. 使用特定于域的语言完全在Ruby中实现数据文件。

    优点:简单易行。

    缺点:用户创建的数据不可信任。

我也愿意接受我可能没有想过的其他建议。 安全实现嵌入数据文件的脚本的最佳解决方案是什么?

编辑2011年12月23日:在DSL中添加了第四个选项,在顶部添加了“附录”以及其他想法/背景。

您可以考虑使用Shikashi gem ,它允许您创建沙箱并在单个对象上定义允许的方法调用的白名单。

考虑使用jRuby而不是Ruby。 Java最初是为了支持移动代码而实现的(早在机顶盒时代),并且有一个经过良好测试的安全模型/实现 ,我怀疑它可以包装足够的jRuby以防止用户脚本/类与其他部分一起造成破坏游戏系统。 jRuby也支持嵌入 ,这可能有助于将游戏核心与用户应用程序分开,尽管我现在还不知道它有多强大。

当然,jRuby是Ruby!