Move UserData checks out of Lua
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaSafeUserData
|
||||
{
|
||||
public IUserDataDescriptor this[string index]
|
||||
{
|
||||
get => LuaUserData.Descriptors.GetValueOrDefault(index);
|
||||
}
|
||||
|
||||
private static bool CanBeRegistered(string typeName)
|
||||
{
|
||||
if (typeName.StartsWith("Barotrauma.Lua", StringComparison.Ordinal) ||
|
||||
typeName.StartsWith("Barotrauma.Cs", StringComparison.Ordinal) ||
|
||||
typeName.StartsWith("Barotrauma.LuaCs", StringComparison.Ordinal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeName == "System.Single") { return true; }
|
||||
|
||||
if (typeName.StartsWith("System.Collections", StringComparison.Ordinal))
|
||||
return true;
|
||||
|
||||
if (typeName.StartsWith("Microsoft.Xna", StringComparison.Ordinal))
|
||||
return true;
|
||||
|
||||
if (typeName.StartsWith("Barotrauma.IO", StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
if (typeName.StartsWith("Barotrauma.ToolBox", StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
if (typeName.StartsWith("Barotrauma.SaveUtil", StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
if (typeName.StartsWith("Barotrauma.", StringComparison.Ordinal))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool CanBeReRegistered(string typeName)
|
||||
{
|
||||
if (typeName.StartsWith("Barotrauma.Lua", StringComparison.Ordinal) ||
|
||||
typeName.StartsWith("Barotrauma.Cs", StringComparison.Ordinal) ||
|
||||
typeName.StartsWith("Barotrauma.LuaCs", StringComparison.Ordinal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsAllowed(string typeName)
|
||||
{
|
||||
if (!CanBeReRegistered(typeName) && LuaUserData.IsRegistered(typeName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanBeRegistered(typeName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void CheckAllowed(string typeName)
|
||||
{
|
||||
if (!IsAllowed(typeName))
|
||||
{
|
||||
throw new ScriptRuntimeException($"Type {typeName} can't be registered");
|
||||
}
|
||||
}
|
||||
|
||||
public static Type GetType(string typeName)
|
||||
{
|
||||
CheckAllowed(typeName);
|
||||
|
||||
return LuaUserData.GetType(typeName);
|
||||
}
|
||||
|
||||
public static IUserDataDescriptor RegisterType(string typeName)
|
||||
{
|
||||
CheckAllowed(typeName);
|
||||
|
||||
return LuaUserData.RegisterType(typeName);
|
||||
}
|
||||
|
||||
public static IUserDataDescriptor RegisterTypeBarotrauma(string typeName)
|
||||
{
|
||||
return RegisterType($"Barotrauma.{typeName}");
|
||||
}
|
||||
|
||||
public static void RegisterExtensionType(string typeName)
|
||||
{
|
||||
CheckAllowed(typeName);
|
||||
LuaUserData.RegisterExtensionType(typeName);
|
||||
}
|
||||
|
||||
public static bool IsRegistered(string typeName)
|
||||
{
|
||||
return LuaUserData.IsRegistered(typeName);
|
||||
}
|
||||
|
||||
public static void UnregisterType(string typeName, bool deleteHistory = false)
|
||||
{
|
||||
LuaUserData.UnregisterType(typeName, deleteHistory);
|
||||
}
|
||||
public static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
|
||||
{
|
||||
CheckAllowed(typeName);
|
||||
return LuaUserData.RegisterGenericType(typeName, typeNameArguements);
|
||||
}
|
||||
|
||||
public static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
|
||||
{
|
||||
LuaUserData.UnregisterGenericType(typeName, typeNameArguements);
|
||||
}
|
||||
|
||||
public static bool IsTargetType(object obj, string typeName)
|
||||
{
|
||||
return LuaUserData.IsTargetType(obj, typeName);
|
||||
}
|
||||
|
||||
public static string TypeOf(object obj)
|
||||
{
|
||||
return LuaUserData.TypeOf(obj);
|
||||
}
|
||||
|
||||
public static object CreateStatic(string typeName)
|
||||
{
|
||||
CheckAllowed(typeName);
|
||||
return LuaUserData.CreateStatic(typeName);
|
||||
}
|
||||
|
||||
public static object CreateEnumTable(string typeName)
|
||||
{
|
||||
return LuaUserData.CreateEnumTable(typeName);
|
||||
}
|
||||
|
||||
public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
|
||||
{
|
||||
LuaUserData.MakeFieldAccessible(IUUD, fieldName);
|
||||
}
|
||||
|
||||
public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
|
||||
{
|
||||
LuaUserData.MakeMethodAccessible(IUUD, methodName, parameters);
|
||||
}
|
||||
|
||||
public static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
|
||||
{
|
||||
LuaUserData.MakePropertyAccessible(IUUD, propertyName);
|
||||
}
|
||||
|
||||
public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
|
||||
{
|
||||
LuaUserData.AddMethod(IUUD, methodName, function);
|
||||
}
|
||||
|
||||
public static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
|
||||
{
|
||||
LuaUserData.AddField(IUUD, fieldName, value);
|
||||
}
|
||||
|
||||
public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
|
||||
{
|
||||
LuaUserData.RemoveMember(IUUD, memberName);
|
||||
}
|
||||
|
||||
public static bool HasMember(object obj, string memberName)
|
||||
{
|
||||
return LuaUserData.HasMember(obj, memberName);
|
||||
}
|
||||
|
||||
public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
|
||||
{
|
||||
return LuaUserData.CreateUserDataFromDescriptor(scriptObject, desiredTypeDescriptor);
|
||||
}
|
||||
|
||||
public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
|
||||
{
|
||||
return LuaUserData.CreateUserDataFromType(scriptObject, desiredType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,24 @@
|
||||
using System;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MoonSharp.Interpreter;
|
||||
using MoonSharp.Interpreter.Interop;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class LuaUserData
|
||||
{
|
||||
public static ReadOnlyDictionary<string, IUserDataDescriptor> Descriptors => new ReadOnlyDictionary<string, IUserDataDescriptor>(descriptors);
|
||||
private static ConcurrentDictionary<string, IUserDataDescriptor> descriptors = new ConcurrentDictionary<string, IUserDataDescriptor>();
|
||||
|
||||
public IUserDataDescriptor this[string index]
|
||||
{
|
||||
get => Descriptors.GetValueOrDefault(index);
|
||||
}
|
||||
|
||||
public static Type GetType(string typeName) => LuaCsSetup.GetType(typeName);
|
||||
|
||||
public static IUserDataDescriptor RegisterType(string typeName)
|
||||
@@ -20,7 +30,15 @@ namespace Barotrauma
|
||||
throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
|
||||
}
|
||||
|
||||
return UserData.RegisterType(type);
|
||||
var descriptor = UserData.RegisterType(type);
|
||||
descriptors.TryAdd(typeName, descriptor);
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public static IUserDataDescriptor RegisterTypeBarotrauma(string typeName)
|
||||
{
|
||||
return RegisterType($"Barotrauma.{typeName}");
|
||||
}
|
||||
|
||||
public static void RegisterExtensionType(string typeName)
|
||||
@@ -102,7 +120,9 @@ namespace Barotrauma
|
||||
|
||||
MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
|
||||
MethodInfo generic = method.MakeGenericMethod(type);
|
||||
return generic.Invoke(null, null);
|
||||
var result = generic.Invoke(null, null);
|
||||
AddCallMetaTable(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static object CreateEnumTable(string typeName)
|
||||
@@ -359,5 +379,47 @@ namespace Barotrauma
|
||||
descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
|
||||
return CreateUserDataFromDescriptor(scriptObject, descriptor);
|
||||
}
|
||||
|
||||
public static void AddCallMetaTable(object userdata)
|
||||
{
|
||||
if (userdata == null) { return; }
|
||||
|
||||
// not sure how to implement this in C#
|
||||
var function = GameMain.LuaCs.Lua.LoadString("""
|
||||
local userdata = ...
|
||||
if userdata == nil then
|
||||
error("Attempted to add a call metatable to a nil value.", 2)
|
||||
end
|
||||
|
||||
if not LuaUserData.HasMember(userdata, ".ctor") then
|
||||
return
|
||||
end
|
||||
|
||||
debug.setmetatable(userdata, {
|
||||
__call = function(obj, ...)
|
||||
if userdata == nil then
|
||||
error("userdata was nil.", 2)
|
||||
end
|
||||
|
||||
local success, result = pcall(userdata.__new, ...)
|
||||
|
||||
|
||||
if not success then
|
||||
error(result, 2)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
})
|
||||
""");
|
||||
|
||||
GameMain.LuaCs.Lua.Call(function, userdata);
|
||||
}
|
||||
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
descriptors.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +347,8 @@ namespace Barotrauma
|
||||
DebugServer.Detach(Lua);
|
||||
}
|
||||
|
||||
LuaUserData.Clear();
|
||||
|
||||
Game?.Stop();
|
||||
|
||||
Hook?.Clear();
|
||||
@@ -416,7 +418,7 @@ namespace Barotrauma
|
||||
UserData.RegisterType<LuaCsFile>();
|
||||
UserData.RegisterType<LuaCsNetworking>();
|
||||
UserData.RegisterType<LuaCsSteam>();
|
||||
UserData.RegisterType<LuaUserData>();
|
||||
var uuid = UserData.RegisterType<LuaUserData>();
|
||||
UserData.RegisterType<LuaCsPerformanceCounter>();
|
||||
UserData.RegisterType<IUserDataDescriptor>();
|
||||
|
||||
@@ -433,6 +435,7 @@ namespace Barotrauma
|
||||
|
||||
Lua.Globals["Logger"] = UserData.CreateStatic<LuaCsLogger>();
|
||||
Lua.Globals["LuaUserData"] = UserData.CreateStatic<LuaUserData>();
|
||||
Lua.Globals["LuaUserDataIUUD"] = uuid;
|
||||
Lua.Globals["Game"] = Game;
|
||||
Lua.Globals["Hook"] = Hook;
|
||||
Lua.Globals["ModStore"] = ModStore;
|
||||
|
||||
Reference in New Issue
Block a user