2011-12-23 18 views
15

Attualmente sto lavorando a un motore di gioco basato su testo in Ruby, con l'app separata in codice Ruby in/lib e dati YAML in/data, che viene caricata quando necessario dal gioco . Voglio consentire ai file di dati di contenere script di base, principalmente in un modello di evento/osservatore. Tuttavia, voglio anche che gli utenti siano in grado di generare e condividere scenari personalizzati senza doversi preoccupare del codice dannoso incorporato nello script.Ruby sandboxing vs. integrazione di un linguaggio di scripting

addendum: mio piano originale era quello di avere contenuti creati separato in due tipi, "moduli", che erano soli dati (e quindi sicuro) e plugin che aggiunge funzionalità aggiuntive (ma ovviamente non erano sicuri). Per fare un'analogia con il gioco da tavolo, i moduli sarebbero come scenari e contenuti di avventura pubblicati e i plugin sarebbero libri di regole contenenti regole e sistemi aggiuntivi.

Script di esempio (sintassi ovviamente soggetta a modifiche in base soluzione):

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

Dal punto di vista della sicurezza, sarebbe ideale se scripting era rigorosamente opt-in, probabilmente attraverso un mixin incluso con un po ' DSL, ad esempio:

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 

ho guardato tre quattro opzioni, ma non sono sicuro che è l'approccio migliore per prendere:

  1. Utilizzare lo script Ruby, ma in una sandbox di qualche tipo.

    Pro: Molto familiare con Ruby, nessuna necessità di codice "colla" o problemi di integrazione di oggetti tra le lingue.

    Contro: Non molto familiare con problemi di sicurezza o sandboxing, non ho trovato nessuna soluzione pronta per l'uso che sembra adattarsi.

  2. Implementare Incorporare un altro linguaggio di scripting, ad es. Lua.

    Pro: Ruby e Lua sono basati su C, quindi i binding dovrebbero essere ragionevolmente semplici. Lua è un linguaggio ragionevolmente popolare, quindi aiuto disponibile se mi imbatto in problemi successivi. Sicuro, dal momento che qualsiasi funzionalità che non associo in modo specifico non sarà disponibile dagli script.

    Contro: Gli attacchi esistenti in Ruby-Lua sembrano essere a senso unico, vecchio e mal gestito, o entrambi. Sembra un acaro dubbia di incorporare un linguaggio di scripting in un altro linguaggio di scripting.

  3. Implementare un linguaggio di scripting personalizzato con l'interprete Ruby. Ho sperimentato con Treetop e non dovrebbe essere troppo difficile fare una semplice grammatica che sarebbe sufficiente per gli script.

    Pro: Non è necessario incorporare un'altra lingua. Solo le funzionalità che ho implementato in modo specifico saranno disponibili per gli script.

    Contro: Overkill. Sindrome "non costruita qui". Probabilmente orrendo nido di insetti in attesa di accadere.

  4. Implementare i file di dati interamente in Ruby, utilizzando un linguaggio specifico del dominio.

    Pro: Semplice e facile.

    Contro: Nessun dato creato dall'utente è affidabile.

Sono aperto anche ad altri suggerimenti non presenti in quella lista a cui non avrei pensato. Qual è la soluzione migliore per implementare in modo sicuro gli script incorporati nei file di dati?

Edit 2011 年 12 月 23 日: Aggiunta quarta opzione con DSL, ha aggiunto "addendum" in alto con l'aggiunta di pensieri/contesto.

+0

Hmm, non ho molta familiarità con lo scripting di giochi, ma perché non utilizzare V8 e Javascript? È veloce e la maggior parte di tutti sarà a suo agio a lavorare con JS. – omninonsense

+0

Buone vacanze, a tutti! –

+1

Dipende davvero da cosa si vuole ottenere, se i plugin sono in ruby ​​sarà difficile impedire a uno di loro di riaprire una classe principale e fare tutto ciò che vogliono nello stesso modo in cui un plugin ruby ​​on rails può fare tutto ciò che vuole . A prescindere dal fatto che l'uso di qualsiasi altra lingua come lingua per i plug-in è eccessivo, farai più lavoro rispetto al gioco stesso;) – Schmurfy

risposta

4

È possibile utilizzare Shikashi gem, che consente di creare sandbox e definire una whitelist di chiamate di metodo consentite su singoli oggetti.

+0

Shikashi sembra molto interessante, più in linea con le mie intenzioni originali qui. Qualcuno (qualcuno) ha qualche esperienza, storie di guerra, suggerimenti o commenti generali su di esso? –

+0

Selezionato come risposta perché risponde meglio alla domanda che avevo originariamente in mente. –

+0

La gemma Shikashi funziona con Rails 5 beta ruby ​​2.3?Non sta installando per me. – abrocks

1

Considerare l'utilizzo di jRuby anziché Ruby. Java è stato originariamente implementato per supportare il codice mobile (nei giorni in cui è stato impostato il set-top) e ha un collaudato codice security model/implementation che potrebbe, sospetto, avvolgere abbastanza jRuby per impedire agli script/classi utente di creare scompiglio con il resto del sistema di gioco . jRuby supporta anche embedding, che può aiutare a separare il nucleo del gioco dalle applicazioni utente, anche se non so quanto sia robusto in questo momento.

E, naturalmente, jRuby è Ruby!

+0

Buona idea con jruby. Ma i test che ho fatto con jruby e jsr 223 non hanno molto successo (passaggio variabile). Spero che questo cambi in futuro. – plang

+0

Fatta eccezione per il fatto (e mi rendo conto di avere il beneficio di altri 2 anni di ritardo nella tempistica o nel mio commento), Java si è rivelato essere pieno di buchi nella sicurezza della sandbox. Naturalmente questo non è davvero un problema Java - la sicurezza del codice in esecuzione sulla propria macchina è un incubo di fiducia, perché alla fine si riduce alla fiducia degli altri programmatori. Affidarsi alla sandbox perché è pubblicizzato come sandbox è forse meglio che non diffidare di nessuno, ma è ancora fiducia. – jefflunt

Problemi correlati