public bool SetIndex(Script script, DynValue index, DynValue value, bool isDirectIndexing) { if (index.Type != DataType.String) throw new ScriptRuntimeException("string property was expected"); lock (m_Lock) { switch (value.Type) { case DataType.Void: case DataType.Nil: m_Values.Remove(index.String); return true; case DataType.UserData: // HERE YOU CAN CHOOSE A DIFFERENT POLICY.. AND TRY TO SHARE IF NEEDED. DANGEROUS, THOUGH. throw new ScriptRuntimeException("Cannot share a value of type {0}", value.Type.ToErrorTypeString()); case DataType.ClrFunction: // HERE YOU CAN CHOOSE A DIFFERENT POLICY.. AND TRY TO SHARE IF NEEDED. DANGEROUS, THOUGH. throw new ScriptRuntimeException("Cannot share a value of type {0}", value.Type.ToErrorTypeString()); case DataType.Boolean: case DataType.Number: case DataType.String: m_Values[index.String] = value.Clone(); return true; case DataType.Function: case DataType.Table: case DataType.Tuple: case DataType.Thread: case DataType.TailCallRequest: case DataType.YieldRequest: default: throw new ScriptRuntimeException("Cannot share a value of type {0}", value.Type.ToErrorTypeString()); } } }
private static void DynAssertValue(object reference, DynValue dynValue) { if (reference == (object)DataType.Void) { Assert.AreEqual(DataType.Void, dynValue.Type); } else if (reference == null) { Assert.AreEqual(DataType.Nil, dynValue.Type); } else if (reference is double) { Assert.AreEqual(DataType.Number, dynValue.Type); Assert.AreEqual((double)reference, dynValue.Number); } else if (reference is int) { Assert.AreEqual(DataType.Number, dynValue.Type); Assert.AreEqual((int)reference, dynValue.Number); } else if (reference is string) { Assert.AreEqual(DataType.String, dynValue.Type); Assert.AreEqual((string)reference, dynValue.String); } }
public LiteralExpression(ScriptLoadingContext lcontext, Token t) : base(lcontext) { switch (t.Type) { case TokenType.Number: case TokenType.Number_Hex: case TokenType.Number_HexFloat: m_Value = DynValue.NewNumber(t.GetNumberValue()).AsReadOnly(); break; case TokenType.String: case TokenType.String_Long: m_Value = DynValue.NewString(t.Text).AsReadOnly(); break; case TokenType.True: m_Value = DynValue.True; break; case TokenType.False: m_Value = DynValue.False; break; case TokenType.Nil: m_Value = DynValue.Nil; break; default: throw new InternalErrorException("type mismatch"); } if (m_Value == null) throw new SyntaxErrorException(t, "unknown literal format near '{0}'", t.Text); lcontext.Lexer.Next(); }
private DynValue GetGlobalSymbol(DynValue dynValue, string name) { if (dynValue.Type != DataType.Table) throw new InvalidOperationException(string.Format("_ENV is not a table but a {0}", dynValue.Type)); return dynValue.Table.Get(name); }
public DynValue Call(DynValue function, DynValue[] args) { List<Processor> coroutinesStack = m_Parent != null ? m_Parent.m_CoroutinesStack : this.m_CoroutinesStack; if (coroutinesStack.Count > 0 && coroutinesStack[coroutinesStack.Count - 1] != this) return coroutinesStack[coroutinesStack.Count - 1].Call(function, args); EnterProcessor(); try { var stopwatch = this.m_Script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Execution); m_CanYield = false; try { int entrypoint = PushClrToScriptStackFrame(CallStackItemFlags.CallEntryPoint, function, args); return Processing_Loop(entrypoint); } finally { m_CanYield = true; if (stopwatch != null) stopwatch.Dispose(); } } finally { LeaveProcessor(); } }
private int Internal_InvokeUnaryMetaMethod(DynValue op1, string eventName, int instructionPtr) { DynValue m = null; if (op1.Type == DataType.UserData) { m = op1.UserData.Descriptor.MetaIndex(m_Script, op1.UserData.Object, eventName); } if (m == null) { var op1_MetaTable = GetMetatable(op1); if (op1_MetaTable != null) { var meta1 = op1_MetaTable.RawGet(eventName); if (meta1 != null && meta1.IsNotNil()) m = meta1; } } if (m != null) { m_ValueStack.Push(m); m_ValueStack.Push(op1); return Internal_ExecCall(1, instructionPtr); } return -1; }
private static DynValue SetErrorHandlerStrategy(string funcName, ScriptExecutionContext executionContext, CallbackArguments args, DynValue handlerBeforeUnwind) { var v = args[0]; var a = new DynValue[args.Count - 1]; for (var i = 1; i < args.Count; i++) a[i - 1] = args[i]; if (args[0].Type == DataType.ClrFunction) { try { var ret = args[0].Callback.Invoke(executionContext, a); if (ret.Type == DataType.TailCallRequest) { if (ret.TailCallData.Continuation != null || ret.TailCallData.ErrorHandler != null) throw new ScriptRuntimeException( "the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); return DynValue.NewTailCallReq(new TailCallData { Args = ret.TailCallData.Args, Function = ret.TailCallData.Function, Continuation = new CallbackFunction(pcall_continuation, funcName), ErrorHandler = new CallbackFunction(pcall_onerror, funcName), ErrorHandlerBeforeUnwind = handlerBeforeUnwind }); } if (ret.Type == DataType.YieldRequest) { throw new ScriptRuntimeException( "the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); } return DynValue.NewTupleNested(DynValue.True, ret); } catch (ScriptRuntimeException ex) { executionContext.PerformMessageDecorationBeforeUnwind(handlerBeforeUnwind, ex); return DynValue.NewTupleNested(DynValue.False, DynValue.NewString(ex.DecoratedMessage)); } } if (args[0].Type != DataType.Function) { return DynValue.NewTupleNested(DynValue.False, DynValue.NewString("attempt to " + funcName + " a non-function")); } return DynValue.NewTailCallReq(new TailCallData { Args = a, Function = v, Continuation = new CallbackFunction(pcall_continuation, funcName), ErrorHandler = new CallbackFunction(pcall_onerror, funcName), ErrorHandlerBeforeUnwind = handlerBeforeUnwind }); }
private string PurifyFromNewLines(DynValue Value) { if (Value == null) return ""; return Value.ToString().Replace('\n', ' ').Replace('\r', ' '); }
// pushes all what's required to perform a clr-to-script function call. function can be null if it's already // at vstack top. private int PushClrToScriptStackFrame(CallStackItemFlags flags, DynValue function, DynValue[] args) { if (function == null) function = m_ValueStack.Peek(); else m_ValueStack.Push(function); // func val args = Internal_AdjustTuple(args); for (int i = 0; i < args.Length; i++) m_ValueStack.Push(args[i]); m_ValueStack.Push(DynValue.NewNumber(args.Length)); // func args count m_ExecutionStack.Push(new CallStackItem() { BasePointer = m_ValueStack.Count, Debug_EntryPoint = function.Function.EntryPointByteCodeLocation, ReturnAddress = -1, ClosureScope = function.Function.ClosureContext, CallingSourceRef = SourceRef.GetClrLocation(), Flags = flags }); return function.Function.EntryPointByteCodeLocation; }
public cZipArchiveEntry CreateEntry(string name, DynValue compression) { if (compression.IsNotNil()) return new cZipArchiveEntry(zip.CreateEntry(name, compression.ToObject<CompressionLevel>())); else return new cZipArchiveEntry(zip.CreateEntry(name)); }
public static StringRange FromLuaRange(DynValue start, DynValue end, int? defaultEnd = null) { int i = start.IsNil() ? 1 : (int)start.Number; int j = end.IsNil() ? (defaultEnd ?? i) : (int)end.Number; return new StringRange(i, j); }
private void SetGlobalSymbol(DynValue dynValue, string name, DynValue value) { if (dynValue.Type != DataType.Table) throw new InvalidOperationException(string.Format("_ENV is not a table but a {0}", dynValue.Type)); dynValue.Table.Set(name, value ?? DynValue.Nil); }
/// <summary> /// Creates a ScriptRuntimeException with a predefined error message specifying that /// a concat operation was attempted on non-strings /// </summary> /// <param name="l">The left operand.</param> /// <param name="r">The right operand.</param> /// <returns>The exception to be raised.</returns> /// <exception cref="InternalErrorException">If both are numbers or strings</exception> public static ScriptRuntimeException ConcatOnNonString(DynValue l, DynValue r) { if (l.Type != DataType.Number && l.Type != DataType.String) return new ScriptRuntimeException("attempt to concatenate a {0} value", l.Type.ToLuaTypeString()); if (r != null && r.Type != DataType.Number && r.Type != DataType.String) return new ScriptRuntimeException("attempt to concatenate a {0} value", r.Type.ToLuaTypeString()); throw new InternalErrorException("ConcatOnNonString - both are numbers/strings"); }
public DynValue[] GetTopArray(int num) { DynValue[] rets = new DynValue[num]; for (int i = 0; i < num; i++) rets[num - i - 1] = Top(i); return rets; }
/// <summary> /// Performs an "index" "set" operation. /// </summary> /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="index">The index.</param> /// <param name="value">The value to be set</param> /// <param name="isDirectIndexing">If set to true, it's indexed with a name, if false it's indexed through brackets.</param> /// <returns></returns> public bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool isNameIndex) { foreach (IUserDataDescriptor dd in m_Descriptors) { if (dd.SetIndex(script, obj, index, value, isNameIndex)) return true; } return false; }
public static void StartBrowse(DynValue v) { if (v == null) return; ValueBrowser b = new ValueBrowser(); b.m_ValueStack.Push(v); b.ShowDialog(); }
/// <summary> /// Performs an "index" "set" operation. /// </summary> /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="index">The index.</param> /// <param name="value">The value to be set</param> /// <param name="isDirectIndexing">If set to true, it's indexed with a name, if false it's indexed through brackets.</param> /// <returns></returns> public bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool isDirectIndexing) { IUserDataType u = obj as IUserDataType; if (u != null) return u.SetIndex(script, index, value, isDirectIndexing); return false; }
/// <summary> /// Performs an "index" "get" operation. /// </summary> /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="index">The index.</param> /// <param name="isDirectIndexing">If set to true, it's indexed with a name, if false it's indexed through brackets.</param> /// <returns></returns> public DynValue Index(Script script, object obj, DynValue index, bool isDirectIndexing) { IUserDataType u = obj as IUserDataType; if (u != null) return u.Index(script, index, isDirectIndexing); return null; }
/// <summary> /// Initializes a new instance of the <see cref="DynValueMemberDescriptor"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="value">The value.</param> public DynValueMemberDescriptor(string name, DynValue value) { m_Value = value; Name = name; if (value.Type == DataType.ClrFunction) MemberAccess = MemberDescriptorAccess.CanRead | MemberDescriptorAccess.CanExecute; else MemberAccess = MemberDescriptorAccess.CanRead; }
/// <summary> /// Initializes a new instance of the <see cref="DynValueMemberDescriptor" /> class. /// </summary> /// <param name="name">The name.</param> /// <param name="serializedTableValue">A string containing a table whose first member is the dynvalue to be deserialized (convoluted...).</param> protected DynValueMemberDescriptor(string name, string serializedTableValue) { Script s = new Script(); var exp = s.CreateDynamicExpression(serializedTableValue); DynValue val = exp.Evaluate(null); m_Value = val.Table.Get(1); Name = name; MemberAccess = MemberDescriptorAccess.CanRead; }
/// <summary> /// Performs an "index" "get" operation. /// </summary> /// <param name="script">The script originating the request</param> /// <param name="obj">The object (null if a static request is done)</param> /// <param name="index">The index.</param> /// <param name="isDirectIndexing">If set to true, it's indexed with a name, if false it's indexed through brackets.</param> /// <returns></returns> public DynValue Index(Script script, object obj, DynValue index, bool isNameIndex) { foreach (IUserDataDescriptor dd in m_Descriptors) { DynValue v = dd.Index(script, obj, index, isNameIndex); if (v != null) return v; } return null; }
private static DynValue MakeReturnTuple(bool retstatus, CallbackArguments args) { DynValue[] rets = new DynValue[args.Count + 1]; for (int i = 0; i < args.Count; i++) rets[i + 1] = args[i]; rets[0] = DynValue.NewBoolean(retstatus); return DynValue.NewTuple(rets); }
/// <summary> /// Creates a ScriptRuntimeException with a predefined error message specifying that /// an arithmetic operation was attempted on non-numbers /// </summary> /// <param name="l">The left operand.</param> /// <param name="r">The right operand (or null).</param> /// <returns>The exception to be raised.</returns> /// <exception cref="InternalErrorException">If both are numbers</exception> public static ScriptRuntimeException ArithmeticOnNonNumber(DynValue l, DynValue r = null) { if (l.Type != DataType.Number && l.Type != DataType.String) return new ScriptRuntimeException("attempt to perform arithmetic on a {0} value", l.Type.ToLuaTypeString()); else if (r != null && r.Type != DataType.Number && r.Type != DataType.String) return new ScriptRuntimeException("attempt to perform arithmetic on a {0} value", r.Type.ToLuaTypeString()); else if (l.Type == DataType.String || (r != null && r.Type == DataType.String)) return new ScriptRuntimeException("attempt to perform arithmetic on a string value"); else throw new InternalErrorException("ArithmeticOnNonNumber - both are numbers"); }
internal DynValue GetMetamethod(DynValue value, string metamethod) { if (value.Type == DataType.UserData) { DynValue v = value.UserData.Descriptor.MetaIndex(m_Script, value.UserData.Object, metamethod); if (v != null) return v; } return GetMetamethodRaw(value, metamethod); }
public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, DynValue value) { if (value != null) { var otherResource = value.GetAsPrivateResource(); if (otherResource != null) { CheckScriptOwnership(containingResource, otherResource); } } }
internal Table GetMetatable(DynValue value) { if (value.Type == DataType.Table) { return value.Table.MetaTable; } if (value.Type.CanHaveTypeMetatables()) { return m_Script.GetTypeMetatable(value.Type); } return null; }
public DynValue Index(Script script, DynValue index, bool isDirectIndexing) { if (index.Type == DataType.String) { if (index.String == "add") return DynValue.NewCallback((c, a) => m_Parent.AddCallback(m_Object, c, a)); else if (index.String == "remove") return DynValue.NewCallback((c, a) => m_Parent.RemoveCallback(m_Object, c, a)); } throw new ScriptRuntimeException("Events only support add and remove methods"); }
public DynValue Index(Script script, DynValue index, bool isDirectIndexing) { if (index.Type != DataType.String) throw new ScriptRuntimeException("string property was expected"); lock (m_Lock) { if (m_Values.ContainsKey(index.String)) return m_Values[index.String].Clone(); else return DynValue.Nil; } }
internal DynValue GetMetamethodRaw(DynValue value, string metamethod) { var metatable = GetMetatable(value); if (metatable == null) return null; var metameth = metatable.RawGet(metamethod); if (metameth == null || metameth.IsNil()) return null; return metameth; }
private DynValue GetNext(DynValue prev) { if (prev.IsNil()) Reset(); while (m_Enumerator.MoveNext()) { DynValue v = ClrToScriptConversions.ObjectToDynValue(m_Script, m_Enumerator.Current); if (!v.IsNil()) return v; } return DynValue.Nil; }
// Shortcut to `SetSpeechThingPositionAndSide` public void SetTail(string side, DynValue position) { SetSpeechThingPositionAndSide(side, position); }
/// <summary> /// Reads a Lua Table and maps it to a CLR type. /// </summary> /// <typeparam name="T">Type of the CLR object.</typeparam> /// <param name="luaTable">Lua Table containing the data for the object.</param> /// <returns>CLR object of type T.</returns> public static T Read <T>(Table luaTable) { return((T)Convert(DynValue.NewTable(luaTable), typeof(T))); }
private void loadFunctions() { _triggerFunc = Script.Globals.Get(TRIGGER_FUNCTION_NAME); }
public DynValue Index(Script script, DynValue index, bool isNameIndex) { return(DynValue.NewNumber(index.Number * 3)); }
public DynValue Index(Script script, object obj, DynValue index, bool dummy) { return(DynValue.NewNumber(index.Number * 4)); }
public Connection Connect(DynValue value) { m_connected.Add(value); return(new Connection(this, value)); }
public void Push(DynValue v) { m_Stack.Add(v); }
/// <summary> /// Sets the value of this member from a <see cref="DynValue" />. /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object owning this member, or null if static.</param> /// <param name="value">The value to be set.</param> /// <exception cref="System.NotImplementedException"></exception> public void SetValue(Script script, object obj, DynValue value) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); }
/// <summary> /// Gets the value of this member as a <see cref="DynValue" /> to be exposed to scripts. /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object owning this member, or null if static.</param> /// <returns> /// The value of this member as a <see cref="DynValue" />. /// </returns> public DynValue GetValue(Script script, object obj) { return(DynValue.NewCallback(this.GetCallbackFunction(script, obj))); }
public DynValue CreateInstance(object fromObject) { return(DynValue.FromObject(script, fromObject)); }
/// <summary> /// Calculates the score for the overload. /// </summary> /// <param name="context">The context.</param> /// <param name="args">The arguments.</param> /// <param name="method">The method.</param> /// <param name="isExtMethod">if set to <c>true</c>, is an extension method.</param> /// <returns></returns> private int CalcScoreForOverload(ScriptExecutionContext context, CallbackArguments args, IOverloadableMemberDescriptor method, bool isExtMethod) { int totalScore = ScriptToClrConversions.WEIGHT_EXACT_MATCH; int argsBase = args.IsMethodCall ? 1 : 0; int argsCnt = argsBase; bool varArgsUsed = false; for (int i = 0; i < method.Parameters.Length; i++) { if (isExtMethod && i == 0) { continue; } if (method.Parameters[i].IsOut) { continue; } Type parameterType = method.Parameters[i].Type; if ((parameterType == typeof(Script)) || (parameterType == typeof(ScriptExecutionContext)) || (parameterType == typeof(CallbackArguments))) { continue; } if (i == method.Parameters.Length - 1 && method.VarArgsArrayType != null) { int varargCnt = 0; DynValue firstArg = null; int scoreBeforeVargars = totalScore; // update score for varargs while (true) { var arg = args.RawGet(argsCnt, false); if (arg == null) { break; } if (firstArg == null) { firstArg = arg; } argsCnt += 1; varargCnt += 1; int score = CalcScoreForSingleArgument(method.Parameters[i], method.VarArgsElementType, arg, isOptional: false); totalScore = Math.Min(totalScore, score); } // check if exact-match if (varargCnt == 1) { if (firstArg.Type == DataType.UserData && firstArg.UserData.Object != null) { if (method.VarArgsArrayType.IsAssignableFrom(firstArg.UserData.Object.GetType())) { totalScore = scoreBeforeVargars; continue; } } } // apply varargs penalty to score if (varargCnt == 0) { totalScore = Math.Min(totalScore, ScriptToClrConversions.WEIGHT_VARARGS_EMPTY); } varArgsUsed = true; } else { var arg = args.RawGet(argsCnt, false) ?? DynValue.Void; int score = CalcScoreForSingleArgument(method.Parameters[i], parameterType, arg, method.Parameters[i].HasDefaultValue); totalScore = Math.Min(totalScore, score); argsCnt += 1; } } if (totalScore > 0) { if ((args.Count - argsBase) <= method.Parameters.Length) { totalScore += ScriptToClrConversions.WEIGHT_NO_EXTRA_PARAMS_BONUS; totalScore *= 1000; } else if (varArgsUsed) { totalScore -= ScriptToClrConversions.WEIGHT_VARARGS_MALUS; totalScore *= 1000; } else { totalScore *= 1000; totalScore -= ScriptToClrConversions.WEIGHT_EXTRA_PARAMS_MALUS * ((args.Count - argsBase) - method.Parameters.Length); totalScore = Math.Max(1, totalScore); } } #if DEBUG_OVERLOAD_RESOLVER System.Diagnostics.Debug.WriteLine(string.Format("[OVERLOAD] : Score {0} for method {1}", totalScore, method.SortDiscriminant)); #endif return(totalScore); }
private static DynValue SetErrorHandlerStrategy(string funcName, ScriptExecutionContext executionContext, CallbackArguments args, DynValue handlerBeforeUnwind) { DynValue v = args[0]; DynValue[] a = new DynValue[args.Count - 1]; for (int i = 1; i < args.Count; i++) { a[i - 1] = args[i]; } if (args[0].Type == DataType.ClrFunction) { try { DynValue ret = args[0].Callback.Invoke(executionContext, a); if (ret.Type == DataType.TailCallRequest) { if (ret.TailCallData.Continuation != null || ret.TailCallData.ErrorHandler != null) { throw new ScriptRuntimeException("the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); } return(DynValue.NewTailCallReq(new TailCallData() { Args = ret.TailCallData.Args, Function = ret.TailCallData.Function, Continuation = new CallbackFunction(pcall_continuation, funcName), ErrorHandler = new CallbackFunction(pcall_onerror, funcName), ErrorHandlerBeforeUnwind = handlerBeforeUnwind })); } else if (ret.Type == DataType.YieldRequest) { throw new ScriptRuntimeException("the function passed to {0} cannot be called directly by {0}. wrap in a script function instead.", funcName); } else { return(DynValue.NewTupleNested(DynValue.True, ret)); } } catch (ScriptRuntimeException ex) { executionContext.PerformMessageDecorationBeforeUnwind(handlerBeforeUnwind, ex); return(DynValue.NewTupleNested(DynValue.False, DynValue.NewString(ex.DecoratedMessage))); } } else if (args[0].Type != DataType.Function) { return(DynValue.NewTupleNested(DynValue.False, DynValue.NewString("attempt to " + funcName + " a non-function"))); } else { return(DynValue.NewTailCallReq(new TailCallData() { Args = a, Function = v, Continuation = new CallbackFunction(pcall_continuation, funcName), ErrorHandler = new CallbackFunction(pcall_onerror, funcName), ErrorHandlerBeforeUnwind = handlerBeforeUnwind })); } }
public void AddEditorButton(string name, DynValue action) { Execute.OnUIThread(() => LuaManager.EditorButtons.Add(new EditorButton(LuaManager, name, action))); }
public static DynValue tonumber(ScriptExecutionContext executionContext, CallbackArguments args) { if (args.Count < 1) { throw ScriptRuntimeException.BadArgumentValueExpected(0, "tonumber"); } DynValue e = args[0]; DynValue b = args.AsType(1, "tonumber", DataType.Number, true); if (b.IsNil()) { if (e.Type == DataType.Number) { return(e); } if (e.Type != DataType.String) { return(DynValue.Nil); } double d; if (double.TryParse(e.String, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) { return(DynValue.NewNumber(d)); } return(DynValue.Nil); } else { //!COMPAT: tonumber supports only 2,8,10 or 16 as base //UPDATE: added support for 3-9 base numbers DynValue ee; if (args[0].Type != DataType.Number) { ee = args.AsType(0, "tonumber", DataType.String, false); } else { ee = DynValue.NewString(args[0].Number.ToString(CultureInfo.InvariantCulture)); }; int bb = (int)b.Number; uint uiv = 0; if (bb == 2 || bb == 8 || bb == 10 || bb == 16) { uiv = Convert.ToUInt32(ee.String.Trim(), bb); } else if (bb < 10 && bb > 2) // Support for 3, 4, 5, 6, 7 and 9 based numbers { foreach (char digit in ee.String.Trim()) { int value = digit - 48; if (value < 0 || value >= bb) { throw new ScriptRuntimeException("bad argument #1 to 'tonumber' (invalid character)"); } uiv = (uint)(uiv * bb) + (uint)value; } } else { throw new ScriptRuntimeException("bad argument #2 to 'tonumber' (base out of range)"); } return(DynValue.NewNumber(uiv)); } }
public bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool dummy) { throw new NotImplementedException(); }
public static DynValue frexp(ScriptExecutionContext executionContext, CallbackArguments args) { // http://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c-sharp DynValue arg = args.AsType(0, "frexp", DataType.Number, false); double d = arg.Number; // Translate the double into sign, exponent and mantissa. long bits = BitConverter.DoubleToInt64Bits(d); // Note that the shift is sign-extended, hence the test against -1 not 1 bool negative = (bits < 0); int exponent = (int)((bits >> 52) & 0x7ffL); long mantissa = bits & 0xfffffffffffffL; // Subnormal numbers; exponent is effectively one higher, // but there's no extra normalisation bit in the mantissa if (exponent == 0) { exponent++; } // Normal numbers; leave exponent as it is but add extra // bit to the front of the mantissa else { mantissa = mantissa | (1L << 52); } // Bias the exponent. It's actually biased by 1023, but we're // treating the mantissa as m.0 rather than 0.m, so we need // to subtract another 52 from it. exponent -= 1075; if (mantissa == 0) { return(DynValue.NewTuple(DynValue.NewNumber(0), DynValue.NewNumber(0))); } /* Normalize */ while ((mantissa & 1) == 0) { /* i.e., Mantissa is even */ mantissa >>= 1; exponent++; } double m = (double)mantissa; double e = (double)exponent; while (m >= 1) { m /= 2.0; e += 1.0; } if (negative) { m = -m; } return(DynValue.NewTuple(DynValue.NewNumber(m), DynValue.NewNumber(e))); }
public bool SetIndex(Script script, DynValue index, DynValue value, bool isNameIndex) { throw new NotImplementedException(); }
private static Random GetRandom(Script s) { DynValue rr = s.Registry.Get("F61E3AA7247D4D1EB7A45430B0C8C9BB_MATH_RANDOM"); return((rr.UserData.Object as AnonWrapper <Random>).Value); }
internal static void InspectVariable(DynValue v, List <Variable> variables) { variables.Add(new Variable("(value)", v.ToPrintString())); variables.Add(new Variable("(type)", v.Type.ToLuaDebuggerString())); variables.Add(new Variable("(val #id)", v.ReferenceID.ToString())); switch (v.Type) { case DataType.Tuple: for (int i = 0; i < v.Tuple.Length; i++) { variables.Add(new Variable("[i]", (v.Tuple[i] ?? DynValue.Void).ToDebugPrintString())); } break; case DataType.Function: variables.Add(new Variable("(address)", v.Function.EntryPointByteCodeLocation.ToString("X8"))); variables.Add(new Variable("(upvalues)", v.Function.GetUpvaluesCount().ToString())); variables.Add(new Variable("(upvalues type)", v.Function.GetUpvaluesType().ToString())); break; case DataType.Table: if (v.Table.MetaTable != null && (v.Table.OwnerScript == null)) { variables.Add(new Variable("(table type)", "prime table with metatable")); } else if (v.Table.MetaTable != null) { variables.Add(new Variable("(table type)", "has metatable")); } else if (v.Table.OwnerScript == null) { variables.Add(new Variable("(table type)", "prime table")); } else { variables.Add(new Variable("(table type)", "standard")); } variables.Add(new Variable("(table #id)", v.Table.ReferenceID.ToString())); if (v.Table.MetaTable != null) { variables.Add(new Variable("(metatable #id)", v.Table.MetaTable.ReferenceID.ToString())); } variables.Add(new Variable("(length)", v.Table.Length.ToString())); foreach (TablePair p in v.Table.Pairs) { variables.Add(new Variable("[" + p.Key.ToDebugPrintString() + "]", p.Value.ToDebugPrintString())); } break; case DataType.UserData: if (v.UserData.Descriptor != null) { variables.Add(new Variable("(descriptor)", v.UserData.Descriptor.Name)); variables.Add(new Variable("(native type)", v.UserData.Descriptor.Type.ToString())); } else { variables.Add(new Variable("(descriptor)", "null!")); } variables.Add(new Variable("(native object)", v.UserData.Object != null ? v.UserData.Object.ToString() : "(null)")); break; case DataType.Thread: variables.Add(new Variable("(coroutine state)", v.Coroutine.State.ToString())); variables.Add(new Variable("(coroutine type)", v.Coroutine.Type.ToString())); variables.Add(new Variable("(auto-yield counter)", v.Coroutine.AutoYieldCounter.ToString())); break; case DataType.ClrFunction: variables.Add(new Variable("(name)", v.Callback.Name ?? "(unnamed)")); break; case DataType.TailCallRequest: case DataType.YieldRequest: case DataType.Nil: case DataType.Void: case DataType.Boolean: case DataType.Number: case DataType.String: default: break; } }
public static DynValue modf(ScriptExecutionContext executionContext, CallbackArguments args) { DynValue arg = args.AsType(0, "modf", DataType.Number, false); return(DynValue.NewTuple(DynValue.NewNumber(Math.Floor(arg.Number)), DynValue.NewNumber(arg.Number - Math.Floor(arg.Number)))); }
/// <summary> /// Reads a Lua variable and maps its contents to a CLR type. /// </summary> /// <typeparam name="T">Type of the CLR object.</typeparam> /// <param name="luaValue">Lua value containing the data for the object.</param> /// <returns>CLR object of type T.</returns> public static T Read <T>(DynValue luaValue) { return((T)Convert(luaValue, typeof(T))); }
public static void AddOnTickListener(DynValue function) { Ticker.OnTick += n => LuaManager.Call(function, DynValue.NewNumber(n)); }
private void loadFunctions() { _startFunc = Script.Globals.Get(START_FUNCTION_NAME); _updateFunc = Script.Globals.Get(UPDATE_FUNCTION_NAME); }
private static void SetRandom(Script s, Random random) { DynValue rr = UserData.Create(new AnonWrapper <Random>(random)); s.Registry.Set("F61E3AA7247D4D1EB7A45430B0C8C9BB_MATH_RANDOM", rr); }
public void ShowBubble(string side = null, DynValue position = null) { bubble = true; containerBubble.SetActive(true); SetSpeechThingPositionAndSide(side, position); }
private static DynValue exec1(CallbackArguments args, string funcName, Func <double, double> func) { DynValue arg = args.AsType(0, funcName, DataType.Number, false); return(DynValue.NewNumber(func(arg.Number))); }
public static void ServerRead(IReadMessage msg, Client c) { c.KickAFKTimer = 0.0f; UInt16 ID = msg.ReadUInt16(); ChatMessageType type = (ChatMessageType)msg.ReadByte(); string txt; Character orderTargetCharacter = null; Entity orderTargetEntity = null; OrderChatMessage orderMsg = null; OrderTarget orderTargetPosition = null; Order.OrderTargetType orderTargetType = Order.OrderTargetType.Entity; int?wallSectionIndex = null; if (type == ChatMessageType.Order) { var orderMessageInfo = OrderChatMessage.ReadOrder(msg); if (orderMessageInfo.OrderIndex < 0 || orderMessageInfo.OrderIndex >= Order.PrefabList.Count) { DebugConsole.ThrowError($"Invalid order message from client \"{c.Name}\" - order index out of bounds ({orderMessageInfo.OrderIndex})."); if (NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID)) { c.LastSentChatMsgID = ID; } return; } orderTargetCharacter = orderMessageInfo.TargetCharacter; orderTargetEntity = orderMessageInfo.TargetEntity; orderTargetPosition = orderMessageInfo.TargetPosition; orderTargetType = orderMessageInfo.TargetType; wallSectionIndex = orderMessageInfo.WallSectionIndex; var orderPrefab = orderMessageInfo.OrderPrefab ?? Order.PrefabList[orderMessageInfo.OrderIndex]; string orderOption = orderMessageInfo.OrderOption ?? (orderMessageInfo.OrderOptionIndex == null || orderMessageInfo.OrderOptionIndex < 0 || orderMessageInfo.OrderOptionIndex >= orderPrefab.Options.Length ? "" : orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value]); orderMsg = new OrderChatMessage(orderPrefab, orderOption, orderMessageInfo.Priority, orderTargetPosition ?? orderTargetEntity as ISpatialEntity, orderTargetCharacter, c.Character) { WallSectionIndex = wallSectionIndex }; txt = orderMsg.Text; } else { txt = msg.ReadString() ?? ""; } if (!NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID)) { return; } c.LastSentChatMsgID = ID; if (txt.Length > MaxLength) { txt = txt.Substring(0, MaxLength); } c.LastSentChatMessages.Add(txt); if (c.LastSentChatMessages.Count > 10) { c.LastSentChatMessages.RemoveRange(0, c.LastSentChatMessages.Count - 10); } float similarity = 0.0f; for (int i = 0; i < c.LastSentChatMessages.Count; i++) { float closeFactor = 1.0f / (c.LastSentChatMessages.Count - i); if (string.IsNullOrEmpty(txt)) { similarity += closeFactor; } else { int levenshteinDist = ToolBox.LevenshteinDistance(txt, c.LastSentChatMessages[i]); similarity += Math.Max((txt.Length - levenshteinDist) / (float)txt.Length * closeFactor, 0.0f); } } //order/report messages can be sent a little faster than normal messages without triggering the spam filter if (orderMsg != null) { similarity *= 0.25f; } bool isOwner = GameMain.Server.OwnerConnection != null && c.Connection == GameMain.Server.OwnerConnection; if (similarity + c.ChatSpamSpeed > 5.0f && !isOwner) { GameMain.Server.KarmaManager.OnSpamFilterTriggered(c); c.ChatSpamCount++; if (c.ChatSpamCount > 3) { //kick for spamming too much GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked")); } else { ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null); c.ChatSpamTimer = 10.0f; GameMain.Server.SendDirectChatMessage(denyMsg, c); } return; } c.ChatSpamSpeed += similarity + 0.5f; if (c.ChatSpamTimer > 0.0f && !isOwner) { ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null); c.ChatSpamTimer = 10.0f; GameMain.Server.SendDirectChatMessage(denyMsg, c); return; } var should = GameMain.Lua.hook.Call("chatMessage", new DynValue[] { DynValue.NewString(txt), UserData.Create(c) }); if (should != null) { if (should.CastToBool()) { return; } else { } } if (type == ChatMessageType.Order) { if (c.Character == null || c.Character.SpeechImpediment >= 100.0f || c.Character.IsDead) { return; } if (orderMsg.Order.IsReport) { HumanAIController.ReportProblem(orderMsg.Sender, orderMsg.Order); } Order order = orderTargetType switch { Order.OrderTargetType.Entity => new Order(orderMsg.Order, orderTargetEntity, orderMsg.Order?.GetTargetItemComponent(orderTargetEntity as Item), orderGiver: orderMsg.Sender), Order.OrderTargetType.Position => new Order(orderMsg.Order, orderTargetPosition, orderGiver: orderMsg.Sender), Order.OrderTargetType.WallSection when orderTargetEntity is Structure s && wallSectionIndex.HasValue => new Order(orderMsg.Order, s, wallSectionIndex, orderGiver: orderMsg.Sender), _ => throw new NotImplementedException() }; if (order != null) { if (order.TargetAllCharacters) { if (order.IsIgnoreOrder) { switch (orderTargetType) { case Order.OrderTargetType.Entity: if (!(orderTargetEntity is IIgnorable ignorableEntity)) { break; } ignorableEntity.OrderedToBeIgnored = order.Identifier == "ignorethis"; break; case Order.OrderTargetType.Position: throw new NotImplementedException(); case Order.OrderTargetType.WallSection: if (!wallSectionIndex.HasValue) { break; } if (!(orderTargetEntity is Structure s)) { break; } if (!(s.GetSection(wallSectionIndex.Value) is IIgnorable ignorableWall)) { break; } ignorableWall.OrderedToBeIgnored = order.Identifier == "ignorethis"; break; } } GameMain.GameSession?.CrewManager?.AddOrder(order, order.IsIgnoreOrder ? (float?)null : order.FadeOutTime); } else if (orderTargetCharacter != null) { orderTargetCharacter.SetOrder(order, orderMsg.OrderOption, orderMsg.OrderPriority, orderMsg.Sender); } } GameMain.Server.SendOrderChatMessage(orderMsg); } else { GameMain.Server.SendChatMessage(txt, null, c); } }
private static int CalcScoreForSingleArgument(ParameterDescriptor desc, Type parameterType, DynValue arg, bool isOptional) { int score = ScriptToClrConversions.DynValueToObjectOfTypeWeight(arg, parameterType, isOptional); if (parameterType.IsByRef || desc.IsOut || desc.IsRef) { score = Math.Max(0, score + ScriptToClrConversions.WEIGHT_BYREF_BONUSMALUS); } return(score); }
public Callback(DynValue function, DynValue[] arguments, bool remove = false) { this.function = function.Function; this.arguments = arguments; this.remove = remove; }