2003.03.21 (金) 14:25:29 <u*j*2*6*> shuusei21118+21156+21182+21183に相当します
shuusei24140:伝言機能(idea by N1K2-J,ミルミル)

diff --dos -wurN 24139/constants.pas 24140/constants.pas
--- 24139/constants.pas	Fri Mar 21 06:15:32 2003
+++ 24140/constants.pas	Fri Mar 21 13:42:26 2003
@@ -27,7 +27,7 @@
  SLAVANAP_VERSION             = '2.4.1';
  SLAVANAP_BUILD               = '108';
  SLAVANAP_BUILD_DATE          = '24 January 2003';
- SLAVANAP_SHUUSEI             = '39';
+ SLAVANAP_SHUUSEI             = '40';
  SLAVANAP_SHUUSEI_DATE        = '21 March 2003';
  SLAVANAP_VERSION_SHORT       = SLAVANAP_TITLE+' '+SLAVANAP_VERSION;
  SLAVANAP_FULL                = SLAVANAP_TITLE+' '+SLAVANAP_VERSION+
@@ -409,6 +409,13 @@
 MSG_CLIENT_SHOWSETTING          = 8126; // show remote server variables
 MSG_CLIENT_SHOWALLSETTINGS      = 8127; // show one setting on all remote servers
 MSG_CLIENT_REBOOT               = 8128; // reboot server pc
+
+// other
+MSG_CLIENT_MSGSERV_READALL      = 10500; //read all messages
+MSG_CLIENT_MSGSERV_READNEW      = 10501; //read new messages
+MSG_CLIENT_MSGSERV_WRITE        = 10502; //leave a message
+MSG_CLIENT_MSGSERV_DELETE       = 10503; //delete a message
+MSG_CLIENT_MSGSERV_CLEAR        = 10504; //delete all messages
 
 // SlavaNap server-server messages
 MSG_SRV_LOGIN                   = 8000;
diff --dos -wurN 24139/handler.pas 24140/handler.pas
--- 24139/handler.pas	Fri Mar 21 06:24:24 2003
+++ 24140/handler.pas	Fri Mar 21 14:09:24 2003
@@ -50,6 +50,7 @@
 function isLogged: Boolean;
 function CheckLevel(func: String;lev: TNapUserLevel): Boolean;
 function CheckParams(count: Integer; show_error: Boolean=true): Boolean;
+procedure Handler_MsgServ;
 
 var
  gcmd: TNapCmd;
@@ -108,7 +109,7 @@
 begin
  case q of
   queryServer: Result:=false;
-  queryOperServ, queryChanServ, queryNickServ, queryChannel: Result:=true;
+  queryOperServ, queryChanServ, queryNickServ, queryMsgServ, queryChannel: Result:=true;
   else if usr=nil then Result:=true
        else Result:=not (userHideErrors in usr^.state);
  end;
@@ -123,6 +124,7 @@
    queryOperServ:  Exec(user,MSG_SERVER_PRIVMSG,'OperServ '+str);
    queryNickServ:  Exec(user,MSG_SERVER_PRIVMSG,'NickServ '+str);
    queryChanServ:  Exec(user,MSG_SERVER_PRIVMSG,'ChanServ '+str);
+   queryMsgServ:   Exec(user,MSG_SERVER_PRIVMSG,'MsgServ '+str);
    queryChannel:   Exec(user,MSG_SERVER_PUBLIC,query_channel+' Server '+str);
    queryRemoteUser,
    queryServer: begin end;
@@ -1290,6 +1292,12 @@
        if loginim[i]<>'' then
          local.Exec(MSG_CLIENT_PRIVMSG,loginimbot+' '+loginim[i]);
  end;
+ tmp_pos:=12264;
+ if enable_msgserv then
+ begin
+   gcmd.cmd:='msgserv read';
+   Handler_MsgServ;
+ end;
  tmp_pos:=205;
  local.Flush;
 end;
@@ -1866,6 +1874,138 @@
   ProcessCommand(local,queryOperServ);
 end;
 
+procedure Handler_MsgServ_ReadAll;
+var
+ t: PStringHashItem;
+begin
+ if not isLogged then exit;
+ t:=db_msgserv.first;//receiver (new|old) date time <sender> "msg"
+ while t<>nil do
+ try
+   if FirstParam(t^.data)=AnsiLowerCase(local.nick) then
+   begin
+     local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ '+NextParam(t^.data,2));
+     if FirstParam(NextParam(t^.data))='new' then
+       t^.data:=FirstParam(t^.data)+' old '+NextParam(t^.data,2);
+   end;
+   t:=t^.next;
+  except
+ end;
+end;
+
+procedure Handler_MsgServ_ReadNew;//伝言を送信者からのIMみたいに表示
+var
+ t: PStringHashItem;
+begin
+ if not isLogged then exit;
+ t:=db_msgserv.first;//receiver (new|old) date time <sender> "msg"
+ while t<>nil do
+ try
+   if FirstParam(t^.data)=AnsiLowerCase(local.nick) then
+   if FirstParam(NextParam(t^.data))='new' then
+   begin
+     local.Exec(MSG_CLIENT_PRIVMSG,FirstParam(NextParam(t^.data,4))
+       +' [伝言] '+FirstParam(NextParam(t^.data,2))
+       +' '+FirstParam(NextParam(t^.data,3))+' '+NextParam(t^.data,5));
+     t^.data:=FirstParam(t^.data)+' old '+NextParam(t^.data,2);
+   end;
+   t:=t^.next;
+  except
+ end;
+end;
+
+procedure Handler_MsgServ_Write;//write sender msg(空白含む)
+begin
+ if not isLogged then exit;
+ if not CheckParams(2) then exit;
+ StrHash_AddEx(db_msgserv,AnsiLowerCase(FirstParam(gcmd.cmd))+' new '+DateTimeToStr(now)
+   +' '+AnsiLowerCase(user^.username)+' "'+NextParam(gcmd.cmd)+'"');
+ //t^.data:='receiver yyyy/mm/dd hh:mm:ss sender "msg"';
+ if user^.server=nil then WriteAllServers(MSG_CLIENT_MSGSERV_WRITE,user^.username,gcmd.cmd);
+ if local<> nil then local.Exec(MSG_SERVER_NOSUCH,'<MsgServ> 伝言メッセージを記憶しました。');
+end;
+
+procedure Handler_MsgServ_Delete;//delete date time <sender> "msg"
+var
+  b: Boolean;
+begin
+ if not isLogged then exit;
+ if not CheckParams(4) then exit;
+ b:=StrHash_Delete(db_msgserv,AnsiLowerCase(user^.username)+' old '+gcmd.cmd,false);
+ if user^.server=nil then WriteAllServers(MSG_CLIENT_MSGSERV_DELETE,user^.username,gcmd.cmd);
+ if local<>nil then
+   if b then
+     local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ 伝言メッセージを1件削除しました')
+   else local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ そのような伝言はないようです');
+end;
+
+procedure Handler_MsgServ_Clear;//clear
+var
+ t,next_t: PStringHashItem;
+begin
+ if not isLogged then exit;
+ t:=db_msgserv.first;
+ while t<>nil do
+ try
+   next_t:=t^.next;
+   if FirstParam(t^.data)=AnsiLowerCase(user^.username) then
+     StrHash_Delete(db_msgserv,t^.data,false);
+   t:=next_t;
+  except
+ end;
+ if user^.server=nil then WriteAllServers(MSG_CLIENT_MSGSERV_CLEAR,user^.username,gcmd.cmd);
+ if local<>nil then local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ 伝言メッセージをすべて削除しました');
+end;
+
+procedure Handler_MsgServ;
+var
+  action: String;
+begin
+  query:=queryMsgServ;
+  if not isLogged then exit;
+  if not isLocal then exit;
+  if not enable_msgserv then
+  begin
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ 停止中!');
+    exit;
+  end;
+  SplitString(gcmd.cmd,hlist);
+  if hlist.count<2 then hlist.Add('help');
+  action:=lowercase(hlist.Strings[1]);
+  gcmd.cmd:=NextParamEx(gcmd.cmd,2);
+  gcmd.id:=0;
+  if (action='readall')     or (action='a') then gcmd.id:=MSG_CLIENT_MSGSERV_READALL
+  else if (action='read')   or (action='r') then gcmd.id:=MSG_CLIENT_MSGSERV_READNEW
+  else if (action='write')  or (action='w') then gcmd.id:=MSG_CLIENT_MSGSERV_WRITE
+  else if (action='delete') or (action='d') then gcmd.id:=MSG_CLIENT_MSGSERV_DELETE
+  else if action='clear'                    then gcmd.id:=MSG_CLIENT_MSGSERV_CLEAR
+  else if action='help' then
+  begin
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ MsgServのコマンドリスト :');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ --------------------------------');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ readall  - 伝言をぜんぶ読む');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ (read|r) - 新しい伝言を読む');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ (write|w) <user> <message> - 伝言を書き残す');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ (delete|d) <date> <time> <user> <message> - 伝言を消去');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ clear    - 伝言をすべて消去');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ help     - このヘルプメッセージを表示');
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ --------------------------------');
+    exit;
+  end
+  else
+  begin
+    local.Exec(MSG_CLIENT_PRIVMSG,'MsgServ '+GetLangT(LNG_INVALIDCOMMAND,action));
+    exit;
+  end;
+  case gcmd.id of
+    MSG_CLIENT_MSGSERV_READNEW:  Handler_MsgServ_ReadNew;
+    MSG_CLIENT_MSGSERV_READALL:  Handler_MsgServ_ReadAll;
+    MSG_CLIENT_MSGSERV_WRITE:    Handler_MsgServ_Write;
+    MSG_CLIENT_MSGSERV_DELETE:   Handler_MsgServ_Delete;
+    MSG_CLIENT_MSGSERV_CLEAR:    Handler_MsgServ_Clear;
+  end;
+end;
+
 procedure Handler_NickServ;
 var
  action: String;
@@ -1978,6 +2118,11 @@
    Handler_ChanServ;
    exit;
  end;
+ if str='msgserv' then
+ begin
+   Handler_MsgServ;
+   exit;
+ end;
  tmp_pos:=272;
  msg:=Copy(NextParamEx(gcmd.cmd),1,max_privmsg_len);
  if trim(msg)='' then exit;
@@ -2049,6 +2194,12 @@
  if user2=nil then
  begin
    UserIsOffline(str,true);
+   if enable_msgserv then
+   begin
+     gcmd.cmd:='msgserv write '+str+' '+msg;
+     SplitString(gcmd.cmd,hlist);
+     Handler_MsgServ;
+   end;
    exit;
  end;
  if userHidePM in user2^.state then exit;
@@ -5224,6 +5375,7 @@
      queryChannel,
      queryOperServ,
      queryNickServ,
+     queryMsgServ,
      queryChanServ: Error('['+IntToStr(ch.users.count)+'] '+ch.channel);
      else Exec(user,MSG_SERVER_CHANNEL_LIST,ch.channel+' '+IntToStr(ch.users.count)+' '+ch.topic);
    end;
@@ -5233,6 +5385,7 @@
   queryChannel,
   queryOperServ,
   queryNickServ,
+  queryMsgServ,
   queryChanServ: Error('.');
   else Exec(user,MSG_SERVER_CHANNEL_LIST_END,'');
  end;
@@ -5255,6 +5408,7 @@
      queryChannel,
      queryOperServ,
      queryNickServ,
+     queryMsgServ,
      queryChanServ: Error('['+IntToStr(ch.users.count)+'] '+ch.channel);
      else Exec(user,MSG_SERVER_FULL_CHANNEL_INFO,ch.channel+' '+IntToStr(ch.users.count)+' '+IntToStr(Ord(chPrivate in ch.state))+' '+IntToStr(Ord(ch.level))+' '+IntToStr(ch.limit)+' '+AddStr(ch.topic));
    end;
@@ -5264,6 +5418,7 @@
   queryChannel,
   queryOperServ,
   queryNickServ,
+  queryMsgServ,
   queryChanServ: Error('.');
   else Exec(user,MSG_CLIENT_FULL_CHANNEL_LIST,'');
  end;
@@ -5346,6 +5501,7 @@
      queryOperServ,
      queryNickServ,
      queryChanServ,
+     queryMsgServ,
      queryChannel: Error(p^.data);
      else Exec(user,MSG_SERVER_CHANNEL_BAN_LIST,ch.channel+' '+p^.data);
    end;
@@ -5356,6 +5512,7 @@
    queryOperServ,
    queryNickServ,
    queryChanServ,
+   queryMsgServ,
    queryChannel: Error('.');
    else Exec(user,MSG_CLIENT_CHANNEL_BAN_LIST,ch.channel);
  end;
@@ -5731,6 +5888,7 @@
      queryChannel,
      queryOperServ,
      queryNickServ,
+     queryMsgServ,
      queryChanServ: begin
                     str:=b^.user+'!'+b^.ip+' '+b^.admin+' '+UnixTimeToStr(b^.time)+'-';
                     if b^.expires>0 then
@@ -5754,6 +5912,7 @@
       queryChannel,
       queryOperServ,
       queryNickServ,
+      queryMsgServ,
       queryChanServ: Error(GetLangT(LNG_ITEMSLISTED,IntToStr(db_bans.count)));
       else Exec(user,MSG_CLIENT_BANLIST,'');
  end;
@@ -7745,7 +7904,7 @@
  ]);
  Exec(user,gcmd.id,str);
  case query of
-  queryOperServ, queryNickServ, queryChanServ, queryChannel: Error('stats: '+str);
+  queryOperServ, queryNickServ, queryChanServ, queryMsgServ, queryChannel: Error('stats: '+str);
  end;
 end;
 
@@ -7761,7 +7920,7 @@
    db_software.SortByID1;
    tmp_pos:=821;
    case query of
-    queryOperServ, queryNickServ, queryChanServ, queryChannel:
+    queryOperServ, queryNickServ, queryMsgServ, queryChanServ, queryChannel:
                    begin
                     Error('クライアントソフトウェアの統計:');
                     Error('形式: <number of users> <software name>');
@@ -7775,7 +7934,7 @@
      end;
      a:=db_software.Items[i];
      case query of
-       queryOperServ, queryNickServ, queryChanServ,
+       queryOperServ, queryNickServ, queryMsgServ, queryChanServ,
        queryChannel:  Error(IntToStr(a^.id1)+'        '+#9+' '+a^.cmd);
        else Exec(user,MSG_CLIENT_VERSION_STATS,AddStr(a^.cmd)+' '+IntToStr(a^.id1));
      end;
@@ -7783,7 +7942,7 @@
  end;
  tmp_pos:=822;
  case query of
-   queryOperServ, queryNickServ, queryChanServ,
+   queryOperServ, queryNickServ, queryMsgServ, queryChanServ,
    queryChannel: Error(GetLangT(LNG_ITEMSLISTED,IntToStr(db_software.count)));
    else Exec(user,MSG_CLIENT_VERSION_STATS,'');
  end;
@@ -10977,6 +11136,11 @@
    MSG_CLIENT_CHANNEL_VOICE           : Handler_ChannelVoice; // 10211 - give voice to speak in channel
    MSG_CLIENT_CHANNEL_UNVOICE         : Handler_ChannelUnvoice; // 10212 - remove voice
    MSG_CLIENT_SHARE_FILE              : Handler_ShareFile;   // 10300 - share non-mp3 file
+   MSG_CLIENT_MSGSERV_READALL         : Handler_MsgServ_ReadAll; // 10500 - read all messages
+   MSG_CLIENT_MSGSERV_READNEW         : Handler_MsgServ_ReadNew; // 10501 - read new messages
+   MSG_CLIENT_MSGSERV_WRITE           : Handler_MsgServ_Write;   // 10502 - leave a message
+   MSG_CLIENT_MSGSERV_DELETE          : Handler_MsgServ_Delete;  // 10503 - delete a message
+   MSG_CLIENT_MSGSERV_CLEAR           : Handler_MsgServ_Clear;   // 10504 - delete all messages
 
 //     MSG_CLIENT_OPENNAPSERVER      : Handler_OpenNapLink; // 10010 - opennap server tries to link
 
diff --dos -wurN 24139/mainform.pas 24140/mainform.pas
--- 24139/mainform.pas	Fri Mar 21 06:08:42 2003
+++ 24140/mainform.pas	Fri Mar 21 10:36:16 2003
@@ -1473,6 +1473,9 @@
   allow_2bytechannel:=ini.ReadBool('Other2','Allow2ByteChannel',false);
   check_loginpass:=ini.ReadBool('Other2','CheckLoginPass',false);
   loginpass:=ini.ReadString('Other2','LoginPass','');
+  enable_msgserv:=ini.ReadBool('Other2','EnableMsgServ',false);
+  StrHash_Reset(db_msgserv);
+  StrHash_LoadFromFile(db_msgserv,ApplicationDir+'dengon');
   // set up console
   LogStartup('mainform::loadconfig: setting up console user');
   cons_channels:=TMyList.Create;
@@ -1933,6 +1936,7 @@
   ini.WriteBool('Other2','Allow2ByteChannel',allow_2bytechannel);
   ini.WriteBool('Other2','CheckLoginPass',check_loginpass);
   ini.WriteString('Other2','LoginPass',loginpass);
+  ini.WriteBool('Other2','EnableMsgServ',enable_msgserv);
   finally
   ini.Free;
  end;
diff --dos -wurN 24139/settings.dfm 24140/settings.dfm
--- 24139/settings.dfm	Fri Mar 21 06:15:18 2003
+++ 24140/settings.dfm	Fri Mar 21 07:22:00 2003
@@ -6102,6 +6102,14 @@
           TabOrder = 6
           Visible = False
         end
+        object cb_enable_msgserv: TCheckBox
+          Left = 8
+          Top = 160
+          Width = 129
+          Height = 17
+          Caption = '伝言機能を使用する'
+          TabOrder = 7
+        end
       end
     end
   end
diff --dos -wurN 24139/settings.pas 24140/settings.pas
--- 24139/settings.pas	Fri Mar 21 06:09:46 2003
+++ 24140/settings.pas	Fri Mar 21 07:24:24 2003
@@ -590,6 +590,7 @@
     cb_check_loginpass: TCheckBox;
     edit_loginpass: TEdit;
     Label157: TLabel;
+    cb_enable_msgserv: TCheckBox;
     procedure Panel3Resize(Sender: TObject);
     procedure headerPaint(Sender: TObject);
     procedure SetTopText(str: String);
@@ -1536,6 +1537,7 @@
  edit_loginpass.Text:=loginpass;
  edit_loginpass.Visible:=cb_check_loginpass.Checked;
  Label157.Visible:=cb_check_loginpass.Checked;
+ cb_enable_msgserv.Checked:=enable_msgserv;
 end;
 
 procedure TSlavaNapSettings.sh_reportShow(Sender: TObject);
@@ -2090,6 +2092,7 @@
    allow_2bytechannel:=cb_allow_2bytechannel.Checked;
    check_loginpass:=cb_check_loginpass.Checked;
    loginpass:=edit_loginpass.Text;
+   enable_msgserv:=cb_enable_msgserv.Checked;
   except
  end;
  btn_restoreClick(nil);
diff --dos -wurN 24139/stypes.pas 24140/stypes.pas
--- 24139/stypes.pas	Fri Mar 21 05:37:16 2003
+++ 24140/stypes.pas	Fri Mar 21 10:38:24 2003
@@ -28,7 +28,8 @@
 type
   time_t          = LongWord;
   Bool3           = (Unknown3, True3, False3);
-  TQuery          = (queryNormal, queryOperServ, queryNickServ, queryChanServ, queryChannel, queryServer, queryRemoteUser);
+  TQuery          = (queryNormal, queryOperServ, queryNickServ, queryChanServ,
+                     queryMsgServ, queryChannel, queryServer, queryRemoteUser);
   TUserState      = set of (userMuzzled, // user is muzzled
                             userChatting, // user is chatting in channel
                             userHideErrors, // usermode ERROR - hide error messages
@@ -1196,6 +1197,7 @@
  if str='chanserv' then exit;
  if str='operator' then exit;
  if str='nickserv' then exit;
+ if str='msgserv'  then exit;
  if str=AnsiLowerCase(loginimbot) then exit;
  if not ignore then
  begin
diff --dos -wurN 24139/thread.pas 24140/thread.pas
--- 24139/thread.pas	Thu Mar 20 17:30:24 2003
+++ 24140/thread.pas	Fri Mar 21 13:18:58 2003
@@ -304,6 +304,12 @@
   StrHash_SaveToFileSorted(db_friends,ApplicationDir+'friends');
   except
  end;
+ {$I checksync.pas}
+ DebugLog('ShutDown - saving dengon', true);
+ try
+  StrHash_SaveToFile(db_msgserv,ApplicationDir+'dengon');
+  except
+ end;
  try
   SaveBlocks;
   except
@@ -357,6 +363,8 @@
   StrHash_Clear(db_motd);
   sleep(5);
   StrHash_Clear(db_friends);
+  sleep(5);
+  StrHash_Clear(db_msgserv);
   DebugLog('ShutDown - 12.1',true);
   {$I checksync.pas}
   sync_reply_list.Free;
@@ -622,6 +630,7 @@
                        SaveChannels(ApplicationDir+'channels');
                        tmp_pos:=1496;
                        StrHash_SaveToFile(db_motd,ApplicationDir+'motd');
+                       StrHash_SaveToFile(db_msgserv,ApplicationDir+'dengon');
                        StrHash_SaveToFile(cons.hotlist,ApplicationDir+'hotlist');
                        tmp_pos:=1497;
                        StrHash_SaveToFile(cons.ignored,ApplicationDir+'ignored');
diff --dos -wurN 24139/vars.pas 24140/vars.pas
--- 24139/vars.pas	Fri Mar 21 06:08:14 2003
+++ 24140/vars.pas	Fri Mar 21 10:44:34 2003
@@ -331,6 +331,8 @@
  allow_2bytechannel: Boolean;
  check_loginpass: Boolean;
  loginpass: String;
+ enable_msgserv: Boolean;
+ db_msgserv: TStringHash;
 implementation
 
 procedure CheckWindows;