Skip to content
Permalink
Browse files

[Script System] Support parsing errors better; fix observer error; ot…

…her fixes

- The script system should now more efficiently and correctly deal with the
  Script dictionary for every script.
    * The Script dictionary for each script is kept available to the bot
      in all cases by keeping a reference to it.
    * The reference should provide faster access to Script dictionary values.
    * IsScriptEnabled() and the ability to track script enabled is now stored
      in Script("Enabled").
      This should keep the state of the bot more in sync. It now requires a
      reload script to re-read the "Enabled" value from Scripts.ini.
      Before it was possible to set the INI and have the bot start/stop sending
      loaded scripts event calls without the UI updating or the load/close
      events firing.
    * IsScriptModuleEnabled() is used in some cases instead of IsScriptEnabled().
      It does the same thing but takes a script module directly, rather than
      finding the module by name in many cases where it was unnecessary to do so
      multiple times.
    * IsScriptEnabledSetting() is used when loading scripts
      (during parsing and SC_Error during load) to check the setting in the INI.

- Fix error when using commands with script observers present.

- The script system is now more robust when dealing with enabled scripts with
  parsing errors.
  If a parsing error occurs:
    * The Script dictionary is still available to the bot. See "is enabled" talk above.
    * Script("Name") is set to a temporary name created from the file name.
    * Script("LoadError") is set to True.
    * The error message is displayed to screen if the cleaned file name
      is not set to Enabled=False in Scripts.ini.
    * Commands and the rest of the bot will react to it in different ways:
      /enable and /disable list the script as it is in the settings
      Script menus list the script as it is in the settings
      /enable will warn that a parsing error occurred and that it won't function until that is fixed
      /scripts lists the script as disabled
      /scriptdetail lists the script with the text "(parse error)" if enabled in settings
      /initperf, further script events, and other interactions treat the script as disabled
  This design is so that reloading scripts after fixing the error leads
  to intuitive behavior of the script still being on.
  It also fixes an issue where enabled scripts may have not been showing
  their parsing errors at any time since SC_Error considered it disabled before.

- Loading scripts and the /scripts command now list an enabled and total count.

- /exec should now be given access to objects such as SSC and BotVars when
  DisableScripts is set.

- AllowUI should now be disabled properly if it changes to be on reload script.

- RunInAll() uses the module metadata to check if an event exists before calling it.

- Fix oversight where script form menus weren't being disposed in .DestroyObjs().

- Fix issue where script form RichTextBoxes would have DisableURLDetect() called
  on them on .ClearObjs() instead of .DestroyObjs().
  • Loading branch information...
nmbook committed Dec 3, 2017
1 parent e8b6f96 commit 20e7ad8e7d23dba22626cee813ea97b76a7e96d1
Showing with 275 additions and 173 deletions.
  1. +5 −4 trunk/frmScript.frm
  2. +14 −29 trunk/modCommandsAdmin.bas
  3. +12 −6 trunk/modCommandsInfo.bas
  4. +2 −2 trunk/modCommandsMisc.bas
  5. +242 −132 trunk/modScripting.bas
@@ -492,7 +492,7 @@ Public Sub DestroyObjs()
ERROR_HANDLER:

frmChat.AddChat g_Color.ErrorMessageText, _
"Error (#" & Err.Number & "): " & Err.Description & " in frmScript::DestroyObjs()."
"Error (#" & Err.Number & "): " & Err.Description & " in frmScript.DestroyObjs()."

Resume Next

@@ -587,6 +587,7 @@ Public Sub DestroyObj(ByVal ObjName As String)
End If

Case "MENU"
m_arrObjs(Index).obj.Class_Terminate

Case "OPTIONBUTTON"
If (m_arrObjs(Index).obj.Index > 0) Then
@@ -613,6 +614,8 @@ Public Sub DestroyObj(ByVal ObjName As String)
End If

Case "RICHTEXTBOX"
DisableURLDetect m_arrObjs(Index).obj.hWnd

If (m_arrObjs(Index).obj.Index > 0) Then
Unload rtb(m_arrObjs(Index).obj.Index)
Else
@@ -665,7 +668,7 @@ Public Sub DestroyObj(ByVal ObjName As String)
ERROR_HANDLER:

frmChat.AddChat g_Color.ErrorMessageText, _
"Error (#" & Err.Number & "): " & Err.Description & " in frmScript::DestroyObjs()."
"Error (#" & Err.Number & "): " & Err.Description & " in frmScript.DestroyObjs()."

Resume Next

@@ -735,8 +738,6 @@ Public Sub ClearObjs()
Case "RICHTEXTBOX"
rtb(m_arrObjs(i).obj.Index).Text = ""

DisableURLDetect m_arrObjs(i).obj.hWnd

Case "TEXTBOX"
txt(m_arrObjs(i).obj.Index).Text = ""

@@ -133,8 +133,6 @@ End Sub
Public Sub OnDisable(Command As clsCommandObj)
Dim Module As Module
Dim Name As String
Dim i As Integer
Dim mnu As clsMenuObj

If modScripting.GetScriptSystemDisabled() Then
Command.Respond "Error: Scripts are globally disabled."
@@ -148,21 +146,11 @@ Public Sub OnDisable(Command As clsCommandObj)
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else
Name = modScripting.GetScriptName(Module.Name)
If (modScripting.IsScriptEnabled(Name) = False) Then
If (modScripting.IsScriptModuleEnabled(Module, True) = False) Then
Command.Respond StringFormat("Error: Script ""{0}"" is already disabled.", Name)
Else
RunInSingle Module, "Event_Close"
SharedScriptSupport.WriteSettingsEntry "Enabled", "False", , Name
modScripting.DestroyObjs Module
Call modScripting.DisableScriptModule(Name, Module)
Command.Respond StringFormat("Script ""{0}"" has been disabled.", Name)
For i = 1 To DynamicMenus.Count
Set mnu = DynamicMenus(i)
If (StrComp(mnu.Name, Chr$(0) & Name & Chr$(0) & "ENABLE|DISABLE", vbTextCompare) = 0) Then
mnu.Checked = False
Exit For
End If
Next i
Set mnu = Nothing
End If
End If
Else
@@ -179,8 +167,6 @@ End Sub
Public Sub OnEnable(Command As clsCommandObj)
Dim Module As Module
Dim Name As String
Dim i As Integer
Dim mnu As clsMenuObj

If modScripting.GetScriptSystemDisabled() Then
Command.Respond "Error: Scripts are globally disabled."
@@ -194,20 +180,19 @@ Public Sub OnEnable(Command As clsCommandObj)
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else
Name = modScripting.GetScriptName(Module.Name)
If (modScripting.IsScriptEnabled(Name) = True) Then
Command.Respond StringFormat("Error: Script ""{0}"" is already enabled.", Name)
If (modScripting.IsScriptModuleEnabled(Module, True) = True) Then
If modScripting.GetScriptDictionary(Module)("LoadError") Then
Command.Respond StringFormat("Error: Script ""{0}"" is already enabled. A parsing error occurred. This script will not function.", Name)
Else
Command.Respond StringFormat("Error: Script ""{0}"" is already enabled.", Name)
End If
Else
SharedScriptSupport.WriteSettingsEntry "Enabled", "True", , Name
Command.Respond StringFormat("Script ""{0}"" has been enabled.", Name)
modScripting.InitScript Module
For i = 1 To DynamicMenus.Count
Set mnu = DynamicMenus(i)
If (StrComp(mnu.Name, Chr$(0) & Name & Chr$(0) & "ENABLE|DISABLE", vbTextCompare) = 0) Then
mnu.Checked = True
Exit For
End If
Next i
Set mnu = Nothing
modScripting.EnableScriptModule Name, Module
If modScripting.GetScriptDictionary(Module)("LoadError") Then
Command.Respond StringFormat("Script ""{0}"" has been enabled. A parsing error occurred. This script will not function.", Name)
Else
Command.Respond StringFormat("Script ""{0}"" has been enabled.", Name)
End If
End If
End If
Else
@@ -307,8 +307,8 @@ On Error GoTo ERROR_HANDLER
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else
Name = modScripting.GetScriptName(Script.Name)
If (modScripting.IsScriptEnabled(Name) = False) Then
Command.Respond StringFormat("Error: Script ""{0}"" is currently disabled.", Name)
If (modScripting.IsScriptModuleEnabled(Script) = False) Then
Command.Respond StringFormat("Error: Script ""{0}"" is currently disabled or failed to load.", Name)
Else
Command.Respond StringFormat("The script ""{0}"" loaded in {1}ms.", _
Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0"))
@@ -324,7 +324,7 @@ On Error GoTo ERROR_HANDLER
For i = 2 To frmChat.SControl.Modules.Count
Set Script = frmChat.SControl.Modules(i)
Name = modScripting.GetScriptName(CStr(i))
If (modScripting.IsScriptEnabled(Name)) Then
If (modScripting.IsScriptModuleEnabled(Script)) Then
If (Command.IsLocal And Not Command.PublicOutput) Then
Command.Respond StringFormat(" ""{0}"": {1}ms.", _
Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0"))
@@ -515,7 +515,11 @@ On Error GoTo ERROR_HANDLER
Author = ScriptInfo("Author")
Description = ScriptInfo("Description")

If modScripting.IsScriptEnabled(Name) = False Then StateStr = " (disabled)"
If modScripting.IsScriptModuleEnabled(Module, True) = False Then
StateStr = " (disabled)"
ElseIf ScriptInfo("LoadError") Then
StateStr = " (parsing error)"
End If
If VerTotal > 0 Then VerStr = " v" & Version
If LenB(Author) > 0 Then AuthorStr = " by " & Author
If LenB(Description) > 0 Then DescrStr = ": " & Description
@@ -542,6 +546,7 @@ On Error GoTo ERROR_HANDLER
Dim Part As String
Dim Comma As String
Dim Name As String
Dim EnCount As Integer
Dim Count As Integer

If modScripting.GetScriptSystemDisabled() Then
@@ -553,16 +558,17 @@ On Error GoTo ERROR_HANDLER
Comma = ", "
For i = 2 To frmChat.SControl.Modules.Count
Name = modScripting.GetScriptName(CStr(i))
Enabled = modScripting.IsScriptEnabled(Name)
Enabled = modScripting.IsScriptModuleEnabled(frmChat.SControl.Modules(i))
Part = "{0}{1}{2}"
If Not Enabled Then Part = "{0}{3}{1}{4}{2}"
If (i = frmChat.SControl.Modules.Count) Then Comma = vbNullString

retVal = StringFormat(Part, retVal, Name, Comma, "(", ")")
Count = (Count + 1)
If Enabled Then EnCount = EnCount + 1
Next i

Command.Respond StringFormat("Scripts ({0}): {1}", Count, retVal)
Command.Respond StringFormat("Scripts ({0}/{1}): {2}", EnCount, Count, retVal)
Else
Command.Respond "There are no scripts currently loaded."
End If
@@ -68,7 +68,7 @@ ERROR_HANDLER:
With frmChat.SControl
ErrType = "runtime"

If InStr(1, .Error.source, "compilation", vbBinaryCompare) > 0 Then ErrType = "parsing"
If InStr(1, .Error.Source, "compilation", vbBinaryCompare) > 0 Then ErrType = "parsing"

Command.Respond StringFormat("Execution {0} error #{1}: {2}", ErrType, .Error.Number, .Error.Description)

@@ -253,7 +253,7 @@ Public Sub OnMath(Command As clsCommandObj)
sStatement = Command.Argument("Expression")

If (InStr(1, sStatement, "CreateObject", vbTextCompare)) Then
Command.Respond "Evaluation error, CreateObject is restricted."
Command.Respond "Evaluation error: CreateObject is restricted."
Else
With frmChat.SCRestricted
.AllowUI = False

0 comments on commit 20e7ad8

Please sign in to comment.
You can’t perform that action at this time.