From 3b41411d220552666c61530a57606298bc991889 Mon Sep 17 00:00:00 2001 From: mysticbbs Date: Tue, 26 Feb 2013 07:45:01 -0500 Subject: [PATCH] Too much stuff to list --- mystic/bbs_cfg_menuedit.pas | 7 +- mystic/bbs_cfg_syscfg.pas | 2 +- mystic/bbs_cfg_useredit.pas | 1 + mystic/bbs_filebase.pas | 178 ++++++++++++++----------- mystic/bbs_io.pas | 149 ++++++++++++--------- mystic/bbs_menus.pas | 259 ++++++++++++++++++++++++++++++++++-- mystic/bbs_msgbase.pas | 45 ++++--- mystic/bbs_nodeinfo.pas | 13 +- mystic/bbs_user.pas | 9 +- mystic/bbs_userchat.pas | 12 +- mystic/default.txt | 1 + mystic/mbbsutil.pas | 2 +- mystic/mide.pas | 2 +- mystic/mplc.pas | 2 +- mystic/mutil.pas | 2 +- mystic/mystic.pas | 2 +- mystic/nodespy.pas | 2 +- mystic/records.pas | 13 +- mystic/whatsnew.txt | 87 ++++++++++++ 19 files changed, 586 insertions(+), 202 deletions(-) diff --git a/mystic/bbs_cfg_menuedit.pas b/mystic/bbs_cfg_menuedit.pas index e2ed057..13547af 100644 --- a/mystic/bbs_cfg_menuedit.pas +++ b/mystic/bbs_cfg_menuedit.pas @@ -30,7 +30,7 @@ Type End; Const - Num_Cmds = 99; + Num_Cmds = 100; MenuCmds : Array[1..Num_Cmds] of CmdRec = ( // AUTOSIG MENU COMMANDS ( Name: 'AE'; Desc: 'Autosig editor' ), @@ -138,6 +138,7 @@ Const // OTHER MENU COMMANDS ( Name: '-D'; Desc: 'Set access flags (set 2)' ), ( Name: '-F'; Desc: 'Set access flags (set 1)' ), + ( Name: '-G'; Desc: 'Show generated menu' ), ( Name: '-I'; Desc: 'Set menu timer' ), ( Name: '-K'; Desc: 'Add keys to input buffer' ), ( Name: '-N'; Desc: 'Ask Yes/No (default No)' ), @@ -473,13 +474,13 @@ Begin Form.AddStr ('D', ' Description' , 9, 7, 24, 7, 13, 30, 30, @Menu.Info.Description, Topic + 'Description of menu'); Form.AddStr ('A', ' Access' , 14, 8, 24, 8, 8, 30, 30, @Menu.Info.Access, Topic + 'Security requirements to access this menu'); Form.AddStr ('B', ' Fallback' , 12, 9, 24, 9, 10, 20, 20, @Menu.Info.Fallback, Topic + 'Menu loaded if user has no access (Blank/Last)'); - Form.AddTog ('T', ' Menu Type' , 11, 10, 24, 10, 11, 13, 0, 2, 'Standard Lightbar Lightbar/Grid', @Menu.Info.MenuType, Topic + 'Type of menu'); + Form.AddTog ('T', ' Menu Type' , 11, 10, 24, 10, 11, 15, 0, 3, 'Standard Lightbar Lightbar/Grid Lightbar/Prompt', @Menu.Info.MenuType, Topic + 'Type of menu'); Form.AddTog ('I', ' Input Type' , 10, 11, 24, 11, 12, 12, 0, 2, 'User_Defined HotKey LongKey', @Menu.Info.InputType, Topic + 'Input type for this menu'); Form.AddTog ('C', ' Input Chars' , 9, 12, 24, 12, 13, 9, 0, 2, 'Uppercase Lowercase Hidden', @Menu.Info.CharType, Topic + 'Input format display'); Form.AddBol ('G', ' Use Global' , 10, 13, 24, 13, 12, 3, @Menu.Info.Global, Topic + 'Include global menu options in this menu?'); Form.AddStr ('N', ' Node Status' , 9, 14, 24, 14, 13, 30, 30, @Menu.Info.NodeStatus, Topic + 'Node/User status set when this menu is loaded'); Form.AddStr ('F', ' Display File', 8, 15, 24, 15, 14, 20, 20, @Menu.Info.DispFile, Topic + 'Display file shown instead of generated menu'); - Form.AddTog ('L', ' Display Cols', 8, 16, 24, 16, 14, 1, 1, 4, '1 2 3 4', @Menu.Info.DispCols, Topic + 'Number of columns in generated menu'); + Form.AddTog ('L', ' Display Cols', 8, 16, 24, 16, 14, 1, 0, 4, '0 1 2 3 4', @Menu.Info.DispCols, Topic + 'Number of columns in generated menu'); Form.AddPipe ('H', ' Menu Header' , 9, 17, 24, 17, 13, 50, 160, @Menu.Info.Header, Topic + 'Menu header displayed in generated menu'); Form.AddPipe ('P', ' Menu Prompt' , 9, 18, 24, 18, 13, 50, 160, @Menu.Info.Footer, Topic + 'Menu prompt displayed in generated menu'); Form.AddByte ('X', ' X' , 19, 19, 24, 19, 3, 2, 0, 80, @Menu.Info.DoneX, Topic + 'Locate to X coordinate after lightbar menu'); diff --git a/mystic/bbs_cfg_syscfg.pas b/mystic/bbs_cfg_syscfg.pas index fed4299..662642d 100644 --- a/mystic/bbs_cfg_syscfg.pas +++ b/mystic/bbs_cfg_syscfg.pas @@ -132,7 +132,7 @@ Begin Form.AddWord ('C', ' Password Change', 18, 9, 37, 9, 17, 5, 0, 65535, @Config.PWChange, Topic + 'Days before forcing PW change (0/Disabled)'); Form.AddBol ('I', ' Password Inquiry', 17, 10, 37, 10, 18, 3, @Config.PWInquiry, Topic + 'Allow password inquiry e-mails?'); Form.AddByte ('W', ' Password Attempts', 16, 11, 37, 11, 19, 2, 1, 99, @Config.PWAttempts, Topic + 'Max Password attempts'); - + Form.AddTog ('O', ' Start Code Page', 18, 12, 37, 12, 17, 5, 0, 1, 'CP437 UTF-8', @Config.StartCodePage, Topic + 'Logging in user''s code page'); Form.AddBol ('U', ' Use Matrix Login', 17, 13, 37, 13, 18, 3, @Config.UseMatrix, Topic + 'Use Matrix login menu?'); Form.AddStr ('M', ' Matrix Menu', 22, 14, 37, 14, 13, 20, 20, @Config.MatrixMenu, Topic + 'Matrix menu file name'); Form.AddPass ('P', ' Matrix Password', 18, 15, 37, 15, 17, 15, 15, @Config.MatrixPW, Topic + 'Matrix password to login (Blank/Disabled)'); diff --git a/mystic/bbs_cfg_useredit.pas b/mystic/bbs_cfg_useredit.pas index f6ce905..db939ed 100644 --- a/mystic/bbs_cfg_useredit.pas +++ b/mystic/bbs_cfg_useredit.pas @@ -150,6 +150,7 @@ Begin Form.AddBol ('X', ' Msg Index' , 7, 11, 23, 11, 14, 3, @U.UseLBIndex, Topic + 'Start reading at message index'); Form.AddBol ('I', ' Mail Index' , 7, 12, 23, 12, 14, 3, @U.UseLBMIdx, Topic + 'Start reading email at message index'); Form.AddTog ('N', ' Node Chat' , 7, 13, 23, 13, 14, 8, 0, 1, 'Standard Full', @U.UseFullChat, Topic + 'User''s node chat type'); + Form.AddTog ('C', ' Code Page' , 7, 14, 23, 14, 14, 5, 0, 1, 'CP437 UTF-8', @U.CodePage, Topic + 'User''s character translation'); End; 4 : Begin Form.Clear; diff --git a/mystic/bbs_filebase.pas b/mystic/bbs_filebase.pas index 577ce6c..528afd0 100644 --- a/mystic/bbs_filebase.pas +++ b/mystic/bbs_filebase.pas @@ -1646,7 +1646,7 @@ End; Procedure TFileBase.FileGroupChange (Ops: String; FirstBase, Intro: Boolean); Var - A : Word; + Count : Word; Total : Word; tGroup : recGroup; tFBase : RecFileBase; @@ -1659,16 +1659,16 @@ Begin If (Ops = '+') or (Ops = '-') Then Begin Reset (FGroupFile); - A := Session.User.ThisUser.LastFGroup - 1; + Count := Session.User.ThisUser.LastFGroup - 1; Repeat Case Ops[1] of - '+' : Inc(A); - '-' : Dec(A); + '+' : Inc(Count); + '-' : Dec(Count); End; {$I-} - Seek (FGroupFile, A); + Seek (FGroupFile, Count); Read (FGroupFile, FGroup); {$I+} @@ -1771,9 +1771,11 @@ Begin Else Begin Session.io.OutFull (Session.GetPrompt(217)); - A := strS2I(Session.io.GetInput(4, 4, 11, '')); + Session.io.OneKeyRange(#13 + 'Q', 1, Total); - If (A > 0) and (A <= Total) Then Begin + Count := Session.io.RangeValue; + + If (Count > 0) and (Count <= Total) Then Begin Total := 0; Reset (FGroupFile); @@ -1781,7 +1783,7 @@ Begin Repeat Read (FGroupFile, FGroup); If Not FGroup.Hidden And Session.User.Access(FGroup.ACS) Then Inc(Total); - If A = Total Then Break; + If Count = Total Then Break; Until False; Session.User.ThisUser.LastFGroup := FilePos(FGroupFile); @@ -1858,7 +1860,6 @@ Var A : Word; Total : Word; Old : RecFileBase; - Str : String[5]; Compress : Boolean; Begin Old := FBase; @@ -1929,16 +1930,17 @@ Begin Repeat Session.io.OutFull (Session.GetPrompt(36)); - Str := Session.io.GetInput(5, 5, 12, ''); - - If Str = '?' Then Begin - Compress := Config.FCompress; - Total := ListFileAreas(Compress); - End Else + Case Session.io.OneKeyRange(#13 + '?Q', 1, Total) of + '?': Begin + Compress := Config.FCompress; + Total := ListFileAreas(Compress); + End; + Else Break; + End; Until False; - A := strS2I(Str); + A := Session.io.RangeValue; If (A > 0) and (A <= Total) Then Begin Reset (FBaseFile); @@ -2611,11 +2613,75 @@ Var Procedure Ascii_List; Var A : LongInt; - B : LongInt; okSave : Byte; Keys : String[20]; + Files : Cardinal; + + Procedure FlagFile (Number: Integer); + Var + Count1 : Integer; + Count2 : Integer; + Begin + If Not Session.User.Access(FBase.DLACS) Then + Session.io.OutFullLn (Session.GetPrompt(224)) + Else Begin + If BatchNum = mysMaxBatchQueue Then Begin + Session.io.OutFullLn (Session.GetPrompt(46)); + Exit; + End; + + If (Number < 1) or (Number > ListSize) Then Exit; + + okSave := 0; + + Seek (FDirFile, List[Number].RecPos); + Read (FDirFile, FDir); + + For Count1 := 1 to BatchNum Do + If FDir.FileName = Batch[Count1].FileName Then Begin + Session.io.PromptInfo[1] := FDir.FileName; + Session.io.PromptInfo[2] := strComma(Batch[Count1].Size); + + Session.io.OutFullLn (Session.GetPrompt(54)); + + For Count2 := Count1 to BatchNum Do + Batch[Count2] := Batch[Count2 + 1]; + + Dec (BatchNum); + + okSave := 2; + End; + + If okSave = 0 Then + Case CheckFileLimits(1, FDir.Size DIV 1024) of + 0 : okSave := 1; + 1 : Session.io.OutFullLn (Session.GetPrompt(224)); + 2 : Session.io.OutFullLn (Session.GetPrompt(58)); + 3 : Session.io.OutFullLn (Session.GetPrompt(211)); + End; + + If okSave = 1 Then Begin + Session.io.PromptInfo[1] := FDir.FileName; + Session.io.PromptInfo[2] := strComma(FDir.Size); + + Session.io.OutFullLn (Session.GetPrompt(50)); + + Inc (BatchNum); + + Batch[BatchNum].FileName := FDir.FileName; + Batch[BatchNum].Size := FDir.Size; + + If Mode = 1 Then + Batch[BatchNum].Area := Session.User.ThisUser.LastFBase + Else + Batch[BatchNum].Area := FilePos(FBaseFile); + End; + End; + End; + Begin ListType := 0; + Files := FileSize(FDirFile); strListFormat := Session.GetPrompt(42); strDesc := Session.GetPrompt(43); @@ -2634,9 +2700,17 @@ Var If Session.User.Access(FBase.SysopACS) Then Keys := Keys + 'E'; Repeat + Session.io.PromptInfo[1] := strI2S(Files); + Session.io.PromptInfo[2] := strI2S(BotPage); + Session.io.OutFull (Session.GetPrompt(44)); - Case Session.io.OneKey(Keys, True) of + Case Session.io.OneKeyRange(Keys, 1, ListSize) of + #00 : Begin + FlagFile(Session.io.RangeValue); + DrawPage; + Continue; + End; 'E' : Begin DoEditor; DrawPage; @@ -2663,7 +2737,9 @@ Var 'V' : Begin Session.io.OutFull (Session.GetPrompt(358)); - A := strS2I(Session.io.GetInput(2, 2, 12, '')); + Session.io.OneKeyRange('Q' + #13, 1, ListSize); + + A := Session.io.RangeValue; If (A > 0) and (A <= ListSize) Then If Not ArchiveView (FBase.Path + List[A].FileName) Then @@ -2671,67 +2747,19 @@ Var DrawPage; End; - 'F' : If Not Session.User.Access(FBase.DLACS) Then - Session.io.OutFullLn (Session.GetPrompt(224)) - Else Begin + 'F' : Begin Repeat - If BatchNum = mysMaxBatchQueue Then Begin - Session.io.OutFullLn (Session.GetPrompt(46)); - Break; - End; - Session.io.OutFull (Session.GetPrompt(357)); - A := strS2I(Session.io.GetInput(2, 2, 12, '')); - If (A < 1) or (A > ListSize) Then Break; - - okSave := 0; - - Seek (FDirFile, List[A].RecPos); - Read (FDirFile, FDir); - - For A := 1 to BatchNum Do - If FDir.FileName = Batch[A].FileName Then Begin - Session.io.PromptInfo[1] := FDir.FileName; - Session.io.PromptInfo[2] := strComma(Batch[A].Size); - Session.io.OutFullLn (Session.GetPrompt(54)); - - For B := A to BatchNum Do - Batch[B] := Batch[B + 1]; - - Dec (BatchNum); - - okSave := 2; - End; - - If okSave = 0 Then - Case CheckFileLimits(1, FDir.Size DIV 1024) of - 0 : okSave := 1; - 1 : Session.io.OutFullLn (Session.GetPrompt(224)); - 2 : Session.io.OutFullLn (Session.GetPrompt(58)); - 3 : Session.io.OutFullLn (Session.GetPrompt(211)); - End; - - If okSave = 1 Then Begin - Session.io.PromptInfo[1] := FDir.FileName; - Session.io.PromptInfo[2] := strComma(FDir.Size); - - Session.io.OutFullLn (Session.GetPrompt(50)); - - Inc (BatchNum); - - Batch[BatchNum].FileName := FDir.FileName; - Batch[BatchNum].Size := FDir.Size; - - If Mode = 1 Then - Batch[BatchNum].Area := Session.User.ThisUser.LastFBase - Else - Batch[BatchNum].Area := FilePos(FBaseFile); + Case Session.io.OneKeyRange('Q' + #13, 1, ListSize) of + #00 : FlagFile(Session.io.RangeValue); + 'Q', + #13 : Break; End; - Until False; + Until False; - DrawPage; - End; + DrawPage; + End; End; Until False; diff --git a/mystic/bbs_io.pas b/mystic/bbs_io.pas index f0674a0..bc6fe4b 100644 --- a/mystic/bbs_io.pas +++ b/mystic/bbs_io.pas @@ -4,7 +4,7 @@ Unit BBS_IO; Interface -{.$DEFINE UTF8} +{.$DEFINE USEUTF8} Uses {$IFDEF WINDOWS} @@ -122,56 +122,7 @@ Uses bbs_General, bbs_NodeInfo; -Constructor TBBSIO.Create (Var Owner: Pointer); -Begin - Core := Owner; - FmtString := False; - FmtLen := 0; - FmtType := 0; - InMacro := False; - InMacroPos := 0; - InMacroStr := ''; - AllowPause := False; - AllowMCI := True; - LocalInput := False; - AllowArrow := False; - IsArrow := False; - UseInField := True; - UseInLimit := False; - UseInSize := False; - InLimit := 0; - InSize := 0; - NoFile := False; - Graphics := 1; - PausePtr := 1; - LastMCIValue := ''; - InputPos := 0; - GetKeyCallBack := NIL; - - FillChar(OutBuffer, SizeOf(OutBuffer), 0); - - OutBufPos := 0; - - {$IFDEF WINDOWS} - If Not TBBSCore(Core).LocalMode Then - SocketEvent := WSACreateEvent; - {$ENDIF} - - Term := TTermAnsi.Create(Screen); -End; - -Destructor TBBSIO.Destroy; -Begin - {$IFDEF WINDOWS} - If Not TBBSCore(Core).LocalMode Then WSACloseEvent(SocketEvent); - {$ENDIF} - - Term.Free; - - Inherited Destroy; -End; - -{$IFDEF UTF8} +{$IFDEF USEUTF8} Function UTF8Encode(Ch : LongInt) : String; Const CP437_Map : Array[0..255] of LongInt = ( @@ -245,10 +196,59 @@ Begin Result := ' '; End; +{$ENDIF} +Constructor TBBSIO.Create (Var Owner: Pointer); +Begin + Core := Owner; + FmtString := False; + FmtLen := 0; + FmtType := 0; + InMacro := False; + InMacroPos := 0; + InMacroStr := ''; + AllowPause := False; + AllowMCI := True; + LocalInput := False; + AllowArrow := False; + IsArrow := False; + UseInField := True; + UseInLimit := False; + UseInSize := False; + InLimit := 0; + InSize := 0; + NoFile := False; + Graphics := 1; + PausePtr := 1; + LastMCIValue := ''; + InputPos := 0; + GetKeyCallBack := NIL; + + FillChar(OutBuffer, SizeOf(OutBuffer), 0); + + OutBufPos := 0; + + {$IFDEF WINDOWS} + If Not TBBSCore(Core).LocalMode Then + SocketEvent := WSACreateEvent; + {$ENDIF} + + Term := TTermAnsi.Create(Screen); +End; + +Destructor TBBSIO.Destroy; +Begin + {$IFDEF WINDOWS} + If Not TBBSCore(Core).LocalMode Then WSACloseEvent(SocketEvent); + {$ENDIF} + + Term.Free; + + Inherited Destroy; +End; + +{$IFDEF USEUTF8} Procedure TBBSIO.BufAddChar (Ch: Char); -Const - ConvertUTF8 : Boolean = True; Var S : String; C : Byte; @@ -257,7 +257,7 @@ Begin Term.Process(Ch); {$ENDIF} - If ConvertUTF8 Then Begin + If Session.User.ThisUser.CodePage = 1 Then Begin S := UTF8Encode(LongInt(Ch)); For C := 1 to Length(S) Do Begin @@ -286,13 +286,13 @@ End; {$ELSE} Procedure TBBSIO.BufAddChar (Ch: Char); Begin + Term.Process(Ch); + OutBuffer[OutBufPos] := Ch; Inc (OutBufPos); If OutBufPos = TBBSIOBufferSize Then BufFlush; - - Term.Process(Ch); End; {$ENDIF} @@ -1622,14 +1622,24 @@ Function TBBSIO.OneKeyRange (Str: String; Lo, Hi: LongInt) : Char; Var Ch : Char; CurStr : String = ''; - LoStr : String[10]; HiStr : String[10]; + Field : Byte; + xPos : Byte; Begin PurgeInputBuffer; RangeValue := -1; - LoStr := strI2S(Lo); HiStr := strI2S(Hi); + Field := Length(strI2S(Hi)); + xPos := Screen.CursorX; + + If UseInField and (Graphics = 1) Then Begin + AnsiColor (TBBSCore(Core).Theme.FieldColor2); + BufAddStr (strRep(Session.Theme.FieldChar, Field)); + AnsiColor (TBBSCore(Core).Theme.FieldColor1); + AnsiMoveX (xPos); + End Else + UseInField := False; Repeat Ch := UpCase(GetKey); @@ -1637,39 +1647,46 @@ Begin If (Pos(Ch, Str) > 0) and (CurStr = '') Then Begin Result := Ch; - OutRawLn(Ch); + OutRaw(Ch); - Exit; + Break End Else Case Ch of #08 : If CurStr <> '' Then Begin Dec (CurStr[0]); - OutRaw (#08#32#08); + + If UseInField Then AnsiColor(TBBSCore(Core).Theme.FieldColor2); + BufAddStr (#8 + Session.Theme.FieldChar + #8); + If UseInField Then AnsiColor(TBBSCore(Core).Theme.FieldColor1); End; #13 : If CurStr <> '' Then Begin RangeValue := strS2I(CurStr); Result := #0; - OutRawLn(''); - - Exit; + Break; + End Else + If Pos(#13, Str) > 0 Then Begin + Result := #13; + Break; End; '0'.. '9' : If (strS2I(CurStr + Ch) >= Lo) and (strS2I(CurStr + Ch) <= Hi) Then Begin CurStr := CurStr + Ch; If Length(CurStr) = Length(HiStr) Then Begin - OutRawLn(Ch); + OutRaw(Ch); RangeValue := strS2I(CurStr); Result := #0; - Exit; + Break; End Else OutRaw (Ch); End; End; Until False; + + OutFullLn ('|16'); End; Function TBBSIO.GetInput (Field, Max, Mode: Byte; Default: String) : String; diff --git a/mystic/bbs_menus.pas b/mystic/bbs_menus.pas index 78ab659..cb0bf07 100644 --- a/mystic/bbs_menus.pas +++ b/mystic/bbs_menus.pas @@ -39,9 +39,10 @@ Type Function SpecialKey (Str: String) : Boolean; Function MenuGetKey : Char; Function ShowMenu : Boolean; - Procedure GenerateMenu; + Procedure GenerateMenu (Cols: Integer; Cmd: Boolean); Procedure DoStandardMenu; Procedure DoLightBarMenu; + Procedure DoLBPromptMenu; End; Implementation @@ -139,6 +140,7 @@ Begin '-' : Case Cmd[2] of 'D' : ToggleAccessFlags(CmdData, Session.User.ThisUser.AF2); 'F' : ToggleAccessFlags(CmdData, Session.User.ThisUser.AF1); + 'G' : GenerateMenu(strS2I(CmdData), True); 'I' : TimerCount := strS2I(CmdData); 'N' : Session.User.AcsOkFlag := Session.io.GetYN(CmdData, False); 'P' : Session.User.AcsOkFlag := Session.io.GetPW(Copy(CmdData, 1, Pos(';', CmdData) - 1), Session.GetPrompt(417), @@ -433,7 +435,7 @@ Begin (Str = 'TIMER'); End; -Procedure TMenuEngine.GenerateMenu; +Procedure TMenuEngine.GenerateMenu (Cols: Integer; Cmd: Boolean); Var Format : Byte; Listed : Word; @@ -445,8 +447,11 @@ Begin Data.Item[Count]^.TimerShow := True; End; - If ShowMenu Then Begin - Case Data.Info.DispCols of + If (Cols < 0) or (Cols > 4) Then + Cols := Data.Info.DispCols; + + If ShowMenu And (Cols > 0) Then Begin + Case Cols of 1 : Format := 79; 2 : Format := 39; 3 : Format := 26; @@ -467,11 +472,11 @@ Begin Then Continue; If Data.Item[Count]^.HotKey = 'LINEFEED' Then Begin - If Listed MOD Data.Info.DispCols <> 0 Then Session.io.OutRawLn(''); + If Listed MOD Cols <> 0 Then Session.io.OutRawLn(''); Session.io.OutFullLn(Data.Item[Count]^.Text); - While Listed Mod Data.Info.DispCols <> 0 Do Inc(Listed); + While Listed Mod Cols <> 0 Do Inc(Listed); End Else Begin Inc (Listed); @@ -483,21 +488,23 @@ Begin While Screen.CursorX < Format Do Session.io.BufAddChar(' '); - If Listed MOD Data.Info.DispCols = 0 Then + If Listed MOD Cols = 0 Then TBBSCore(Owner).io.OutFullLn (''); End; End; - If Listed MOD Data.Info.DispCols <> 0 Then + If Listed MOD Cols <> 0 Then TBBSCore(Owner).io.OutFullLn (''); TBBSCore(Owner).io.BufFlush; End; - If ExecuteByHotKey('AFTER', 0) = 2 Then Exit; + If Not Cmd Then Begin + If ExecuteByHotKey('AFTER', 0) = 2 Then Exit; - If Data.Info.Footer <> '' Then - TBBSCore(Owner).io.OutFull(Data.Info.Footer); + If Data.Info.Footer <> '' Then + TBBSCore(Owner).io.OutFull(Data.Info.Footer); + End; TBBSCore(Owner).io.BufFlush; End; @@ -542,7 +549,7 @@ Begin If Not ViewOnly Then If ExecuteByHotKey('EVERY', 0) = 2 Then Exit; - If ReDraw Then GenerateMenu; + If ReDraw Then GenerateMenu(-1, False); TBBSCore(Owner).io.AllowArrow := True; @@ -626,6 +633,226 @@ Begin End; End; +Procedure TMenuEngine.DoLBPromptMenu; +Var + CurItem : Word = 0; + ItemX : Byte = 1; + ItemY : Byte = 1; + MaxLBSize : Byte = 1; + MaxDESize : Byte = 1; + + Procedure FindNextItem; + Var + SavedItem : Integer; + Wrapped : Boolean = False; + Begin + SavedItem := CurItem; + + Repeat + Inc (CurItem); + + If (CurItem = SavedItem) and Wrapped Then + Break + Else + If (CurItem > Data.NumItems) Then Begin + CurItem := 1; + + If Wrapped Then Break; + + CurItem := 1; + Wrapped := True; + End; + + If Not SpecialKey(Data.Item[CurItem]^.HotKey) Then + If TBBSCore(Owner).User.Access(Data.Item[CurItem]^.Access) Then Break; + Until False; + End; + + Procedure FindPrevItem; + Var + SavedItem : Integer; + Wrapped : Boolean = False; + Begin + SavedItem := CurItem; + + Repeat + Dec (CurItem); + + If (CurItem = SavedItem) and Wrapped Then + Break + Else + If (CurItem < 1) Then Begin + CurItem := Data.NumItems; + + If Wrapped Then Break; + + CurItem := Data.NumItems; + Wrapped := True; + End; + + If Not SpecialKey(Data.Item[CurItem]^.HotKey) Then + If TBBSCore(Owner).User.Access(Data.Item[CurItem]^.Access) Then Break; + Until False; + End; + + Function FindByKey (Str: String) : Boolean; + Var + SavedItem : Integer; + Wrapped : Boolean = False; + Begin + SavedItem := CurItem; + Result := False; + + Repeat + Inc (CurItem); + + If (CurItem = SavedItem) and Wrapped Then + Break + Else + If (CurItem > Data.NumItems) Then Begin + CurItem := 1; + + If Wrapped Then Begin + CurItem := SavedItem; + Break; + End; + + CurItem := 1; + Wrapped := True; + End; + + If (Length(Data.Item[CurItem]^.HotKey) >= Length(Str)) And (strUpper(Copy(Data.Item[CurItem]^.HotKey, 1, Length(Str))) = Str) And Not SpecialKey(Data.Item[CurItem]^.HotKey) And TBBSCore(Owner).User.Access(Data.Item[CurItem]^.Access) Then Begin + Result := True; + Break; + End; + Until False; + + If (Length(Data.Item[CurItem]^.HotKey) >= Length(Str)) And (strUpper(Copy(Data.Item[CurItem]^.HotKey, 1, Length(Str))) = Str) And Not SpecialKey(Data.Item[CurItem]^.HotKey) And TBBSCore(Owner).User.Access(Data.Item[CurItem]^.Access) Then + Result := True; + End; + + Procedure DrawItem; + Begin + If ItemY >= Session.User.ThisUser.ScreenSize {24} Then Begin + Session.io.OutRawLn(''); + + //ItemY := Session.User.ThisUser.ScreenSize - 1; + + Dec (ItemY); + End; + + If Data.Item[CurItem]^.TextLo <> '' Then Begin + IF Data.Item[CurItem]^.X <> 0 Then + Session.io.AnsiGotoXY (Data.Item[CurItem]^.X, ItemY + 1) + Else + Session.io.AnsiGotoXY (ItemX, ItemY + 1); + + Session.io.OutFull(Data.Item[CurItem]^.TextLo); + + If Screen.CursorX > MaxDESize Then + MaxDESize := Screen.CursorX; + + While Screen.CursorX < MaxDESize Do + Session.io.OutRaw(' '); + End; + + Session.io.AnsiGotoXY (ItemX, ItemY); + Session.io.OutFull (Data.Item[CurItem]^.TextHi); + + If Screen.CursorX > MaxLBSize Then + MaxLBSize := Screen.CursorX; + + While Screen.CursorX < MaxLBSize Do + Session.io.OutRaw(' '); + End; + +Var + HotKey : String; + Ch : Char; +Begin + While Not TBBSCore(Owner).ShutDown Do Begin + If Not ViewOnly Then + If ExecuteByHotKey('EVERY', 0) = 2 Then Exit; + + If ReDraw Then GenerateMenu(-1, False); + + ItemX := Screen.CursorX; + ItemY := Screen.CursorY; + + TBBSCore(Owner).io.AllowArrow := True; + + If SetAction Then + If Data.Info.NodeStatus <> '' Then + Set_Node_Action(Data.Info.NodeStatus) + Else + Set_Node_Action(TBBSCore(Owner).GetPrompt(346)); + + HotKey := ''; + + If CurItem = 0 Then FindNextItem; + + DrawItem; + + While Not TBBSCore(Owner).ShutDown Do Begin + Ch := MenuGetKey; + + If TBBSCore(Owner).ShutDown Then Exit; + + If UseTimer And (Ch = #02) Then Begin + If TimerReload Then Exit; + If ReDraw Then Break; + End; + + If Session.io.IsArrow Then Begin + Case Ch of + #72, + #75 : Begin + FindPrevItem; + DrawItem; + End; + #77, + #80 : Begin + FindNextItem; + DrawItem; + End; + End; + End Else Begin + Case Ch of + #13 : Begin + HotKey := Data.Item[CurItem]^.HotKey; + + Break; + End; + #32.. + #126: Begin + HotKey := HotKey + UpCase(Ch); + + If Not FindByKey(HotKey) Then Begin + HotKey := UpCase(Ch); + + If Not FindByKey(HotKey) Then + HotKey := ''; + End; + + DrawItem; + + If (HotKey <> '') And (HotKey = Data.Item[CurItem]^.HotKey) And UseHotKeys Then + Break; + End; + End; + End; + End; + + Session.io.OutFullLn('|CR'); + + If ViewOnly Then Exit; + + If Not TBBSCore(Owner).ShutDown Then + If ExecuteByHotKey(HotKey, 0) = 2 Then + Exit; + End; +End; + Function TMenuEngine.MenuGetKey : Char; Var LastSec : LongInt; @@ -1034,6 +1261,10 @@ Begin DoLightBarMenu Else DoStandardMenu; + 3 : If TBBSCore(Owner).io.Graphics > 0 Then + DoLBPromptMenu + Else + DoStandardMenu; End; Exit; @@ -1099,6 +1330,10 @@ Begin DoLightBarMenu Else DoStandardMenu; + 3 : If TBBSCore(Owner).io.Graphics > 0 Then + DoLBPromptMenu + Else + DoStandardMenu; End; End; diff --git a/mystic/bbs_msgbase.pas b/mystic/bbs_msgbase.pas index a8315a7..049b287 100644 --- a/mystic/bbs_msgbase.pas +++ b/mystic/bbs_msgbase.pas @@ -388,7 +388,6 @@ Var Count : LongInt; Total : Word; Old : RecMessageBase; - Str : String[5]; Compress : Boolean; Begin Compress := Config.MCompress; @@ -471,16 +470,17 @@ Begin Repeat Session.io.OutFull (Session.GetPrompt(102)); - Str := Session.io.GetInput(5, 5, 12, ''); - - If Str = '?' Then Begin - Compress := Config.MCompress; - Total := ListAreas(Compress); - End Else + Case Session.io.OneKeyRange(#13 + '?Q', 1, Total) of + '?': Begin + Compress := Config.MCompress; + Total := ListAreas(Compress); + End; + Else Break; + End; Until False; - Count := strS2I(Str); + Count := Session.io.RangeValue; If (Count > 0) and (Count <= Total) Then Begin Reset (MBaseFile); @@ -671,7 +671,7 @@ End; Procedure TMsgBase.MessageGroupChange (Ops : String; FirstBase, Intro : Boolean); Var - A : Word; + Count : Word; Total : Word; tGroup : RecGroup; tMBase : RecMessageBase; @@ -684,16 +684,16 @@ Begin If (Ops = '+') or (Ops = '-') Then Begin Reset (GroupFile); - A := Session.User.ThisUser.LastMGroup - 1; + Count := Session.User.ThisUser.LastMGroup - 1; Repeat Case Ops[1] of - '+' : Inc(A); - '-' : Dec(A); + '+' : Inc(Count); + '-' : Dec(Count); End; {$I-} - Seek (GroupFile, A); + Seek (GroupFile, Count); Read (GroupFile, Group); {$I+} @@ -731,7 +731,7 @@ Begin Exit; End; - Seek (GroupFile, Data-1); + Seek (GroupFile, Data - 1); Read (GroupFile, Group); If Session.User.Access(Group.ACS) Then Begin @@ -804,9 +804,11 @@ Begin Else Begin Session.io.OutFull (Session.GetPrompt(177)); - A := strS2I(Session.io.GetInput(5, 5, 11, '')); + Session.io.OneKeyRange(#13 + 'Q', 1, Total); - If (A > 0) and (A <= Total) Then Begin + Count := Session.io.RangeValue; + + If (Count > 0) and (Count <= Total) Then Begin Total := 0; Reset (GroupFile); @@ -816,7 +818,7 @@ Begin If Not Group.Hidden And Session.User.Access(Group.ACS) Then Inc(Total); - If A = Total Then Break; + If Count = Total Then Break; Until False; Session.User.ThisUser.LastMGroup := FilePos(GroupFile); @@ -2253,7 +2255,7 @@ Var 'L' : Begin Session.io.PausePtr := 1; Session.io.AllowPause := True; - A := MsgBase^.GetMsgNum; + A := MsgBase^.GetMsgNum; Session.io.OutFullLn(Session.GetPrompt(411)); @@ -2273,6 +2275,9 @@ Var MsgBase^.SeekFirst(A); MsgBase^.MsgStartup; + + Session.io.PromptInfo[1] := strI2S(MsgBase^.GetMsgNum); + Session.io.PromptInfo[2] := strI2S(MsgBase^.GetHighMsgNum); End; 'M' : Begin If MoveMessage(False) Then @@ -2428,7 +2433,9 @@ Begin Session.io.OutFull (Session.GetPrompt(338)); - MsgNum := strS2I(Session.io.GetInput(6, 6, 12, '')); + Session.io.OneKeyRange(#13, 1, MsgBase^.GetHighMsgNum); + + MsgNum := Session.io.RangeValue; End; Set_Node_Action (Session.GetPrompt(348)); diff --git a/mystic/bbs_nodeinfo.pas b/mystic/bbs_nodeinfo.pas index fb5fe09..0fe2b54 100644 --- a/mystic/bbs_nodeinfo.pas +++ b/mystic/bbs_nodeinfo.pas @@ -125,7 +125,6 @@ Var ToNode : Byte; A, B, C : Byte; Temp : ChatRec; - Str : String[3]; NodeMsgFile : File of NodeMsgRec; NodeMsg : NodeMsgRec; SkipCurrent : Boolean = False; @@ -133,11 +132,15 @@ Begin If Data = '' Then Begin Repeat Session.io.OutFull (Session.GetPrompt(146)); - Str := Session.io.GetInput(3, 3, 12, ''); - If Str = '?' Then WhosOnline Else Break; + + Case Session.io.OneKeyRange('?Q', 1, Config.INetTNNodes) of + #00 : Break; + '?' : WhosOnline; + 'Q' : Break; + End; Until False; - ToNode := strS2I(Str); + ToNode := Session.io.RangeValue; If (ToNode < 0) or (ToNode > Config.INetTNNodes) Then Begin Session.io.OutFullLn (Session.GetPrompt(147)); @@ -290,4 +293,4 @@ Begin Session.InMessage := False; End; -End. +End. \ No newline at end of file diff --git a/mystic/bbs_user.pas b/mystic/bbs_user.pas index 20ec062..8f98ce5 100644 --- a/mystic/bbs_user.pas +++ b/mystic/bbs_user.pas @@ -108,6 +108,7 @@ Begin ThisUser.LastMGroup := Config.StartMGroup; ThisUser.UseLBQuote := True; ThisUser.UseFulLChat := True; + ThisUser.CodePage := Config.StartCodePage; IgnoreGroup := False; InChat := False; @@ -1193,11 +1194,11 @@ Begin Halt(0); End; -// Session.io.AnsiClear; -// Session.io.OutFullLn('|CR' + strPadC(mysSoftwareID + ' BBS v' + mysVersion + ' [' + OSID + '] : Node |ND', 79, ' ')); -// Session.io.OutFullLn(strPadC(CopyID, 79, ' ')); + //Session.io.OutFullLn('|CL|CR' + strPadC(mysSoftwareID + ' BBS Version ' + mysVersion + ' for ' + OSID, 79, ' ')); + //Session.io.OutFullLn(strPadC(CopyID, 79, ' ')); + //Session.io.OutFullLn('|CR' + strPadC(mysWebSite, 79, ' ')); - Session.io.OutFullLn ('|CL' + mysSoftwareID + ' BBS v' + mysVersion + ' [' + OSID + '] : Node |ND'); + Session.io.OutFullLn ('|CL' + mysSoftwareID + ' BBS Version ' + mysVersion + ' for ' + OSID + ' : Node |ND'); Session.io.OutFullLn (CopyID); If Config.DefTermMode = 0 Then diff --git a/mystic/bbs_userchat.pas b/mystic/bbs_userchat.pas index 3b3efa7..438f570 100644 --- a/mystic/bbs_userchat.pas +++ b/mystic/bbs_userchat.pas @@ -19,7 +19,6 @@ Uses Procedure PageUserForChat; Var - Str : String; ToNode : Byte; ReqType : Byte = 8; TempChat : ChatRec; @@ -27,13 +26,14 @@ Begin Repeat Session.io.OutFull (Session.GetPrompt(479)); - Str := Session.io.GetInput(3, 3, 12, ''); - - If Str = '?' Then WhosOnline Else - If Str = 'Q' Then Exit Else Break; + Case Session.io.OneKeyRange('Q?', 1, Config.INetTNNodes) of + #00 : Break; + 'Q' : Exit; + '?' : WhosOnline; + End; Until False; - ToNode := strS2I(Str); + ToNode := Session.io.RangeValue; If (Not GetChatRecord(ToNode, TempChat)) or (ToNode = Session.NodeNum) or (Not TempChat.Active) or (Not TempChat.Available) Then Begin diff --git a/mystic/default.txt b/mystic/default.txt index 5c9f763..1fbb194 100644 --- a/mystic/default.txt +++ b/mystic/default.txt @@ -107,6 +107,7 @@ ; &1 = size, &2 = date, &3 = DLs, &4 = desc, &5 = uploader 043 |07|$D29 |&4 ; File listing pause prompt +; &1 = total files &1 = current file 044 |CR|01[|10þ|01] |09Pause: |01(|07N|01)|09ext, |01(|07P|01)|09rev, |01(|07F|01)|09lag, |01(|07V|01)|09iew, or |01(|07Q|01)|09uit? |07 ; Standard file list, ext desc: &4 = description 045 |07|$D29 |&4 diff --git a/mystic/mbbsutil.pas b/mystic/mbbsutil.pas index 619dd8e..32e593a 100644 --- a/mystic/mbbsutil.pas +++ b/mystic/mbbsutil.pas @@ -1,5 +1,5 @@ // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/mide.pas b/mystic/mide.pas index ed8c4a5..92915b6 100644 --- a/mystic/mide.pas +++ b/mystic/mide.pas @@ -1,5 +1,5 @@ // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/mplc.pas b/mystic/mplc.pas index 9867748..9051668 100644 --- a/mystic/mplc.pas +++ b/mystic/mplc.pas @@ -1,5 +1,5 @@ // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/mutil.pas b/mystic/mutil.pas index 01d99d7..7b5e98f 100644 --- a/mystic/mutil.pas +++ b/mystic/mutil.pas @@ -1,7 +1,7 @@ Program MUTIL; // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/mystic.pas b/mystic/mystic.pas index 74fbab6..12c32f9 100644 --- a/mystic/mystic.pas +++ b/mystic/mystic.pas @@ -1,5 +1,5 @@ // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/nodespy.pas b/mystic/nodespy.pas index 3f4002c..f654846 100644 --- a/mystic/nodespy.pas +++ b/mystic/nodespy.pas @@ -1,5 +1,5 @@ // ==================================================================== -// Mystic BBS Software Copyright 1997-2012 By James Coyle +// Mystic BBS Software Copyright 1997-2013 By James Coyle // ==================================================================== // // This file is part of Mystic BBS. diff --git a/mystic/records.pas b/mystic/records.pas index 9fdd307..cd04a7d 100644 --- a/mystic/records.pas +++ b/mystic/records.pas @@ -1,6 +1,6 @@ { =========================================================================== - Mystic BBS Software Copyright (C) 1997-2012 By James Coyle + Mystic BBS Software Copyright (C) 1997-2013 By James Coyle =========================================================================== File | RECORDS.PAS Desc | This file holds the data file records for all data files used @@ -22,8 +22,9 @@ Const mysSoftwareID = 'Mystic'; // no idea - mysCopyYear = '1997-2012'; // its been a long time! - mysVersion = '1.10 A25'; // current version + mysCopyYear = '1997-2013'; // its been a long time! + mysWebsite = 'sourceforge.net/projects/mysticbbs'; + mysVersion = '1.10 A26'; // current version mysDataChanged = '1.10 A11'; // version of last records change {$IFDEF WIN32} @@ -278,7 +279,8 @@ Type // UNSORTED inetTNHidden : Boolean; ThemeOnStart : Boolean; - Reserved : Array[1..844] of Char; + StartCodePage : Byte; + Reserved : Array[1..843] of Char; End; Const @@ -357,7 +359,8 @@ Type UseFullChat : Boolean; { use full screen teleconference } Credits : LongInt; Protocol : Char; - Reserved : Array[1..389] of Byte; + CodePage : Byte; // 0 = CP437, 1 = UTF8 + Reserved : Array[1..388] of Byte; End; // day of week diff --git a/mystic/whatsnew.txt b/mystic/whatsnew.txt index e6df1eb..f05f196 100644 --- a/mystic/whatsnew.txt +++ b/mystic/whatsnew.txt @@ -2431,3 +2431,90 @@ a message number on the prompt to automatically jump to that message. + + ! After doing a list of message in the standard message reader, the + current message number on the prompt will no longer show the wrong + message number. + + + Added two MCI codes to prompt #44: &1 total files in base &2 last listed + file number. + + + In a standard generated menu you can now set the "display columns" to + zero which will cause the generated menu to only show the menu prompt. + + + Added new menu command: -G. This command shows the currently loaded + internally generated menu. The optional data field will determine the + number of display columns to use to format the menu. The -G command does + not display the menu prompt or execute "EVERY" menu commands. + + + Added a new menu type that can be created in the menu editor. You can + now set a "Lightbar/Prompt" type menu, which will allow you to create + menus similar to the old Searchlight style with a lightbar prompt. Users + can scroll through commands with the arrow keys or also search by simply + typing in letters. Our version supports commands with hotkeys that + contain more than one character among other things that Searchlight + didn't do. + + If the user has hotkeys enabled, or the menu forces hotkeys, the command + will be executed as soon as a match of a hotkey is inputted from the user. + + If the user has hotkeys disabled, or the menu forces longkeys, then the + user will always have to press enter to execute the selected command. + + Each menu item is created similar to a standard type menu, with the the + following changes: + + 1. The "Lightbar Hi" text contains the look of the selected lightbar + command. The location prompt will be generated where the cursor + is after the menu prompt is displayed. + + 2. The "Lightbar Lo" text contains the description that will be + displayed below the currently selected command. If this is blank + the extended description will not be used. + + The description will automatically be aligned below the lightbar + command, unless the "X" value of the command is defined. If the X + is not equal to 0, Mystic will print the description at that X + column instead. + + A new menu has been included with the default installation called + testlbprompt.mnu. Please use this to experiment with these types of + menus if it interests you. + + + The smart input used by the standard message base reader to jump between + messages now creates an input field according to the selected theme. You + can of course turn it off for specific prompts using the IF MCI code if + you don't like it. + + + The message base change command now uses the smart input function for + input while prompting to select a message base. + + + The message group change command now uses the smart input function for + input while prompting to select a message group. + + + The file base change command now uses the smart input function for input + while prompting to select a file base. + + + The file group change command now uses the smart input function for input + while prompting to select a file group. + + + Rewrote the file tagging system in the standard file listing. The old + way still works, by pressing F to flag a file. However, you can now + just type in the file number to add or remove a file from your batch + queue without every pressing the F key. + + + The F flag command now uses smart input when prompting for the file number + to add/remove from queue (in standard file listing) + + + The V view command now uses smart input when prompting for the file number + to view in the standard file listing. + + + Sending a node message will now use the smart input function when + prompting for the node number. + + + Paging a user for user/user chat now uses the smart input function. + + + When selecting "Forward" reading, Mystic now uses the smart input + function to prompt for the message start number. + +