Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- JD Command Socket Components
- by Jerry Dodge
- TJDServerSocket: Wraps TServerSocket
- TJDClientSocket: Wraps TClientSocket
- TJDClientServerSocket: Wraps client side TCustomWinSocket
- TJDServerClientSocket: Wraps server side TCustomWinSocket
- TSvrCommands: Collection of TSvrCommand
- TSvrCommand: Executed on server when command is received from client
- TCliCommands: Collection of TCliCommand
- TCliCommand: Executed on client when command is received from server
- TScktProps: List of property strings referenced by name strings
- Abilities:
- > Command/Parameter based packet structure
- > Both sides send/receive command packets the same way
- > Integer based command ID
- > Either array of string or TStrings as parameters in commands
- > Overloaded procedure "SendPacket" to send commands
- > procedure SendPacket(const Cmd: Integer; const Data: TStrings);
- > procedure SendPacket(const Cmd: Integer; const Data: array of String);
- > procedure SendPacket(const Cmd: Integer);
- > Event "OnCommand" triggered on either side when packet is received
- > Command collections are ADDITIONAL to OnCommand event (see below)
- > OnCommand is called first, then the command collection events next
- > Collection of commands with unique events
- > TCollection property on both sides, holding a set of Commands
- > TSvrCommands on Server and TCliCommands on Client (command collections)
- > TSvrCommand on Server and TCliCommand on Client (individual commands)
- > Each command has unique ID (command number) and a Name
- > Each command has its own event handler (OnCommand)
- > Provides packet data received as TStrings
- > Each command has its pre-defined number of parameters
- > -1 = Any, 0 = None, 1+ = Fixed
- > (PARAMETER COUNT CHECKING NOT YET IMPLEMENTED)
- > TO DO: Make sure all ID's are unique and not repeating
- > TO DO: Implement enforcement of parameter count
- > Automatic login authentication
- > Client specifies credentials
- > Server triggers event OnLoginRequest, and property "Accept" is set accordingly
- > Client triggers event OnLoginResponse, and property "Accept" is used accordingly
- > Client can be set either to login automatically or login on demand
- > Client and server can be set to different levels of authentication
- > None, Login, Login/Cookie, Fixed
- > Fixed login allows all clients to use same user/pass
- > Both Server and Client are expected to have same authentication mode set
- > In event handler OnLoginRequest or OnCookieLoginRequest on the Server,
- you can pass back SessionID, UserID, and Cookie as var parameters
- > Cookie authentication
- > Server produces unique cookie string for new sessions
- > Existing session can be resumed by using cookie login
- > Server event "OnCookieLoginRequest" when client logs in with cookie
- > Works similar to OnLoginRequest but providing cookie instead of user/pass
- > Server automatically generates cookies
- > Event "OnCookieLookup" when server needs to know just if a cookie exists
- > Property on server "CookieSize" to specify number of characters in cookies
- > Custom property synchronizing
- > Name/Value properties stored on both sides per session
- > Wrapped in class TScktProps
- > Implemented in TJDServerClientSocket and TJDClientServerSocket as "Props"
- > Custom properties, not associated with sockets
- > Changing a property from one place syncs that value with other end
- > Event when a property has been synchronized
- > TO DO: Restrict property names to only alpha-numeric strings
- > Property names are CASE SENSITIVE
- > Other features
- > IP Blacklist on Server - immediately drops connections from any IP listed
- > Encryption with auto key gen and synchronization
- Event orders
- > Server Events
- > Client connected
- - OnConnection(csConnecting)
- - OnConnecting
- <if Accept = True>
- - OnConnection(csConnected)
- > Client disconnected
- - OnConnection(csDisconnecting)
- <if LoginState = lsAllow>
- - OnLogout (not yet implemented)
- - OnConnection(csDisconnected)
- > Client logs in with user/pass
- - OnLoginRequest
- > Both directions
- > Command packet received
- - OnCommand
- <if Cmd ID is listed in collection>
- - CollectionItem.OnCommand
- <else>
- - Collection.OnUnknownCommand
- Notes
- > Sockets internally use negative numbers for their own commands,
- so custom commands must always use positive numbers.
- TO DO LIST
- > Force use of positive numbers in command ID's
- > Add internal command SendPacketX which does not restrict negatives
- > Modify SendPacket to accept only positives
- > Modify command collection items to accept only positive ID's
- > Load-test and check for proper exception handling
- > Wrap TJDServerClientSocket and TJDClientServerSocket into threads
- > Need option of whether or not to use threads
- > Implement sending streams (partially started)
- > Monitor data sent/received and keep records
- > Properly implement login/logout when AutoLogin is False
- > Differentiate "Connection Sessions" from "Login Sessions"
- > Two different session structures, with their own ID's
- > Change "OnConnection" to "OnClientConnected" and "OnClientDisconnected"
- > (No need to have connecting and disconnecting)
- > Finish implementing cross-error handling
- > Error occurs on one end
- > Error alert sent to opposite end
- > Event triggered on opposite end OnRemoteError
- }
- unit JDSockets;
- interface
- uses
- Classes, Windows, SysUtils, StrUtils, ScktComp, ExtCtrls;
- const
- JDS_DAT_DIV = '#'; //Used as packet divider
- JDS_CMD_LOGIN = -1;
- JDS_CMD_ERROR = -2;
- JDS_CMD_COOKIE = -3;
- JDS_CMD_USER_ID = -4;
- JDS_CMD_SESS_ID = -5;
- JDS_CMD_LOGOUT = -6;
- JDS_CMD_PROP = -7;
- JDS_CMD_KEY = -8;
- type
- TJDServerClientSocket = class;
- TJDClientServerSocket = class;
- TJDServerSocket = class;
- TJDClientSocket = class;
- TSvrCommands = class;
- TSvrCommand = class;
- TCliCommands = class;
- TCliCommand = class;
- TScktProps = class;
- TJDScktConnState = (csConnected, csDisconnected, csConnecting, csDisconnecting);
- TJDScktLoginState = (lsNone, lsAllow, lsDeny, lsError);
- TJDScktRecState = (rsIdle, rsCommand);
- TJDScktAuthMode = (amNone, amLogin, amLoginCookie, amFixed);
- TJDScktErrorType = (etSocket, etInternal, etRemote);
- //amNone: No authentication required
- //amLogin: Login/password required, and are each unique
- //amLoginCookie: Same as amLogin, but includes cookie authentication
- //amFixed: Login/password required, and are always the same
- ////////////////////////////////////////////////////////////////////////////////
- // Command Collections
- // Goal: Allow entering pre-set commands with unique Name and ID
- // Each command has its own event which is triggered when command is received
- //Determines how commands are displayed in collection editor in design-time
- TJDCmdDisplay = (cdName, cdID, cdCaption, cdIDName, cdIDCaption);
- //Server side commands
- TJDScktSvrCmdEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const Data: TStrings) of object;
- TSvrCommands = class(TCollection)
- private
- fOwner: TPersistent;
- fOnUnknownCommand: TJDScktSvrCmdEvent;
- fDisplay: TJDCmdDisplay;
- function GetItem(Index: Integer): TSvrCommand;
- procedure SetItem(Index: Integer; Value: TSvrCommand);
- procedure SetDisplay(const Value: TJDCmdDisplay);
- protected
- function GetOwner: TPersistent; override;
- public
- constructor Create(AOwner: TPersistent);
- destructor Destroy;
- procedure DoCommand(const Socket: TJDServerClientSocket;
- const Cmd: Integer; const Data: TStrings);
- function Add: TSvrCommand;
- property Items[Index: Integer]: TSvrCommand read GetItem write SetItem;
- published
- property Display: TJDCmdDisplay read fDisplay write SetDisplay;
- property OnUnknownCommand: TJDScktSvrCmdEvent
- read fOnUnknownCommand write fOnUnknownCommand;
- end;
- TSvrCommand = class(TCollectionItem)
- private
- fID: Integer;
- fOnCommand: TJDScktSvrCmdEvent;
- fName: String;
- fParamCount: Integer;
- fCollection: TSvrCommands;
- fCaption: String;
- procedure SetID(Value: Integer);
- procedure SetName(Value: String);
- procedure SetCaption(const Value: String);
- protected
- function GetDisplayName: String; override;
- public
- procedure Assign(Source: TPersistent); override;
- constructor Create(Collection: TCollection); override;
- destructor Destroy; override;
- published
- property ID: Integer read fID write SetID;
- property Name: String read fName write SetName;
- property Caption: String read fCaption write SetCaption;
- property ParamCount: Integer read fParamCount write fParamCount;
- property OnCommand: TJDScktSvrCmdEvent read fOnCommand write fOnCommand;
- end;
- //Client side commands
- TJDScktCliCmdEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const Data: TStrings) of object;
- TCliCommands = class(TCollection)
- private
- fOwner: TPersistent;
- fOnUnknownCommand: TJDScktCliCmdEvent;
- fDisplay: TJDCmdDisplay;
- function GetItem(Index: Integer): TCliCommand;
- procedure SetItem(Index: Integer; Value: TCliCommand);
- procedure SetDisplay(const Value: TJDCmdDisplay);
- protected
- function GetOwner: TPersistent; override;
- public
- constructor Create(AOwner: TPersistent);
- destructor Destroy;
- procedure DoCommand(const Socket: TJDClientServerSocket;
- const Cmd: Integer; const Data: TStrings);
- function Add: TCliCommand;
- property Items[Index: Integer]: TCliCommand read GetItem write SetItem;
- published
- property Display: TJDCmdDisplay read fDisplay write SetDisplay;
- property OnUnknownCommand: TJDScktCliCmdEvent
- read fOnUnknownCommand write fOnUnknownCommand;
- end;
- TCliCommand = class(TCollectionItem)
- private
- fCollection: TCliCommands;
- fID: Integer;
- fName: String;
- fOnCommand: TJDScktCliCmdEvent;
- fParamCount: Integer;
- fCaption: String;
- procedure SetID(Value: Integer);
- procedure SetName(Value: String);
- procedure SetCaption(const Value: String);
- protected
- function GetDisplayName: String; override;
- public
- procedure Assign(Source: TPersistent); override;
- constructor Create(Collection: TCollection); override;
- destructor Destroy; override;
- published
- property ID: Integer read fID write SetID;
- property Name: String read fName write SetName;
- property Caption: String read fCaption write SetCaption;
- property ParamCount: Integer read fParamCount write fParamCount;
- property OnCommand: TJDScktCliCmdEvent read fOnCommand write fOnCommand;
- end;
- // END Command Collections
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- // TScktProps - Socket Property Synchronization
- // Represents a group of string properties referenced by string names
- // Goal: Provide custom properties which automatically synchronize
- // between the TJDServerClientSocket and the TJDClientServerSocket
- // NOTE: Property names are CASE SENSITIVE so 'myprop' is different from 'MyProp'
- // property Props: TScktProps on TJDServerClientSocket and TJDClientServerSocket
- // Read Example: MyStr:= Props['PropNameStr'];
- // Write Example: Props['PropNameStr']:= MyStr;
- // Write Example (no event): Props.SetPropX('PropNameStr', MyStr);
- // Use SetPropX to set a property value WITHOUT triggering event
- // Primarily when property is received from remote socket
- // Using the standard method will trigger event (which synchs new value)
- TJDScktPropEvent = procedure(Sender: TObject; const Name, Val: String) of object;
- TScktProps = class(TObject)
- private
- fItems: TStringList;
- fOnGotProp: TJDScktPropEvent;
- function GetProp(Name: String): String;
- procedure SetProp(Name: String; const Value: String);
- procedure SetPropX(Name: String; const Value: String);
- public
- constructor Create;
- destructor Destroy; override;
- property Prop[Name: String]: String read GetProp write SetProp; default;
- function PropExists(Name: String): Bool;
- property OnGotProp: TJDScktPropEvent read fOnGotProp write fOnGotProp;
- end;
- // END Socket Property Synchronization
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////
- // TJDServerClientSocket
- // Server side - client connection
- // Represents unique socket on the server for a single connection from a client
- TJDSvrCliConnEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const OldState, NewState: TJDScktConnState) of object;
- TJDSvrCliErrEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- var ErrMsg: String; var ErrCode: Integer) of object;
- TJDSvrCliCmdEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const Cmd: Integer; const Data: TStrings) of object;
- TJDScktLoginRequestEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const Username, Password: String; var Accept: Bool; var Cookie: String;
- var UserID, SessionID: Integer) of object;
- TJDScktCookieLoginRequestEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const Cookie: String; var Accept: Bool; var Username: String;
- var UserID, SessionID: Integer) of object;
- TJDSvrCliAcceptEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- var Accept: Bool) of object;
- TJDSvrCookieLookupEvent = procedure(Sender: TObject; const Cookie: String;
- var Exists: Bool) of object;
- TJDSvrScktPropEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
- const Name, Val: String) of object;
- TJDServerClientSocket = class(TObject)
- private
- //Created Objects
- fErrors: TStringList;
- fTimer: TTimer;
- fProps: TScktProps;
- //Assigned Objects
- fOwner: TJDServerSocket;
- fSocket: TCustomWinSocket;
- //More Variables
- fConnState: TJDScktConnState;
- fLoginState: TJDScktLoginState;
- fRecState: TJDScktRecState;
- fBusy: Bool;
- fBuffer: String;
- fSize: Integer;
- fCommand: Integer;
- fProtocol: Integer;
- fData: Pointer;
- fUserID: Integer;
- fUsername: String;
- fSessionID: Integer;
- fCookie: String;
- //Events
- fOnConnection: TJDSvrCliConnEvent;
- fOnCommand: TJDSvrCliCmdEvent;
- fOnError: TJDSvrCliErrEvent;
- fOnLoginRequest: TJDScktLoginRequestEvent;
- fOnCookieLoginRequest: TJDScktCookieLoginRequestEvent;
- fOnCookieLookup: TJDSvrCookieLookupEvent;
- fOnGotProp: TJDSvrScktPropEvent;
- fKey: Word;
- //Child event handlers
- procedure TimerOnTimer(Sender: TObject);
- procedure PropsGotProp(Sender: TObject; const Name, Val: String);
- //Internal methods
- procedure ProcessCommand(const S: String);
- procedure SetCookie(const Value: String);
- procedure SetSessionID(const Value: Integer);
- procedure SetUsername(const Value: String);
- procedure SetUserID(const Value: Integer);
- procedure SetKey(const Value: Word);
- public
- //Construct/Destruct
- constructor Create(ASocket: TCustomWinSocket; AOwner: TJDServerSocket);
- destructor Destroy; override;
- //Public methods
- procedure SendPacket(Cmd: Integer; Data: TStrings); overload;
- procedure SendPacket(Cmd: Integer; Data: array of String); overload;
- procedure SendPacket(Cmd: Integer); overload;
- procedure SendStream(Cmd: Integer; Data: TStream);
- //Public properties
- property Owner: TJDServerSocket read fOwner;
- property Socket: TCustomWinSocket read fSocket;
- property ConnState: TJDScktConnState read fConnState;
- property LoginState: TJDScktLoginState read fLoginState;
- property ReceiveState: TJDScktRecState read fRecState;
- property Command: Integer read fCommand;
- property Size: Integer read fSize;
- property Protocol: Integer read fProtocol;
- property Data: Pointer read fData write fData;
- property Username: String read fUsername write SetUsername;
- property SessionID: Integer read fSessionID write SetSessionID;
- property UserID: Integer read fUserID write SetUserID;
- property Cookie: String read fCookie write SetCookie;
- property Props: TScktProps read fProps;
- property EncrKey: Word read fKey write SetKey;
- //Public events
- property OnConnection: TJDSvrCliConnEvent
- read fOnConnection write fOnConnection;
- property OnCommand: TJDSvrCliCmdEvent
- read fOnCommand write fOnCommand;
- property OnError: TJDSvrCliErrEvent
- read fOnError write fOnError;
- property OnLoginRequest: TJDScktLoginRequestEvent
- read fOnLoginRequest write fOnLoginRequest;
- property OnCookieLoginRequest: TJDScktCookieLoginRequestEvent
- read fOnCookieLoginRequest write fOnCookieLoginRequest;
- property OnCookieLookup: TJDSvrCookieLookupEvent
- read fOnCookieLookup write fOnCookieLookup;
- property OnGotProp: TJDSvrScktPropEvent
- read fOnGotProp write fOnGotProp;
- end;
- ////////////////////////////////////////////////////////////////////////////////
- //Client side - server connection
- // Represents unique socket on the client for a single connection to the server
- TJDCliSvrConnEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const OldState, NewState: TJDScktConnState) of object;
- TJDCliSvrErrEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- var ErrMsg: String; var ErrCode: Integer) of object;
- TJDCliSvrCmdEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const Cmd: Integer; const Data: TStrings) of object;
- TJDScktLoginResponseEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const Accept: Bool) of object;
- TJDScktStringEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const NewValue: String) of object;
- TJDScktIntegerEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- const NewValue: Integer) of object;
- TJDScktSvrNeedLoginEvent = procedure(Sender: TObject; Socket: TJDClientServerSocket;
- var Username, Password: String) of object;
- TJDClientServerSocket = class(TObject)
- private
- //Created objects
- fErrors: TStringList;
- fTimer: TTimer;
- fProps: TScktProps;
- //Assigned objects
- fOwner: TJDClientSocket;
- fSocket: TCustomWinSocket;
- //Variables
- fConnState: TJDScktConnState;
- fLoginState: TJDScktLoginState;
- fRecState: TJDScktRecState;
- fBusy: Bool;
- fBuffer: String;
- fSize: Integer;
- fCommand: Integer;
- fProtocol: Integer;
- fCookie: String;
- fSessionID: Integer;
- fUserID: Integer;
- //Events
- fOnConnection: TJDCliSvrConnEvent;
- fOnCommand: TJDCliSvrCmdEvent;
- fOnError: TJDCliSvrErrEvent;
- fOnLoginResponse: TJDScktLoginResponseEvent;
- fOnGotUserID: TJDScktIntegerEvent;
- fOnGotSessID: TJDScktIntegerEvent;
- fOnGotCookie: TJDScktStringEvent;
- fOnNeedLogin: TJDScktSvrNeedLoginEvent;
- fKey: Word;
- //Child event handlers
- procedure TimerOnTimer(Sender: TObject);
- procedure PropsGotProp(Sender: TObject; const Name, Val: String);
- //Other
- procedure ProcessCommand(const S: String);
- procedure HandleError(Sender: TObject; const ErrType: TJDScktErrorType;
- const ErrMsg: String; var ErrCode: Integer);
- procedure SetKey(const Value: Word);
- public
- constructor Create(ASocket: TCustomWinSocket; AOwner: TJDClientSocket);
- destructor Destroy; override;
- procedure SendPacket(Cmd: Integer; Data: TStrings); overload;
- procedure SendPacket(Cmd: Integer; Data: Array of String); overload;
- procedure SendPacket(Cmd: Integer); overload;
- procedure Login(const Username, Password: String);
- procedure CookieLogin(const Cookie: String);
- property Socket: TCustomWinSocket read fSocket;
- property ConnState: TJDScktConnState read fConnState;
- property LoginState: TJDScktLoginState read fLoginState;
- property ReceiveState: TJDScktRecState read fRecState;
- property Command: Integer read fCommand;
- property Size: Integer read fSize;
- property Buffer: String read fBuffer;
- property Protocol: Integer read fProtocol;
- property Cookie: String read fCookie;
- property SessionID: Integer read fSessionID;
- property UserID: Integer read fUserID;
- property Props: TScktProps read fProps;
- property EncrKey: Word read fKey write SetKey;
- property OnConnection: TJDCliSvrConnEvent
- read fOnConnection write fOnConnection;
- property OnCommand: TJDCliSvrCmdEvent
- read fOnCommand write fOnCommand;
- property OnError: TJDCliSvrErrEvent
- read fOnError write fOnError;
- property OnLoginResponse: TJDScktLoginResponseEvent
- read fOnLoginResponse write fOnLoginResponse;
- property OnGotCookie: TJDScktStringEvent read fOnGotCookie write fOnGotCookie;
- property OnGotUserID: TJDScktIntegerEvent read fOnGotUserID write fOnGotUserID;
- property OnGotSessID: TJDScktIntegerEvent read fOnGotSessID write fOnGotSessID;
- property OnNeedLogin: TJDScktSvrNeedLoginEvent read fOnNeedLogin write fOnNeedLogin;
- end;
- ////////////////////////////////////////////////////////////////////////////////
- //Server Socket Component
- // Represents all server side functionality
- TJDServerEvent = procedure(Sender: TObject; Socket: TJDServerSocket) of object;
- TJDServerSocket = class(TComponent)
- private
- fSocket: TServerSocket;
- fClients: TList;
- fBlackList: TStringList;
- fCommands: TSvrCommands;
- fFixedUsername: String;
- fFixedPassword: String;
- fMaxConnect: Integer;
- fLastSessionID: Integer;
- fCookieSize: Integer;
- fAuth: TJDScktAuthMode;
- fOnConnection: TJDSvrCliConnEvent;
- fOnError: TJDSvrCliErrEvent;
- fOnLoginRequest: TJDScktLoginRequestEvent;
- fOnCommand: TJDSvrCliCmdEvent;
- fOnActivate: TJDServerEvent;
- fOnDeactivate: TJDServerEvent;
- fOnConnecting: TJDSvrCliAcceptEvent;
- fOnCookieLoginRequest: TJDScktCookieLoginRequestEvent;
- fOnCookieLookup: TJDSvrCookieLookupEvent;
- fOnGotProp: TJDSvrScktPropEvent;
- fEncryption: Bool;
- procedure ScktConnect(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktDisconnect(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktRead(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktError(Sender: TObject; Socket: TCustomWinSocket;
- ErrorEvent: TErrorEvent; var ErrorCode: Integer);
- procedure ScktCommand(Sender: TObject; Socket: TJDServerClientSocket;
- const Cmd: Integer; const Data: TStrings);
- procedure ScktLoginRequest(Sender: TObject; Socket: TJDServerClientSocket;
- const Username, Password: String; var Accept: Bool; var Cookie: String;
- var UserID, SessionID: Integer);
- procedure ScktCookieLoginRequest(Sender: TObject; Socket: TJDServerClientSocket;
- const Cookie: String; var Accept: Bool; var Username: String;
- var UserID, SessionID: Integer);
- procedure ScktCookieLookup(Sender: TObject; const Cookie: String;
- var Exists: Bool);
- function GetPort: Integer;
- function GetActive: Bool;
- function GetClient(Index: Integer): TJDServerClientSocket;
- function GetClientCount: Integer;
- function GetNextSessionID: Integer;
- function GetNewCookie: String;
- function GetBlackList: TStrings;
- procedure SetPort(Value: Integer);
- procedure SetActive(Value: Bool);
- procedure SetAuth(const Value: TJDScktAuthMode);
- procedure SetFixedPassword(const Value: String);
- procedure SetFixedUsername(const Value: String);
- procedure SetMaxConnect(const Value: Integer);
- procedure SetLastSessionID(const Value: Integer);
- procedure SetCookieSize(const Value: Integer);
- procedure SetBlackList(const Value: TStrings);
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property Clients[Index: Integer]: TJDServerClientSocket read GetClient;
- procedure SendGroupPacket(const Cmd: Integer; const Data: TStrings); overload;
- procedure SendGroupPacket(const Cmd: Integer; const Data: Array of String); overload;
- function CookieExists(const Cookie: String): Bool;
- property ClientCount: Integer read GetClientCount;
- published
- property Active: Bool read GetActive write SetActive;
- property Port: Integer read GetPort write SetPort;
- property Commands: TSvrCommands read fCommands write fCommands;
- property Authentication: TJDScktAuthMode read fAuth write SetAuth;
- property FixedUsername: String read fFixedUsername write SetFixedUsername;
- property FixedPassword: String read fFixedPassword write SetFixedPassword;
- property MaxConnect: Integer read fMaxConnect write SetMaxConnect;
- property LastSessionID: Integer read fLastSessionID write SetLastSessionID;
- property CookieSize: Integer read fCookieSize write SetCookieSize;
- property BlackList: TStrings read GetBlackList write SetBlackList;
- property Encryption: Bool read fEncryption write fEncryption;
- property OnConnection: TJDSvrCliConnEvent
- read fOnConnection write fOnConnection;
- property OnError: TJDSvrCliErrEvent read fOnError write fOnError;
- property OnLoginRequest: TJDScktLoginRequestEvent
- read fOnLoginRequest write fOnLoginRequest;
- property OnCommand: TJDSvrCliCmdEvent
- read fOnCommand write fOnCommand;
- property OnActivate: TJDServerEvent read fOnActivate write fOnActivate;
- property OnDeactivate: TJDServerEvent read fOnDeactivate write fOnDeactivate;
- property OnConnecting: TJDSvrCliAcceptEvent
- read fOnConnecting write fOnConnecting;
- property OnCookieLoginRequest: TJDScktCookieLoginRequestEvent
- read fOnCookieLoginRequest write fOnCookieLoginRequest;
- property OnCookieLookup: TJDSvrCookieLookupEvent
- read fOnCookieLookup write fOnCookieLookup;
- property OnGotProp: TJDSvrScktPropEvent read fOnGotProp write fOnGotProp;
- end;
- ////////////////////////////////////////////////////////////////////////////////
- //Client Socket Component
- // Represents all client side functionality
- TJDClientSocket = class(TComponent)
- private
- fSocket: TClientSocket;
- fUsername: String;
- fPassword: String;
- fCommands: TCliCommands;
- fAuth: TJDScktAuthMode;
- fAutoLogin: Bool;
- fOnConnection: TJDCliSvrConnEvent;
- fOnError: TJDCliSvrErrEvent;
- fOnLoginResponse: TJDScktLoginResponseEvent;
- fOnCommand: TJDCliSvrCmdEvent;
- fOnGotUserID: TJDScktIntegerEvent;
- fOnGotSessID: TJDScktIntegerEvent;
- fOnGotCookie: TJDScktStringEvent;
- fOnNeedLogin: TJDScktSvrNeedLoginEvent;
- fOnGotProp: TJDScktPropEvent;
- fEncryption: Bool;
- function GetPort: Integer;
- function GetHost: String;
- function GetActive: Bool;
- function GetSocket: TJDClientServerSocket;
- procedure SetPort(Value: Integer);
- procedure SetHost(Value: String);
- procedure SetActive(Value: Bool);
- procedure SetUsername(Value: String);
- procedure SetPassword(Value: String);
- procedure ScktConnection(Sender: TObject; Socket: TJDClientServerSocket;
- const OldState, NewState: TJDScktConnState);
- procedure ScktCommand(Sender: TObject; Socket: TJDClientServerSocket;
- const Cmd: Integer; const Data: TStrings);
- procedure ScktLoginResponse(Sender: TObject; Socket: TJDClientServerSocket;
- const Accept: Bool);
- procedure ScktGotCookie(Sender: TObject; Socket: TJDClientServerSocket;
- const NewValue: String);
- procedure ScktGotSessID(Sender: TObject; Socket: TJDClientServerSocket;
- const NewValue: Integer);
- procedure ScktGotUserID(Sender: TObject; Socket: TJDClientServerSocket;
- const NewValue: Integer);
- procedure ScktNeedLogin(Sender: TObject; Socket: TJDClientServerSocket;
- var Username, Password: String);
- procedure ScktConnect(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktDisconnect(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktRead(Sender: TObject; Socket: TCustomWinSocket);
- procedure ScktError(Sender: TObject; Socket: TCustomWinSocket;
- ErrorEvent: TErrorEvent; var ErrorCode: Integer);
- procedure SetAuth(const Value: TJDScktAuthMode);
- procedure SetCookie(const Value: String);
- function GetCookie: String;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- property Socket: TJDClientServerSocket read GetSocket;
- published
- property Host: String read GetHost write SetHost;
- property Port: Integer read GetPort write SetPort default 0;
- property Active: Bool read GetActive write SetActive;
- property Username: String read fUsername write SetUsername;
- property Password: String read fPassword write SetPassword;
- property Commands: TCliCommands read fCommands write fCommands;
- property Cookie: String read GetCookie write SetCookie;
- property Authentication: TJDScktAuthMode read fAuth write SetAuth;
- property AutoLogin: Bool read fAutoLogin write fAutoLogin default True;
- property Encryption: Bool read fEncryption write fEncryption;
- property OnConnection: TJDCliSvrConnEvent
- read fOnConnection write fOnConnection;
- property OnError: TJDCliSvrErrEvent read fOnError write fOnError;
- property OnLoginResponse: TJDScktLoginResponseEvent
- read fOnLoginResponse write fOnLoginResponse;
- property OnCommand: TJDCliSvrCmdEvent
- read fOnCommand write fOnCommand;
- property OnGotCookie: TJDScktStringEvent read fOnGotCookie write fOnGotCookie;
- property OnGotUserID: TJDScktIntegerEvent read fOnGotUserID write fOnGotUserID;
- property OnGotSessID: TJDScktIntegerEvent read fOnGotSessID write fOnGotSessID;
- property OnNeedLogin: TJDScktSvrNeedLoginEvent read fOnNeedLogin write fOnNeedLogin;
- property OnGotProp: TJDScktPropEvent read fOnGotProp write fOnGotProp;
- end;
- //Misc. Methods
- function CopyToDelim(var S: String; const Delim: String): String; overload;
- function CopyToDelim(var S: String): String; overload;
- function Encrypt(const s: string; Key: Word): string;
- function Decrypt(const s: string; Key: Word): string;
- procedure Register;
- ////////////////////////////////////////////////////////////////////////////////
- implementation
- {$R JDSockets.dcr}
- ////////////////////////////////////////////////////////////////////////////////
- { Component Registration }
- procedure Register;
- begin
- RegisterComponents('JD Custom', [TJDServerSocket, TJDClientSocket]);
- end;
- { Encryption }
- const
- c1 = 52845;
- c2 = 22719;
- function Encrypt(const s: string; Key: Word): string;
- var
- i: byte;
- ResultStr: string;
- begin
- Result:= s;
- SetLength(Result, Length(S));
- for i:= 1 to (length(Result)) do begin
- Result[i]:= Char(byte(s[i]) xor (Key shr 8));
- Key:= (byte(Result[i]) + Key) * c1 + c2;
- end;
- end;
- function Decrypt(const s: string; Key: Word): string;
- var
- i : byte;
- begin
- Result:= s;
- SetLength(Result, Length(S));
- for i:= 1 to (length(Result)) do begin
- Result[i]:= Char(byte(s[i]) xor (Key shr 8));
- Key:= (byte(s[i]) + Key) * c1 + c2;
- end;
- end;
- { Shared Methods }
- //Searches for first found deliminator
- // If found, returns everything up to deliminator and removes deliminator
- function CopyToDelim(var S: String; const Delim: String): String;
- begin
- if Pos(Delim, S) > 1 then begin
- Result:= Copy(S, 1, Pos(Delim, S)-1);
- Delete(S, 1, Pos(Delim, S)+Length(Delim)-1);
- end else begin
- Result:= '';
- end;
- end;
- function CopyToDelim(var S: String): String;
- begin
- Result:= CopyToDelim(S, JDS_DAT_DIV);
- end;
- { TScktProps }
- constructor TScktProps.Create;
- begin
- fItems:= TStringList.Create;
- end;
- destructor TScktProps.Destroy;
- begin
- fItems.Free;
- inherited;
- end;
- function TScktProps.GetProp(Name: String): String;
- var
- X, L: Integer;
- N: String;
- begin
- Result:= '';
- //Name must be alpha-numeric
- L:= Length(Name)+1;
- for X:= 0 to fItems.Count - 1 do begin
- N:= fItems[X];
- if Name+'#' = Copy(N, 1, L) then begin
- Result:= Copy(N, L, Length(N));
- Break;
- end;
- end;
- end;
- function TScktProps.PropExists(Name: String): Bool;
- var
- X, L: Integer;
- N: String;
- begin
- Result:= False;
- //Name must be alpha-numeric
- L:= Length(Name)+1;
- for X:= 0 to fItems.Count - 1 do begin
- N:= fItems[X];
- if Name+'#' = Copy(N, 1, L) then begin
- Result:= True;
- Break;
- end;
- end;
- end;
- procedure TScktProps.SetProp(Name: String; const Value: String);
- var
- X, L: Integer;
- N: String;
- S: Bool;
- begin
- S:= False;
- //Name must be alpha-numeric
- L:= Length(Name)+1;
- for X:= 0 to fItems.Count - 1 do begin
- N:= fItems[X];
- if Name+'#' = Copy(N, 1, L) then begin
- fItems[X]:= Name+'#'+Value;
- S:= True;
- Break;
- end;
- end;
- if not S then
- fItems.Append(Name+'#'+Value);
- if assigned(fOnGotProp) then
- Self.fOnGotProp(Self, Name, Value);
- end;
- procedure TScktProps.SetPropX(Name: String; const Value: String);
- var
- X, L: Integer;
- N: String;
- S: Bool;
- begin
- S:= False;
- //Name must be alpha-numeric
- L:= Length(Name)+1;
- for X:= 0 to fItems.Count - 1 do begin
- N:= fItems[X];
- if Name+'#' = Copy(N, 1, L) then begin
- fItems[X]:= Name+'#'+Value;
- S:= True;
- Break;
- end;
- end;
- if not S then
- fItems.Append(Name+'#'+Value);
- end;
- { TSvrCommands }
- function TSvrCommands.Add: TSvrCommand;
- begin
- Result:= inherited Add as TSvrCommand;
- end;
- constructor TSvrCommands.Create(AOwner: TPersistent);
- begin
- inherited Create(TSvrCommand);
- Self.fOwner:= AOwner;
- end;
- destructor TSvrCommands.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TSvrCommands.DoCommand(const Socket: TJDServerClientSocket;
- const Cmd: Integer; const Data: TStrings);
- var
- X: Integer;
- C: TSvrCommand;
- F: Bool;
- begin
- F:= False;
- for X:= 0 to Self.Count - 1 do begin
- C:= GetItem(X);
- if C.ID = Cmd then begin
- F:= True;
- try
- if assigned(C.fOnCommand) then
- C.fOnCommand(Self, Socket, Data);
- except
- on e: exception do begin
- raise Exception.Create(
- 'Failed to execute command '+IntToStr(Cmd)+': '+#10+e.Message);
- end;
- end;
- Break;
- end;
- end;
- if not F then begin
- //Command not found
- end;
- end;
- function TSvrCommands.GetItem(Index: Integer): TSvrCommand;
- begin
- Result:= TSvrCommand(inherited GetItem(Index));
- end;
- function TSvrCommands.GetOwner: TPersistent;
- begin
- Result:= fOwner;
- end;
- procedure TSvrCommands.SetDisplay(const Value: TJDCmdDisplay);
- begin
- fDisplay := Value;
- //Refresh collection items
- end;
- procedure TSvrCommands.SetItem(Index: Integer; Value: TSvrCommand);
- begin
- inherited SetItem(Index, Value);
- end;
- { TSvrCommand }
- procedure TSvrCommand.Assign(Source: TPersistent);
- begin
- inherited;
- end;
- constructor TSvrCommand.Create(Collection: TCollection);
- begin
- inherited Create(Collection);
- fCollection:= TSvrCommands(Collection);
- end;
- destructor TSvrCommand.Destroy;
- begin
- inherited Destroy;
- end;
- function TSvrCommand.GetDisplayName: String;
- begin
- case Self.fCollection.fDisplay of
- cdName: begin
- Result:= fName;
- end;
- cdID: begin
- Result:= '['+IntToStr(fID)+']';
- end;
- cdCaption: begin
- Result:= fCaption;
- end;
- cdIDName: begin
- Result:= '['+IntToStr(fID)+'] '+fName;
- end;
- cdIDCaption: begin
- Result:= '['+IntToStr(fID)+'] '+fCaption;
- end;
- end;
- end;
- procedure TSvrCommand.SetCaption(const Value: String);
- begin
- fCaption := Value;
- end;
- procedure TSvrCommand.SetID(Value: Integer);
- begin
- fID:= Value;
- end;
- procedure TSvrCommand.SetName(Value: String);
- begin
- fName:= Value;
- end;
- { TCliCommands }
- function TCliCommands.Add: TCliCommand;
- begin
- Result:= inherited Add as TCliCommand;
- end;
- constructor TCliCommands.Create(AOwner: TPersistent);
- begin
- inherited Create(TCliCommand);
- Self.fOwner:= AOwner;
- Self.fDisplay:= cdName;
- end;
- destructor TCliCommands.Destroy;
- begin
- inherited Destroy;
- end;
- procedure TCliCommands.DoCommand(const Socket: TJDClientServerSocket;
- const Cmd: Integer; const Data: TStrings);
- var
- X: Integer;
- C: TCliCommand;
- F, E: Bool;
- begin
- F:= False;
- E:= False;
- for X:= 0 to Self.Count - 1 do begin
- C:= GetItem(X);
- if C.ID = Cmd then begin
- F:= True;
- if assigned(C.fOnCommand) then begin
- E:= True;
- C.fOnCommand(Self, Socket, Data);
- end;
- Break;
- end;
- end;
- if not F then begin
- //Command not found
- end else begin
- if not E then begin
- //No event handler assigned to OnCommand - RAISE ERROR
- end;
- end;
- end;
- function TCliCommands.GetItem(Index: Integer): TCliCommand;
- begin
- Result:= TCliCommand(inherited GetItem(Index));
- end;
- function TCliCommands.GetOwner: TPersistent;
- begin
- Result:= fOwner;
- end;
- procedure TCliCommands.SetDisplay(const Value: TJDCmdDisplay);
- begin
- fDisplay := Value;
- //Refresh collection items
- end;
- procedure TCliCommands.SetItem(Index: Integer; Value: TCliCommand);
- begin
- inherited SetItem(Index, Value);
- end;
- { TCliCommand }
- procedure TCliCommand.Assign(Source: TPersistent);
- begin
- inherited;
- end;
- constructor TCliCommand.Create(Collection: TCollection);
- begin
- inherited;
- Self.fCollection:= TCliCommands(Collection);
- end;
- destructor TCliCommand.Destroy;
- begin
- inherited;
- end;
- function TCliCommand.GetDisplayName: String;
- begin
- case Self.fCollection.fDisplay of
- cdName: begin
- Result:= fName;
- end;
- cdID: begin
- Result:= '['+IntToStr(fID)+']';
- end;
- cdCaption: begin
- Result:= fCaption;
- end;
- cdIDName: begin
- Result:= '['+IntToStr(fID)+'] '+fName;
- end;
- cdIDCaption: begin
- Result:= '['+IntToStr(fID)+'] '+fCaption;
- end;
- end;
- end;
- procedure TCliCommand.SetCaption(const Value: String);
- begin
- fCaption := Value;
- end;
- procedure TCliCommand.SetID(Value: Integer);
- begin
- fID:= Value;
- end;
- procedure TCliCommand.SetName(Value: String);
- begin
- fName:= Value;
- end;
- { TJDServerClientSocket }
- constructor TJDServerClientSocket.Create(ASocket: TCustomWinSocket;
- AOwner: TJDServerSocket);
- begin
- fBusy:= True;
- try
- fOwner:= AOwner;
- fSocket:= ASocket;
- fSocket.Data:= Self;
- fErrors:= TStringList.Create;
- fProps:= TScktProps.Create;
- fProps.OnGotProp:= PropsGotProp;
- fTimer:= TTimer.Create(nil);
- fTimer.OnTimer:= TimerOnTimer;
- fTimer.Interval:= 1;
- fLoginState:= lsNone;
- fKey:= 1;
- finally
- fBusy:= False;
- end;
- end;
- destructor TJDServerClientSocket.Destroy;
- begin
- if assigned(fTimer) then fTimer.Free;
- if assigned(fProps) then fProps.Free;
- if assigned(fErrors) then fErrors.Free;
- inherited;
- end;
- procedure TJDServerClientSocket.ProcessCommand(const S: String);
- var
- X, P, Z: Integer;
- Str, T: String;
- L: TStringList;
- Pas: String;
- Val: Bool;
- CID: Integer;
- begin
- L:= TStringList.Create;
- try
- Str:= S;
- while Length(Str) > 0 do begin
- T:= CopyToDelim(Str);
- if Length(T) > 0 then begin
- Z:= StrToIntDef(T, 0);
- T:= Copy(Str, 1, Z);
- Delete(Str, 1, Z);
- L.Append(T);
- end else begin
- Str:= '';
- //Raise error - invalid packet
- end;
- end;
- case fCommand of
- JDS_CMD_LOGIN: begin
- //Client sent request to log in
- if assigned(fOnLoginRequest) then begin
- fUsername:= L[0];
- Pas:= L[1];
- Val:= False;
- fOnLoginRequest(Self, Self, fUsername, Pas, Val, fCookie,
- fUserID, fSessionID);
- if Val then begin
- Self.fLoginState:= lsAllow;
- Self.SendPacket(JDS_CMD_LOGIN, ['1']);
- end else begin
- Self.fLoginState:= lsDeny;
- Self.SendPacket(JDS_CMD_LOGIN, ['0']);
- end;
- end else begin
- //No procedure assigned to event - raise error (no login event)
- Self.SendPacket(JDS_CMD_LOGIN, ['0']);
- end;
- end;
- JDS_CMD_ERROR: begin
- //Client sent error
- end;
- JDS_CMD_COOKIE: begin
- if assigned(fOnCookieLoginRequest) then begin
- fCookie:= L[0];
- Self.fOnCookieLoginRequest(Self, Self, fCookie, Val, fUsername,
- fUserID, fSessionID);
- if Val then begin
- Self.fLoginState:= lsAllow;
- Self.SendPacket(JDS_CMD_LOGIN, ['1']);
- Self.SendPacket(JDS_CMD_SESS_ID, [IntToStr(fSessionID)]);
- Self.SendPacket(JDS_CMD_USER_ID, [IntToStr(fUserID)]);
- end else begin
- Self.fLoginState:= lsDeny;
- Self.SendPacket(JDS_CMD_LOGIN, ['0']);
- end;
- end else begin
- //No procedure assigned to event - raise error (no cookie login event)
- end;
- end;
- JDS_CMD_PROP: begin
- Self.fProps.SetPropX(L[0], L[1]);
- if assigned(fOwner.fOnGotProp) then
- Self.fOwner.fOnGotProp(fOwner, Self, L[0], L[1]);
- end;
- JDS_CMD_KEY: begin
- if L.Count > 0 then
- Self.fKey:= StrToIntDef(L[0], 1);
- end;
- else begin
- if fCommand >= 0 then begin
- if fLoginState = lsAllow then begin
- if assigned(fOnCommand) then
- fOnCommand(Self, Self, fCommand, L);
- end;
- fOwner.fCommands.DoCommand(Self, fCommand, L);
- end else begin
- end;
- end;
- end; //case
- finally
- L.Free;
- end;
- end;
- procedure TJDServerClientSocket.PropsGotProp(Sender: TObject;
- const Name, Val: String);
- begin
- Self.SendPacket(JDS_CMD_PROP, [Name, Val]);
- end;
- procedure TJDServerClientSocket.SendPacket(Cmd: Integer; Data: TStrings);
- var
- S: String;
- X: Integer;
- begin
- S:= '';
- if assigned(Data) then
- if Data <> nil then
- for X:= 0 to Data.Count - 1 do
- S:= S + IntToStr(Length(Data[X])) + JDS_DAT_DIV + Data[X];
- if fOwner.fEncryption then
- if Cmd <> JDS_CMD_KEY then
- S:= Encrypt(S, fKey);
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- IntToStr(Length(S)) + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV +
- S);
- end;
- procedure TJDServerClientSocket.SendPacket(Cmd: Integer;
- Data: array of String);
- var
- S: String;
- X: Integer;
- begin
- S:= '';
- for X:= 0 to Length(Data) - 1 do
- S:= S + IntToStr(Length(Data[X])) + JDS_DAT_DIV + Data[X];
- if fOwner.fEncryption then
- if Cmd <> JDS_CMD_KEY then
- S:= Encrypt(S, fKey);
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- IntToStr(Length(S)) + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV +
- S);
- end;
- procedure TJDServerClientSocket.SendPacket(Cmd: Integer);
- begin
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- '0' + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV);
- end;
- procedure TJDServerClientSocket.SendStream(Cmd: Integer; Data: TStream);
- begin
- Data.Position:= 0;
- Socket.SendText(IntToStr(Cmd) + JDS_DAT_DIV + IntToStr(Data.Size) + JDS_DAT_DIV);
- Socket.SendStream(Data);
- end;
- procedure TJDServerClientSocket.SetCookie(const Value: String);
- begin
- fCookie := Value;
- Self.SendPacket(JDS_CMD_COOKIE, [Value]);
- end;
- procedure TJDServerClientSocket.SetSessionID(const Value: Integer);
- begin
- fSessionID := Value;
- Self.SendPacket(JDS_CMD_SESS_ID, [IntToStr(Value)]);
- end;
- procedure TJDServerClientSocket.SetUserID(const Value: Integer);
- begin
- fUserID := Value;
- Self.SendPacket(JDS_CMD_USER_ID, [IntToStr(Value)]);
- end;
- procedure TJDServerClientSocket.SetUsername(const Value: String);
- begin
- fUsername := Value;
- end;
- procedure TJDServerClientSocket.TimerOnTimer(Sender: TObject);
- var
- S: String;
- P: Integer;
- begin
- if not fBusy then begin
- fBusy:= True;
- try
- case fRecState of
- rsIdle: begin
- if Length(fBuffer) > 0 then begin
- try
- S:= CopyToDelim(fBuffer);
- fCommand:= StrToIntDef(S, 0);
- S:= CopyToDelim(fBuffer);
- fSize:= StrToIntDef(S, 0);
- S:= CopyToDelim(fBuffer);
- fKey:= StrToIntDef(S, 1);
- finally
- fRecState:= rsCommand;
- end;
- end;
- end;
- rsCommand: begin
- if Length(fBuffer) >= fSize then begin
- try
- S:= Copy(fBuffer, 1, fSize);
- Delete(fBuffer, 1, fSize);
- if fOwner.fEncryption then
- S:= Decrypt(S, fKey);
- ProcessCommand(S);
- finally
- fRecState:= rsIdle;
- end;
- end;
- end;
- end;
- finally
- fBusy:= False;
- end;
- end;
- end;
- procedure TJDServerClientSocket.SetKey(const Value: Word);
- begin
- Self.SendPacket(JDS_CMD_KEY, [IntToStr(Value)]);
- end;
- { TJDClientServerSocket }
- constructor TJDClientServerSocket.Create(ASocket: TCustomWinSocket; AOwner: TJDClientSocket);
- begin
- fOwner:= AOwner;
- fSocket:= ASocket;
- fProps:= TScktProps.Create;
- fProps.OnGotProp:= Self.PropsGotProp;
- fErrors:= TStringList.Create;
- fTimer:= TTimer.Create(nil);
- fTimer.Interval:= 1;
- fTimer.OnTimer:= TimerOnTimer;
- fTimer.Enabled:= True;
- fSocket.Data:= Self;
- fCookie:= '';
- fSessionID:= 0;
- fUserID:= 0;
- fKey:= 1;
- end;
- destructor TJDClientServerSocket.Destroy;
- begin
- if assigned(fErrors) then fErrors.Free;
- if assigned(fTimer) then fTimer.Free;
- if assigned(fProps) then fProps.Free;
- inherited;
- end;
- procedure TJDClientServerSocket.Login(const Username, Password: String);
- begin
- Self.SendPacket(JDS_CMD_LOGIN, [Username, Password]);
- end;
- procedure TJDClientServerSocket.CookieLogin(const Cookie: String);
- begin
- Self.SendPacket(JDS_CMD_COOKIE, [Cookie]);
- end;
- procedure TJDClientServerSocket.ProcessCommand(const S: String);
- var
- Z: Integer;
- Str, T: String;
- L: TStringList;
- Val: Bool;
- begin
- L:= TStringList.Create;
- try
- Str:= S;
- while Length(Str) > 0 do begin
- T:= CopyToDelim(Str);
- if Length(T) > 0 then begin
- Z:= StrToIntDef(T, 0);
- L.Append(Copy(Str, 1, Z));
- Delete(Str, 1, Z);
- end else begin
- Str:= '';
- //Raise error - invalid packet
- end;
- end;
- case fCommand of
- JDS_CMD_LOGIN: begin
- //Server is sending login response to client
- if assigned(fOnLoginResponse) then begin
- Val:= L[0] = '1';
- if Val then begin
- Self.fLoginState:= lsAllow;
- Self.fOnLoginResponse(Self, Self, True);
- end else begin
- Self.fLoginState:= lsDeny;
- if (fCookie <> '') and (fOwner.Username <> '') then begin
- fCookie:= ''; //Clear cookie so it doesn't try again
- //Retry login with username/password instead of cookie
- SendPacket(JDS_CMD_LOGIN, [fOwner.Username, fOwner.Password]);
- end else begin
- Self.fOnLoginResponse(Self, Self, False);
- end;
- end;
- end else begin
- //No procedure assigned to event - raise error (no login event assigned)
- end;
- end;
- JDS_CMD_LOGOUT: begin
- Self.fLoginState:= lsNone;
- end;
- JDS_CMD_ERROR: begin
- //Server is sending error to client
- // P0: Error Code (int)
- // P1: Error Severity (int 0-5)
- // P2: Error Message (str)
- end;
- JDS_CMD_COOKIE: begin
- Self.fCookie:= L[0];
- if assigned(fOnGotCookie) then
- Self.fOnGotCookie(Self, Self, fCookie);
- end;
- JDS_CMD_USER_ID: begin
- Self.fUserID:= StrToIntDef(L[0], 0);
- if assigned(fOnGotUserID) then
- Self.fOnGotUserID(Self, Self, fUserID);
- end;
- JDS_CMD_SESS_ID: begin
- Self.fSessionID:= StrToIntDef(L[0], 0);
- if assigned(fOnGotSessID) then
- Self.fOnGotSessID(Self, Self, fSessionID);
- end;
- JDS_CMD_PROP: begin
- Self.fProps.SetPropX(L[0], L[1]);
- if assigned(fOwner.fOnGotProp) then
- Self.fOwner.fOnGotProp(fOwner, L[0], L[1]);
- end;
- JDS_CMD_KEY: begin
- if L.Count > 0 then begin
- Self.SendPacket(JDS_CMD_KEY, [L[0]]);
- Self.fKey:= StrToIntDef(L[0], 1);
- Sleep(100);
- Sleep(100);
- Sleep(100);
- Sleep(100);
- end;
- end;
- else begin
- if fCommand >= 0 then begin
- fOwner.fCommands.DoCommand(Self, fCommand, L);
- if assigned(fOnCommand) then
- fOnCommand(Self, Self, fCommand, L);
- end;
- end;
- end;
- finally
- L.Free;
- end;
- end;
- procedure TJDClientServerSocket.SendPacket(Cmd: Integer;
- Data: array of String);
- var
- S: String;
- X: Integer;
- begin
- S:= '';
- for X:= 0 to Length(Data) - 1 do
- S:= S + IntToStr(Length(Data[X])) + JDS_DAT_DIV + Data[X];
- if fOwner.fEncryption then
- S:= Encrypt(S, fKey);
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- IntToStr(Length(S)) + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV +
- S);
- end;
- procedure TJDClientServerSocket.SendPacket(Cmd: Integer; Data: TStrings);
- var
- S: String;
- X: Integer;
- begin
- S:= '';
- if assigned(Data) then
- if Data <> nil then
- for X:= 0 to Data.Count - 1 do
- S:= S + IntToStr(Length(Data[X])) + JDS_DAT_DIV + Data[X];
- if fOwner.fEncryption then
- S:= Encrypt(S, fKey);
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- IntToStr(Length(S)) + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV +
- S);
- end;
- procedure TJDClientServerSocket.SendPacket(Cmd: Integer);
- begin
- Socket.SendText(
- IntToStr(Cmd) + JDS_DAT_DIV +
- '0' + JDS_DAT_DIV +
- IntToStr(fKey) + JDS_DAT_DIV);
- end;
- procedure TJDClientServerSocket.TimerOnTimer(Sender: TObject);
- var
- S: String;
- P: Integer;
- begin
- if not fBusy then begin
- fBusy:= True;
- try
- case fRecState of
- rsIdle: begin
- if Pos(JDS_DAT_DIV, fBuffer) >= 1 then begin
- try
- S:= CopyToDelim(fBuffer);
- fCommand:= StrToIntDef(S, 0);
- S:= CopyToDelim(fBuffer);
- fSize:= StrToIntDef(S, 0);
- S:= CopyToDelim(fBuffer);
- fKey:= StrToIntDef(S, 1);
- finally
- fRecState:= rsCommand;
- end;
- end;
- end;
- rsCommand: begin
- if Length(fBuffer) >= fSize then begin
- try
- S:= Copy(fBuffer, 1, fSize);
- Delete(fBuffer, 1, fSize);
- if fOwner.fEncryption then
- if Self.fCommand <> JDS_CMD_KEY then
- S:= Decrypt(S, fKey);
- ProcessCommand(S);
- finally
- fRecState:= rsIdle;
- end;
- end;
- end;
- end;
- finally
- fBusy:= False;
- end;
- end;
- end;
- procedure TJDClientServerSocket.PropsGotProp(Sender: TObject; const Name,
- Val: String);
- begin
- //Local property has been set, sync with server
- Self.SendPacket(JDS_CMD_PROP, [Name, Val]);
- end;
- procedure TJDClientServerSocket.HandleError(Sender: TObject;
- const ErrType: TJDScktErrorType; const ErrMsg: String; var ErrCode: Integer);
- var
- EM: String;
- begin
- case ErrType of
- etSocket: begin
- if assigned(fOnError) then
- fOnError(Sender, Self, EM, ErrCode);
- if ErrCode <> 0 then begin
- raise Exception.Create(
- 'Socket Error (Code '+IntToStr(ErrCode)+'): '+ErrMsg);
- end;
- end;
- etInternal: begin
- if assigned(fOnError) then
- fOnError(Sender, Self, EM, ErrCode);
- if ErrCode <> 0 then begin
- raise Exception.Create(
- 'Internal Error (Code '+IntToStr(ErrCode)+'): '+ErrMsg);
- end;
- end;
- etRemote: begin
- if assigned(fOnError) then
- fOnError(Sender, Self, EM, ErrCode);
- if ErrCode <> 0 then begin
- raise Exception.Create(
- 'Remote Error (Code '+IntToStr(ErrCode)+'): '+ErrMsg);
- end;
- end;
- end;
- end;
- procedure TJDClientServerSocket.SetKey(const Value: Word);
- begin
- fKey := Value;
- end;
- { TJDServerSocket }
- constructor TJDServerSocket.Create(AOwner: TComponent);
- begin
- inherited;
- fSocket:= TServerSocket.Create(nil);
- fSocket.OnClientConnect:= ScktConnect;
- fSocket.OnClientDisconnect:= ScktDisconnect;
- fSocket.OnClientRead:= ScktRead;
- fSocket.OnClientError:= ScktError;
- fCommands:= TSvrCommands.Create(Self);
- fBlackList:= TStringList.Create;
- fMaxConnect:= 30;
- fLastSessionID:= 0;
- fCookieSize:= 10;
- end;
- destructor TJDServerSocket.Destroy;
- begin
- fSocket.Free;
- fCommands.Free;
- fBlackList.Free;
- inherited;
- end;
- function TJDServerSocket.GetActive: Bool;
- begin
- Result:= fSocket.Active;
- end;
- function TJDServerSocket.GetClient(Index: Integer): TJDServerClientSocket;
- begin
- Result:= TJDServerClientSocket(fSocket.Socket.Connections[Index].Data);
- end;
- function TJDServerSocket.GetPort: Integer;
- begin
- Result:= fSocket.Port;
- end;
- procedure TJDServerSocket.ScktCommand(Sender: TObject;
- Socket: TJDServerClientSocket; const Cmd: Integer; const Data: TStrings);
- begin
- if assigned(fOnCommand) then fOnCommand(Self, Socket, Cmd, Data);
- end;
- procedure TJDServerSocket.ScktConnect(Sender: TObject; Socket: TCustomWinSocket);
- var
- S: TJDServerClientSocket;
- A: Bool;
- Addr: String;
- K: Word;
- begin
- //Check black list
- Addr:= Socket.RemoteAddress;
- if fBlackList.IndexOf(Addr) >= 0 then begin
- Socket.Close; //Deny access
- end else begin
- A:= True;
- S:= TJDServerClientSocket.Create(Socket, Self);
- Socket.Data:= S;
- S.OnCommand:= ScktCommand;
- S.OnLoginRequest:= ScktLoginRequest;
- S.OnCookieLoginRequest:= ScktCookieLoginRequest;
- S.OnCookieLookup:= ScktCookieLookup;
- S.fSessionID:= GetNextSessionID;
- if Self.fSocket.Socket.ActiveConnections >= Self.fMaxConnect then begin
- A:= False;
- end;
- if A then begin
- if assigned(fOnConnecting) then
- fOnConnecting(Self, S, A);
- end;
- if A then begin
- Randomize;
- K:= Random(250) + 5;
- S.SendPacket(JDS_CMD_KEY, [IntToStr(K)]);
- S.EncrKey:= K;
- case Self.fAuth of
- amNone: begin
- S.fLoginState:= lsAllow;
- end;
- end;
- if assigned(fOnConnection) then
- fOnConnection(Self, S, csConnecting, csConnected);
- end else begin
- S.Free;
- Socket.Close;
- end;
- end;
- end;
- procedure TJDServerSocket.ScktDisconnect(Sender: TObject;
- Socket: TCustomWinSocket);
- var
- S: TJDServerClientSocket;
- begin
- S:= TJDServerClientSocket(Socket.Data);
- if assigned(S) then begin
- if S <> nil then begin
- if assigned(fOnConnection) then begin
- fOnConnection(Self, S, csDisconnecting, csDisconnected);
- S.Free;
- end;
- end;
- end;
- end;
- procedure TJDServerSocket.ScktError(Sender: TObject;
- Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
- var ErrorCode: Integer);
- var
- EM: String;
- begin
- EM:= 'Error in server socket';
- Self.fOnError(Self, TJDServerClientSocket(Socket.Data),
- EM, ErrorCode);
- if ErrorCode <> 0 then begin
- ErrorCode:= 0;
- end;
- end;
- procedure TJDServerSocket.ScktCookieLoginRequest(Sender: TObject;
- Socket: TJDServerClientSocket; const Cookie: String; var Accept: Bool;
- var Username: String; var UserID, SessionID: Integer);
- begin
- case fAuth of
- amNone: begin
- Accept:= True;
- end;
- amLogin: begin
- Accept:= False;
- end;
- amLoginCookie: begin
- Accept:= False;
- end;
- amFixed: begin
- //Cookie login not allowed in fixed mode
- end;
- end;
- if assigned(fOnCookieLoginRequest) then begin
- Self.fOnCookieLoginRequest(Self, Socket, Cookie, Accept, Username,
- UserID, SessionID);
- end else begin
- if fAuth in [amLoginCookie] then begin
- //Event not assigned - raise error (no cookie login event assigned)
- end;
- end;
- end;
- procedure TJDServerSocket.ScktLoginRequest(Sender: TObject;
- Socket: TJDServerClientSocket; const Username, Password: String;
- var Accept: Bool; var Cookie: String; var UserID, SessionID: Integer);
- begin
- case fAuth of
- amNone: begin
- Accept:= True;
- end;
- amLogin: begin
- Accept:= False;
- end;
- amLoginCookie: begin
- Accept:= False;
- Cookie:= Self.GetNewCookie;
- end;
- amFixed: begin
- Accept:= (UpperCase(Username) = UpperCase(fFixedUsername)) and
- (Password = fFixedPassword);
- end;
- end;
- if assigned(fOnLoginRequest) then begin
- fOnLoginRequest(Self, Socket, Username, Password, Accept, Cookie,
- UserID, SessionID);
- if Accept then begin
- if fAuth = amLoginCookie then begin
- Socket.fCookie:= Cookie;
- Socket.SendPacket(JDS_CMD_COOKIE, [Cookie]);
- end;
- if fAuth in [amLogin, amLoginCookie] then begin
- Socket.fSessionID:= SessionID;
- Socket.SendPacket(JDS_CMD_SESS_ID, [IntToStr(SessionID)]);
- Socket.fUserID:= UserID;
- Socket.SendPacket(JDS_CMD_USER_ID, [IntToStr(UserID)]);
- end;
- end;
- end else begin
- if fAuth in [amLogin, amLoginCookie] then begin
- //Event not assigned - raise error (No login event assigned)
- end;
- end;
- end;
- procedure TJDServerSocket.ScktRead(Sender: TObject;
- Socket: TCustomWinSocket);
- var
- S: TJDServerClientSocket;
- begin
- S:= TJDServerClientSocket(Socket.Data);
- S.fBuffer:= S.fBuffer + Socket.ReceiveText;
- end;
- procedure TJDServerSocket.SendGroupPacket(const Cmd: Integer;
- const Data: TStrings);
- var
- X: Integer;
- S: TJDServerClientSocket;
- begin
- for X:= 0 to Self.fSocket.Socket.ActiveConnections - 1 do begin
- S:= TJDServerClientSocket(fSocket.Socket.Connections[X].Data);
- if S.LoginState = lsAllow then begin
- S.SendPacket(Cmd, Data);
- end;
- end;
- end;
- procedure TJDServerSocket.SendGroupPacket(const Cmd: Integer;
- const Data: array of String);
- var
- X: Integer;
- S: TJDServerClientSocket;
- begin
- for X:= 0 to Self.fSocket.Socket.ActiveConnections - 1 do begin
- S:= TJDServerClientSocket(fSocket.Socket.Connections[X].Data);
- if S.LoginState = lsAllow then begin
- S.SendPacket(Cmd, Data);
- end;
- end;
- end;
- procedure TJDServerSocket.SetActive(Value: Bool);
- var
- S: TJDServerClientSocket;
- X: Integer;
- begin
- if Value then begin
- try
- fSocket.Active:= True;
- if assigned(fOnActivate) then
- fOnActivate(Self, Self);
- except
- on e: exception do begin
- fSocket.Active:= False;
- if assigned(fOnDeactivate) then
- fOnDeactivate(Self, Self);
- raise Exception.Create('Failed to activate server socket: '+e.Message);
- end;
- end;
- end else begin
- for X:= 0 to Self.fSocket.Socket.ActiveConnections - 1 do begin
- S:= TJDServerClientSocket(fSocket.Socket.Connections[X].Data);
- S.Socket.Close;
- end;
- fSocket.Active:= False;
- if assigned(fOnDeactivate) then
- fOnDeactivate(Self, Self);
- end;
- end;
- procedure TJDServerSocket.SetAuth(const Value: TJDScktAuthMode);
- begin
- fAuth := Value;
- end;
- procedure TJDServerSocket.SetFixedPassword(const Value: String);
- begin
- fFixedPassword := Value;
- end;
- procedure TJDServerSocket.SetFixedUsername(const Value: String);
- begin
- fFixedUsername := Value;
- end;
- procedure TJDServerSocket.SetPort(Value: Integer);
- begin
- fSocket.Port:= Value;
- end;
- procedure TJDServerSocket.SetMaxConnect(const Value: Integer);
- begin
- fMaxConnect := Value;
- end;
- procedure TJDServerSocket.SetLastSessionID(const Value: Integer);
- begin
- if Self.Active then begin
- if Value > fLastSessionID then
- fLastSessionID := Value
- else begin
- //Cannot set last session ID smaller than current when active
- // Raise error
- end;
- end else begin
- fLastSessionID:= Value;
- end;
- end;
- function TJDServerSocket.GetNextSessionID: Integer;
- begin
- Inc(fLastSessionID);
- Result:= fLastSessionID;
- end;
- function TJDServerSocket.GetNewCookie: String;
- var
- X, I, P: Integer;
- begin
- repeat
- Result:= '';
- for X:= 1 to fCookieSize do begin
- Randomize;
- P:= Random(30);
- if P > 20 then begin
- I:= Random(26) + 65;
- end else
- if P < 10 then begin
- I:= Random(26) + 97;
- end else begin
- I:= Random(10) + 48;
- end;
- Result:= Result + Chr(I);
- end;
- until not CookieExists(Result);
- end;
- procedure TJDServerSocket.SetCookieSize(const Value: Integer);
- begin
- fCookieSize := Value;
- end;
- function TJDServerSocket.CookieExists(const Cookie: String): Bool;
- var
- X: Integer;
- S: TJDServerClientSocket;
- begin
- Result:= False;
- for X:= 0 to Self.fSocket.Socket.ActiveConnections - 1 do begin
- S:= Self.Clients[X];
- if S.Cookie = Cookie then begin
- Result:= True;
- Break;
- end;
- end;
- if not Result then begin
- if assigned(fOnCookieLookup) then
- fOnCookieLookup(Self, Cookie, Result);
- end;
- end;
- procedure TJDServerSocket.ScktCookieLookup(Sender: TObject;
- const Cookie: String; var Exists: Bool);
- begin
- if assigned(fOnCookieLookup) then
- fOnCookieLookup(Self, Cookie, Exists);
- end;
- function TJDServerSocket.GetClientCount: Integer;
- begin
- Result:= Self.fSocket.Socket.ActiveConnections;
- end;
- function TJDServerSocket.GetBlackList: TStrings;
- begin
- Result:= TStrings(fBlackList);
- end;
- procedure TJDServerSocket.SetBlackList(const Value: TStrings);
- begin
- fBlackList.Assign(Value);
- end;
- { TJDClientSocket }
- constructor TJDClientSocket.Create(AOwner: TComponent);
- var
- S: TJDClientServerSocket;
- begin
- inherited;
- fSocket:= TClientSocket.Create(nil);
- S:= TJDClientServerSocket.Create(fSocket.Socket, Self);
- S.OnCommand:= Self.ScktCommand;
- S.OnLoginResponse:= Self.ScktLoginResponse;
- S.OnGotCookie:= Self.ScktGotCookie;
- S.OnGotSessID:= Self.ScktGotSessID;
- S.OnGotUserID:= Self.ScktGotUserID;
- fSocket.Socket.Data:= S;
- fSocket.OnConnect:= ScktConnect;
- fSocket.OnDisconnect:= ScktDisconnect;
- fSocket.OnRead:= ScktRead;
- fSocket.OnError:= ScktError;
- fCommands:= TCliCommands.Create(Self);
- Self.fAutoLogin:= True;
- end;
- destructor TJDClientSocket.Destroy;
- var
- S: TJDClientServerSocket;
- begin
- S:= TJDClientServerSocket(fSocket.Socket.Data);
- S.Free;
- fSocket.Free;
- fCommands.Free;
- inherited;
- end;
- function TJDClientSocket.GetActive: Bool;
- begin
- Result:= fSocket.Active;
- end;
- function TJDClientSocket.GetHost: String;
- begin
- Result:= fSocket.Host;
- end;
- function TJDClientSocket.GetPort: Integer;
- begin
- Result:= fSocket.Port;
- end;
- function TJDClientSocket.GetSocket: TJDClientServerSocket;
- begin
- Result:= TJDClientServerSocket(fSocket.Socket.Data);
- end;
- procedure TJDClientSocket.ScktCommand(Sender: TObject;
- Socket: TJDClientServerSocket; const Cmd: Integer; const Data: TStrings);
- begin
- if assigned(fOnCommand) then
- fOnCommand(Self, Socket, Cmd, Data);
- end;
- procedure TJDClientSocket.ScktConnection(Sender: TObject;
- Socket: TJDClientServerSocket; const OldState,
- NewState: TJDScktConnState);
- begin
- if assigned(fOnConnection) then
- fOnConnection(Self, Socket, OldState, NewState);
- end;
- procedure TJDClientSocket.ScktConnect(Sender: TObject;
- Socket: TCustomWinSocket);
- begin
- ScktConnection(Self, Self.GetSocket, csConnecting, csConnected);
- case fAuth of
- amLogin: begin
- if Self.fAutoLogin then begin
- Self.Socket.Login(fUsername, fPassword);
- end;
- end;
- amLoginCookie: begin
- if Self.fAutoLogin then begin
- if Self.Socket.fCookie <> '' then begin
- Self.Socket.CookieLogin(Self.Socket.fCookie);
- end else begin
- Self.Socket.Login(fUsername, fPassword);
- end;
- end;
- end;
- amFixed: begin
- if Self.fAutoLogin then begin
- Self.Socket.Login(fUsername, fPassword);
- end;
- end;
- end;
- end;
- procedure TJDClientSocket.ScktDisconnect(Sender: TObject;
- Socket: TCustomWinSocket);
- begin
- Self.Socket.fLoginState:= lsNone;
- ScktConnection(Self, Self.GetSocket, csDisconnecting, csDisconnected);
- end;
- procedure TJDClientSocket.ScktError(Sender: TObject;
- Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
- var ErrorCode: Integer);
- var
- EM: String;
- begin
- EM:= 'Socket Error Code: '+IntToStr(ErrorCode);
- if assigned(fOnError) then
- fOnError(Self, TJDClientServerSocket(Socket.Data), EM, ErrorCode);
- if ErrorCode <> 0 then begin
- raise Exception.Create(EM);
- ErrorCode:= 0;
- end;
- end;
- procedure TJDClientSocket.ScktRead(Sender: TObject;
- Socket: TCustomWinSocket);
- var
- S: TJDClientServerSocket;
- begin
- S:= TJDClientServerSocket(Socket.Data);
- S.fBuffer:= S.fBuffer + Socket.ReceiveText;
- end;
- procedure TJDClientSocket.ScktLoginResponse(Sender: TObject;
- Socket: TJDClientServerSocket; const Accept: Bool);
- begin
- if assigned(fOnLoginResponse) then
- fOnLoginResponse(Self, Socket, Accept);
- end;
- procedure TJDClientSocket.SetActive(Value: Bool);
- begin
- if Value then begin
- if assigned(fOnConnection) then
- fOnConnection(Self, Self.GetSocket, csDisconnected, csConnecting);
- end else begin
- if assigned(fOnConnection) then
- fOnConnection(Self, Self.GetSocket, csConnected, csDisconnecting);
- end;
- fSocket.Active:= Value;
- end;
- procedure TJDClientSocket.SetHost(Value: String);
- begin
- fSocket.Host:= Value;
- end;
- procedure TJDClientSocket.SetPort(Value: Integer);
- begin
- fSocket.Port:= Value;
- end;
- procedure TJDClientSocket.SetPassword(Value: String);
- begin
- fPassword:= Value;
- end;
- procedure TJDClientSocket.SetUsername(Value: String);
- begin
- fUsername:= Value;
- end;
- procedure TJDClientSocket.ScktGotCookie(Sender: TObject;
- Socket: TJDClientServerSocket; const NewValue: String);
- begin
- if assigned(fOnGotCookie) then
- Self.fOnGotCookie(Self, Socket, NewValue);
- end;
- procedure TJDClientSocket.ScktGotSessID(Sender: TObject;
- Socket: TJDClientServerSocket; const NewValue: Integer);
- begin
- if assigned(fOnGotSessID) then
- Self.fOnGotSessID(Self, Socket, NewValue);
- end;
- procedure TJDClientSocket.ScktGotUserID(Sender: TObject;
- Socket: TJDClientServerSocket; const NewValue: Integer);
- begin
- if assigned(fOnGotUserID) then
- Self.fOnGotUserID(Self, Socket, NewValue);
- end;
- procedure TJDClientSocket.SetAuth(const Value: TJDScktAuthMode);
- begin
- fAuth := Value;
- end;
- procedure TJDClientSocket.SetCookie(const Value: String);
- begin
- if assigned(Self.Socket) then begin
- if Self.Socket <> nil then begin
- Self.Socket.fCookie:= Value;
- end;
- end;
- end;
- function TJDClientSocket.GetCookie: String;
- begin
- if assigned(Self.Socket) then begin
- if Self.Socket <> nil then begin
- Result:= Self.Socket.fCookie;
- end;
- end;
- end;
- procedure TJDClientSocket.ScktNeedLogin(Sender: TObject;
- Socket: TJDClientServerSocket; var Username, Password: String);
- begin
- if assigned(fOnNeedLogin) then begin
- fOnNeedLogin(Self, Socket, Username, Password);
- end else begin
- end;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement