Statistics
| Branch: | Tag: | Revision:

root / Server / UConnectionHandling.pas @ 13:c78b5eafa10e

History | View | Annotate | Download (5.9 kB)

1
(*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License, Version 1.0 only
6
 * (the "License").  You may not use this file except in compliance
7
 * with the License.
8
 *
9
 * You can obtain a copy of the license at
10
 * http://www.opensource.org/licenses/cddl1.php.
11
 * See the License for the specific language governing permissions
12
 * and limitations under the License.
13
 *
14
 * When distributing Covered Code, include this CDDL HEADER in each
15
 * file and include the License file at
16
 * http://www.opensource.org/licenses/cddl1.php.  If applicable,
17
 * add the following below this CDDL HEADER, with the fields enclosed
18
 * by brackets "[]" replaced with your own identifying * information:
19
 *      Portions Copyright [yyyy] [name of copyright owner]
20
 *
21
 * CDDL HEADER END
22
 *
23
 *
24
 *      Portions Copyright 2008 Andreas Schneider
25
 *)
26
unit UConnectionHandling;
27
28
{$mode objfpc}{$H+}
29
30
interface
31
32
uses
33
  Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
34
  UEnhancedMemoryStream, UEnums;
35
  
36
type
37
38
  { TProtocolVersion }
39
40
  TProtocolVersionPacket = class(TPacket)
41
    constructor Create(AVersion: Cardinal);
42
  end;
43
44
  { TLoginResponsePacket }
45
46
  TLoginResponsePacket = class(TPacket)
47
    constructor Create(AState: TLoginState; AAccessLevel: TAccessLevel = alNone);
48
  end;
49
  
50
  { TServerStatePacket }
51
52
  TServerStatePacket = class(TPacket)
53
    constructor Create(AState: TServerState; AMessage: string = '');
54
  end;
55
56
procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
57
procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
58
procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
59
60
var
61
  ConnectionPacketHandlers: array[0..$FF] of TPacketHandler;
62
63
implementation
64
65
uses
66
  md5, UCEDServer, UClientHandling, UPackets;
67
68
procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
69
var
70
  packetHandler: TPacketHandler;
71
begin
72
  packetHandler := ConnectionPacketHandlers[ABuffer.ReadByte];
73
  if packetHandler <> nil then
74
    packetHandler.Process(ABuffer, ANetState);
75
end;
76
77
procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream;
78
  ANetState: TNetState);
79
var
80
  username, passwordHash: string;
81
  account: TAccount;
82
  netState: TNetState;
83
  invalid: Boolean;
84
begin
85
  username := ABuffer.ReadStringNull;
86
  passwordHash := MD5Print(MD5String(ABuffer.ReadStringNull));
87
  account := Config.Accounts.Find(username);
88
  if account <> nil then
89
  begin
90
    if account.AccessLevel > alNone then
91
    begin
92
      if account.PasswordHash = passwordHash then
93
      begin
94
        invalid := False;
95
        CEDServerInstance.TCPServer.IterReset;
96
        if CEDServerInstance.TCPServer.Iterator <> nil then
97
        begin
98
          repeat
99
            netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
100
            if (netState <> nil) and (netState.Account = account) then
101
            begin
102
              CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsAlreadyLoggedIn));
103
              CEDServerInstance.Disconnect(ANetState.Socket);
104
              invalid := True;
105
              Break;
106
            end;
107
          until not CEDServerInstance.TCPServer.IterNext;
108
        end;
109
110
        if not invalid then
111
        begin
112
          Writeln(TimeStamp, 'Login (', username, '): ', ANetState.Socket.PeerAddress);
113
          ANetState.Account := account;
114
          CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsOK, account.AccessLevel));
115
          CEDServerInstance.SendPacket(ANetState, TCompressedPacket.Create(
116
            TClientListPacket.Create(ANetState)));
117
          CEDServerInstance.SendPacket(nil, TClientConnectedPacket.Create(username));
118
          CEDServerInstance.SendPacket(ANetState, TSetClientPosPacket.Create(account.LastPos));
119
        end;
120
      end else
121
      begin
122
        Writeln(TimeStamp, 'Invalid password for ', username);
123
        CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidPassword));
124
        CEDServerInstance.Disconnect(ANetState.Socket);
125
      end;
126
    end else
127
    begin
128
      Writeln(TimeStamp, 'Access denied for ', username);
129
      CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsNoAccess));
130
      CEDServerInstance.Disconnect(ANetState.Socket);
131
    end;
132
  end else
133
  begin
134
    Writeln(TimeStamp, 'Invalid account specified: ', ANetState.Socket.PeerAddress);
135
    CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidUser));
136
    CEDServerInstance.Disconnect(ANetState.Socket);
137
  end;
138
end;
139
140
procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
141
begin
142
  CEDServerInstance.Disconnect(ANetState.Socket);
143
end;
144
145
{ TProtocolVersionPacket }
146
147
constructor TProtocolVersionPacket.Create(AVersion: Cardinal);
148
begin
149
  inherited Create($02, 0);
150
  FStream.WriteByte($01);
151
  FStream.WriteCardinal(AVersion);
152
end;
153
154
{ TLoginResponsePacket }
155
156
constructor TLoginResponsePacket.Create(AState: TLoginState;
157
  AAccessLevel: TAccessLevel = alNone);
158
begin
159
  inherited Create($02, 0);
160
  FStream.WriteByte($03);
161
  FStream.WriteByte(Byte(AState));
162
  if AState = lsOK then
163
  begin
164
    FStream.WriteByte(Byte(AAccessLevel));
165
    FStream.WriteWord(Config.Map.Width);
166
    FStream.WriteWord(Config.Map.Height);
167
  end;
168
end;
169
170
{ TServerStatePacket }
171
172
constructor TServerStatePacket.Create(AState: TServerState; AMessage: string = '');
173
begin
174
  inherited Create($02, 0);
175
  FStream.WriteByte($04);
176
  FStream.WriteByte(Byte(AState));
177
  if AState = ssOther then
178
    FStream.WriteStringNull(AMessage);
179
end;
180
181
{$WARNINGS OFF}
182
var
183
  i: Integer;
184
185
initialization
186
  for i := 0 to $FF do
187
    ConnectionPacketHandlers[i] := nil;
188
  ConnectionPacketHandlers[$03] := TPacketHandler.Create(0, @OnLoginRequestPacket);
189
  ConnectionPacketHandlers[$05] := TPacketHandler.Create(0, @OnQuitPacket);
190
finalization
191
  for i := 0 to $FF do
192
    if ConnectionPacketHandlers[i] <> nil then
193
      ConnectionPacketHandlers[i].Free;
194
{$WARNINGS ON}
195
196
end.
197