Example #1
0
        /// <summary>
        /// Start multiple scripts in the object
        /// </summary>
        /// <param name="part"></param>
        /// <param name="items"></param>
        /// <param name="startParam"></param>
        /// <param name="postOnRez"></param>
        /// <param name="engine"></param>
        /// <param name="stateSource"></param>
        /// <param name="RezzedFrom"></param>
        public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items,
                                int startParam, bool postOnRez, int stateSource, UUID RezzedFrom)
        {
            List <LUStruct> ItemsToStart = new List <LUStruct>();

            foreach (TaskInventoryItem item in items)
            {
                LUStruct itemToQueue = m_scriptEngine.StartScript(part, item.ItemID,
                                                                  startParam, postOnRez, (StateSource)stateSource, RezzedFrom);
                if (itemToQueue.Action != LUType.Unknown)
                {
                    ItemsToStart.Add(itemToQueue);
                }
            }
            if (ItemsToStart.Count != 0)
            {
                m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray());
            }
        }
 public void AddScriptChange(LUStruct[] items, LoadPriority priority)
 {
     if (RunInMainProcessingThread)
         StartScripts(items);
     else
     {
         LUQueue.Add(items, priority);
         if (!ScriptChangeIsRunning)
             StartThread("Change");
     }
 }
        public void StartScripts(LUStruct[] items)
        {
            List<LUStruct> NeedsFired = new List<LUStruct>();
            foreach (LUStruct item in items)
            {
                if (m_ScriptEngine.ConsoleDisabled || m_ScriptEngine.Disabled || m_ScriptEngine.Scene == null ||
                    !m_ScriptEngine.Scene.ShouldRunHeartbeat)
                    break;

                if (item.Action == LUType.Unload)
                {
                    //Close
                    item.ID.CloseAndDispose(true);
                }
                else if (item.Action == LUType.Load ||
                         item.Action == LUType.Reupload)
                {
                    try
                    {
                        //Start
                        if (item.ID.Start(item))
                            NeedsFired.Add(item);
                    }
                    catch (Exception ex)
                    {
                        MainConsole.Instance.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " +
                                                   ex);
                    }
                }
            }
            foreach (LUStruct item in NeedsFired)
            {
                //Fire the events afterward so that they all start at the same time
                item.ID.FireEvents();
            }
        }
Example #4
0
 public void StartScripts(LUStruct[] items)
 {
     List<LUStruct> NeedsFired = new List<LUStruct>();
     foreach (LUStruct item in items)
     {
         if (item.Action == LUType.Unload)
         {
             //Close
             item.ID.CloseAndDispose(true);
         }
         else if (item.Action == LUType.Load)
         {
             try
             {
                 //Start
                 if (item.ID.Start(false))
                     NeedsFired.Add(item);
             }
             catch (Exception ex)
             {
                 MainConsole.Instance.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex);
             }
         }
         else if (item.Action == LUType.Reupload)
         {
             try
             {
                 //Start, but don't add to the queue's again
                 if (item.ID.Start(true))
                     NeedsFired.Add(item);
             }
             catch (Exception ex)
             {
                 MainConsole.Instance.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex);
             }
         }
     }
     foreach (LUStruct item in NeedsFired)
     {
         //Fire the events afterward so that they all start at the same time
         item.ID.FireEvents();
     }
 }
Example #5
0
 public async Task AddScriptChange(LUStruct[] items)
 {
     await TaskEx.Run(() =>
         {
             List<LUStruct> NeedsFired = new List<LUStruct>();
             foreach (LUStruct item in items)
             {
                 if (item.Action == LUType.Unload)
                 {
                     item.ID.CloseAndDispose(false);
                 }
                 else if (item.Action == LUType.Load)
                 {
                     try
                     {
                         item.ID.Start(false);
                         NeedsFired.Add(item);
                     }
                     catch (Exception ex) { m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex); }
                 }
                 else if (item.Action == LUType.Reupload)
                 {
                     try
                     {
                         item.ID.Start(true);
                         NeedsFired.Add(item);
                     }
                     catch (Exception ex) { m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex); }
                 }
             }
             foreach (LUStruct item in NeedsFired)
             {
                 item.ID.FireEvents();
             }
         });
 }
Example #6
0
        /// <summary>
        ///   This starts the script and sets up the variables.
        /// </summary>
        /// <returns></returns>
        public bool Start(LUStruct startInfo)
        {
            bool reupload = startInfo.Action == LUType.Reupload;
            DateTime StartTime = DateTime.Now.ToUniversalTime();
            Running = true;
            Suspended = false;

            //Clear out the removing of events for this script.
            IgnoreNew = false;
            Interlocked.Increment(ref VersionID);

            //Reset this
            StartedFromSavedState = false;

            //Clear out previous errors if they were not cleaned up
            m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID);

            //Find the inventory item
            Part.TaskInventory.TryGetValue(ItemID, out InventoryItem);

            if (InventoryItem == null)
            {
                MainConsole.Instance.Warn("[ADNE]: Could not find inventory item for script " + ItemID + ", part" + Part.Name + "@" +
                           Part.AbsolutePosition);
                return false;
            }

            //Try to see if this was rezzed from someone's inventory
            UserInventoryItemID = Part.FromUserInventoryItemID;

            //Try to find the avatar who started this.
            IScenePresence presence = World.GetScenePresence(Part.OwnerID);


            if (startInfo.ClearStateSaves)
                m_ScriptEngine.StateSave.DeleteFrom(this);
            //Now that the initial loading is complete,
            // we need to find the state save and start loading the info from it
            StateSave LastStateSave = m_ScriptEngine.StateSave.FindScriptStateSave(this);
            if (!reupload && Loading && LastStateSave != null)
            {
                //Deserialize the most important pieces first
                Source = LastStateSave.Source;
            }
            if (string.IsNullOrEmpty(Source))
            {
                AssetBase asset = Part.ParentEntity.Scene.AssetService.Get(InventoryItem.AssetID.ToString());
                if (null == asset)
                {
                    MainConsole.Instance.ErrorFormat(
                        "[ScriptData]: " +
                        "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
                        InventoryItem.Name, InventoryItem.ItemID, Part.AbsolutePosition,
                        Part.ParentEntity.Scene.RegionInfo.RegionName, InventoryItem.AssetID);
                    ScriptEngine.ScriptProtection.RemoveScript(this);
                    return false;
                }
                Source = Utils.BytesToString(asset.Data);
            }
            if (string.IsNullOrEmpty(Source))
            {
                MainConsole.Instance.ErrorFormat(
                    "[ScriptData]: " +
                    "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
                    InventoryItem.Name, InventoryItem.ItemID, Part.AbsolutePosition,
                    Part.ParentEntity.Scene.RegionInfo.RegionName, InventoryItem.AssetID);
                ScriptEngine.ScriptProtection.RemoveScript(this);
                return false;
            }

            #region HTML Reader

            if (ScriptEngine.ScriptProtection.AllowHTMLLinking)
            {
                //Read the URL and load it.
                if (Source.Contains("#IncludeHTML "))
                {
                    string URL = "";
                    int line = Source.IndexOf("#IncludeHTML ");
                    URL = Source.Remove(0, line);
                    URL = URL.Replace("#IncludeHTML ", "");
                    URL = URL.Split('\n')[0];
                    string webSite = Utilities.ReadExternalWebsite(URL);
                    Source = Source.Replace("#IncludeHTML " + URL, webSite);
                }
            }
            else
            {
                //Remove the line then
                if (Source.Contains("#IncludeHTML "))
                {
                    string URL = "";
                    int line = Source.IndexOf("#IncludeHTML ");
                    URL = Source.Remove(0, line);
                    URL = URL.Replace("#IncludeHTML ", "");
                    URL = URL.Split('\n')[0];
                    Source = Source.Replace("#IncludeHTML " + URL, "");
                }
            }

            #endregion

            //Find the default state save
            DefaultState = m_ScriptEngine.Compiler.FindDefaultStateForScript(Source);
            State = DefaultState;

            //If the saved state exists, if it isn't a reupload (something changed), and if the assembly exists, load the state save
            if (!reupload && Loading && LastStateSave != null
                && File.Exists(LastStateSave.AssemblyName))
            {
                //Retrive the previous assembly
                AssemblyName = LastStateSave.AssemblyName;
            }
            else
            {
                Compiled = false;
                //if (!reupload && Loading && LastStateSave != null && !LastStateSave.Compiled)
                //    return false;//If we're trying to start up and we failed before, just give up
                if (reupload)
                {
                    LastStateSave = null;
                    //Close the previous script
                    CloseAndDispose(false); //We don't want to back it up
                    Interlocked.Increment(ref VersionID);
                    m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false); // accept new events
                }

                //Try to find a previously compiled script in this instance
                string PreviouslyCompiledAssemblyName =
                    ScriptEngine.ScriptProtection.TryGetPreviouslyCompiledScript(Source);
                if (PreviouslyCompiledAssemblyName != null)
                    //Already exists in this instance, so we do not need to check whether it exists
                    AssemblyName = PreviouslyCompiledAssemblyName;
                else
                {
                    try
                    {
                        m_ScriptEngine.Compiler.PerformScriptCompile(Source, ItemID, Part.OwnerID, out AssemblyName);

                        #region Errors and Warnings

                        #region Errors

                        string[] compileerrors = m_ScriptEngine.Compiler.GetErrors();

                        if (compileerrors.Length != 0)
                        {
                            string error = string.Empty;
                            foreach (string compileerror in compileerrors)
                            {
                                error += compileerror;
                            }
                            DisplayUserNotification(error, "compiling", reupload, true);
                            //It might have failed, but we still need to add it so that we can reuse this script data class later
                            ScriptEngine.ScriptProtection.AddNewScript(this);
                            m_ScriptEngine.StateSave.SaveStateTo(this, true);
                            return false;
                        }

                        #endregion

                        #region Warnings

                        if (m_ScriptEngine.ShowWarnings)
                        {
                            string[] compilewarnings = m_ScriptEngine.Compiler.GetWarnings();

                            if (compilewarnings != null && compilewarnings.Length != 0)
                            {
                                string error = string.Empty;
                                foreach (string compileerror in compilewarnings)
                                {
                                    error += compileerror;
                                }
                                DisplayUserNotification(error, "compiling", reupload, false);
                                //It might have failed, but we still need to add it so that we can reuse this script data class later
                                ScriptEngine.ScriptProtection.AddNewScript(this);
                                return false;
                            }
                        }

                        #endregion

                        #endregion
                    }
                    catch (Exception ex)
                    {
                        //LEAVE IT AS ToString() SO THAT WE GET THE STACK TRACE TOO
                        DisplayUserNotification(ex.ToString(), "(exception) compiling", reupload, true);
                        //It might have failed, but we still need to add it so that we can reuse this script data class later
                        ScriptEngine.ScriptProtection.AddNewScript(this);
                        return false;
                    }
                }
            }

            bool useDebug = false;
            if (useDebug)
                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Stage 1 compile: " +
                            (DateTime.Now.ToUniversalTime() - StartTime).TotalSeconds);

            //Create the app domain if needed.
            try
            {
                Script = m_ScriptEngine.AppDomainManager.LoadScript(AssemblyName, "Script.ScriptClass", out AppDomain);
                m_ScriptEngine.Compiler.FinishCompile(this, Script);
                //Add now so that we don't add it too early and give it the possibility to fail
                ScriptEngine.ScriptProtection.AddPreviouslyCompiled(Source, this);
            }
            catch (FileNotFoundException) // Not valid!!!
            {
                MainConsole.Instance.Error("[" + m_ScriptEngine.ScriptEngineName +
                            "]: File not found in app domain creation. Corrupt state save! " + AssemblyName);
                ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(Source);
                return Start(startInfo); // Lets restart the script if this happens
            }
            catch (Exception ex)
            {
                DisplayUserNotification(ex.ToString(), "app domain creation", reupload, true);
                //It might have failed, but we still need to add it so that we can reuse this script data class later
                ScriptEngine.ScriptProtection.AddNewScript(this);
                return false;
            }
            Source = null; //Don't keep it in memory, we don't need it anymore
            Compiled = true; //We compiled successfully

            //ILease lease = (ILease)RemotingServices.GetLifetimeService(Script as MarshalByRefObject);
            //if (lease != null) //Its null if it is all running in the same app domain
            //    lease.Register(Script.Sponsor);

            //If its a reupload, an avatar is waiting for the script errors
            if (reupload)
                m_ScriptEngine.ScriptErrorReporter.AddError(ItemID, new ArrayList(new[] { "SUCCESSFULL" }));

            if (useDebug)
                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Stage 2 compile: " +
                            (DateTime.Now.ToUniversalTime() - StartTime).TotalSeconds);

            SetApis();

            //Now do the full state save finding now that we have an app domain.
            if (LastStateSave != null)
            {
                string assy = AssemblyName;
                // don't restore the assembly name, the one we have is right (if re-compiled or not)
                m_ScriptEngine.StateSave.Deserialize(this, LastStateSave);
                AssemblyName = assy;
                if (this.State == "" && DefaultState != this.State)
                //Sometimes, "" is a valid state for other script languages
                {
                    MainConsole.Instance.Warn("BROKEN STATE SAVE!!! - " + this.Part.Name + " @ " + this.Part.AbsolutePosition);
                    this.State = DefaultState;
                    m_ScriptEngine.StateSave.SaveStateTo(this, true);
                }
                else
                {
                    // we get new rez events on sim restart, too
                    // but if there is state, then we fire the change
                    // event
                    StartedFromSavedState = true;
                }

                // ItemID changes sometimes (not sure why, but observed it)
                // If so we want to clear out the old save state,
                // which would otherwise have hung around in the object forever
                if (LastStateSave.ItemID != ItemID)
                {
                    m_ScriptEngine.StateSave.DeleteFrom(Part, LastStateSave.ItemID);
                    m_ScriptEngine.StateSave.SaveStateTo(this, true);
                }
            }
            else
            {
                //Make a new state save now
                m_ScriptEngine.StateSave.SaveStateTo(this, true);
            }

            //Set the event flags
            Part.SetScriptEvents(ItemID, Script.GetStateEventFlags(State));

            // Add it to our script memstruct so it can be found by other scripts
            ScriptEngine.ScriptProtection.AddNewScript(this);

            //All done, compiled successfully
            Loading = false;

            if (MainConsole.Instance.IsDebugEnabled)
            {
                TimeSpan time = (DateTime.Now.ToUniversalTime() - StartTime);

                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName +
                            "]: Started Script " + InventoryItem.Name +
                            " in object " + Part.Name + "@" + Part.ParentEntity.RootChild.AbsolutePosition +
                            (presence != null ? " by " + presence.Name : "") +
                            " in region " + Part.ParentEntity.Scene.RegionInfo.RegionName +
                            " in " + time.TotalSeconds + " seconds.");
            }
            return true;
        }
Example #7
0
        /// <summary>
        /// Disables and unloads a script
        /// </summary>
        /// <param name="localID"></param>
        /// <param name="itemID"></param>
        public void StopScript(uint localID, UUID itemID)
        {
            ScriptData data = ScriptProtection.GetScript(itemID);
            if (data == null)
                return;

            LUStruct ls = new LUStruct();

            ls.ID = data;
            ls.Action = LUType.Unload;

            MaintenanceThread.AddScriptChange(new LUStruct[] { ls }, LoadPriority.Stop);

            //Disconnect from other modules
            ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
            if (handlerObjectRemoved != null)
                handlerObjectRemoved(ls.ID.part.UUID);

            ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
            if (handlerScriptRemoved != null)
                handlerScriptRemoved(itemID);
        }
Example #8
0
        public void UpdateScript(UUID partID, UUID itemID, string script, int startParam, bool postOnRez, int stateSource)
        {
            ScriptData id = ScriptProtection.GetScript(partID, itemID);
            LUStruct ls = new LUStruct();
            //Its a change of the script source, needs to be recompiled and such.
            if (id == null)
                id = new ScriptData(this);
            ls.Action = LUType.Reupload;
            id.PostOnRez = postOnRez;
            id.StartParam = startParam;
            id.stateSource = (StateSource)stateSource;
            id.State = "default";
            id.Source = script;
            id.EventDelayTicks = 0;
            id.part = findPrim(partID);
            id.ItemID = itemID;
            id.EventDelayTicks = 0;

            //No SOP, no compile.
            if (id.part == null)
            {
                m_log.ErrorFormat("[{0}]: Could not find scene object part corresponding " + "to localID {1} to start script", ScriptEngineName, partID);
                return;
            }
            id.World = id.part.ParentGroup.Scene;
            ls.ID = id;
            MaintenanceThread.AddScriptChange(new LUStruct[] { ls }, LoadPriority.Restart);
        }
Example #9
0
 /// <summary>
 /// Fetches, loads and hooks up a script to an objects events
 /// </summary>
 /// <param name="itemID"></param>
 /// <param name="localID"></param>
 public LUStruct StartScript(SceneObjectPart part, UUID itemID, string Script, int startParam, bool postOnRez, StateSource statesource, UUID RezzedFrom)
 {
     ScriptData id = ScriptProtection.GetScript(part.UUID, itemID);
     
     LUStruct ls = new LUStruct();
     //Its a change of the script source, needs to be recompiled and such.
     if (id != null)
     {
         //Ignore prims that have crossed regions, they are already started and working
         if ((statesource & StateSource.PrimCrossing) != 0)
         {
             //Post the changed event though
             AddToScriptQueue(id, "changed", new DetectParams[0], id.VersionID, EventPriority.FirstStart, new Object[] { new LSL_Types.LSLInteger(512) });
             return new LUStruct() { Action = LUType.Unknown };
         }
         else
         {
             //Restart other scripts
             ls.Action = LUType.Load;
         }
         id.EventDelayTicks = 0;
         ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(id.Source);
     }
     else
         ls.Action = LUType.Load;
     if (id == null)
         id = new ScriptData(this);
     id.ItemID = itemID;
     id.PostOnRez = postOnRez;
     id.StartParam = startParam;
     id.stateSource = statesource;
     id.State = "default";
     id.Source = Script;
     id.part = part;
     id.World = part.ParentGroup.Scene;
     id.RezzedFrom = RezzedFrom;
     ls.ID = id;
     return ls;
 }
 public void AddScriptChange(LUStruct[] items, LoadPriority priority)
 {
     if (RunInMainProcessingThread)
     {
         List<LUStruct> NeedsFired = new List<LUStruct>();
         foreach (LUStruct item in items)
         {
             if (item.Action == LUType.Unload)
             {
                 item.ID.CloseAndDispose (true);
             }
             else if (item.Action == LUType.Load)
             {
                 try
                 {
                     if(item.ID.Start(false))
                         NeedsFired.Add(item);
                 }
                 catch (Exception ex) { m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex); }
             }
             else if (item.Action == LUType.Reupload)
             {
                 try
                 {
                     if(item.ID.Start(true))
                         NeedsFired.Add(item);
                 }
                 catch (Exception ex) { m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: LEAKED COMPILE ERROR: " + ex); }
             }
         }
         foreach (LUStruct item in NeedsFired)
         {
             item.ID.FireEvents();
         }
     }
     else
     {
         LUQueue.Add(items, priority);
         if (!ScriptChangeIsRunning)
             StartThread("Change");
     }
 }
Example #11
0
        /// <summary>
        ///     This starts the script and sets up the variables.
        /// </summary>
        /// <returns></returns>
        public bool Start(LUStruct startInfo)
        {
            bool     reupload  = startInfo.Action == LUType.Reupload;
            DateTime StartTime = DateTime.Now.ToUniversalTime();

            Running   = true;
            Suspended = false;

            //Clear out the removing of events for this script.
            IgnoreNew = false;
            Interlocked.Increment(ref VersionID);

            //Reset this
            StartedFromSavedState = false;

            //Clear out previous errors if they were not cleaned up
            m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID);

            //Find the inventory item
            Part.TaskInventory.TryGetValue(ItemID, out InventoryItem);

            if (InventoryItem == null)
            {
                MainConsole.Instance.Warn("[ADNE]: Could not find inventory item for script " + ItemID + ", part" +
                                          Part.Name + "@" +
                                          Part.AbsolutePosition);
                return(false);
            }

            //Try to see if this was rezzed from someone's inventory
            UserInventoryItemID = Part.FromUserInventoryItemID;

            //Try to find the avatar who started this.
            IScenePresence presence = World.GetScenePresence(Part.OwnerID);


            if (startInfo.ClearStateSaves)
            {
                m_ScriptEngine.StateSave.DeleteFrom(this);
            }
            //Now that the initial loading is complete,
            // we need to find the state save and start loading the info from it
            StateSave LastStateSave = m_ScriptEngine.StateSave.FindScriptStateSave(this);

            if (!reupload && Loading && LastStateSave != null)
            {
                //Deserialize the most important pieces first
                Source = LastStateSave.Source;
            }
            if (string.IsNullOrEmpty(Source))
            {
                byte[] asset = Part.ParentEntity.Scene.AssetService.GetData(InventoryItem.AssetID.ToString());
                if (null == asset)
                {
                    MainConsole.Instance.ErrorFormat(
                        "[ScriptData]: " +
                        "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
                        InventoryItem.Name, InventoryItem.ItemID, Part.AbsolutePosition,
                        Part.ParentEntity.Scene.RegionInfo.RegionName, InventoryItem.AssetID);
                    ScriptEngine.ScriptProtection.RemoveScript(this);
                    return(false);
                }
                Source = Utils.BytesToString(asset);
            }
            if (string.IsNullOrEmpty(Source))
            {
                MainConsole.Instance.ErrorFormat(
                    "[ScriptData]: " +
                    "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
                    InventoryItem.Name, InventoryItem.ItemID, Part.AbsolutePosition,
                    Part.ParentEntity.Scene.RegionInfo.RegionName, InventoryItem.AssetID);
                ScriptEngine.ScriptProtection.RemoveScript(this);
                return(false);
            }

            #region HTML Reader

            if (ScriptEngine.ScriptProtection.AllowHTMLLinking)
            {
                //Read the URL and load it.
                if (Source.Contains("#IncludeHTML "))
                {
                    string URL  = "";
                    int    line = Source.IndexOf("#IncludeHTML ");
                    URL = Source.Remove(0, line);
                    URL = URL.Replace("#IncludeHTML ", "");
                    URL = URL.Split('\n')[0];
                    string webSite = Utilities.ReadExternalWebsite(URL);
                    Source = Source.Replace("#IncludeHTML " + URL, webSite);
                }
            }
            else
            {
                //Remove the line then
                if (Source.Contains("#IncludeHTML "))
                {
                    string URL  = "";
                    int    line = Source.IndexOf("#IncludeHTML ");
                    URL    = Source.Remove(0, line);
                    URL    = URL.Replace("#IncludeHTML ", "");
                    URL    = URL.Split('\n')[0];
                    Source = Source.Replace("#IncludeHTML " + URL, "");
                }
            }

            #endregion

            //Find the default state save
            DefaultState = m_ScriptEngine.Compiler.FindDefaultStateForScript(Source);
            State        = DefaultState;

            //If the saved state exists, if it isn't a reupload (something changed), and if the assembly exists, load the state save
            if (!reupload && Loading && LastStateSave != null &&
                File.Exists(LastStateSave.AssemblyName))
            {
                //Retrive the previous assembly
                AssemblyName = LastStateSave.AssemblyName;
            }
            else
            {
                Compiled = false;

                if (reupload)
                {
                    LastStateSave = null;
                    //Close the previous script
                    CloseAndDispose(false);                                                //We don't want to back it up
                    Interlocked.Increment(ref VersionID);
                    m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false); // accept new events
                }

                //Try to find a previously compiled script in this instance
                string PreviouslyCompiledAssemblyName =
                    ScriptEngine.ScriptProtection.TryGetPreviouslyCompiledScript(Source);
                if (PreviouslyCompiledAssemblyName != null)
                {
                    //Already exists in this instance, so we do not need to check whether it exists
                    AssemblyName = PreviouslyCompiledAssemblyName;
                }
                else
                {
                    try
                    {
                        m_ScriptEngine.Compiler.PerformScriptCompile(Source, Part.OwnerID, out AssemblyName);

                        #region Errors and Warnings

                        #region Errors

                        string[] compileerrors = m_ScriptEngine.Compiler.GetErrors();

                        if (compileerrors.Length != 0)
                        {
                            string error = string.Empty;
                            foreach (string compileerror in compileerrors)
                            {
                                error += compileerror;
                            }
                            DisplayUserNotification(error, "compiling", reupload, true);
                            //It might have failed, but we still need to add it so that we can reuse this script data class later
                            ScriptEngine.ScriptProtection.AddNewScript(this);
                            m_ScriptEngine.StateSave.SaveStateTo(this, true);
                            return(false);
                        }

                        #endregion

                        #region Warnings

                        if (m_ScriptEngine.ShowWarnings)
                        {
                            string[] compilewarnings = m_ScriptEngine.Compiler.GetWarnings();

                            if (compilewarnings != null && compilewarnings.Length != 0)
                            {
                                string error = string.Empty;
                                foreach (string compileerror in compilewarnings)
                                {
                                    error += compileerror;
                                }
                                DisplayUserNotification(error, "compiling", reupload, false);
                                //It might have failed, but we still need to add it so that we can reuse this script data class later
                                ScriptEngine.ScriptProtection.AddNewScript(this);
                                return(false);
                            }
                        }

                        #endregion

                        #endregion
                    }
                    catch (Exception ex)
                    {
                        //LEAVE IT AS ToString() SO THAT WE GET THE STACK TRACE TOO
                        DisplayUserNotification(ex.ToString(), "(exception) compiling", reupload, true);
                        //It might have failed, but we still need to add it so that we can reuse this script data class later
                        ScriptEngine.ScriptProtection.AddNewScript(this);
                        return(false);
                    }
                }
            }

            bool useDebug = false;
            if (useDebug)
            {
                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Stage 1 compile: " +
                                           (DateTime.Now.ToUniversalTime() - StartTime).TotalSeconds);
            }

            //Create the app domain if needed.
            try
            {
                Script = m_ScriptEngine.AppDomainManager.LoadScript(AssemblyName, "Script.ScriptClass", out AppDomain);
                m_ScriptEngine.Compiler.FinishCompile(this, Script);
                //Add now so that we don't add it too early and give it the possibility to fail
                ScriptEngine.ScriptProtection.AddPreviouslyCompiled(Source, this);
            }
            catch (FileNotFoundException) // Not valid!!!
            {
                MainConsole.Instance.Error("[" + m_ScriptEngine.ScriptEngineName +
                                           "]: File not found in app domain creation. Corrupt state save! " +
                                           AssemblyName);
                ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(Source);
                return(Start(startInfo)); // Lets restart the script if this happens
            }
            catch (Exception ex)
            {
                DisplayUserNotification(ex.ToString(), "app domain creation", reupload, true);
                //It might have failed, but we still need to add it so that we can reuse this script data class later
                ScriptEngine.ScriptProtection.AddNewScript(this);
                return(false);
            }
            Compiled = true; //We compiled successfully

            //If its a reupload, an avatar is waiting for the script errors
            if (reupload)
            {
                m_ScriptEngine.ScriptErrorReporter.AddError(ItemID, new ArrayList(new[] { "SUCCESSFULL" }));
            }

            if (useDebug)
            {
                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Stage 2 compile: " +
                                           (DateTime.Now.ToUniversalTime() - StartTime).TotalSeconds);
            }

            SetApis();

            //Now do the full state save finding now that we have an app domain.
            if (LastStateSave != null)
            {
                string assy = AssemblyName;
                // don't restore the assembly name, the one we have is right (if re-compiled or not)
                m_ScriptEngine.StateSave.Deserialize(this, LastStateSave);
                AssemblyName = assy;
                if (string.IsNullOrEmpty(this.State) && DefaultState != this.State)
                //Sometimes, "" is a valid state for other script languages
                {
                    MainConsole.Instance.Warn("BROKEN STATE SAVE!!! - " + this.Part.Name + " @ " +
                                              this.Part.AbsolutePosition);
                    this.State = DefaultState;
                    m_ScriptEngine.StateSave.DeleteFrom(Part, LastStateSave.ItemID);
                    m_ScriptEngine.StateSave.SaveStateTo(this, true);
                }
                else
                {
                    // we get new rez events on sim restart, too
                    // but if there is state, then we fire the change
                    // event
                    StartedFromSavedState = true;
                }

                // ItemID changes sometimes (not sure why, but observed it)
                // If so we want to clear out the old save state,
                // which would otherwise have hung around in the object forever
                if (LastStateSave.ItemID != ItemID)
                {
                    m_ScriptEngine.StateSave.DeleteFrom(Part, LastStateSave.ItemID);
                    m_ScriptEngine.StateSave.SaveStateTo(this, true);
                }
            }
            else
            {
                //Make a new state save now
                m_ScriptEngine.StateSave.SaveStateTo(this, true);
            }

            //Set the event flags
            Part.SetScriptEvents(ItemID, Script.GetStateEventFlags(State));

            // Add it to our script memstruct so it can be found by other scripts
            ScriptEngine.ScriptProtection.AddNewScript(this);

            //All done, compiled successfully
            Loading = false;

            if (MainConsole.Instance.IsDebugEnabled)
            {
                TimeSpan time = (DateTime.Now.ToUniversalTime() - StartTime);

                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName +
                                           "]: Started Script " + InventoryItem.Name +
                                           " in object " + Part.Name + "@" +
                                           Part.ParentEntity.RootChild.AbsolutePosition +
                                           (presence != null ? " by " + presence.Name : "") +
                                           " in region " + Part.ParentEntity.Scene.RegionInfo.RegionName +
                                           " in " + time.TotalSeconds + " seconds.");
            }
            return(true);
        }