示例#1
0
		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());
				}
			}
		}
示例#2
0
文件: Utils.cs 项目: cyecp/moonsharp
		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);
			}
		}
示例#3
0
		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();
		}
示例#4
0
        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;
        }
示例#7
0
        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
            });
        }
示例#8
0
		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;
		}
示例#10
0
 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));
 }
示例#11
0
		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);
		}
示例#12
0
        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");
 }
示例#14
0
		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;
		}
示例#16
0
		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;
		}
示例#22
0
		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);
		}
示例#23
0
		/// <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);
		}
示例#25
0
		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");
			}
示例#28
0
		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;
		}
示例#30
0
		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;
		}
示例#31
0
 // Shortcut to `SetSpeechThingPositionAndSide`
 public void SetTail(string side, DynValue position)
 {
     SetSpeechThingPositionAndSide(side, position);
 }
示例#32
0
 /// <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)));
 }
示例#33
0
 private void loadFunctions()
 {
     _triggerFunc = Script.Globals.Get(TRIGGER_FUNCTION_NAME);
 }
示例#34
0
 public DynValue Index(Script script, DynValue index, bool isNameIndex)
 {
     return(DynValue.NewNumber(index.Number * 3));
 }
示例#35
0
 public DynValue Index(Script script, object obj, DynValue index, bool dummy)
 {
     return(DynValue.NewNumber(index.Number * 4));
 }
示例#36
0
 public Connection Connect(DynValue value)
 {
     m_connected.Add(value);
     return(new Connection(this, value));
 }
示例#37
0
 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)));
 }
示例#40
0
 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);
        }
示例#42
0
        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
                }));
            }
        }
示例#43
0
 public void AddEditorButton(string name, DynValue action)
 {
     Execute.OnUIThread(() => LuaManager.EditorButtons.Add(new EditorButton(LuaManager, name, action)));
 }
示例#44
0
        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));
            }
        }
示例#45
0
 public bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool dummy)
 {
     throw new NotImplementedException();
 }
示例#46
0
        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)));
        }
示例#47
0
 public bool SetIndex(Script script, DynValue index, DynValue value, bool isNameIndex)
 {
     throw new NotImplementedException();
 }
示例#48
0
        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;
            }
        }
示例#50
0
        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))));
        }
示例#51
0
 /// <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)));
 }
示例#52
0
 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);
 }
示例#54
0
        public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, DynValue value)
        {
            if (value != null)
            {
                var otherResource = value.GetAsPrivateResource();

                if (otherResource != null)
                {
                    CheckScriptOwnership(containingResource, otherResource);
                }
            }
        }
示例#55
0
        private static void SetRandom(Script s, Random random)
        {
            DynValue rr = UserData.Create(new AnonWrapper <Random>(random));

            s.Registry.Set("F61E3AA7247D4D1EB7A45430B0C8C9BB_MATH_RANDOM", rr);
        }
示例#56
0
 public void ShowBubble(string side = null, DynValue position = null)
 {
     bubble = true;
     containerBubble.SetActive(true);
     SetSpeechThingPositionAndSide(side, position);
 }
示例#57
0
        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);
        }
示例#60
0
 public Callback(DynValue function, DynValue[] arguments, bool remove = false)
 {
     this.function  = function.Function;
     this.arguments = arguments;
     this.remove    = remove;
 }