2011-12-23 67 views
15

我目前正在研究Ruby中的基于文本的游戏引擎,应用程序分为Ruby代码和/数据中的/ lib和YAML数据,在游戏需要时加载。我想允许数据文件包含基本脚本,主要是在事件/观察者模型中。不过,我也希望用户能够生成和共享自定义场景,而不必担心嵌入脚本中的恶意代码。我最初的计划是将用户创建的内容分为两种类型,“模块”是仅数据(因此是安全的)和插件,增加了额外的功能(但显然不安全)。为了类比桌面游戏,模块将像发布的冒险场景和内容一样,插件将是包含附加规则和系统的规则手册。Ruby沙盒与集成脚本语言

示例脚本(当然受到的语法更改基于溶液):

--- 
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的实验,并且制作一个足以处理脚本的简单语法应该不会太难。

    优点:无需嵌入其他语言。只有我特别实现的功能才能用于脚本。

    缺点:矫枉过正。 “不在此建”综合征。可能发生的可怕的错误巢等待发生。

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

    优点:简单而简单。

    缺点:没有用户创建的数据是可信的。

我也开放给其他建议,不在列表中,我可能没有想到。安全地实现嵌入数据文件中的脚本的最佳解决方案是什么?

编辑2011年12月23日:添加了DSL的第四个选项,在顶部添加了“addendum”以及其他想法/上下文。

+0

嗯,我不是很熟悉游戏脚本,但为什么不使用V8和Javascript?它闪电般快速,大多数人都会很喜欢JS的工作。 – omninonsense 2011-12-23 19:53:03

+0

大家节日快乐! – 2011-12-25 20:35:23

+1

这真的取决于你想达到什么,如果插件是在ruby中,很难阻止其中一个重新打开一个核心类,并以同样的方式做任何他们想做的事情,一个Ruby插件可以做任何事情。除了使用任何其他语言作为插件语言是矫枉过正之外,你会做比它更多的工作;) – Schmurfy 2011-12-26 15:38:14

回答

4

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

+0

Shikashi看起来很有趣,更符合我在这里的初衷。你(有没有人)有任何经验,战争故事,技巧或一般性评论? – 2012-01-03 08:18:58

+0

被选为答案,因为它最好地回答了我原先想到的问题。 – 2012-01-17 22:52:18

+0

Shikashi gem是否可以使用Rails 5 beta ruby​​ 2.3?这不是为我安装。 – abrocks 2016-02-20 19:16:16

1

考虑使用jRuby而不是Ruby。 Java最初是为了支持移动代码而实施的(回到机顶盒时代),并且有一个经过良好测试的security model/implementation,我怀疑它可以包装足够的jRuby来保持用户脚本/类不会对游戏系统的其他部分造成破坏。 jRuby同样支持embedding,这可能有助于将游戏内核与用户应用程序分开,但我不知道它目前有多强大。

而且,当然,jRuby是Ruby!

+0

jruby的好主意。但是我使用jruby&jsr 223所做的测试并不真正成功(变量传递)。希望这将在未来发生改变。 – plang 2012-02-21 09:37:01

+0

除了这个事实(并且我意识到在时间或我的评论中我还有另外两年的好处),那个Java已经变成了充满沙盒的安全漏洞。当然,这不是一个真正的Java问题 - 在自己的机器上运行的代码的安全性是一个信任的噩梦,因为它最终归结为对其他程序员的信任。信任沙盒,因为它被广告为沙盒也许比不信任任何人更好,但它仍然是信任。 – jefflunt 2014-03-10 20:32:18