Add Lua reserved name checking and exception hooks
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user