Skip to content

Commit

Permalink
[Script System] Support parsing errors better; fix observer error; ot…
Browse files Browse the repository at this point in the history
…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 20e7ad8
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 173 deletions.
9 changes: 5 additions & 4 deletions trunk/frmScript.frm
Expand Up @@ -492,7 +492,7 @@ Public Sub DestroyObjs()
ERROR_HANDLER: ERROR_HANDLER:


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


Resume Next Resume Next


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


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


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


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

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


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


Resume Next Resume Next


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


DisableURLDetect m_arrObjs(i).obj.hWnd

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


Expand Down
43 changes: 14 additions & 29 deletions trunk/modCommandsAdmin.bas
Expand Up @@ -133,8 +133,6 @@ End Sub
Public Sub OnDisable(Command As clsCommandObj) Public Sub OnDisable(Command As clsCommandObj)
Dim Module As Module Dim Module As Module
Dim Name As String Dim Name As String
Dim i As Integer
Dim mnu As clsMenuObj


If modScripting.GetScriptSystemDisabled() Then If modScripting.GetScriptSystemDisabled() Then
Command.Respond "Error: Scripts are globally disabled." Command.Respond "Error: Scripts are globally disabled."
Expand All @@ -148,21 +146,11 @@ Public Sub OnDisable(Command As clsCommandObj)
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name) Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else Else
Name = modScripting.GetScriptName(Module.Name) 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) Command.Respond StringFormat("Error: Script ""{0}"" is already disabled.", Name)
Else Else
RunInSingle Module, "Event_Close" Call modScripting.DisableScriptModule(Name, Module)
SharedScriptSupport.WriteSettingsEntry "Enabled", "False", , Name
modScripting.DestroyObjs Module
Command.Respond StringFormat("Script ""{0}"" has been disabled.", Name) 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
End If End If
Else Else
Expand All @@ -179,8 +167,6 @@ End Sub
Public Sub OnEnable(Command As clsCommandObj) Public Sub OnEnable(Command As clsCommandObj)
Dim Module As Module Dim Module As Module
Dim Name As String Dim Name As String
Dim i As Integer
Dim mnu As clsMenuObj


If modScripting.GetScriptSystemDisabled() Then If modScripting.GetScriptSystemDisabled() Then
Command.Respond "Error: Scripts are globally disabled." Command.Respond "Error: Scripts are globally disabled."
Expand All @@ -194,20 +180,19 @@ Public Sub OnEnable(Command As clsCommandObj)
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name) Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else Else
Name = modScripting.GetScriptName(Module.Name) Name = modScripting.GetScriptName(Module.Name)
If (modScripting.IsScriptEnabled(Name) = True) Then If (modScripting.IsScriptModuleEnabled(Module, True) = True) Then
Command.Respond StringFormat("Error: Script ""{0}"" is already enabled.", Name) 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 Else
SharedScriptSupport.WriteSettingsEntry "Enabled", "True", , Name modScripting.EnableScriptModule Name, Module
Command.Respond StringFormat("Script ""{0}"" has been enabled.", Name) If modScripting.GetScriptDictionary(Module)("LoadError") Then
modScripting.InitScript Module Command.Respond StringFormat("Script ""{0}"" has been enabled. A parsing error occurred. This script will not function.", Name)
For i = 1 To DynamicMenus.Count Else
Set mnu = DynamicMenus(i) Command.Respond StringFormat("Script ""{0}"" has been enabled.", Name)
If (StrComp(mnu.Name, Chr$(0) & Name & Chr$(0) & "ENABLE|DISABLE", vbTextCompare) = 0) Then End If
mnu.Checked = True
Exit For
End If
Next i
Set mnu = Nothing
End If End If
End If End If
Else Else
Expand Down
18 changes: 12 additions & 6 deletions trunk/modCommandsInfo.bas
Expand Up @@ -307,8 +307,8 @@ On Error GoTo ERROR_HANDLER
Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name) Command.Respond StringFormat("Error: Could not find the script ""{0}"".", Name)
Else Else
Name = modScripting.GetScriptName(Script.Name) Name = modScripting.GetScriptName(Script.Name)
If (modScripting.IsScriptEnabled(Name) = False) Then If (modScripting.IsScriptModuleEnabled(Script) = False) Then
Command.Respond StringFormat("Error: Script ""{0}"" is currently disabled.", Name) Command.Respond StringFormat("Error: Script ""{0}"" is currently disabled or failed to load.", Name)
Else Else
Command.Respond StringFormat("The script ""{0}"" loaded in {1}ms.", _ Command.Respond StringFormat("The script ""{0}"" loaded in {1}ms.", _
Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0")) Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0"))
Expand All @@ -324,7 +324,7 @@ On Error GoTo ERROR_HANDLER
For i = 2 To frmChat.SControl.Modules.Count For i = 2 To frmChat.SControl.Modules.Count
Set Script = frmChat.SControl.Modules(i) Set Script = frmChat.SControl.Modules(i)
Name = modScripting.GetScriptName(CStr(i)) Name = modScripting.GetScriptName(CStr(i))
If (modScripting.IsScriptEnabled(Name)) Then If (modScripting.IsScriptModuleEnabled(Script)) Then
If (Command.IsLocal And Not Command.PublicOutput) Then If (Command.IsLocal And Not Command.PublicOutput) Then
Command.Respond StringFormat(" ""{0}"": {1}ms.", _ Command.Respond StringFormat(" ""{0}"": {1}ms.", _
Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0")) Name, Format$(GetScriptDictionary(Script)("InitPerf"), "#,##0"))
Expand Down Expand Up @@ -515,7 +515,11 @@ On Error GoTo ERROR_HANDLER
Author = ScriptInfo("Author") Author = ScriptInfo("Author")
Description = ScriptInfo("Description") 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 VerTotal > 0 Then VerStr = " v" & Version
If LenB(Author) > 0 Then AuthorStr = " by " & Author If LenB(Author) > 0 Then AuthorStr = " by " & Author
If LenB(Description) > 0 Then DescrStr = ": " & Description If LenB(Description) > 0 Then DescrStr = ": " & Description
Expand All @@ -542,6 +546,7 @@ On Error GoTo ERROR_HANDLER
Dim Part As String Dim Part As String
Dim Comma As String Dim Comma As String
Dim Name As String Dim Name As String
Dim EnCount As Integer
Dim Count As Integer Dim Count As Integer


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


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


Command.Respond StringFormat("Scripts ({0}): {1}", Count, retVal) Command.Respond StringFormat("Scripts ({0}/{1}): {2}", EnCount, Count, retVal)
Else Else
Command.Respond "There are no scripts currently loaded." Command.Respond "There are no scripts currently loaded."
End If End If
Expand Down
4 changes: 2 additions & 2 deletions trunk/modCommandsMisc.bas
Expand Up @@ -68,7 +68,7 @@ ERROR_HANDLER:
With frmChat.SControl With frmChat.SControl
ErrType = "runtime" 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) Command.Respond StringFormat("Execution {0} error #{1}: {2}", ErrType, .Error.Number, .Error.Description)


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


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

0 comments on commit 20e7ad8

Please sign in to comment.