问题描述
我目前正在使用Ruby开发基于文本的游戏引擎,该应用程序分为/lib中的Ruby代码和/data中的YAML数据,可在游戏需要时加载.我想允许数据文件包含基本脚本,主要是在事件/观察者模型中.但是,我还希望用户能够生成和共享自定义方案,而不必担心脚本中嵌入的恶意代码.
附录:我最初的计划是将用户创建的内容分为两种类型:模块"(仅数据)(因此是安全的)和插件,其添加了附加功能(但显然是不安全).与桌面游戏类似,模块就像已发布的冒险场景和内容,而插件则是包含其他规则和系统的规则手册.
示例脚本(语法可能会根据解决方案而有所变化)
---
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
我已经看过四个选项,但是我不确定哪种方法最好:
-
使用Ruby脚本,但在某种类型的沙箱中.
嵌入另一种脚本语言,例如卢阿.
four options, but I'm not sure which is the best approach to take:
Use Ruby scripting, but in a sandbox of some kind.
Embed another scripting language, e.g. Lua.
Pros: Ruby and Lua are C-based, so bindings should be reasonably simple. Lua is a reasonably popular language, so help available if I run into issues later. Secure, since any functionality I don't specifically bind will be unavailable from scripts.
Cons: Existing Ruby-Lua bindings seem to be one-way, old and poorly maintained, or both. Seems a mite dodgy to embed a scripting language inside another scripting language.
Implement a custom scripting language with Ruby interpreter. I've been experimenting with Treetop, and it shouldn't be too hard to make a simple grammar that would suffice for the scripts.
Pros: No need to embed another language. Only functionality I've specifically implemented will be available to scripts.
Cons: Overkill. "Not built here" syndrome. Probably horrible nest of bugs waiting to happen.
Implement the data files entirely in Ruby, using a domain-specific language.
Pros: Simple and easy.
Cons: No user-created data is trustable.
I am also open to other suggestions not on that list that I may not have thought of. What is the best solution to safely implement scripts embedded in data files?
Edit 2011年12月23日: Added fourth option with DSL, added "addendum" at top with additional thoughts/context.
解决方案You might consider using the Shikashi gem, which allows you to create sandboxes and define a whitelist of allowed method calls on individual objects.
这篇关于Ruby沙箱与集成脚本语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!