⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actuser.pas

📁 flash视频源码 flash视频源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit actuser;

interface

uses Classes, abstuser, misc;

type TActUser = class(TUser)
      private
       { Private-Deklarationen }
       tokens:TStringList;

       Away:Boolean;
       AwayReason,Invited:string;
       RegUser:PRegUser;
      protected
       procedure CheckAway(cmd:Char;user:TActUser;room:string);
       procedure Execute; override;
       procedure IncommingData(st:string); override;
       function LoggedIn(msg:Char):Boolean;
      public
       Color:string[6];
       Hidden:Boolean;
       Lastact:TDateTime;
       Nick:string[20];
       Rooms:TStringList;
       procedure SendLine(cmd,stat,err:Char;msg:string);
       procedure UpdateUserInfo;
       procedure UserAction(action,status:Char;user:TActUser;msg:string);
       function UserStatus(room:Pointer;showaway:Boolean):Char;
     end;

implementation

{ Wichtig: Methoden und Eigenschaften eines Objekts in der VCL
           k鰊nen nur in einem Methodenaufruf mit SYNCHRONIZE
           genutzt werden, z.B.

      Synchronize(UpdateCaption);

  und UpdateCaption k鰊nte sein,

    procedure TActUser.UpdateCaption;
    begin
      Form1.Caption := 'Updated in einem Thread';
    end; }

{ TActUser }

uses room, SysUtils, tools, Windows, WinSock;

{$I ..\..\defines.inc}

function StrToBool(st:string;default:Boolean):Boolean;
  begin
    Result:=default;
    if (Length(st)>0)and(st[1] in ['0'..'1']) then Result:=Boolean(Byte(st[1])-48);
  end;

function ValidNickname(st:string):Boolean;
var i,l:Integer;
  begin
    Result:=false;
    l:=Length(st);
    if l in [1..20]=false then Exit;
    Result:=true;
    for i:=1 to l do Result:=(Result)and(st[i] in [#33..#255])and(st[i]<>#160);
  end;

procedure WriteUserData(ru:PRegUser);
var i:Integer;
  begin
    SetFilePointer(userdb,RegUsers.IndexOfObject(TObject(ru))*soru,nil,FILE_BEGIN);
    WriteFile(userdb,ru^,soru,i,nil);
    FlushFileBuffers(userdb);
  end;


procedure TActUser.CheckAway(cmd:Char;user:TActUser;room:string);
  begin
    if Away then user.SendLine(cmd,SC_USERISAWAY,EC_NOERROR,Nick+#1+AwayReason+#1+room);
  end;

procedure TActUser.Execute;
var i:Integer;acc_conn:Boolean;
  begin
//    ActUsers.AddObject(' '+IntToStr(Socket),self);
//    Writeln('User connected: Connected users ',ActUsers.Count);

    tokens:=TStringList.Create;
    Rooms:=TStringList.Create;

    Away:=false;
    AwayReason:='';
    Color:='000000';
    Hidden:=true;
    Invited:='';
    Lastact:=Now;
    Nick:=' '+IntToStr(Socket);
    RegUser:=nil;

    EnterCriticalSection(synchronizer);

    ActUsers.AddObject(Nick,self);
    Log('Incoming user connection from '+inet_ntoa(IP)+' - User connections: '+IntToStr(ActUsers.Count));

    acc_conn:=true;
    if (maxusers>0)and(ActUsers.Count>maxusers) then
      begin
        SendLine(PM_DISCONN,SC_NORMAL,EC_TOOMANYUSERS,'');
        acc_conn:=false;
      end;
    if AllowedIP(inet_ntoa(IP),UserIPs,true)=false then
      begin
        SendLine(PM_DISCONN,SC_NORMAL,EC_BANNED,'');
        acc_conn:=false;
      end;
    i:=OPKicked.IndexOfObject(Pointer(IP.S_addr));
    if i>-1 then
      begin
        if StrToFloat(OPKicked[i])>Now then
          begin
            SendLine(PM_DISCONN,SC_NORMAL,EC_TEMPBANNED,'');
            acc_conn:=false;
          end else OPKicked.Delete(i);
      end;

    if acc_conn then
      begin
        SendLine(PM_HELLO,SC_NORMAL,EC_NOERROR,'3.'+IntToStr(Build));
        LeaveCriticalSection(synchronizer);
        inherited Execute;
        EnterCriticalSection(synchronizer);
      end else Close;

    ActUsers.Delete(ActUsers.IndexOf(Nick));
    for i:=Rooms.Count-1 downto 0 do TRoom(Rooms.Objects[i]).RemoveUser(self);
    if Hidden=false then for i:=0 to ActUsers.Count-1 do TActUser(Actusers.Objects[i]).SendLine(PM_USERLIST,SC_REMOVE,EC_NOERROR,Nick);

    LeaveCriticalSection(synchronizer);

    Rooms.Free;
    tokens.Free;
    Log('Closed user connection for '+inet_ntoa(IP)+' ('+Nick+') - User connections: '+IntToStr(ActUsers.Count));
  end;

procedure TActUser.IncommingData(st:string);
var cmd,stat:Char;i{,i2}:Integer;room:TRoom;au:TActUser;ru:PRegUser;
  begin
    if Length(st)<2 then Exit;
    cmd:=st[1];
    stat:=st[2];
    Delete(st,1,2);

    Lastact:=Now;

    case cmd of
      PM_HELLO      :begin
                       SendLine(PM_INIT,SC_INFO,EC_NOERROR,chatname+#1+welcome.Text);

                       if bannerupdate>0 then SendLine(PM_INIT,SC_BANNER,EC_NOERROR,IntToStr(bannerupdate)+':'+banners.Text);

                       st:='';
                       for i:=0 to RoomList.Count-1 do
                         begin
                           room:=TRoom(RoomList.Objects[i]);
                           if room.Hidden=false then st:=st+room.RoomInfo+#2;
                         end;
                       SendLine(PM_INIT,SC_ROOMLIST,EC_NOERROR,st);

                       st:='';
                       for i:=0 to ActUsers.Count-1 do
                         begin
                           au:=TActUser(ActUsers.Objects[i]);
                           if au.Hidden=false then st:=st+au.Nick+#1+au.Color+#1+au.UserStatus(nil,true)+#2;
                         end;
                       SendLine(PM_INIT,SC_USERLIST,EC_NOERROR,st);
                     end;
      PM_NICK       :begin
                       DivUp(st,#1,tokens,2,2);
                       Log(inet_ntoa(IP)+' wants to log in as '+tokens[0]);

                       if ValidNickname(tokens[0])=false then
                         begin
                           Log('Nickname is invalid ('+tokens[0]+')');
                           SendLine(PM_NICK,SC_NORMAL,EC_INVALIDNICK,'');
                           Exit;
                         end;

                       if ActUsers.IndexOf(tokens[0])>-1 then
                         begin
                           Log('Nickname is already in use ('+tokens[0]+')');
                           SendLine(PM_NICK,SC_NORMAL,EC_NICKINUSE,'');
                           Exit;
                         end;

                       i:=RegUsers.IndexOf(tokens[0]);
                       if (i=-1)and(noanos) then
                         begin
                           SendLine(PM_NICK,SC_NORMAL,EC_NOANONYMOUS,'');
                           Exit;
                         end;

                       if i>-1 then
                         begin
                           if tokens[1]<>IntToStr(PRegUser(RegUsers.Objects[i])^.pwd) then
                             begin
                               SendLine(PM_NICK,SC_NORMAL,EC_WRONGPWD,'');
                               Exit;
                             end;

                           if PRegUser(RegUsers.Objects[i])^.active=false then
                             begin
                               SendLine(PM_NICK,SC_NORMAL,EC_ACCTDISABLED,'');
                               Exit;
                             end;
                           RegUser:=Pointer(RegUsers.Objects[i]);

                           RegUser^.lastlogin:=Now;
                           WriteUserData(RegUser);
                         end else RegUser:=nil;

                       st:=Nick;

                       ActUsers[ActUsers.IndexOf(Nick)]:=tokens[0];
                       Nick:=tokens[0];
                       if RegUser<>nil then Color:=Format('%.6x',[RegUser^.color]);

                       for i:=0 to Rooms.Count-1 do
                         begin
                           with TRoom(Rooms.Objects[i]) do
                             begin
                               Users[Users.IndexOf(st)]:=Nick;
                               RoomAction(RA_NICK,SC_NORMAL,self,st+#1+UserStatus(Rooms.Objects[i],true));
                             end;
                         end;

                       cmd:=UserStatus(nil,true);
                       for i:=0 to ActUsers.Count-1 do
                         begin
                           au:=TActUser(ActUsers.Objects[i]);

                           if (st[1]<>' ')and(Hidden=false) then au.SendLine(PM_USERLIST,SC_REMOVE,EC_NOERROR,st);
                           if ((st[1]<>' ')xor(Hidden))and not((RegUser<>nil)and(RegUser^.cloak)) then au.SendLine(PM_USERLIST,SC_ADD,EC_NOERROR,Nick+#1+Color+#1+cmd);
                         end;

                       Hidden:=not (((st[1]<>' ')xor(Hidden))and not((RegUser<>nil)and(RegUser^.cloak)));

                       Log(inet_ntoa(IP)+' successfully logged in as '+tokens[0]);
                       if RegUser=nil then SendLine(PM_NICK,SC_NORMAL,EC_NOERROR,'') else SendLine(PM_NICK,SC_NORMAL,EC_NOERROR,Color);
                     end;
      PM_CLOAK      :begin
                       if LoggedIn(PM_CLOAK)=false then Exit;

                       case stat of
                         SC_NORMAL:Hidden:=not Hidden;
                         SC_SET   :if Hidden=false then Hidden:=true else Exit;
                         SC_UNSET :if Hidden=true then Hidden:=false else Exit;
                       end;

                       if Hidden=false then
                         begin
                           st:=Nick+#1+Color+#1+UserStatus(nil,true);
                           for i:=0 to ActUsers.Count-1 do TActUser(ActUsers.Objects[i]).SendLine(PM_USERLIST,SC_ADD,EC_NOERROR,st);
                         end else for i:=0 to ActUsers.Count-1 do TActUser(ActUsers.Objects[i]).SendLine(PM_USERLIST,SC_REMOVE,EC_NOERROR,Nick);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -