コード例 #1
0
        public ScriptContext(World world, WorldRenderer worldRenderer, IEnumerable <string> scripts)
        {
            LuaRuntime.LoadAndroidAsset += (string filename) =>
            {
                using (StreamReader sr = new StreamReader(Android.App.Application.Context.Assets.Open(Platform.ResolvePath(".", "lua", filename))))
                {
                    var luaContent = sr.ReadToEnd();
                    if (!string.IsNullOrEmpty(luaContent))
                    {
                        runtime.LoadBuffer(luaContent, filename);
                    }
                }
            };
            runtime = new MemoryConstrainedLuaRuntime();

            this.World         = world;
            this.WorldRenderer = worldRenderer;

            knownActorCommands = WarGame.ModData.ObjectCreator.GetTypesImplementing <ScriptActorProperties>().ToArray();

            ActorCommands = new Cache <ActorInfo, Type[]>(FilterActorCommands);


            var knownPlayerCommands = WarGame.ModData.ObjectCreator.GetTypesImplementing <ScriptPlayerProperties>().ToArray();

            PlayerCommands = FilterCommands(world.Map.Rules.Actors["player"], knownPlayerCommands);

            runtime.Globals["GameDir"] = Platform.SupportDir;

            //var directory = Directory.GetCurrentDirectory();
            //var directory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            //var directory = Android.App.Application.Context.ApplicationContext.PackageResourcePath;
            var    directory = Platform.ResolvePath(".", "lua", "scriptwrapper.lua");
            string content;

            using (StreamReader sr = new StreamReader(Android.App.Application.Context.Assets.Open(Platform.ResolvePath(".", "lua", "scriptwrapper.lua"))))
            {
                content = sr.ReadToEnd();
            }
            //runtime.DoBuffer(File.Open(directory, FileMode.Open, FileAccess.Read).ReadAllText(), "scriptwrapper.lua").Dispose();
            runtime.DoBuffer(content, "scriptwrapper.lua").Dispose();
            tick = (LuaFunction)runtime.Globals["Tick"];

            //Register globals
            using (var fatalError = runtime.CreateFunctionFromDelegate((Action <string>)FatalError))
            {
                runtime.Globals["FatalError"] = fatalError;
            }
            runtime.Globals["MaxUserScriptInstructions"] = MaxUserScriptInstructions;

            using (var registerGlobal = (LuaFunction)runtime.Globals["RegisterSandboxedGlobal"])
            {
                using (var log = runtime.CreateFunctionFromDelegate((Action <string>)LogDebugMessage))
                {
                    registerGlobal.Call("print", log).Dispose();
                }

                //Register global tables
                var bindings = WarGame.ModData.ObjectCreator.GetTypesImplementing <ScriptGlobal>();
                foreach (var bind in bindings)
                {
                    var ctor = bind.GetConstructors(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(c => {
                        var p = c.GetParameters();
                        return(p.Length == 1 && p.First().ParameterType == typeof(ScriptContext));
                    });


                    if (ctor == null)
                    {
                        throw new InvalidOperationException("{0} must define a constructor that takes a ScriptContext context parameter");
                    }

                    var binding = (ScriptGlobal)ctor.Invoke(new[] { this });
                    using (var obj = binding.ToLuaValue(this))
                        registerGlobal.Call(binding.Name, obj).Dispose();
                }
            }

            //System functions do not count towards the memory limit
            //系统函数不计入内存限制
            runtime.MaxMemoryUse = runtime.MemoryUse + MaxUserScriptMemory;
            using (var loadScript = (LuaFunction)runtime.Globals["ExecuteSandboxedScript"])
            {
                foreach (var s in scripts)
                {
                    loadScript.Call(s, world.Map.Open(s).ReadAllText()).Dispose();
                }
            }
        }