mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 15:42:35 +00:00
Initial work on Scripting sandbox, no longer Entity's responsibility.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
origin = self.position
|
origin = entity.position
|
||||||
|
|
||||||
on.entity_moved do |event|
|
on.entity_moved do |event|
|
||||||
if origin.distance3d(event.entity.position) <= 3.0
|
if origin.distance3d(event.entity.position) <= 3.0
|
||||||
self.position = origin + Vector.up * 2.4
|
entity.position = origin + Vector.up * 2.4
|
||||||
else
|
else
|
||||||
self.position = origin
|
entity.position = origin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -56,7 +56,6 @@ require_relative "lib/ui/menus/main_menu"
|
|||||||
require_relative "lib/states/game_states/game"
|
require_relative "lib/states/game_states/game"
|
||||||
require_relative "lib/states/game_states/loading_state"
|
require_relative "lib/states/game_states/loading_state"
|
||||||
|
|
||||||
require_relative "lib/scripting"
|
|
||||||
require_relative "lib/subscription"
|
require_relative "lib/subscription"
|
||||||
require_relative "lib/publisher"
|
require_relative "lib/publisher"
|
||||||
require_relative "lib/event"
|
require_relative "lib/event"
|
||||||
@@ -65,6 +64,10 @@ require_relative "lib/event_handlers/input"
|
|||||||
require_relative "lib/event_handlers/entity_moved"
|
require_relative "lib/event_handlers/entity_moved"
|
||||||
require_relative "lib/event_handlers/entity_lifecycle"
|
require_relative "lib/event_handlers/entity_lifecycle"
|
||||||
|
|
||||||
|
require_relative "lib/scripting"
|
||||||
|
require_relative "lib/scripting/sandbox"
|
||||||
|
require_relative "lib/scripting/whitelist"
|
||||||
|
|
||||||
require_relative "lib/component"
|
require_relative "lib/component"
|
||||||
require_relative "lib/components/building"
|
require_relative "lib/components/building"
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ class IMICFPS
|
|||||||
# A game object is any renderable thing
|
# A game object is any renderable thing
|
||||||
class Entity
|
class Entity
|
||||||
include CommonMethods
|
include CommonMethods
|
||||||
include Scripting
|
|
||||||
|
|
||||||
attr_accessor :scale, :visible, :renderable, :backface_culling
|
attr_accessor :scale, :visible, :renderable, :backface_culling
|
||||||
attr_accessor :position, :orientation, :velocity
|
attr_accessor :position, :orientation, :velocity
|
||||||
@@ -38,6 +37,7 @@ class IMICFPS
|
|||||||
|
|
||||||
@last_position = Vector.new(@position.x, @position.y, @position.z)
|
@last_position = Vector.new(@position.x, @position.y, @position.z)
|
||||||
|
|
||||||
|
@sandboxes = []
|
||||||
load_scripts
|
load_scripts
|
||||||
|
|
||||||
setup
|
setup
|
||||||
@@ -56,15 +56,7 @@ class IMICFPS
|
|||||||
|
|
||||||
def load_scripts
|
def load_scripts
|
||||||
@manifest.scripts.each do |script|
|
@manifest.scripts.each do |script|
|
||||||
instance_eval(script.source)
|
@sandboxes << Scripting::SandBox.new(entity: self, script: script)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def method_missing(method, *args, &block)
|
|
||||||
unless component = Component.get(method)
|
|
||||||
raise NoMemoryError, "undefined method '#{method}' for #<#{self.class}:#{self.object_id}>"
|
|
||||||
else
|
|
||||||
return component
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
module Scripting
|
module Scripting
|
||||||
def on
|
def on
|
||||||
Subscription.new(self)
|
# self is a Scripting::SandBox
|
||||||
|
Subscription.new(self.entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
def component(name)
|
def component(name)
|
||||||
|
|||||||
25
lib/scripting/sandbox.rb
Normal file
25
lib/scripting/sandbox.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class IMICFPS
|
||||||
|
module Scripting
|
||||||
|
class SandBox
|
||||||
|
include Scripting
|
||||||
|
def initialize(entity:, script:)
|
||||||
|
@entity = entity
|
||||||
|
@script = script.name
|
||||||
|
|
||||||
|
execute(script.source) if source_safe?(script.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_safe?(source)
|
||||||
|
true # TODO: implement whitelisting/safety checks
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(source)
|
||||||
|
instance_eval(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
def entity
|
||||||
|
@entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
59
lib/scripting/whitelist.rb
Normal file
59
lib/scripting/whitelist.rb
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
class IMICFPS
|
||||||
|
module Scripting
|
||||||
|
CONSTANTS_WHITELIST = [
|
||||||
|
# Basic types
|
||||||
|
Array, Hash, String, Math, Time, Struct, Integer, Float, Numeric, Range, Proc,
|
||||||
|
# Ruby information
|
||||||
|
RUBY_VERSION, RUBY_ENGINE,
|
||||||
|
# Local
|
||||||
|
Vector, BoundingBox, Ray,
|
||||||
|
]
|
||||||
|
|
||||||
|
METHOD_WHITELIST = [
|
||||||
|
Subscription.subscribable_events,
|
||||||
|
:|, :<, :<<, :>, :>>, :<=, :>=, :<=>, :==, :===, :=~, :[], :[]=,
|
||||||
|
# Maths
|
||||||
|
:+, :%, :*, :/, :-, :&, :**,
|
||||||
|
:acos, :acosh, :asin, :asinh, :atan, :atan2, :atanh, :cbrt, :cos, :cosh,
|
||||||
|
:erf, :erfc, :exp, :frexp, :gamma, :hypot, :ldexp, :lgamma, :log, :log10, :log2,
|
||||||
|
:sin, :sinh, :sqrt, :tan, :tanh,
|
||||||
|
# Keywords
|
||||||
|
:do, :if, :else, :elsif, :case, :when, :and, :or,
|
||||||
|
# Object
|
||||||
|
:new, :class, :name, :clone, :dup,
|
||||||
|
# Proc
|
||||||
|
:call,
|
||||||
|
# Time
|
||||||
|
:at, :now, :utc, :gm, :local, :mktime,
|
||||||
|
# Printing
|
||||||
|
:inspect, :puts, :print, :console, :stdin,
|
||||||
|
# Querying
|
||||||
|
:between?, :block_given?, :is_a?, :kind_of?, :instance_of?, :empty?, :respond_to?, :equal?,
|
||||||
|
# String
|
||||||
|
:ascii_only?, :b, :bytes, :bytesize, :byteslice, :capitalize, :capitalize!, :casecmp, :casecmp?, :center, :chars,
|
||||||
|
:chomp, :chomp!, :chop, :chop!, :chr, :clear, :codepoints, :concat, :count, :crypt, :delete, :delete!, :delete_prefix,
|
||||||
|
:delete_prefix!, :delete_suffix, :delete_suffix!, :downcase, :downcase!, :dump, :each_byte, :each_char, :each_codepoint,
|
||||||
|
:each_grapheme_cluster, :each_line, :empty?, :encode, :encode!, :encoding, :end_with?, :eql?, :force_encoding, :freeze, :getbyte,
|
||||||
|
:grapheme_clusters, :gsub, :gsub!, :hash, :hex, :include?, :index, :insert, :inspect, :intern, :length, :lines, :ljust, :lstrip,
|
||||||
|
:lstrip!, :match, :match?, :next, :next!, :oct, :ord, :partition, :prepend, :replace, :reverse, :reverse!, :rindex, :rjust, :rpartition,
|
||||||
|
:rstrip, :rstrip!, :scan, :scrub, :scrub!, :setbyte, :size, :slice, :slice!, :split, :squeeze, :squeeze!, :start_with?, :strip, :strip!,
|
||||||
|
:sub, :sub!, :succ, :succ!, :sum, :swapcase, :swapcase!, :tr, :tr!, :tr_s, :tr_s!, :undump, :unicode_normalize, :unicode_normalize!,
|
||||||
|
:unicode_normalized?, :unpack, :unpack1, :upcase, :upcase!, :upto, :valid_encoding?,
|
||||||
|
# Array/Hash/Enumerable
|
||||||
|
:all?, :any?, :append, :assoc, :at, :bsearch, :bsearch_index, :chain, :chunk, :chunk_while, :clear, :collect, :collect!, :collect_concat,
|
||||||
|
:combination, :compact, :compact!, :compare_by_identity, :compare_by_identity?, :concat, :count, :cycle, :default, :default=, :default_proc,
|
||||||
|
:default_proc=, :delete, :delete_at, :delete_if, :detect, :difference, :dig, :drop, :drop_while, :each, :each_cons, :each_entry, :each_index,
|
||||||
|
:each_key, :each_pair, :each_slice, :each_value, :each_with_index, :each_with_object, :empty?, :entries, :eql?, :fetch, :fetch_values, :fill,
|
||||||
|
:filter, :filter!, :find, :find_all, :find_index, :first, :flat_map, :flatten, :flatten!, :grep, :grep_v, :group_by, :has_key?, :has_value?,
|
||||||
|
:hash, :include?, :index, :inject, :insert, :inspect, :invert, :join, :keep_if, :key, :key?, :keys, :last, :lazy, :length, :map, :map!,
|
||||||
|
:max, :max_by, :member?, :merge, :merge!, :min, :min_by, :minmax, :minmax_by, :none?, :one?, :pack, :partition, :permutation, :pop, :prepend,
|
||||||
|
:product, :push, :rassoc, :reduce, :rehash, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!,
|
||||||
|
:reverse_each, :rindex, :rotate, :rotate!, :sample, :select, :select!, :shift, :shuffle, :shuffle!, :size, :slice, :slice!, :slice_after, :slice_before,
|
||||||
|
:slice_when, :sort, :sort!, :sort_by, :sort_by!, :store, :sum, :take, :take_while, :to_a, :to_ary, :to_h, :to_hash, :to_proc, :to_s, :to_set,
|
||||||
|
:transform_keys, :transform_keys!, :transform_values, :transform_values!, :transpose, :union, :uniq, :uniq!, :unshift, :update, :value?, :values,
|
||||||
|
:values_at, :zip,
|
||||||
|
# Casting
|
||||||
|
:to_c, :to_f, :to_i, :to_r, :to_str, :to_ary, :to_h, :to_hash, :to_proc, :to_a, :to_s, :to_sym,
|
||||||
|
].flatten
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,7 +10,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(event, *args, &block)
|
def method_missing(event, *args, &block)
|
||||||
return unless subscribable_events.include?(event)
|
return unless Subscription.subscribable_events.include?(event)
|
||||||
|
|
||||||
@event, @args, @block = event, args, block
|
@event, @args, @block = event, args, block
|
||||||
Publisher.subscribe(self)
|
Publisher.subscribe(self)
|
||||||
@@ -22,7 +22,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private def subscribable_events
|
def self.subscribable_events
|
||||||
[
|
[
|
||||||
:tick,
|
:tick,
|
||||||
:create, :move, :destroy,
|
:create, :move, :destroy,
|
||||||
|
|||||||
Reference in New Issue
Block a user