Server LuaCsForBarotrauma
LuaConverters.cs
1 using System;
2 using MoonSharp.Interpreter;
3 using Microsoft.Xna.Framework;
4 using FarseerPhysics.Dynamics;
5 using LuaCsCompatPatchFunc = Barotrauma.LuaCsPatch;
7 using System.Collections.Immutable;
8 
9 namespace Barotrauma
10 {
11  partial class LuaCsSetup
12  {
13  private void RegisterLuaConverters()
14  {
15  RegisterAction<Item>();
16  RegisterAction<Character>();
17  RegisterAction<Character, Character>();
18  RegisterAction<Entity>();
19  RegisterAction<float>();
20  RegisterAction();
21 
22  RegisterFunc<Fixture, Vector2, Vector2, float, float>();
23  RegisterFunc<AIObjective, bool>();
24 
25  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsAction), v => (LuaCsAction)(args =>
26  {
27  if (v.Function.OwnerScript == Lua)
28  {
29  CallLuaFunction(v.Function, args);
30  }
31  }));
32 
33  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsFunc), v => (LuaCsFunc)(args =>
34  {
35  if (v.Function.OwnerScript == Lua)
36  {
37  return CallLuaFunction(v.Function, args);
38  }
39  return default;
40  }));
41 
42  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsCompatPatchFunc), v => (LuaCsCompatPatchFunc)((self, args) =>
43  {
44  if (v.Function.OwnerScript == Lua)
45  {
46  return CallLuaFunction(v.Function, self, args);
47  }
48  return default;
49  }));
50 
51  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(LuaCsPatchFunc), v => (LuaCsPatchFunc)((self, args) =>
52  {
53  if (v.Function.OwnerScript == Lua)
54  {
55  return CallLuaFunction(v.Function, self, args);
56  }
57  return default;
58  }));
59 
60 
61  DynValue Call(object function, params object[] arguments) => CallLuaFunction(function, arguments);
62  void RegisterHandler<T>(Func<Closure, T> converter) => Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(T), v => converter(v.Function));
63 
64  RegisterHandler(f => (Character.OnDeathHandler)((a1, a2) => Call(f, a1, a2)));
65  RegisterHandler(f => (Character.OnAttackedHandler)((a1, a2) => Call(f, a1, a2)));
66 
67 #if CLIENT
68  RegisterAction<Microsoft.Xna.Framework.Graphics.SpriteBatch, GUICustomComponent>();
69  RegisterAction<float, Microsoft.Xna.Framework.Graphics.SpriteBatch>();
70  RegisterAction<Microsoft.Xna.Framework.Graphics.SpriteBatch, float>();
71 
72  {
73  RegisterHandler(f => (GUIComponent.SecondaryButtonDownHandler)(
74  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
75 
76  RegisterHandler(f => (GUIButton.OnClickedHandler)(
77  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
78  RegisterHandler(f => (GUIButton.OnButtonDownHandler)(
79  () => Call(f)?.CastToBool() ?? default));
80  RegisterHandler(f => (GUIButton.OnPressedHandler)(
81  () => Call(f)?.CastToBool() ?? default));
82 
83  RegisterHandler(f => (GUIColorPicker.OnColorSelectedHandler)(
84  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
85 
86  RegisterHandler(f => (GUIDropDown.OnSelectedHandler)(
87  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
88 
89  RegisterHandler(f => (GUIListBox.OnSelectedHandler)(
90  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
91  RegisterHandler(f => (GUIListBox.OnRearrangedHandler)(
92  (a1, a2) => Call(f, a1, a2)));
93  RegisterHandler(f => (GUIListBox.CheckSelectedHandler)(
94  () => Call(f)?.ToObject() ?? default));
95 
96  RegisterHandler(f => (GUINumberInput.OnValueEnteredHandler)(
97  (a1) => Call(f, a1)));
98  RegisterHandler(f => (GUINumberInput.OnValueChangedHandler)(
99  (a1) => Call(f, a1)));
100 
101  RegisterHandler(f => (GUIProgressBar.ProgressGetterHandler)(
102  () => (float)(Call(f)?.CastToNumber() ?? default)));
103 
104  RegisterHandler(f => (GUIRadioButtonGroup.RadioButtonGroupDelegate)(
105  (a1, a2) => Call(f, a1, a2)));
106 
107  RegisterHandler(f => (GUIScrollBar.OnMovedHandler)(
108  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
109  RegisterHandler(f => (GUIScrollBar.ScrollConversion)(
110  (a1, a2) => (float)(Call(f, a1, a2)?.CastToNumber() ?? default)));
111 
112  RegisterHandler(f => (GUITextBlock.TextGetterHandler)(
113  () => Call(f, new object[0])?.CastToString() ?? default));
114 
115  RegisterHandler(f => (GUITextBox.OnEnterHandler)(
116  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
117  RegisterHandler(f => (GUITextBox.OnTextChangedHandler)(
118  (a1, a2) => Call(f, a1, a2)?.CastToBool() ?? default));
119  RegisterHandler(f => (TextBoxEvent)(
120  (a1, a2) => Call(f, a1, a2)));
121 
122  RegisterHandler(f => (GUITickBox.OnSelectedHandler)(
123  (a1) => Call(f, a1)?.CastToBool() ?? default));
124 
125  }
126 #endif
127 
128  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(Pair<JobPrefab, int>), v =>
129  {
130  return new Pair<JobPrefab, int>((JobPrefab)v.Table.Get(1).ToObject(), (int)v.Table.Get(2).CastToNumber());
131  });
132 
133  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion<ulong>((Script script, ulong v) =>
134  {
135  return DynValue.NewString(v.ToString());
136  });
137 
138  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.String, typeof(ulong), v =>
139  {
140  return ulong.Parse(v.String);
141  });
142 
143  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
144  scriptDataType: DataType.UserData,
145  clrDataType: typeof(sbyte),
146  canConvert: luaValue => luaValue.UserData?.Object is LuaSByte,
147  converter: luaValue => luaValue.UserData.Object is LuaSByte v
148  ? (sbyte)v
149  : throw new ScriptRuntimeException("use SByte(value) to pass primitive type 'sbyte' to C#"));
150  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
151  scriptDataType: DataType.UserData,
152  clrDataType: typeof(byte),
153  canConvert: luaValue => luaValue.UserData?.Object is LuaByte,
154  converter: luaValue => luaValue.UserData.Object is LuaByte v
155  ? (byte)v
156  : throw new ScriptRuntimeException("use Byte(value) to pass primitive type 'byte' to C#"));
157  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
158  scriptDataType: DataType.UserData,
159  clrDataType: typeof(short),
160  canConvert: luaValue => luaValue.UserData?.Object is LuaInt16,
161  converter: luaValue => luaValue.UserData.Object is LuaInt16 v
162  ? (short)v
163  : throw new ScriptRuntimeException("use Int16(value) to pass primitive type 'short' to C#"));
164  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
165  scriptDataType: DataType.UserData,
166  clrDataType: typeof(ushort),
167  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt16,
168  converter: luaValue => luaValue.UserData.Object is LuaUInt16 v
169  ? (ushort)v
170  : throw new ScriptRuntimeException("use UInt16(value) to pass primitive type 'ushort' to C#"));
171  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
172  scriptDataType: DataType.UserData,
173  clrDataType: typeof(int),
174  canConvert: luaValue => luaValue.UserData?.Object is LuaInt32,
175  converter: luaValue => luaValue.UserData.Object is LuaInt32 v
176  ? (int)v
177  : throw new ScriptRuntimeException("use Int32(value) to pass primitive type 'int' to C#"));
178  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
179  scriptDataType: DataType.UserData,
180  clrDataType: typeof(uint),
181  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt32,
182  converter: luaValue => luaValue.UserData.Object is LuaUInt32 v
183  ? (uint)v
184  : throw new ScriptRuntimeException("use UInt32(value) to pass primitive type 'uint' to C#"));
185  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
186  scriptDataType: DataType.UserData,
187  clrDataType: typeof(long),
188  canConvert: luaValue => luaValue.UserData?.Object is LuaInt64,
189  converter: luaValue => luaValue.UserData.Object is LuaInt64 v
190  ? (long)v
191  : throw new ScriptRuntimeException("use Int64(value) to pass primitive type 'long' to C#"));
192  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
193  scriptDataType: DataType.UserData,
194  clrDataType: typeof(ulong),
195  canConvert: luaValue => luaValue.UserData?.Object is LuaUInt64,
196  converter: luaValue => luaValue.UserData.Object is LuaUInt64 v
197  ? (ulong)v
198  : throw new ScriptRuntimeException("use UInt64(value) to pass primitive type 'ulong' to C#"));
199  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
200  scriptDataType: DataType.UserData,
201  clrDataType: typeof(float),
202  canConvert: luaValue => luaValue.UserData?.Object is LuaSingle,
203  converter: luaValue => luaValue.UserData.Object is LuaSingle v
204  ? (float)v
205  : throw new ScriptRuntimeException("use Single(value) to pass primitive type 'float' to C#"));
206  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(
207  scriptDataType: DataType.UserData,
208  clrDataType: typeof(double),
209  canConvert: luaValue => luaValue.UserData?.Object is LuaDouble,
210  converter: luaValue => luaValue.UserData.Object is LuaDouble v
211  ? (double)v
212  : throw new ScriptRuntimeException("use Double(value) to pass primitive type 'double' to C#"));
213 
214  RegisterOption<Character>(DataType.UserData);
215  RegisterOption<AccountId>(DataType.UserData);
216  RegisterOption<ContentPackageId>(DataType.UserData);
217  RegisterOption<SteamId>(DataType.UserData);
218  RegisterOption<DateTime>(DataType.UserData);
219  RegisterOption<BannedPlayer>(DataType.UserData);
220  RegisterOption<Address>(DataType.UserData);
221 
222  RegisterOption<int>(DataType.Number);
223 
224  RegisterEither<Address, AccountId>();
225 
226  RegisterImmutableArray<FactionPrefab.HireableCharacter>();
227  }
228 
229  private void RegisterImmutableArray<T>()
230  {
231  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Table, typeof(ImmutableArray<T>), v =>
232  {
233  return v.ToObject<T[]>().ToImmutableArray();
234  });
235  }
236 
237  private void RegisterEither<T1, T2>()
238  {
239  DynValue convertEitherIntoDynValue(Either<T1, T2> either)
240  {
241  if (either.TryGet(out T1 value1))
242  {
243  return UserData.Create(value1);
244  }
245 
246  if (either.TryGet(out T2 value2))
247  {
248  return UserData.Create(value2);
249  }
250 
251  return null;
252  }
253 
254  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(EitherT<T1, T2>), (Script v, object obj) =>
255  {
256  if (obj is EitherT<T1, T2> either)
257  {
258  return convertEitherIntoDynValue(either);
259  }
260 
261  return null;
262  });
263 
264  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(EitherU<T1, T2>), (Script v, object obj) =>
265  {
266  if (obj is EitherU<T1, T2> either)
267  {
268  return convertEitherIntoDynValue(either);
269  }
270 
271  return null;
272  });
273  }
274 
275  private void RegisterOption<T>(DataType dataType)
276  {
277  Script.GlobalOptions.CustomConverters.SetClrToScriptCustomConversion(typeof(Option<T>), (Script v, object obj) =>
278  {
279  if (obj is Option<T> option)
280  {
281  if (option.TryUnwrap(out T outValue))
282  {
283  return UserData.Create(outValue);
284  }
285  }
286 
287  return DynValue.Nil;
288  });
289 
290  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(dataType, typeof(Option<T>), v =>
291  {
292  return Option<T>.Some(v.ToObject<T>());
293  });
294 
295  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Nil, typeof(Option<T>), v =>
296  {
297  return Option<T>.None();
298  });
299  }
300 
301  private void RegisterAction<T>()
302  {
303  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T>), v =>
304  {
305  var function = v.Function;
306  return (Action<T>)(p => CallLuaFunction(function, p));
307  });
308 
309  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action<T>), v =>
310  {
311  var function = v.Function;
312  return (Action<T>)(p => CallLuaFunction(function, p));
313  });
314  }
315 
316  private void RegisterAction<T1, T2>()
317  {
318  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action<T1, T2>), v =>
319  {
320  var function = v.Function;
321  return (Action<T1, T2>)((a1, a2) => CallLuaFunction(function, a1, a2));
322  });
323 
324  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action<T1, T2>), v =>
325  {
326  var function = v.Function;
327  return (Action<T1, T2>)((a1, a2) => CallLuaFunction(function, a1, a2));
328  });
329  }
330 
331  private void RegisterAction()
332  {
333  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Action), v =>
334  {
335  var function = v.Function;
336  return (Action)(() => CallLuaFunction(function));
337  });
338 
339  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Action), v =>
340  {
341  var function = v.Function;
342  return (Action)(() => CallLuaFunction(function));
343  });
344  }
345 
346  private void RegisterFunc<T1>()
347  {
348  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1>), v =>
349  {
350  var function = v.Function;
351  return () => function.Call().ToObject<T1>();
352  });
353 
354  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Func<T1>), v =>
355  {
356  var function = v.Function;
357  return () => function.Call().ToObject<T1>();
358  });
359  }
360 
361  private void RegisterFunc<T1, T2>()
362  {
363  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2>), v =>
364  {
365  var function = v.Function;
366  return (T1 a) => function.Call(a).ToObject<T2>();
367  });
368 
369  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.ClrFunction, typeof(Func<T1, T2>), v =>
370  {
371  var function = v.Function;
372  return (T1 a) => function.Call(a).ToObject<T2>();
373  });
374  }
375 
376  private void RegisterFunc<T1, T2, T3, T4, T5>()
377  {
378  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2, T3, T4, T5>), v =>
379  {
380  var function = v.Function;
381  return (T1 a, T2 b, T3 c, T4 d) => function.Call(a, b, c, d).ToObject<T5>();
382  });
383 
384  Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(DataType.Function, typeof(Func<T1, T2, T3, T4, T5>), v =>
385  {
386  var function = v.Function;
387  return (T1 a, T2 b, T3 c, T4 d) => function.Call(a, b, c, d).ToObject<T5>();
388  });
389  }
390  }
391 }
delegate void OnDeathHandler(Character character, CauseOfDeath causeOfDeath)
delegate void OnAttackedHandler(Character attacker, AttackResult attackResult)
DynValue CallLuaFunction(object function, params object[] args)
Definition: LuaCsSetup.cs:282
delegate void LuaCsAction(params object[] args)
delegate DynValue LuaCsPatchFunc(object instance, LuaCsHook.ParameterTable ptable)
delegate object LuaCsFunc(params object[] args)