2011-12-23 10 views
15

Actualmente estoy trabajando en un motor de juego basado en texto en Ruby, con la aplicación separada en código Ruby en/lib y datos YAML en/data, que se carga cuando el juego lo necesita . Quiero permitir que los archivos de datos contengan scripts básicos, principalmente en un modelo de evento/observador. Sin embargo, también quiero que los usuarios puedan generar y compartir escenarios personalizados sin tener que preocuparse por códigos maliciosos incrustados en el script.Ruby sandboxing vs. Integración de un lenguaje de script

Adición: Mi plan original era tener contenido creado por el usuario separa en dos tipos, "módulos" que eran sólo de datos (y por tanto segura) y plugins que añade funcionalidad adicional (pero obviamente no eran seguros). Para hacer una analogía con los juegos de mesa, los módulos serían como escenarios de aventuras publicadas y contenido, y los complementos serían libros de reglas que contienen reglas y sistemas adicionales.

Script de ejemplo (sintaxis, por supuesto, sujeta a cambios basados ​​en la solución):

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

Desde un punto de vista de la seguridad, sería ideal si scripting era estrictamente opt-in, probablemente a través de un mixin incluido con un poco DSL, por ejemplo:

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 

he mirado en tres cuatro opciones, pero no estoy seguro de cuál es el mejor enfoque a adoptar:

  1. Usa las secuencias de comandos de Ruby, pero en una caja de arena de algún tipo.

    Pros: Muy familiarizado con Ruby, no hay necesidad de código "pegamento" o problemas de integración de objetos entre idiomas.

    Contras: No muy familiarizados con los problemas de seguridad o sandboxing, no se han encontrado soluciones listas para usar que parezcan encajar.

  2. Implemento Incruste otro lenguaje de scripting, p. Lua.

    Pros: Ruby y Lua están basados ​​en C, por lo que las fijaciones deben ser razonablemente simples. Lua es un lenguaje razonablemente popular, por lo que me ayudaré si tengo problemas después. Seguro, ya que cualquier funcionalidad que no vincule específicamente no estará disponible desde los scripts.

    Contras: Los enlaces existentes de Ruby-Lua parecen ser de una sola dirección, viejos y mal mantenidos, o ambos. Parece un poco dudoso para incrustar un lenguaje de scripting dentro de otro lenguaje de scripting.

  3. Implemente un lenguaje de scripting personalizado con el intérprete Ruby. He estado experimentando con Treetop, y no debería ser demasiado difícil hacer una gramática simple que sea suficiente para los scripts.

    Pros: No es necesario incrustar otro idioma. Solo la funcionalidad que he implementado específicamente estará disponible para los scripts.

    Contras: Overkill. Síndrome "No construido aquí". Probablemente horrible nido de errores esperando a suceder.

  4. Implemente los archivos de datos completamente en Ruby, usando un lenguaje específico de dominio.

    Pros: Simple y fácil.

    Contras: Ningún dato creado por el usuario es confiable.

También estoy abierto a otras sugerencias no en esa lista en las que no haya pensado. ¿Cuál es la mejor solución para implementar scripts de manera segura incrustados en los archivos de datos?

Editar 2011 年 12 月 23 日: Se agregó cuarta opción con DSL, se agregó "adición" en la parte superior con pensamientos/contexto adicionales.

+0

Hmm, no estoy tan familiarizado con las secuencias de comandos del juego, pero ¿por qué no usar V8 y Javascript? Es rapidísimo y la mayoría de las personas se sentirán cómodas trabajando con JS. – omninonsense

+0

¡Felices fiestas, a todos! –

+1

Realmente depende de lo que desee lograr, si los complementos están en ruby ​​será difícil evitar que uno de ellos vuelva a abrir una clase principal y haga lo que quiera de la misma manera que un plugin de ruby ​​on rails puede hacer lo que quiera . Además de que usar cualquier otro idioma como un lenguaje de complemento es excesivo, harás más trabajo en él que en el propio juego;) – Schmurfy

Respuesta

4

Puede considerar usar Shikashi gem, que le permite crear entornos limitados y definir una lista blanca de llamadas a métodos permitidos en objetos individuales.

+0

Shikashi se ve muy interesante, más en la línea de mis intenciones originales aquí. ¿Tiene usted (¿alguien) alguna experiencia, historias de guerra, consejos o comentarios generales al respecto? –

+0

Seleccionado como respuesta porque responde mejor a la pregunta que originalmente tenía en mente. –

+0

¿La gema Shikashi funciona con Rails 5 beta ruby ​​2.3?No está instalando para mí. – abrocks

1

Considere usar jRuby en lugar de Ruby. Java se implementó originalmente para admitir código móvil (en los días de set-top) y tiene un bien probado security model/implementation que podría, sospecho, envolver suficiente jRuby para evitar que los scripts/clases de usuario causen estragos en el resto del sistema de juego. . jRuby también admite embedding, lo que puede ayudar a separar el núcleo del juego de las aplicaciones de usuario, aunque no sé cuán robusto es en este momento.

Y, por supuesto, jRuby es Ruby!

+0

Buena idea con jruby. Pero las pruebas que realicé con jruby & jsr 223 no fueron realmente exitosas (aprobación variable). Espero que esto cambie en el futuro. – plang

+0

Excepto por el hecho (y me doy cuenta de que tengo el beneficio de un adicional de 2 años de parte trasera en el tiempo o mi comentario), que Java ha resultado plagado de agujeros de seguridad de quiebra. Por supuesto, esto no es tanto un problema de Java: la seguridad del código que se ejecuta en la máquina es una pesadilla de confianza, porque en última instancia se reduce a la confianza del otro programador. Confiar en la caja de arena porque se anuncia como un arenero es quizás mejor que nunca desconfiar de nadie, pero sigue siendo confianza. – jefflunt

Cuestiones relacionadas