www.pudn.com > pino3srv-src.zip > room.pas


unit room; 
 
interface 
 
uses Classes, SysUtils, ActUser; 
 
type TRoom = class(TObject) 
      private 
       { Private-Deklarationen } 
      protected 
       { Protected-Deklarationen } 
      public 
       { Public-Deklarationen } 
       BannedIPs:TList; 
       BgCol:string[6]; 
       Closed,Hidden,System:Boolean; 
       Gagged:TList; 
       MaxUsers:Word; 
       Name,Topic:string; 
       Owner:TActUser; 
       ROPS:TList; 
       Users:TStringList; 
 
       constructor Create(n:string); 
       destructor Destroy; override; 
       procedure AddUser(user:TActUser;addalways:Boolean); 
       procedure RemoveUser(user:TActUser); 
       procedure RoomAction(action,status:Char;user:TActUser;msg:string); 
       function RoomInfo:string; 
       procedure UpdateRoomInfo; 
     end; 
 
implementation 
 
uses misc; 
 
{$I ..\..\defines.inc} 
 
constructor TRoom.Create(n:string); 
  begin 
    inherited Create; 
 
    if RoomList.IndexOf(n)>-1 then raise Exception.Create('The room already exists.'); 
    BannedIPs:=TList.Create; 
    BgCol:='FFFFFF'; 
    Closed:=false; 
    Gagged:=TList.Create; 
    Hidden:=false; 
    MaxUsers:=0; 
    Name:=n; 
    Owner:=nil; 
    ROPS:=TList.Create; 
    System:=false; 
    Topic:=''; 
    Users:=TStringList.Create; 
 
    RoomList.AddObject(Name,self); 
  end; 
 
destructor TRoom.Destroy; 
var i:Integer; 
  begin 
    for i:=0 to ActUsers.Count-1 do TActUser(ActUsers.Objects[i]).SendLine(PM_ROOMLIST,SC_REMOVE,EC_NOERROR,Name); 
    RoomList.Delete(RoomList.IndexOf(Name)); 
 
    Users.Free; 
    ROPS.Free; 
    Gagged.Free; 
    BannedIPs.Free; 
    inherited Destroy; 
  end; 
 
procedure TRoom.AddUser(user:TActUser;addalways:Boolean); 
var i:Integer;UserSettings:string;du:TActUser; 
  begin 
    if Users.IndexOfObject(user)>-1 then Exit; 
 
    if addalways=false then 
      begin 
        if BannedIPs.IndexOf(Pointer(user.IP.S_addr))>-1 then 
          begin 
            user.SendLine(PM_JOIN,SC_NORMAL,EC_BANNED,Name); 
            Exit; 
          end; 
 
        if (MaxUsers>0)and(Users.Count>=MaxUsers) then 
          begin 
            user.SendLine(PM_JOIN,SC_NORMAL,EC_TOOMANYUSERS,Name); 
            RoomAction(RA_KNOCK,SC_NORMAL,nil,user.Nick); 
            Exit; 
          end; 
 
        if Closed then 
          begin 
            user.SendLine(PM_JOIN,SC_NORMAL,EC_LOCKED,Name); 
            RoomAction(RA_KNOCK,SC_NORMAL,nil,user.Nick); 
            Exit; 
          end; 
      end; 
 
    Users.AddObject(user.Nick,user);                                                        // Adds the user to the userlist of the room 
    if (Users.Count=1)and(System=false) then                                                // If the room is newly created and is not a system room the user is appointed as RoomOP 
      begin 
        Owner:=user; 
        ROPS.Add(user); 
      end; 
 
    user.Rooms.AddObject(Name,self);                                                        // Adds the room to the roomlist of the user 
    user.SendLine(PM_JOIN,SC_NORMAL,EC_NOERROR,Name+#1+BgCol);                              // Sends the user a confirmation 
 
    UserSettings:=Name+#1+user.Nick+#1+user.Color+#1+user.UserStatus(self,true); 
    for i:=0 to Users.Count-1 do 
      begin 
        du:=TActUser(Users.Objects[i]); 
 
        if du<>user then user.SendLine(PM_ROOMACTION,RA_INITLIST,EC_NOERROR,SC_NORMAL+Name+#1+du.Nick+#1+du.Color+#1+du.UserStatus(self,true)); 
        du.SendLine(PM_ROOMACTION,RA_USERJOINED,EC_NOERROR,SC_NORMAL+UserSettings); 
      end; 
    UpdateRoomInfo; 
  end; 
 
procedure TRoom.RemoveUser(user:TActUser); 
var i:Integer; 
  begin 
    i:=Users.IndexOf(user.Nick); 
    if i=-1 then Exit; 
 
    Users.Delete(i); 
    ROPS.Remove(user); 
    if Owner=user then Owner:=nil; 
    user.Rooms.Delete(user.Rooms.IndexOf(Name)); 
 
    if (Users.Count>0)or(System=true) then 
      begin 
        RoomAction(RA_USERLEFT,SC_NORMAL,user,''); 
        UpdateRoomInfo; 
      end else Free; 
  end; 
 
procedure TRoom.RoomAction(action,status:Char;user:TActUser;msg:string); 
var i:Integer; 
  begin 
    if user=nil then msg:=PM_ROOMACTION+action+EC_NOERROR+status+Name+#1+''+#1+''+#1+msg 
      else msg:=PM_ROOMACTION+action+EC_NOERROR+status+Name+#1+user.Nick+#1+user.Color+#1+msg; 
    for i:=0 to Users.Count-1 do TActUser(Users.Objects[i]).Send(msg); 
  end; 
 
function TRoom.RoomInfo:string; 
  begin 
    Result:=Name+#1+Topic+#1+BgCol+#1+IntToStr(Users.Count)+#1+IntToStr(MaxUsers)+#1+BS[System]+#1+BS[Closed]+#1+BS[Hidden]; 
  end; 
 
procedure TRoom.UpdateRoomInfo; 
var i:Integer;st:string; 
  begin 
    if Hidden then Exit; 
 
    st:=RoomInfo; 
    for i:=0 to ActUsers.Count-1 do TActUser(ActUsers.Objects[i]).SendLine(PM_ROOMLIST,SC_ADD,EC_NOERROR,st); 
  end; 
 
end.