 Rem File: Cmd143.bas
 Rem Sub: Chat.Loop
 Rem $Include: 'dndbbs.inc'
 If Chained<>-2 Then
    Color 15,0
    Print "DNDBBS Command 143 -- Chat.Loop."
    Color 7,0
    End
 Endif
 Var1=Hidden.Player
 Call Chat.Loop
 Hidden.Player=Var1
Main.Resume:
 Chain DND.Path+"DNDBBS.EXE"
 End
Main.Error:
 Resume Main.Resume

Sub Chat.Loop
 On Local Error Goto Err.Trap24
 Gosub Get.Config
 Dim Alarm.Flags(1 to Max.Alarms) As Integer
 Dim Alarm.Start(1 to Max.Alarms) As Single
 Dim Alarm.Time(1 to Max.Alarms) As Single
 For VarZ=1 To Max.Alarms
    Alarm.Flags(VarZ)=0
    Alarm.Start(VarZ)=0!
    Alarm.Time(VarZ)=0!
 Next
 If Chat.Mode=True Then
    Var$="Press <ctrl-break>/<ctrl-c> to interrupt"
    If Local.Mode=False Then
       Var$="Press <control-c>/<control-k> to interrupt"
    Endif
    Select Case Last.Command.Number ' 1, 4, 14
    Case AutoCommand
       Strng="Chat Auto-mode."
    Case ChatCommand
       Strng="Chat Talk-mode."
       If Len(Config3(78)) Then
          Var$="Enter "+Config3(78)+"Quit to exit. Type "+Config3(78)+"? for Help"
       Endif
    Case WaitCommand
       Strng="Chat Wait-mode."
    Case Else
       Strng="Chat mode."
    End Select
    Strng=Strng+" "+Var$+"."
    Graphics.Off=False
    Call IO.O
 Endif
 Allow.Break=True
 Auto.Break=False
 Break=False
 Var1!=Timeit!
 Var2=False
 Var3=Last.Command.Number
 Var4=Command.Time.Limit
 Var5=Var4
 VarZ#=0#
 Last.Command="Chatting"
 Call Update.Mess(4)
 Do While Security.Guard
    Allow.Break=True
    If New.Room Then
       Call Enter.New.Room
    Endif
    If Var3=AutoCommand Or Var3=WaitCommand Then
       VarQ!=Timeit!
       Do While Lost.Carrier=False
          If option1!>0! Then
             If Time.Elapsed(VarQ!,Option1!) Then
                Exit Do
             Endif
          Endif
          Call Keyboard(Var1)
          If Break Then
             If Option4 Then
                Strng="<escape>"
                Call IO.O
             Endif
             Exit Do
          Endif
          Call Get.Modem(False)
          If Len(Buffer) Then
             If Instr(Buffer,Chr$(27)) Then
                Buffer=Nul
                If Option4 Then
                   Strng="<escape>"
                   Call IO.O
                Endif
                Exit Do
             Endif
             Buffer=Nul
          Endif
          Call Check.Break
          If Auto.Break Then
             'Strng="*break*"
             'Call IO.O
             Exit Do
          Endif
          Call Check.Carrier
          Call Read.Mess

          ' online user entered /chat and started talking.
          If Chat.Mode=1 Then
             Chat.Mode=True
             ' switch from /wait mode to /chat mode.
             If Var3=WaitCommand Then
                If option2 Then
                   Strng="*switch*"
                   Call IO.O
                Endif
                Var3=ChatCommand
                Var4=Var5
                Exit Do
             Endif
          Endif

          Call IO.Timing
          Call Read.Node.Mess
          If Local.Mode Then
             Call Release.Time(1)
          Endif
       Loop
    Endif
    If Var4>False Then
       If Time.Elapsed(Var1!,Csng(Var4)) Then
          Var2=True
          Exit Do
       Endif
    Endif
    If Option1#>0# Then
       VarZ#=VarZ#+1#
       If VarZ#>Option1# Then
          Var2=-2
          Exit Do
       Endif
    Endif
    If Var3=ChatCommand Then
       Graphics.Off=True
       Graphics.On=True
       If Rtrim$(NodeX)=Nul Then
          Strng="#>"
       Else
          Strng=NodeX+">"
       Endif
       Call Modem.ANSI(4,37,15)
       Call ScreenANSI(4,37,15)
       Call IO.I
       For VarZZ=1 To Max.Alarms
          If Alarm.Time(VarZZ)=0! Then
             Alarm.Flags(VarZZ)=0
          Endif
       Next
       For VarZZ=1 To Max.Alarms
          VarZ5=Alarm.Flags(VarZZ)
          VarZ2!=Alarm.Start(VarZZ)
          VarZ3!=Alarm.Time(VarZZ)
          If VarZ5 Then
             If VarZ2!>0! And VarZ3!>0! Then
                If Time.Elapsed(VarZ2!,VarZ3!) Then
                   VarZ=-1
                   Alarm.Flags(VarZZ)=False
                   If Alarm.Beep Then
                      Call Put.Modem(Chr$(7))
                      Sound Option21, Option22
                   Endif
                   Strng="Alarm"+Str$(VarZZ)+" notice! It is now "+Fclock$
                   Call IO.O
                Endif
             Endif
          Endif
       Next
       If Lost.Carrier Then
          Exit Do
       Endif
       If Node.Abort Then
          Exit Do
       Endif
       If Auto.Break Then
          Call IO.O
          Exit Do
       Endif
       Graphics.Off=False
       If Len(Out2) Then
          ' parse mode command
          VarZ=0
          If Lcase$(Out2)="!break" Then
             VarZ=-1
             Option3=Not Option3
             If Option3 Then
                Strng="Break display on."
             Else
                Strng="Break display off."
             Endif
             Call IO.O
          Endif
          If Lcase$(Out2)="!switch" Then
             VarZ=-1
             Option2=Not Option2
             If Option2 Then
                Strng="Switch display on."
             Else
                Strng="Switch display off."
             Endif
             Call IO.O
          Endif
          If Lcase$(Out2)="!alarmbeep" Then
             VarZ=-1
             Alarm.Beep=Not Alarm.Beep
             If Alarm.Beep Then
                Strng="Alarm beep on."
             Else
                Strng="Alarm beep off."
             Endif
             Call IO.O
          Endif
          If Lcase$(Out2)="!alarmhelp" Then
             VarZ=-1
             Graphics.On=False
             Graphics.Off=False
             Strng="Helplist for alarms.."
             Call IO.O
             Graphics.Off=True
             Strng="!alarm" : Call IO.O
             Strng="  sets seconds per alarm for"+Str$(Max.Alarms)+" alarms." : Call IO.O
             Strng="!alarmbeep" : Call IO.O
             Strng="  toggles alarm beeps." : Call IO.O
             Strng="!alarmlist" : Call IO.O
             Strng="  lists settings for all alarms set." : Call IO.O
             Strng="!alarmcount" : Call IO.O
             Strng="  displays number of alarms set." : Call IO.O
             Graphics.Off=False
             Call More.Prompt
          Endif
          If Lcase$(Out2)="!alarmcount" Then
             VarZ=-1
             Temp5=0
             For VarZZ=1 To Max.Alarms
                If Alarm.Flags(VarZZ) Then
                   Temp5=Temp5+1
                Endif
             Next
             If Temp5=0 Then
                Strng="No alarms are set."
                Call IO.O
             Else
                Strng="There are"+Str$(Temp5)+" alarms set."
                Call IO.O
             Endif
          Endif
          If Lcase$(Out2)="!alarmlist" Then
             Temp5=0 : TempC=0
             VarZ=-1
             VarZ1=0
             For VarZZ=1 To Max.Alarms
                If Alarm.Flags(VarZZ) Then
                   VarZ1=-1
                   Strng="Alarm"+Str$(VarZZ)+" set to"+Str$(Alarm.Time(VarZZ))+" seconds."

                   Elapsed!=Timeit!-Alarm.Start(VarZZ)
                   If Elapsed!<0! Then Elapsed!=Elapsed!+86400!
                   Remaining!=Alarm.Time(VarZZ)-Elapsed!
                   Strng=Strng+" ("+Ltrim$(Str$(Remaining!))+" seconds remaining)"

                   Call IO.O
                   Temp5=Temp5+1
                   If Temp5>=User.Pagelength-2 Then
                      If Continuous=False Then
                         Call More.Prompt
                         Temp5=False
                         If No Or Quit Then
                            Exit FOr
                         Endif
                      Endif
                   Endif
                Endif
             Next
             If Temp5 Then
                Call More.Prompt
             Endif
             If VarZ1=0 Then
                Strng="No alarms set."
                Call IO.O
             Endif
          Endif
          If Lcase$(Out2)="!alarm" Then
             VarZ=-1
             Strng="Enter alarm(1-"+Ltrim$(Str$(Max.Alarms))+")? "
             Call IO.I
             VarZZ=Int(Val(Out2))
             If VarZZ>=1 And VarZZ<=Max.Alarms Then
                Strng="Enter alarm time(seconds)? "
                Call IO.I
                If Int(Val(Out2))=0 Then
                   Alarm.Flags(VarZZ)=0
                   Strng="Alarm cleared." : Call IO.O
                Endif
                If Int(Val(Out2))>0 And Int(Val(Out2))<=86400 Then
                   Alarm.Flags(VarZZ)=-1
                   Alarm.Start(VarZZ)=Timeit!
                   Alarm.Time(VarZZ)=Int(Val(Out2))
                   Strng="Alarm set." : Call IO.O
                Endif
             Endif
          Endif
          If Lcase$(Out2)="!maxnodes" Then
             VarZ=-1
             Strng="Maxnodes:"+Str$(MaxNodes+1)+"."
             Call IO.O
          Endif
          If Lcase$(Out2)="!time" Then
             VarZ=-1
             Call Time.Online(False)
          Endif
          If Lcase$(Out2)="!clock" Then
             VarZ=-1
             Strng="It is now: "+Fclock$
             Call IO.O
          Endif
          If Lcase$(Out2)="!prefix" Then
             VarZ=-1
             If Len(Config3(78)) Then
                Strng="Prefix is "+Config3(78)
                Call IO.O
             Endif
          Endif
          If Lcase$(Out2)="!count" Then
             VarZ=-1
             VarQ=0
             VarQ2=0
             VarQ3=0
             For VarX=False To MaxNodes
                Call Read.Message.Record(MessWorkFile1,VarX+1)
                Strng=Rtrim$(MessWorkRecord1.UserName)
                Call Valid.Name(Strng)
                If TempA Then
                   If MessWorkRecord1.Chatting Then
                      VarQ2=VarQ2+1
                   Endif
                   If MessWorkRecord1.Monitor Then
                      VarQ3=VarQ3+1
                   Endif
                   VarQ=VarQ+1
                Endif
             Next
             Strng="There are"+Str$(VarQ)+" users online and"+Str$(VarQ2)+" users chatting."
             Call IO.O
             If VarQ3 Then
                Strng="Users monitoring:"+Str$(VarQ3)+"."
                Call IO.O
             Endif
          Endif

          If Lcase$(Out2)="!monitor" Then
             VarZ=-1
             VarQ3=0
             For VarX=False To MaxNodes
                Call Read.Message.Record(MessWorkFile1,VarX+1)
                Strng=Rtrim$(MessWorkRecord1.UserName)
                Call Valid.Name(Strng)
                If TempA Then
                   If MessWorkRecord1.Monitor Then
                      VarQ3=VarQ3+1
                   Endif
                Endif
             Next
             Strng="Users monitoring:"+Str$(VarQ3)+"."
             Call IO.O
          Endif

          VarZZ=0
          If Lcase$(Out2)="!users" Then
             VarZZ=1
          Endif
          If Lcase$(Out2)="!userrooms" Then
             VarZZ=2
          Endif
          If Lcase$(Out2)="!userlevels" Then
             VarZZ=3
          Endif
          If VarZZ Then
             VarZ=-1
             VarQ=0
             VarQ2=0
             VarQ3=0
             For VarX=False To MaxNodes
                Call Read.Message.Record(MessWorkFile1,VarX+1)
                Strng=Rtrim$(MessWorkRecord1.UserName)
                Call Valid.Name(Strng)
                If TempA Then
                   If MessWorkRecord1.Monitor Then
                      VarQ3=VarQ3+1
                   Endif
                   If MessWorkRecord1.Chatting Then
                      VarQ2=VarQ2+1
                   Endif
                   VarQ=VarQ+1
                Endif
             Next
             Strng="Users online:"+Str$(VarQ)+", users chatting:"+Str$(VarQ2)+"."
             Call IO.O
             If VarQ3 Then
                Strng="Users monitoring:"+Str$(VarQ3)+"."
                Call IO.O
             Endif
             Strng=Nul
             Select Case VarZZ
             Case 1
                Strng="Userlist:"
             Case 2
                Strng="Userlist rooms:"
             Case 3
                Strng="Userlist levels:"
             Case Else
                Strng="Userlist:"
             End Select
             Call IO.O
             VarY=0
             Strng=Nul
             For VarX=False To MaxNodes
                Call Read.Message.Record(MessWorkFile1,VarX+1)
                Strng2=Rtrim$(MessWorkRecord1.UserName)
                Call Valid.Name(Strng2)
                If TempA Then
                   Strng2=Lcase$(Strng2)
                   Mid$(Strng2,1,1)=Ucase$(Mid$(Strng2,1,1))
                   If VarZZ=2 Then
                      Strng2=Strng2+" ("+Ltrim$(Str$(MessWorkRecord1.RoomNumber))+")"
                   Endif
                   If VarZZ=3 Then
                      Strng2=Strng2+" ["+Ltrim$(Str$(MessWorkRecord1.Level))+"]"
                   Endif
                   ' detect wordwrap and paginate.
                   If Len(Strng+Strng2+", ")>=User.LineLength Then
                      Call IO.O
                      Strng=Nul
                      VarY=VarY+1
                      If VarY>=User.PageLength-2 Then
                         VarY=0
                         Call More.Prompt
                      Endif
                      Strng=Strng2+", "
                   Else
                      Strng=Strng+Strng2+", "
                   Endif
                Endif
             Next
             If Len(Strng) Then
                Strng=Left$(Strng,Len(Strng)-2)+"."
                Call IO.O
             Endif
          Endif
          ' always allow /quit
          If Len(Config3(78))=0 Then
             If Lcase$(Out2)="/quit" Then
                VarZ=-1
                Exit Do
             Endif
             If Lcase$(Out2)="/q" Then
                VarZ=-1
                Exit Do
             Endif
          Endif
          ' parse node command
          If Len(Config3(78)) Then
             If VarZ=0 Then
                If Left$(Out2,Len(Config3(78)))=Config3(78) Then
                   VarZ=-1
                   Call Command.Loop
                   ' /quit
                   If Last.Command.Number=12 Then
                      Exit Do
                   Endif
                   ' enter /auto or /wait.
                   If Last.Command.Number=AutoCommand Or _
                      Last.Command.Number=WaitCommand Then
                      Var3=Last.Command.Number
                      Var4=Command.Time.Limit
                   Endif
                Endif
             Endif
          Endif
          If VarZ=0 Then
             ' send a /chat message to other nodes.
             If Len(Out2) Then
                Call Send.Mess(26,SFalse,SFalse,Out2)
                Out2=Nul
             Endif
          Endif
       Endif
    Endif
    If Auto.Break Then
       If Var3=ChatCommand Then
          Exit Do
       Endif
       If Option3 Then
          Strng="*break*"
          Call IO.O
       Endif
       Auto.Break=False
       Break=False
       Var3=ChatCommand
       Var4=Var5
       Strng="Chat Talk-mode."
       If Len(Config3(78)) Then
          Strng=Strng+" Enter "+Config3(78)+"Quit to exit. Type "+Config3(78)+"? for Help.."
       Endif
       Call IO.O
    Endif

    Call Get.Modem(False)
    If Len(Buffer) Then
       If Instr(Buffer,Chr$(27)) Then
          Buffer=Nul
          If Option4 Then
             Strng="<escape>"
             Call IO.O
          Endif
          Exit Do
       Endif
       Buffer=Nul
    Endif

    Call Keyboard(Var1)
    If Lost.Carrier Then
       Exit Do
    Endif
    If Node.Abort Then
       Exit Do
    Endif
    If Auto.Break Then
       'Strng="*break*"
       'Call IO.O
       Exit Do
    Endif
    Hidden.Player=True
    Call Write.Record(UserFile,User.Index)
    Timeout=Timeit!
    Call IO.Timing
    Call Read.Node.Mess
    Select Case Var3
    Case AutoCommand
       Last.Command="Chat Auto-Mode"
    Case ChatCommand
       Last.Command="Chat Talk-Mode"
    Case WaitCommand
       Last.Command="Chat Wait-Mode"
    Case Else
       Last.Command="Chat Mode"
    End Select
    Call Update.Mess(4)
    Call Read.Mess

    ' online user entered /chat and started talking.
    If Chat.Mode=1 Then
       Chat.Mode=True
       ' switch from /wait mode to /chat mode.
       If Var3=WaitCommand Then
          If option2 Then
             Strng="*switch*"
             Call IO.O
          Endif
          Var3=ChatCommand
          Var4=Var5
       Endif
    Endif

    If Local.Mode Then
       Call Release.Time(1)
    Endif
 Loop
 If Auto.Break Then
    If Option3 Then
       Strng="*break*"
       Call IO.O
    Endif
 Endif
 Allow.Break=False
 Auto.Break=False
 Chat.Mode=False
 Break=False
 Wait.Mode=False
 Last.Command="Exit Chat"
 Call Update.Mess(4)
 If Var2=True Then
    Strng="Command time limit!"
    Call IO.O
 Endif
 If Var2=-2 Then
    Strng="Command rounds exceeded!"
    Call IO.O
 Endif
 Exit Sub
Get.Config:
 VarX=0
 Option1#=-1#
 Option1!=-1!
 Option2=0
 Option3=-1
 Option4=-1
 Max.Alarms=9
 Alarm.Beep=-1
 ' sound frequency
 Option21 = 900
 ' sound duration
 Option22 = 6
 Do
    VarX=VarX+1
    If VarX>Options.Lines Then
       Exit Do
    Endif
    Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
    If Ucase$(Var$)="[CMD143]" Then
       Do
          VarX=VarX+1
          If VarX>Options.Lines Then
             Return
          Endif
          Var$=Ltrim$(Rtrim$(Options.Array(VarX)))
          If Ucase$(Var$)="[END]" Then
             Return
          Endif
          Var=Instr(Var$,"=")
          If Var Then
             Var2$=Ltrim$(Rtrim$(Left$(Var$,Var-1)))
             Var3$=Ltrim$(Rtrim$(Mid$(Var$,Var+1)))
             Var4=Int(Val(Var3$))
             Select Case Lcase$(Var2$)
             Case "escape.switch"
                Select Case Ucase$(Var3$)
                Case "0", "FALSE","OFF"
                   Option4=0
                End Select
             Case "break.switch"
                Select Case Ucase$(Var3$)
                Case "0", "FALSE","OFF"
                   Option3=0
                End Select
             Case "debug.switch"
                Select Case Ucase$(Var3$)
                Case "-1", "TRUE","ON"
                   Option2=-1
                End Select
             Case "alarm.beep"
                Select Case Ucase$(Var3$)
                Case "0", "FALSE","OFF"
                   Alarm.Beep=0
                End Select
             Case "sound.frequency"
                If Var4>37 And Var4<=32767 Then
                   option21=Var4
                Endif
             Case "sound.duration"
                If Var4>=1 And Var4<=32767 Then
                   option22=Var4
                Endif
             Case "maximum.alarms"
                If Var4>0 And Var4<=100 Then
                   Max.Alarms=Var4
                Endif
             Case "maximum.rounds.counter"
                Option1#=Int(Val(Var3$))
             Case "round.time.delay"
                Option1!=Csng(Val(Var3$))
             End Select
          Endif
       Loop
    Endif
 Loop
 Return
Err.Resume24:
 Exit Sub
Err.Trap24:
 If Debug.Mode Then
    Strng="Error"+Str$(Err)
    Call IO.O
 Endif
 Resume Err.Resume24
End Sub

Sub Command.Loop
 On Local Error Goto Err.Trp18
 Last.Command.Number=False
 Out2=Ltrim$(Out2)
 Var1=False
 VarX=False
 Stored.Parsed.Command1=Out2
 Out2=Ucase$(Out2)
 Stored.Parsed.Command2=Out2
 If Out2=Config3(78)+"?" Or Out2=Config3(78)+"HELP" Then
    If Brief.Messages Then
       FileName=Config3(52)+Config3(65)+"M"+File.Extension2 ' catalogm.doc
    Else
       FileName=Config3(52)+Config3(50)+"M"+File.Extension2 ' summarym.doc
    Endif
    If Len(Dir$(Filename)) Then
       Call Out.File2(Filename)
    Endif
    Strng=Nul : Call IO.O
    Strng="!time - time online." : Call IO.O
    Strng="!clock - current time." : Call IO.O
    Strng="!prefix - display prefix." : Call IO.O
    Strng="!users - display userlist." : Call IO.O
    Strng=" !userrooms - display userlist with roomnumber." : Call IO.O
    Strng=" !userlevels - display userlist with userlevel." : Call IO.O
    Strng="!count - display user count." : Call IO.O
    Strng="!maxnodes - display maximum nodes." : Call IO.O
    Strng="!monitor - display number of monitors." : Call IO.O
    Strng="!alarmhelp - display alarm functions." : Call IO.O
    Graphics.Off=False
    Strng="Chat Talk-Mode. Enter "+Config3(78)+"Quit to exit. Type "+Config3(78)+"? for Help.."
    Call IO.O
    Exit Sub
 Endif
 If Out2=Config3(10) Then
    User.Command=Previous.Command1
    Stored.Parsed.Command1=Previous.Command2
    Stored.Parsed.Command2=Previous.Command3
 Else
    User.Command=Out2
    Previous.Command1=User.Command
    Previous.Command2=Stored.Parsed.Command1
    Previous.Command3=Stored.Parsed.Command2
 Endif
 If User.Command=Nul Then
    Last.Command=Enter$
    Call Update.Mess(4)
    Exit Sub
 Endif
 Entry.Command=False
 Magic.Spell=False
 Temp.Command=User.Command
 If Instr(Temp.Command," ") Then
    Temp.Command=Left$(Temp.Command,Instr(Temp.Command," ")-1)
 Endif
 Parser=Instr(User.Command," ")
 If Parser Then
    Parsed.Command1=Mid$(User.Command,Parser+1)
    Parsed.Command2=Parsed.Command1
    VarX=Instr(Stored.Parsed.Command1," ")+1
    Stored.Parsed.Command1=Mid$(Stored.Parsed.Command1,VarX)
    Stored.Parsed.Command2=Mid$(Stored.Parsed.Command2,VarX)
    Call Numeric
 Endif
 TempY=Parse.Temp
 Call Numeric2
 TempX=Parse.Temp
 Parse.Temp=TempY
 TempQ=False
 Temp.Command=Mid$(Temp.Command,Len(Config3(78))+1)
 For Last.Command.Number=1 To MaxNodeCommands
    TempZ=Last.Command.Number+MaxUserCommands+MaxDMcommands+MaxSysopCommands
    Call Read.Message.Record(MessWorkFile8,TempZ)
    Last.Command=UserCommandRecord.CommandSet(1)
    Last.Command=Rtrim$(Left$(Last.Command,10))
    If Left$(Last.Command,Len(Temp.Command))=Temp.Command Then
       TempQ=True
       Exit For
    Endif
 Next
 If TempQ=False Then
    Strng="Unknown command!"
    Call IO.O
    Last.Command="<unknown>"
    Call Update.Mess(4)
    Exit Sub
 Endif

 ' check appended #<n> for /Sta and /Who
 If Last.Command.Number<>10 Then
    If Last.Command.Number<>15 Then
       If TempX Then
          Strng="Unknown command!"
          Call IO.O
          Last.Command="<unknown>"
          Call Update.Mess(4)
          Exit Sub
       Endif
    Endif
 Endif

 ' always allow /quit
 If Last.Command.Number=12 Then
    Goto Next.Line
 Endif

 ' check command restriction
 If Normal.User Then
    If UserRecord.ClassType<AsstDM Then
       If UserCommandRecord.CommandClass(UserRecord.ClassType) Then
	  Graphics.Off=True
	  Strng="Command restriction!"
	  Call IO.O
	  Graphics.Off=False
          Last.Command="<restrict>"
          Call Update.Mess(4)
	  Exit Sub
       Endif
    Endif
 Endif

 ' check command restriction
 Var1=MaxUserCommands+MaxDMCommands+MaxSysopCommands+Last.Command.Number
 Call Check.Restriction(Var1,Var2)
 If Var2 Then Exit Sub

 ' implement node command
Next.Line:
 Call Update.Mess(4)
 Command.Time.Limit=UserCommandRecord.CommandLimit
 Select Case Last.Command.Number
 Case 1 ' /auto
    Chat.Mode=True
    Var$="Press <ctrl-break>/<ctrl-c> to interrupt"
    If Local.Mode=False Then
       Var$="Press <control-c>/<control-k> to interrupt"
    Endif
    Strng="Chat Auto-mode. "+Var$+"."
    Call IO.O
 Case 2 ' /block
    Call Block
 Case 3 ' /brief
    Brief.Messages = NOT Brief.Messages
    If Brief.Messages Then
       Strng="Brief messaging on."
    Else
       Strng="Brief messaging off."
    Endif
    Call IO.O
 Case 4 ' /chat
    If Chat.Mode Then
       Strng="You are already in chat mode."
    Else
       Chat.Mode=True
       Strng="Chat Talk-mode. Enter "+Config3(78)+"Quit to exit. Type "+Config3(78)+"? for Help.."
    Endif
    Call IO.O
 Case 5 ' /echo
    Call Flag.Toggles(2)
 Case 6 ' /group
    Call Group.Send
 Case 7 ' /nosend
    Call No.Send
 Case 8 ' /say
    If Parser=False Then
       Strng="Say what? "
       Call IO.I
       If Out2=Nul Then
          Exit Sub
       Endif
       Stored.Parsed.Command1=Out2
    Endif
    Call Send.Mess(3,SFalse,Room,Stored.Parsed.Command1)
 Case 9 ' /send
    If Parser=False Then
       Strng="Send what? "
       Call IO.I
       If Out2=Nul Then
          Exit Sub
       Endif
       Stored.Parsed.Command1=Out2
    Endif
    Call Send.Mess(1,SFalse,SFalse,Stored.Parsed.Command1)
 Case 10 ' /status
    Call Read.Status
 Case 11 ' /sendto
    If Parser=False Then
       Strng="Send to whom? "
       Call IO.I
       If Out2=Nul Then
          Exit Sub
       Endif
       Stored.Parsed.Command1=Out2
    Endif
    Call Send.Message
 Case 12 ' /quit
    Auto.Break=False
    Chat.Mode=False
    Strng="Chat mode ended."
    Call IO.O
    Exit Sub
 Case 13 ' /whisper
    If Parser=False Then
       Strng="Whisper to whom? "
       Call IO.I
       If Out2=Nul Then
          Exit Sub
       Endif
       Stored.Parsed.Command1=Out2
    Endif
    Call Whisper
 Case 14 ' /wait
    Chat.Mode=True
    Var$="Press <ctrl-break>/<ctrl-c> to interrupt"
    If Local.Mode=False Then
       Var$="Press <control-c>/<control-k> to interrupt"
    Endif
    Strng="Chat Wait-mode. "+Var$+"."
    Call IO.O
 Case 15 ' /who
    Call Whos.On
 Case 16 ' /yell
    If Parser=False Then
       Strng="Yell what? "
       Call IO.I
       If Out2=Nul Then
          Exit Sub
       Endif
       Stored.Parsed.Command1=Out2
    Endif
    Call Send.Mess(2,SFalse,-1!,Stored.Parsed.Command1)
 End Select
Err.Rsm18:
 Exit Sub
Err.Trp18:
 Resume Err.Rsm18
End Sub

Sub Group.Send
 On Local Error Goto Err.Trp16
 Graphics.Off=False
 Strng="Enter grouped message. 9 lines max."
 Call IO.O
 Strng="Press "+Enter$+" on a blank line to send."
 Call IO.O
 Graphics.Off=True
 TempZ=False
 Redim Temp.ArrayS(1 To 9) As String
 For TempX=1 To 9
    Line.Length=79
    Strng="?"
    Call IO.I
    If Lost.Carrier Then
       Exit Sub
    Endif
    If Out2=Nul Then
       Exit For
    Endif
    TempZ=TempZ+1
    Temp.ArrayS(TempZ)=Out2
 Next
 If TempZ Then
    Do
       TempA$=Str$(Timer)
       ' find group message with same time
       VarX=False
       For Var!=1! To Lof(MessWorkFile2)/MessWorkRecLen2
          Call Read.Record(MessWorkFile2,Var!)
          If MessWorkRecord2.MessageType=25 Then
             TempQ$=MessWorkRecord2.Message2
             TempQ$=Mid$(TempQ$,3)
             TempQ$=Rtrim$(TempQ$)
             If TempA$=TempQ$ Then
                VarX=True
                Exit For
             Endif
          Endif
       Next
       If VarX=False Then Exit Do
    Loop
    ' send group message
    For TempX=1 To TempZ
       VarZ$=Temp.ArrayS(TempX)
       Call Send.Mess(25,SFalse,Room,VarZ$)
    Next
 Endif
 Graphics.Off=False
 If TempZ Then
    Strng="Grouped message sent."
 Else
    Strng="No grouped message sent."
 Endif
 Call IO.O
 Erase Temp.ArrayS
Err.Rsm16:
 Exit Sub
Err.Trp16:
 Resume Err.Rsm16
End Sub

Sub Block
 On Local Error Goto Err.Trp14
 If Lcase$(Parsed.Command1)="self" Then
    Var=Not UserRecord.Block1
    UserRecord.Block1=Var
    If Var Then
       Strng="User block on."
    Else
       Strng="User block off."
    Endif
    Call IO.O
    Exit Sub
 Endif
 Call Get.Node(Var!)
 If Var!=SFalse Then
    Strng="That player is not online!"
    Call IO.O
    Exit Sub
 Endif
 TempC=Temp
 If TempC=Node Then
    Strng="Can't block yourself!"
    Call IO.O
    Exit Sub
 Endif
 Out2=Lcase$(Strng)
 Mid$(Out2,1,1)=Ucase$(Mid$(Out2,1,1))
 VarX2=Node+1
 Call Read.Message.Record(MessWorkFile1,VarX2)
 TempA=Val(Mid$(MessWorkRecord1.ReceiveFlags,TempC+1,1))
 If TempA=False Then
    TempA=1
    Strng="No longer blocking "+Out2+"."
 Else
    TempA=False
    Strng="Now blocking "+Out2+"."
 Endif
 Call IO.O
 Mid$(MessWorkRecord1.ReceiveFlags,TempC+1,1)=Ltrim$(Str$(TempA))
 VarX2=Node+1
 Call Write.Message.Record(MessWorkFile1,VarX2)
Err.Rsm14:
 Exit Sub
Err.Trp14:
 Resume Err.Rsm14
End Sub

Sub No.Send
 On Local Error Goto Err.Trp15
 If Lcase$(Parsed.Command1)="self" Then
    Var=Not UserRecord.Block2
    UserRecord.Block2=Var
    If Var Then
       Strng="User nosend on."
    Else
       Strng="User nosend off."
    Endif
    Call IO.O
    Exit Sub
 Endif
 Call Get.Node(Var!)
 If Var!=SFalse Then
    Strng="That player is not online!"
    Call IO.O
    Exit Sub
 Endif
 TempC=Temp
 If TempC=Node Then
    Strng="Can't nosend yourself!"
    Call IO.O
    Exit Sub
 Endif
 Out2=Lcase$(Strng)
 Mid$(Out2,1,1)=Ucase$(Mid$(Out2,1,1))
 VarX2=Node+1
 Call Read.Message.Record(MessWorkFile1,VarX2)
 TempA=Val(Mid$(MessWorkRecord1.SendFlags,TempC+1,1))
 If TempA=False Then
    TempA=1
    Strng="Now sending to "+Out2+"."
 Else
    TempA=False
    Strng="No longer sending to "+Out2+"."
 Endif
 Call IO.O
 Mid$(MessWorkRecord1.SendFlags,TempC+1,1)=Ltrim$(Str$(TempA))
 VarX2=Node+1
 Call Write.Message.Record(MessWorkFile1,VarX2)
Err.Rsm15:
 Exit Sub
Err.Trp15:
 Resume Err.Rsm15
End Sub

Sub Send.Message
 On Local Error Goto Err.Trp13
 Call Get.Node(Var!)
 If Var!=SFalse Then
    Strng="That player is not online!"
    Call IO.O
    Exit Sub
 Endif
 TempC=Temp
 If TempC=Node Then
    Strng="Can't send to yourself!"
    Call IO.O
    Exit Sub
 Endif
 Strng="Send what? "
 Call IO.I
 If Len(Out2) Then
    Call Send.Mess(6,TempB!,SFalse,Out2)
 Endif
Err.Rsm13:
 Exit Sub
Err.Trp13:
 Resume Err.Rsm13
End Sub

Sub Whisper
 On Local Error Goto Err.Trp12
 Call Search.Mess(SFalse)
 If Temp!<>Room Then
    Strng="That player is not in this room!"
    Call IO.O
    Exit Sub
 Endif
 If TempC=Node Then
    Strng="Can't whisper to yourself!"
    Call IO.O
    Exit Sub
 Endif
 Strng="Whisper what? "
 Call IO.I
 If Len(Out2) Then
    Call Send.Mess(7,TempB!,Room,Out2)
 Endif
Err.Rsm12:
 Exit Sub
Err.Trp12:
 Resume Err.Rsm12
End Sub

Sub Read.Status
 On Local Error Goto ErrTrap8
 If Parser Then
'    Parsed.Command1=Stored.Parsed.Command1
    If Lcase$(Parsed.Command1)="self" Then
       TempC=Node
       Gosub Read.Status.Header
       Gosub Read.User.Status
       Exit Sub
    Endif
    Call Get.Node(Var!)
    If Var!=SFalse Then
       Strng="That player is not online!"
       Call IO.O
    Else
       TempC=Temp
       Gosub Read.Status.Header
       Gosub Read.User.Status
    Endif
    Exit Sub
 Endif
 Gosub Read.Status.Header
 If Node=False Then
    Temp5=Temp5+1
    TempC=False
    Strng=UserRecord.CodeName
    Call Make.Mess.Work1
    Gosub Read.User.Status
 Endif
 For TempC=1 To MaxNodes
    Call Read.Message.Record(MessWorkFile1,TempC+1)
    Strng=Rtrim$(MessWorkRecord1.Username)
    Call Valid.Name(Strng)
    If TempA Then
       Gosub Read.User.Status
       Temp5=Temp5+1
       If Temp5>=User.Pagelength-2 Then
          If Continuous=False Then
             Call More.Prompt
             Temp5=False
             If No Or Quit Then
                Exit For
             Endif
             Gosub Read.Status.Header
          Endif
       Endif
    Endif
 Next
 If Temp5 Then
    Call More.Prompt
 Endif
 Exit Sub

Read.Status.Header:
 Temp5=4
 Graphics.Off=True
 Strng="DNDBBS v"+Version$+" Status Report For "+Left$(Fclock$,15)+"."
 Call IO.O
 Strng=Nul
 Call IO.O
 Select Case TempX
 Case 3
    Strng="Port Y  H  Username                       Timeon   Last Command"
    Call IO.O
    Call Display.Line(63)
 Case 2
    Strng="Port Y  H  Username                       Timeon   Level"
    Call IO.O
    Call Display.Line(58)
 Case Else
    Strng="Port Y  H  Username                       Timeon"
    Call IO.O
    Call Display.Line(50)
 End Select
 Return

Read.User.Status:
 Select Case TempC
 Case 0
    Strng="P##"
 Case 1 To 10 ' 0-9
    Strng="P#"+Mid$(Str$(TempC-1),2)
 Case 11 To 36 ' A-Z
    Strng="P#"+Chr$(TempC+54)
 Case 37 To 126 ' 10-99
    Strng="P#"+Mid$(Str$(TempC-27),2)
 End Select
 Strng=Strng+Space$(5-Len(Strng))
 If TempC=Node Then
    Strng=Strng+"-- -- "
 Else
    VarX2=Node+1
    Call Read.Message.Record(MessWorkFile1,VarX2)
    Var1$=MessWorkRecord1.SendFlags
    Var2$=MessWorkRecord1.ReceiveFlags
    If Mid$(Var1$,TempC+1,1)="1" Then
       Strng=Strng+"S"
    Else
       Strng=Strng+" "
    Endif
    If Mid$(Var2$,TempC+1,1)="1" Then
       Strng=Strng+"R"
    Else
       Strng=Strng+" "
    Endif
    Strng=Strng+" "
    Call Read.Message.Record(MessWorkFile1,TempC+1)
    Var1$=MessWorkRecord1.SendFlags
    Var2$=MessWorkRecord1.ReceiveFlags
    If Mid$(MessWorkRecord1.SendFlags,Node+1,1)="1" Then
       Strng=Strng+"S"
    Else
       Strng=Strng+" "
    Endif
    If Mid$(MessWorkRecord1.ReceiveFlags,Node+1,1)="1" Then
       Strng=Strng+"R"
    Else
       Strng=Strng+" "
    Endif
    Strng=Strng+" "
 Endif
 Out3=Nul
 Out2=Lcase$(MessWorkRecord1.UserName)
 Mid$(Out2,1,1)=Ucase$(Mid$(Out2,1,1))
 If TempX=2 Then
    Out3=Ltrim$(Str$(MessWorkRecord1.Level))
 Else
    If TempX=3 Then
       Out3=MessWorkRecord1.LastCommand
       Select Case Left$(Out3,1)
       Case "a" To "z", "A" To "Z"
          Out3=Lcase$(Out3)
          Mid$(Out3,1,1)=Ucase$(Mid$(Out3,1,1))
       End Select
    Endif
 Endif
 Strng=Strng+Out2+" "+MessWorkRecord1.TimeOn+" "+Out3
 Call IO.O
 Return
ErrResume8:
 Exit Sub
ErrTrap8:
 Resume ErrResume8
End Sub

Sub Whos.On
 On Local Error Goto ErrorTrap19a
 If Parser Then
'    Parsed.Command1=Stored.Parsed.Command1
    If Lcase$(Parsed.Command1)="self" Then
       TempC=Node
       Gosub Read.Who.Header
       Gosub Read.Who.Status
       Exit Sub
    Endif
    Call Get.Node(Var!)
    If Var!=SFalse Then
       Strng="That player is not online!"
       Call IO.O
    Else
       TempC=Temp
       Gosub Read.Who.Header
       Gosub Read.Who.Status
    Endif
    Exit Sub
 Endif
 Gosub Read.Who.Header
 If Rtrim$(NodeX)=Nul Then
    Temp5=Temp5+1
    TempC=False
    Strng=UserRecord.CodeName
    Call Make.Mess.Work1
    Gosub Read.Who.Status
 Endif
 For TempC=1 To MaxNodes
    Call Read.Message.Record(MessWorkFile1,TempC+1)
    Strng=Rtrim$(MessWorkRecord1.Username)
    Call Valid.Name(Strng)
    If TempA Then
       Gosub Read.Who.Status
       Temp5=Temp5+1
       If Temp5>=User.Pagelength-2 Then
          If Continuous=False Then
             Call More.Prompt
             Temp5=False
             If No Or Quit Then
                Exit FOr
             Endif
             Gosub Read.Who.Header
          Endif
       Endif
    Endif
 Next
 If Temp5 Then
    Call More.Prompt
 Endif
 Exit Sub

Read.Who.Header:
 Temp5=4
 Graphics.Off=True
 Strng="DNDBBS v"+Version$+" Who Status Report For "+Left$(Fclock$,15)+"."
 Call IO.O
 Strng=Nul
 Call IO.O
 If TempX=2 Then
    Strng="Port Username                       Timeon   Room     Classname"
 Else
    Strng="Port Username                       Timeon   Room     Score"
 Endif
 Call IO.O
 Call Display.Line(71)
 Return

Read.Who.Status:
 Select Case TempC
 Case 0
    Strng="P##"
 Case 1 To 10 ' 0-9
    Strng="P#"+Mid$(Str$(TempC-1),2)
 Case 11 To 36 ' A-Z
    Strng="P#"+Chr$(TempC+54)
 Case 37 To 126 ' 10-99
    Strng="P#"+Mid$(Str$(TempC-27),2)
 End Select
 Strng=Strng+Space$(5-Len(Strng))
 Out2=Lcase$(MessWorkRecord1.UserName)
 Mid$(Out2,1,1)=Ucase$(Mid$(Out2,1,1))
 Out3=Mid$(Str$(MessWorkRecord1.RoomNumber),2)
 Out3=Out3+Space$(8-Len(Out3))
 If TempX=2 Then
    Out4=Rtrim$(MessWorkRecord1.Classname)
 Else
    VarX#=MessWorkRecord1.Score3*MessWorkRecord1.Level*10+ _
    MessWorkRecord1.Score1*MessWorkRecord1.Level*2+ _
    MessWorkRecord1.Score2*MessWorkRecord1.Level
    Out4=Mid$(Str$(VarX#),2)
 Endif
 Strng=Strng+Out2+" "+MessWorkRecord1.TimeOn+" "+Out3+" "+Out4
 Call IO.O
 Return
ErrorResume19a:
 Exit Sub
ErrorTrap19a:
 Resume ErrorResume19a
End Sub

Sub Get.Node(Var!)
 On Local Error Goto ErrorTrap1
 Temp=False
 Var!=SFalse
 Var$=Rtrim$(Ltrim$(Parsed.Command1))
 Select Case Len(Var$)
 Case 1
    Select Case Ucase$(Var$)
    Case "0" To "9" ' 1-10
       Temp=Val(Parsed.Command1)+1
    Case "A" To "Z" ' 11-36
       Temp=Asc(Ucase$(Var$))-54
    End Select
 Case 2
    VarX=Int(Val(Var$))
    If VarX>=10 And VarX<=99 Then
       Temp=VarX+27 ' 37-126
    Endif
 End Select
 If Temp Then
    Call Read.Message.Record(MessWorkFile1,Temp+1)
    Strng=Rtrim$(MessWorkRecord1.UserName)
    Call Valid.Name(Strng)
    If TempA Then
       Var!=MessWorkRecord1.UserIndex
       Exit Sub
    Endif
 Endif
 Call Search.Mess(SFalse)
 If Temp! Then
    Temp=TempC
    Var!=MessWorkRecord1.UserIndex
 Endif
ErrorResume1:
 Exit Sub
ErrorTrap1:
 Resume ErrorResume1
End Sub

Sub Numeric2
 On Local Error Goto ErrorTrp6a
 Var=False
 Var1=Instr(Temp.Command,"#")
 If Var1 Then
    Var=Int(Val(Mid$(Temp.Command,Var1+1)))
    Temp.Command=Left$(Temp.Command,Var1-1)
    User.Command=Left$(User.Command,Var1-1)
 Endif
 Parse.Temp=Var
ErrorRsm6a:
 Exit Sub
ErrorTrp6a:
 Resume ErrorRsm6a
End Sub

 ' date/time logged on, time used.
Sub Time.Online(Var)
 On Local Error Goto Err.Trp1
 Graphics.Off=True
 Strng="It is now "+Fclock$
 Call IO.O
 ' calculate serialized date
 Trap=-1
 OnDate#=DateValue(Date.On)
 Strng2=Format$(OnDate#,"ddd dd mmm yyyy")
 ' calculate serialized time
 OnTime#=TimeValue(Time.On)
 Strng3=Format$(OnTime#,"hh:mma/p")
Resume1a:
 Trap=0
 If Trap.Err Then
    Strng="You logged on at "+Date.On+", "+Time.On+"."
 Else
    Strng="You logged on at "+Strng2+", "+Strng3+"."
 Endif
 Call IO.O
 Trap=-2
 d1$=format$(now,"mm-dd-yyyy")
 Var#=DateValue(d1$)-OnDate# ' serialized date
Resume2a:
 Trap=0
 If Var#>=2# Then
    Strng="You have been on for"+Str$(Var#)+" days!"
    Call IO.O
 Else
    ' time online
    Var1!=Timeit!-Timeon ' elapsed
    If Var1!<0! Then Var1!=Var1!+86400! ' midnight
    Strng="You have been on for"
    Strng2="."
    Gosub Time.Display
 Endif
 ' time remaining
 If UserRecord.TimeLimit<SFalse Then
    Strng="You have unlimited time remaining."
    Call IO.O
 Else
    If Var#<2# Then
       Var2!=Timeit!-Timeon ' elapsed
       If Var2!<0! Then Var2!=Var2!+86400! ' midnight
       Var1!=Time.Left-Var2! ' remaining
       If Var1!<0! Then Var1!=0!
       Strng="You have"
       Strng2=" remaining."
       Gosub Time.Display
    Endif
 Endif
 ' usage
 Strng="You have used "+Lcase$(ProgramName$)
 Var#=UserRecord.TimesLogon+1#
 Gosub Time.String
 Strng=Strng+Strng2
 Var#=UserRecord.TimesDied
 Gosub Time.String
 Strng=Strng+" and died"+Strng2+"."
 Call IO.O
 Exit Sub
Time.String:
 Select Case Var#
 Case 1
    Strng2=" once"
 Case 2 To 10
    Strng2=" "+Rtrim$(Numeral(Var#))+" times"
 Case Else
    Call Amount(Var#,VarQ$)
    Strng2=VarQ$+" times"
 End Select
 Return
Time.Display:
 Hours=Int(Var1!/3600!)
 Var1!=Var1!-Hours*3600!
 Minutes=Int(Var1!/60!)
 Var1!=Var1!-Minutes*60!
 Seconds=Int(Var1!)
 If Hours>=23 Then
    Strng=Strng+" a very long time"+Strng2
    Call IO.O
    Return
 Endif
 If Hours=False Then
    If Minutes=False Then
       If Seconds=False Then
          Strng=Strng+" 0 seconds"+Strng2
          Call IO.O
          Return
       Endif
    Endif
 Endif
 If Hours>False Then
    Strng=Strng+Str$(Hours)+" hour"
    If Hours>1 Then
       Strng=Strng+"s"
    Endif
    Strng=Strng+","
 Endif
 If Minutes>False Then
    Strng=Strng+Str$(Minutes)+" minute"
    If Minutes>1 Then
       Strng=Strng+"s"
    Endif
    Strng=Strng+","
 Else
    If Seconds=False Then
       Strng=Left$(Strng,Len(Strng)-1)
    Endif
 Endif
 If Seconds>False Then
    Strng=Strng+Str$(Seconds)+" second"
    If Seconds>1 Then
       Strng=Strng+"s"
    Endif
 Else
    Strng=Left$(Strng,Len(Strng)-1)
 Endif
 Strng=Strng+Strng2
 Call IO.O
 Return
Err.Rsm1:
 Exit Sub
 ' test for illegal function call when serialized date is beyond 2078.
Err.Trp1:
 If Trap=-1 Then
    Trap.Err=-1
    Resume Resume1a
 Endif
 If Trap=-2 Then
    Var#=0#
    Resume Resume2a
 Endif
 Resume Err.Rsm1
End Sub

' specialized file display function.
Sub Out.File2(Var$)
 On Local Error Goto ErrorTrap23x
 If Dir$(Var$)=Nul Then
    If Local.Mode And Debug.Mode Then
       Carriage.Return=False
       Strng="Filename: "+Var$+" <not found>"
       Call IO.O
    Endif
    Exit Sub
 Endif
 Var=1
 If Local.Mode And Debug.Mode Then
    Carriage.Return=False
    Var=Var+1
    Strng="Filename: "+Var$
    Call IO.O
 Endif
 Var=Var+1
 Graphics.Off=False
 Strng="File list. "
 Var2$="Press <ctrl-break>/<ctrl-c> to interrupt."
 If Local.Mode=False Then
    Var2$="Press <control-c>/<control-k> to interrupt."
 Endif
 Strng=Strng+Var2$
 Call IO.O
 Allow.Break=True
 Break=False
 Continuous=False
 Graphics.Off=True
 VarQ=False
 VarR=False
 Close #TempFile1
 Open Var$ For Input Shared As #TempFile1
 Call Modem.ANSI(4,37,15)
 Call ScreenANSI(4,37,15)
 Do While Lost.Carrier=False
    Allow.Break=True
    If Eof(TempFile1) Then
       Exit Do
    Endif
    Line Input #TempFile1,Strng
    ' convert prefix string
    If Len(Strng) Then
       If Len(Config3(78)) Then
          VarP=0
          Do
             VarP=Instr(VarP+1,Strng,"/")
             If VarP Then
                Strng=Left$(Strng,VarP-1)+Config3(78)+Mid$(Strng,VarP+1)
                VarP=VarP+Len(Config3(78))
             Else
                Exit Do
             Endif
          Loop
       Endif
    Endif
    Strng2=Strng
    Graphics.On=True
    Call IO.O
    Graphics.On=False
    If Break Then
       Exit Do
    Endif
    Var=Var+1
    If Var>=User.Pagelength-2 Then
       Var=False
       If Continuous=False Then
          Call More.Prompt
          If No Or Quit Then
             Exit Do
          Endif
       Endif
    Endif
 Loop
 If Var>1 Then
    If Break=False Then
       Call More.Prompt
    Endif
 Endif
 Allow.Break=False
 Break=False
 Graphics.Off=True
ErrorResume23x:
 Exit Sub
ErrorTrap23x:
 Resume ErrorResume23x
End Sub

' Var1=command number
' Var2=return value
Sub Check.Restriction(Var1,Var2)
 ' fixed 09/05/2019
 On Local Error Goto Err.Trp23
 ' return value
 Var2=False
 ' check command pointer
 Var!=UserRecord.NodeList2
 If Var!=SFalse Then
    Exit Sub
 Endif
 ' open restriction file
 FileName=DND.Path+"restrict.dat"
 Close #TempFile1
 Open FileName For Random Shared As #TempFile1 Len=13
 ' Byte 1/0, FromHour/FromMin/ToHour/ToMin, ClassType, Level.
 Field #TempFile1,1 As B$,2 As FH$,2 As FM$,2 As TH$,2 As TM$,2 As CL$,2 As LV$
 ' get record length of sum of all commands
 Records!=MaxUserCommands+MaxDMCommands+MaxSysopCommands+MaxNodeCommands
 RecLen!=Records!*13!
 ' check command restricted from user record pointer
 If Var!>0! And Var!<=Lof(TempFile1)/RecLen! Then
    VarN!=Csng(Var1)
    If VarN!>0! And VarN!<=Records! Then
       VarR!=(Var!-1!)*Records!+VarN!
       Get #TempFile1,VarR!
       ' command restricted.
       If B$="0" Then
          Strng="Command is currently restricted."
          Goto Restrict
       Endif
       ' command time restriction
       Var1!=Csng(Cvi(FH$))*3600!+Csng(Cvi(FM$))*60! ' from
       Var2!=Csng(Cvi(TH$))*3600!+Csng(Cvi(TM$))*60! ' to
       If Var1!>SFalse Or Var2!>SFalse Then
          Call Check.Time2(Var3,Var1!,Var2!)
          If Var3=False Then
             Graphics.Off=True
             Strng="Command time restriction!"
             Call IO.O
             Strng="Command is currently restricted from "

             Z1$=Ltrim$(Str$(Cvi(FH$))) ' from hour
             Z1$=Right$("00"+Z1$,2)
             Z2$=Ltrim$(Str$(Cvi(FM$))) ' from minute
             Z2$=Right$("00"+Z2$,2)

             Z3$=Ltrim$(Str$(Cvi(TH$))) ' to hour
             Z3$=Right$("00"+Z3$,2)
             Z4$=Ltrim$(Str$(Cvi(TM$))) ' to minute
             Z4$=Right$("00"+Z4$,2)
             Strng=Strng+Z1$+":"+Z2$+" to "+Z3$+":"+Z4$

             Goto Restrict
          Endif
       Endif
       ' classtype restriction.
       C=Cvi(CL$)
       If (C And 2^UserRecord.ClassType)=2^UserRecord.ClassType Then
          Strng="Command is currently restricted from your classtype."
          Goto Restrict
       Endif
       ' level restriction.
       L=Cvi(LV$)
       If UserRecord.Level<L Then
          Strng="Command is currently restricted to level "+Form$(Cdbl(L))+"."
          Goto Restrict
       Endif
    Endif
 Endif
 Exit Sub

Restrict:
 Graphics.Off=True
 Call IO.O
 Graphics.Off=False
 Last.Command="<restrict>"
 Call Update.Mess(4)
 Var2=True
 Exit Sub
Err.Rsm23:
 Exit Sub
Err.Trp23:
 Resume Err.Rsm23
End Sub
