Add Lua reserved name checking and exception hooks

This commit is contained in:
ScottNZ
2013-12-06 03:23:54 +13:00
parent c39bd53e2a
commit 452a0c0e25
2 changed files with 29 additions and 7 deletions

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using NLua; using NLua;
using NLua.Event;
using OpenRA.FileFormats; using OpenRA.FileFormats;
namespace OpenRA.Mods.RA.Scripting namespace OpenRA.Mods.RA.Scripting
@@ -26,6 +27,7 @@ namespace OpenRA.Mods.RA.Scripting
{ {
Log.Write("debug", "Creating Lua script context"); Log.Write("debug", "Creating Lua script context");
Lua = new Lua(); Lua = new Lua();
Lua.HookException += OnLuaException;
functionCache = new Cache<string, LuaFunction>(Lua.GetFunction); functionCache = new Cache<string, LuaFunction>(Lua.GetFunction);
} }
@@ -79,11 +81,21 @@ namespace OpenRA.Mods.RA.Scripting
} }
} }
void LogException(Exception e) void OnLuaException(object sender, HookExceptionEventArgs e)
{ {
Game.Debug("{0}", e.Message); ShowException(e.Exception);
}
void ShowException(Exception e)
{
ShowErrorMessage(e.Message, e.ToString());
}
public void ShowErrorMessage(string shortMessage, string longMessage)
{
Game.Debug("{0}", shortMessage);
Game.Debug("See debug.log for details"); Game.Debug("See debug.log for details");
Log.Write("debug", "{0}", e); Log.Write("debug", "{0}", longMessage ?? shortMessage);
} }
public void LoadLuaScripts(Func<string, string> getFileContents, params string[] files) public void LoadLuaScripts(Func<string, string> getFileContents, params string[] files)
@@ -98,7 +110,7 @@ namespace OpenRA.Mods.RA.Scripting
} }
catch (Exception e) catch (Exception e)
{ {
LogException(e); ShowException(e);
} }
} }
} }
@@ -114,7 +126,7 @@ namespace OpenRA.Mods.RA.Scripting
} }
catch (Exception e) catch (Exception e)
{ {
LogException(e); ShowException(e);
return null; return null;
} }
} }

View File

@@ -43,7 +43,7 @@ namespace OpenRA.Mods.RA.Scripting
public void WorldLoaded(World w, WorldRenderer wr) public void WorldLoaded(World w, WorldRenderer wr)
{ {
world = w; world = w;
AddMapActorGlobals();
context.Lua["World"] = w; context.Lua["World"] = w;
context.Lua["WorldRenderer"] = wr; context.Lua["WorldRenderer"] = wr;
context.RegisterObject(this, "Internal", false); context.RegisterObject(this, "Internal", false);
@@ -55,17 +55,27 @@ namespace OpenRA.Mods.RA.Scripting
context.RegisterType(typeof(WRange), "WRange", true); context.RegisterType(typeof(WRange), "WRange", true);
context.RegisterType(typeof(int2), "int2", true); context.RegisterType(typeof(int2), "int2", true);
context.RegisterType(typeof(float2), "float2", true); context.RegisterType(typeof(float2), "float2", true);
var sharedScripts = Game.modData.Manifest.LuaScripts ?? new string[0]; var sharedScripts = Game.modData.Manifest.LuaScripts ?? new string[0];
if (sharedScripts.Any()) if (sharedScripts.Any())
context.LoadLuaScripts(f => FileSystem.Open(f).ReadAllText(), sharedScripts); context.LoadLuaScripts(f => FileSystem.Open(f).ReadAllText(), sharedScripts);
AddMapActorGlobals();
context.LoadLuaScripts(f => w.Map.Container.GetContent(f).ReadAllText(), info.LuaScripts); context.LoadLuaScripts(f => w.Map.Container.GetContent(f).ReadAllText(), info.LuaScripts);
context.InvokeLuaFunction("WorldLoaded"); context.InvokeLuaFunction("WorldLoaded");
} }
void AddMapActorGlobals() void AddMapActorGlobals()
{ {
foreach (var kv in world.WorldActor.Trait<SpawnMapActors>().Actors) foreach (var kv in world.WorldActor.Trait<SpawnMapActors>().Actors)
context.Lua[kv.Key] = kv.Value; {
if (context.Lua[kv.Key] != null)
context.ShowErrorMessage("{0}: The global name '{1}' is reserved and may not be used by map actor {2}".F(GetType().Name, kv.Key, kv.Value), null);
else
context.Lua[kv.Key] = kv.Value;
}
} }
public void Tick(Actor self) public void Tick(Actor self)