Client LuaCsForBarotrauma
LuaUserData.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5 using MoonSharp.Interpreter;
6 using MoonSharp.Interpreter.Interop;
7 
8 namespace Barotrauma
9 {
10  partial class LuaUserData
11  {
12  public static Type GetType(string typeName) => LuaCsSetup.GetType(typeName);
13 
14  public static IUserDataDescriptor RegisterType(string typeName)
15  {
16  Type type = GetType(typeName);
17 
18  if (type == null)
19  {
20  throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
21  }
22 
23  return UserData.RegisterType(type);
24  }
25 
26  public static void RegisterExtensionType(string typeName)
27  {
28  Type type = GetType(typeName);
29 
30  if (type == null)
31  {
32  throw new ScriptRuntimeException($"tried to register a type that doesn't exist: {typeName}.");
33  }
34 
35  UserData.RegisterExtensionType(type);
36  }
37 
38  public static bool IsRegistered(string typeName)
39  {
40  Type type = GetType(typeName);
41 
42  if (type == null)
43  {
44  return false;
45  }
46 
47  return UserData.GetDescriptorForType(type, true) != null;
48  }
49 
50  public static void UnregisterType(string typeName, bool deleteHistory = false)
51  {
52  Type type = GetType(typeName);
53 
54  if (type == null)
55  {
56  throw new ScriptRuntimeException($"tried to unregister a type that doesn't exist: {typeName}.");
57  }
58 
59  UserData.UnregisterType(type, deleteHistory);
60  }
61  public static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
62  {
63  Type type = GetType(typeName);
64  Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
65  Type genericType = type.MakeGenericType(typeArguements);
66  return UserData.RegisterType(genericType);
67  }
68 
69  public static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
70  {
71  Type type = GetType(typeName);
72  Type[] typeArguements = typeNameArguements.Select(x => GetType(x)).ToArray();
73  Type genericType = type.MakeGenericType(typeArguements);
74  UserData.UnregisterType(genericType);
75  }
76 
77  public static bool IsTargetType(object obj, string typeName)
78  {
79  if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
80  Type targetType = GetType(typeName);
81  if (targetType == null) { throw new ScriptRuntimeException("target type not found"); }
82 
83  Type type = obj is Type ? (Type)obj : obj.GetType();
84  return targetType.IsAssignableFrom(type);
85  }
86 
87  public static string TypeOf(object obj)
88  {
89  if (obj == null) { throw new ScriptRuntimeException("userdata is nil"); }
90 
91  return obj.GetType().FullName;
92  }
93 
94  public static object CreateStatic(string typeName)
95  {
96  Type type = GetType(typeName);
97 
98  if (type == null)
99  {
100  throw new ScriptRuntimeException($"tried to create a static userdata of a type that doesn't exist: {typeName}.");
101  }
102 
103  MethodInfo method = typeof(UserData).GetMethod(nameof(UserData.CreateStatic), 1, new Type[0]);
104  MethodInfo generic = method.MakeGenericMethod(type);
105  return generic.Invoke(null, null);
106  }
107 
108  public static object CreateEnumTable(string typeName)
109  {
110  Type type = GetType(typeName);
111 
112  if (type == null)
113  {
114  throw new ScriptRuntimeException($"tried to create an enum table with a type that doesn't exist:: {typeName}.");
115  }
116 
117  Dictionary<string, object> result = new Dictionary<string, object>();
118 
119  foreach (var value in Enum.GetValues(type))
120  {
121  string name = Enum.GetName(type, value);
122 
123  result[name] = value;
124  }
125 
126  return result;
127  }
128 
129  private static FieldInfo FindFieldRecursively(Type type, string fieldName)
130  {
131  var field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
132 
133  if (field == null && type.BaseType != null)
134  {
135  return FindFieldRecursively(type.BaseType, fieldName);
136  }
137 
138  return field;
139  }
140 
141  public static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
142  {
143  if (IUUD == null)
144  {
145  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {fieldName} accessible.");
146  }
147 
148  var descriptor = (StandardUserDataDescriptor)IUUD;
149  FieldInfo field = FindFieldRecursively(IUUD.Type, fieldName);
150 
151  if (field == null)
152  {
153  throw new ScriptRuntimeException($"tried to make field '{fieldName}' accessible, but the field doesn't exist.");
154  }
155 
156  descriptor.RemoveMember(fieldName);
157  descriptor.AddMember(fieldName, new FieldMemberDescriptor(field, InteropAccessMode.Default));
158  }
159 
160  private static MethodInfo FindMethodRecursively(Type type, string methodName, Type[] types = null)
161  {
162  MethodInfo method;
163 
164  if (types == null)
165  {
166  method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
167  }
168  else
169  {
170  method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, types);
171  }
172 
173  if (method == null && type.BaseType != null)
174  {
175  return FindMethodRecursively(type.BaseType, methodName, types);
176  }
177 
178  return method;
179  }
180 
181  public static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters = null)
182  {
183  if (IUUD == null)
184  {
185  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {methodName} accessible.");
186  }
187 
188  Type[] parameterTypes = null;
189 
190 
191  if (parameters != null)
192  {
193  parameterTypes = new Type[parameters.Length];
194 
195  for (int i = 0; i < parameters.Length; i++)
196  {
197  Type type = LuaUserData.GetType(parameters[i]);
198  if (type == null)
199  {
200  throw new ScriptRuntimeException($"invalid parameter type '{parameters[i]}'");
201  }
202  parameterTypes[i] = type;
203  }
204  }
205 
206  var descriptor = (StandardUserDataDescriptor)IUUD;
207 
208  MethodBase method;
209 
210  try
211  {
212  method = FindMethodRecursively(IUUD.Type, methodName, parameterTypes);
213  }
214  catch (AmbiguousMatchException ex)
215  {
216  throw new ScriptRuntimeException("ambiguous method signature.");
217  }
218 
219  if (method == null)
220  {
221  throw new ScriptRuntimeException($"tried to make method '{methodName}' accessible, but the method doesn't exist.");
222  }
223 
224  descriptor.AddMember(methodName, new MethodMemberDescriptor(method, InteropAccessMode.Default));
225  }
226 
227  private static PropertyInfo FindPropertyRecursively(Type type, string propertyName)
228  {
229  var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
230 
231  if (property == null && type.BaseType != null)
232  {
233  return FindPropertyRecursively(type.BaseType, propertyName);
234  }
235 
236  return property;
237  }
238 
239  public static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
240  {
241  if (IUUD == null)
242  {
243  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to make {propertyName} accessible.");
244  }
245 
246  var descriptor = (StandardUserDataDescriptor)IUUD;
247  PropertyInfo property = FindPropertyRecursively(IUUD.Type, propertyName);
248 
249  if (property == null)
250  {
251  throw new ScriptRuntimeException($"tried to make property '{propertyName}' accessible, but the property doesn't exist.");
252  }
253 
254  descriptor.RemoveMember(propertyName);
255  descriptor.AddMember(propertyName, new PropertyMemberDescriptor(property, InteropAccessMode.Default, property.GetGetMethod(true), property.GetSetMethod(true)));
256  }
257 
258  public static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
259  {
260  if (IUUD == null)
261  {
262  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add method {methodName}.");
263  }
264 
265  var descriptor = (StandardUserDataDescriptor)IUUD;
266 
267  descriptor.RemoveMember(methodName);
268  descriptor.AddMember(methodName, new ObjectCallbackMemberDescriptor(methodName, (object arg1, ScriptExecutionContext arg2, CallbackArguments arg3) =>
269  {
270  if (GameMain.LuaCs != null)
271  return GameMain.LuaCs.CallLuaFunction(function, arg3.GetArray());
272  return null;
273  }));
274  }
275 
276  public static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
277  {
278  if (IUUD == null)
279  {
280  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to add field {fieldName}.");
281  }
282 
283  var descriptor = (StandardUserDataDescriptor)IUUD;
284  descriptor.RemoveMember(fieldName);
285  descriptor.AddMember(fieldName, new DynValueMemberDescriptor(fieldName, value));
286  }
287 
288  public static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
289  {
290  if (IUUD == null)
291  {
292  throw new ScriptRuntimeException($"tried to use a UserDataDescriptor that is null to remove the member {memberName}.");
293  }
294 
295  var descriptor = (StandardUserDataDescriptor)IUUD;
296  descriptor.RemoveMember(memberName);
297  }
298 
299  public static bool HasMember(object obj, string memberName)
300  {
301  if (obj == null) { throw new ScriptRuntimeException("object is nil"); }
302 
303  Type type;
304  if (obj is Type)
305  {
306  type = (Type)obj;
307  }
308  else if(obj is IUserDataDescriptor descriptor)
309  {
310  type = descriptor.Type;
311 
312  if (((StandardUserDataDescriptor)descriptor).HasMember(memberName))
313  {
314  return true;
315  }
316  }
317  else
318  {
319  type = obj.GetType();
320  }
321 
322  if (type.GetMember(memberName).Length == 0)
323  {
324  return false;
325  }
326 
327  return true;
328  }
329 
330 
337  public static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
338  {
339  return UserData.Create(scriptObject.ToObject(desiredTypeDescriptor.Type), desiredTypeDescriptor);
340  }
341 
356  public static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
357  {
358  IUserDataDescriptor descriptor = UserData.GetDescriptorForType(desiredType, true);
359  descriptor ??= new StandardUserDataDescriptor(desiredType, InteropAccessMode.Default);
360  return CreateUserDataFromDescriptor(scriptObject, descriptor);
361  }
362  }
363 }
static LuaCsSetup LuaCs
Definition: GameMain.cs:26
static Type GetType(string typeName, bool throwOnError=false, bool ignoreCase=false)
DynValue CallLuaFunction(object function, params object[] args)
static void UnregisterType(string typeName, bool deleteHistory=false)
Definition: LuaUserData.cs:50
static bool IsRegistered(string typeName)
Definition: LuaUserData.cs:38
static void AddField(IUserDataDescriptor IUUD, string fieldName, DynValue value)
Definition: LuaUserData.cs:276
static void UnregisterGenericType(string typeName, params string[] typeNameArguements)
Definition: LuaUserData.cs:69
static void AddMethod(IUserDataDescriptor IUUD, string methodName, object function)
Definition: LuaUserData.cs:258
static Type GetType(string typeName)
static void RegisterExtensionType(string typeName)
Definition: LuaUserData.cs:26
static object CreateEnumTable(string typeName)
Definition: LuaUserData.cs:108
static object CreateStatic(string typeName)
Definition: LuaUserData.cs:94
static bool IsTargetType(object obj, string typeName)
Definition: LuaUserData.cs:77
static void MakePropertyAccessible(IUserDataDescriptor IUUD, string propertyName)
Definition: LuaUserData.cs:239
static DynValue CreateUserDataFromDescriptor(DynValue scriptObject, IUserDataDescriptor desiredTypeDescriptor)
See CreateUserDataFromType.
Definition: LuaUserData.cs:337
static void MakeFieldAccessible(IUserDataDescriptor IUUD, string fieldName)
Definition: LuaUserData.cs:141
static IUserDataDescriptor RegisterType(string typeName)
Definition: LuaUserData.cs:14
static DynValue CreateUserDataFromType(DynValue scriptObject, Type desiredType)
Converts a Lua value to a CLR object of a desired type and wraps it in a userdata....
Definition: LuaUserData.cs:356
static bool HasMember(object obj, string memberName)
Definition: LuaUserData.cs:299
static string TypeOf(object obj)
Definition: LuaUserData.cs:87
static void MakeMethodAccessible(IUserDataDescriptor IUUD, string methodName, string[] parameters=null)
Definition: LuaUserData.cs:181
static void RemoveMember(IUserDataDescriptor IUUD, string memberName)
Definition: LuaUserData.cs:288
static IUserDataDescriptor RegisterGenericType(string typeName, params string[] typeNameArguements)
Definition: LuaUserData.cs:61