如何使用MoonSharp加载Lua表格?

在研究了各种Lua解释器后,发现只有一个真正纯C#的 - MoonSharp。LuaInterpreter(从2009年不再使用)后来成为了NLua,依赖于两个其他C#库KeraLua或另一个库,并且需要定制的lua52.dll(无法使用来自lua.org的那个)。他们有一个已关闭的错误报告,说看一下读取文件的下载位置等等,但是它不存在。你被迫从各种来源下载这些库,并祈祷它们可以一起工作,并且由于某些lua52.dll版本的多文件发行,可能会/可能会导致与其他程序有兼容性问题(假设他们不仅仅使用你的程序)。

NLua中的一个闪光点是它的明显受欢迎程度,然而该项目在几年内没有得到重大更新。 MoonSharp另一方面似乎完全是自包含的,但是在像加载使用lua构建的表并对其进行操作这样的常见任务方面缺乏文档。

我根据他们在Git上提供的示例代码以及在moonsharp.org上复制的代码(先写哪个我不确定,但只有一个示例是不够的)编写了以下代码:

using System;
using System.IO;
using MoonSharp.Interpreter;

class Foo {

       function Bar( string accountName, string warcraftPath ) {
             string datastore = Path.Combine(warcraftPath, "WTF", "Account", accountName, "SavedVariables", "DataStore_Containers.lua";

             DynValue table = Script.RunString( File.ReadAllText( datastore ) );

             Console.WriteLine( table.Table.Keys.Count().ToString() );
       }
}

结果是以下内容(图片中的代码略有不同,因为我在这里调整了复制的代码以使其更加整洁,更容易使用pastebin链接中的表数据重新生成问题):

[![MoonSharp.Interpreter Table Load Lua Failure](https://i.stack.imgur.com/a9zym.png)](https://i.stack.imgur.com/a9zym.png)

我要读取的表格看起来像以下内容(简化后必须粘贴到pastebin中,因为大小超过30,000个字符):

[World of Warcraft - 数据存储_容器Lua表样本数据](http://pastebin.com/z5CLya8h)

我有一些东西已经工作了,它有一点不稳定,但似乎没有办法循环遍历值或显式获取子表/值或值的关键字。

    Script s = new Script(CoreModules.Preset_Complete);

    // hacked by appending ' return DataStore_ContainersDB ' to return the table as DoString seems to only work to run a function expecting a result to be returned.
    DynValue dv = s.DoString(luaTable + "\nreturn DataStore_ContainersDB;");
    Table t = dv.Table;
    foreach(var v in t.Keys)
    {
        Console.WriteLine( v.ToPrintString() );
    }

问题在于似乎没有任何方式让我输入子表结果集或显式访问这些结果,例如t ["global"]t.global

点赞
用户5402940
用户5402940

处理表格中的表格,这是我喜欢的方法。我想出了这个。

Script s = new Script();
s.DoString(luaCode);
Table tableData = s.Globals[rootTableIndex] as Table;

for (int i = 1; i < tableData.Length + 1; i++) {
    Table subTable = tableData.Get(i).Table;

    //在这里处理数据
}

当然,这需要您知道 Global rootTable 的索引。

对于我的使用,我做了以下操作(仍在测试中)

    string luaCode = File.ReadAllText(Path.Combine(weaponDataPath, "rifles.Lua"));

    Script script = new Script();
    script.DoString(luaCode);
    Gun rifle = new Gun();
    Table rifleData = script.Globals["rifles"] as Table;

    for (int i = 1; i < rifleData.Length + 1; i++) {

        Table rifleTable = rifleData.Get(i).Table;

        rifle.Name = rifleTable.Get("Name").String;
        rifle.BaseDamage = (int)rifleTable.Get("BaseDamage").Number;
        rifle.RoundsPerMinute = (int)rifleTable.Get("RoundsPerMinute").Number;
        rifle.MaxAmmoCapacity = (int)rifleTable.Get("MaxAmmoCapacity").Number;
        rifle.Caliber = rifleTable.Get("Caliber").String;
        rifle.WeaponType = "RIFLE";

        RiflePrototypes.Add(rifle.Name, rifle);
    }

这需要对表格和值名称做出一些假设,但如果您将其用于对象成员赋值,我认为您不需要关心表格中不属于对象的元素。用赋值类型.Member = table.Get(member equivalent index).member type。

2017-07-18 06:20:38