root / Server / UAdminHandling.pas @ 13:c78b5eafa10e
History | View | Annotate | Download (12.4 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 UAdminHandling;
|
| 27 | |
| 28 | {$mode objfpc}{$H+} |
| 29 | |
| 30 | interface
|
| 31 | |
| 32 | uses
|
| 33 | Classes, SysUtils, math, UPacket, UPacketHandlers, UConfig, UAccount, |
| 34 | UNetState, UEnhancedMemoryStream, UEnums, URegions; |
| 35 | |
| 36 | type
|
| 37 | |
| 38 | { TModifyUserResponsePacket }
|
| 39 | |
| 40 | TModifyUserResponsePacket = class(TPacket)
|
| 41 | constructor Create(AStatus: TModifyUserStatus; AAccount: TAccount);
|
| 42 | end;
|
| 43 | |
| 44 | { TDeleteUserResponsePacket }
|
| 45 | |
| 46 | TDeleteUserResponsePacket = class(TPacket)
|
| 47 | constructor Create(AStatus: TDeleteUserStatus; AUsername: string); |
| 48 | end;
|
| 49 | |
| 50 | { TUserListPacket }
|
| 51 | |
| 52 | TUserListPacket = class(TPacket)
|
| 53 | constructor Create;
|
| 54 | end;
|
| 55 | |
| 56 | { TModifyRegionResponsePacket }
|
| 57 | |
| 58 | TModifyRegionResponsePacket = class(TPacket)
|
| 59 | constructor Create(AStatus: TModifyRegionStatus; ARegion: TRegion);
|
| 60 | end;
|
| 61 | |
| 62 | { TDeleteRegionResponsePacket }
|
| 63 | |
| 64 | TDeleteRegionResponsePacket = class(TPacket)
|
| 65 | constructor Create(AStatus: TDeleteRegionStatus; ARegionName: string); |
| 66 | end;
|
| 67 | |
| 68 | { TUserRegionsPacket }
|
| 69 | |
| 70 | TRegionListPacket = class(TPacket)
|
| 71 | constructor Create;
|
| 72 | end;
|
| 73 | |
| 74 | procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 75 | procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 76 | procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 77 | procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 78 | procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 79 | procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 80 | procedure OnModifyRegionPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 81 | procedure OnDeleteRegionPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 82 | procedure OnListRegionsPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 83 | |
| 84 | |
| 85 | var
|
| 86 | AdminPacketHandlers: array[0..$FF] of TPacketHandler; |
| 87 | |
| 88 | implementation
|
| 89 | |
| 90 | uses
|
| 91 | md5, UCEDServer, UPackets, UClientHandling; |
| 92 | |
| 93 | procedure AdminBroadcast(AAccessLevel: TAccessLevel; APacket: TPacket);
|
| 94 | var
|
| 95 | netState: TNetState; |
| 96 | begin
|
| 97 | CEDServerInstance.TCPServer.IterReset; |
| 98 | while CEDServerInstance.TCPServer.IterNext do |
| 99 | begin
|
| 100 | netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData); |
| 101 | if (netState <> nil) and (netState.Account.AccessLevel >= AAccessLevel) then |
| 102 | CEDServerInstance.SendPacket(netState, APacket, False); |
| 103 | end;
|
| 104 | APacket.Free; |
| 105 | end;
|
| 106 | |
| 107 | procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream;
|
| 108 | ANetState: TNetState); |
| 109 | var
|
| 110 | packetHandler: TPacketHandler; |
| 111 | begin
|
| 112 | if not ValidateAccess(ANetState, alAdministrator) then Exit; |
| 113 | packetHandler := AdminPacketHandlers[ABuffer.ReadByte]; |
| 114 | if packetHandler <> nil then |
| 115 | packetHandler.Process(ABuffer, ANetState); |
| 116 | end;
|
| 117 | |
| 118 | procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 119 | begin
|
| 120 | CEDServerInstance.Landscape.Flush; |
| 121 | Config.Flush; |
| 122 | end;
|
| 123 | |
| 124 | procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
|
| 125 | begin
|
| 126 | CEDServerInstance.Quit := True; |
| 127 | end;
|
| 128 | |
| 129 | procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream;
|
| 130 | ANetState: TNetState); |
| 131 | var
|
| 132 | account: TAccount; |
| 133 | username, password: string;
|
| 134 | accessLevel: TAccessLevel; |
| 135 | netState: TNetState; |
| 136 | regions: TStringList; |
| 137 | i, regionCount: Integer; |
| 138 | begin
|
| 139 | username := ABuffer.ReadStringNull; |
| 140 | password := ABuffer.ReadStringNull; |
| 141 | accessLevel := TAccessLevel(ABuffer.ReadByte); |
| 142 | |
| 143 | regionCount := ABuffer.ReadByte; |
| 144 | |
| 145 | account := Config.Accounts.Find(username); |
| 146 | if account <> nil then |
| 147 | begin
|
| 148 | if password <> '' then |
| 149 | account.PasswordHash := MD5Print(MD5String(password)); |
| 150 | |
| 151 | account.Regions.Clear; |
| 152 | for i := 0 to regionCount - 1 do |
| 153 | account.Regions.Add(ABuffer.ReadStringNull); |
| 154 | account.Invalidate; |
| 155 | |
| 156 | if account.AccessLevel <> accessLevel then |
| 157 | begin
|
| 158 | account.AccessLevel := accessLevel; |
| 159 | CEDServerInstance.TCPServer.IterReset; |
| 160 | while CEDServerInstance.TCPServer.IterNext do |
| 161 | begin
|
| 162 | netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData); |
| 163 | if (netState <> nil) and (netState.Account = account) then |
| 164 | begin
|
| 165 | CEDServerInstance.SendPacket(netState, |
| 166 | TAccessLevelChangedPacket.Create(accessLevel)); |
| 167 | end;
|
| 168 | end;
|
| 169 | end;
|
| 170 | CEDServerInstance.SendPacket(ANetState, |
| 171 | TModifyUserResponsePacket.Create(muModified, account)); |
| 172 | end else |
| 173 | begin
|
| 174 | if username = '' then |
| 175 | begin
|
| 176 | CEDServerInstance.SendPacket(ANetState, |
| 177 | TModifyUserResponsePacket.Create(muInvalidUsername, account)); |
| 178 | Exit; |
| 179 | end else |
| 180 | begin
|
| 181 | regions := TStringList.Create; |
| 182 | for i := 0 to regionCount - 1 do |
| 183 | regions.Add(ABuffer.ReadStringNull); |
| 184 | |
| 185 | account := TAccount.Create(Config.Accounts, username, |
| 186 | MD5Print(MD5String(password)), accessLevel, regions); |
| 187 | |
| 188 | Config.Accounts.Add(account); |
| 189 | Config.Accounts.Invalidate; |
| 190 | CEDServerInstance.SendPacket(ANetState, |
| 191 | TModifyUserResponsePacket.Create(muAdded, account)); |
| 192 | end;
|
| 193 | end;
|
| 194 | end;
|
| 195 | |
| 196 | procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream;
|
| 197 | ANetState: TNetState); |
| 198 | var
|
| 199 | account: TAccount; |
| 200 | username: string;
|
| 201 | netState: TNetState; |
| 202 | begin
|
| 203 | username := ABuffer.ReadStringNull; |
| 204 | account := Config.Accounts.Find(username); |
| 205 | if (account <> nil) and (account <> ANetState.Account) then |
| 206 | begin
|
| 207 | CEDServerInstance.TCPServer.IterReset; |
| 208 | while CEDServerInstance.TCPServer.IterNext do |
| 209 | begin
|
| 210 | netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData); |
| 211 | if (netState <> nil) and (netState.Account = account) then |
| 212 | begin
|
| 213 | CEDServerInstance.Disconnect(CEDServerInstance.TCPServer.Iterator); |
| 214 | netState.Account := nil;
|
| 215 | end;
|
| 216 | end;
|
| 217 | Config.Accounts.Remove(account); |
| 218 | Config.Invalidate; |
| 219 | CEDServerInstance.SendPacket(ANetState, |
| 220 | TDeleteUserResponsePacket.Create(duDeleted, username)); |
| 221 | end else |
| 222 | CEDServerInstance.SendPacket(ANetState, |
| 223 | TDeleteUserResponsePacket.Create(duNotFound, username)); |
| 224 | end;
|
| 225 | |
| 226 | procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream;
|
| 227 | ANetState: TNetState); |
| 228 | begin
|
| 229 | CEDServerInstance.SendPacket(ANetState, |
| 230 | TCompressedPacket.Create(TUserListPacket.Create)); |
| 231 | end;
|
| 232 | |
| 233 | procedure OnModifyRegionPacket(ABuffer: TEnhancedMemoryStream;
|
| 234 | ANetState: TNetState); |
| 235 | var
|
| 236 | regionName: string;
|
| 237 | region: TRegion; |
| 238 | status: TModifyRegionStatus; |
| 239 | i, areaCount: Integer; |
| 240 | x1, y1, x2, y2: Word; |
| 241 | begin
|
| 242 | regionName := ABuffer.ReadStringNull; |
| 243 | |
| 244 | region := Config.Regions.Find(regionName); |
| 245 | if region = nil then |
| 246 | begin
|
| 247 | region := TRegion.Create(Config.Regions, regionName); |
| 248 | Config.Regions.Add(region); |
| 249 | status := mrAdded; |
| 250 | end else |
| 251 | begin
|
| 252 | region.Areas.Clear; |
| 253 | status := mrModified; |
| 254 | end;
|
| 255 | |
| 256 | areaCount := ABuffer.ReadByte; |
| 257 | for i := 0 to areaCount - 1 do |
| 258 | begin
|
| 259 | x1 := ABuffer.ReadWord; |
| 260 | y1 := ABuffer.ReadWord; |
| 261 | x2 := ABuffer.ReadWord; |
| 262 | y2 := ABuffer.ReadWord; |
| 263 | region.Areas.Add(Min(x1, x2), Min(y1, y2), |
| 264 | Max(x1, x2), Max(y1, y2)); |
| 265 | end;
|
| 266 | |
| 267 | Config.Regions.Invalidate; |
| 268 | |
| 269 | AdminBroadcast(alAdministrator, |
| 270 | TModifyRegionResponsePacket.Create(status, region)); |
| 271 | end;
|
| 272 | |
| 273 | procedure OnDeleteRegionPacket(ABuffer: TEnhancedMemoryStream;
|
| 274 | ANetState: TNetState); |
| 275 | var
|
| 276 | regionName: string;
|
| 277 | regions: TRegionList; |
| 278 | i: Integer; |
| 279 | status: TDeleteRegionStatus; |
| 280 | begin
|
| 281 | regionName := ABuffer.ReadStringNull; |
| 282 | i := 0;
|
| 283 | status := drNotFound; |
| 284 | regions := Config.Regions; |
| 285 | while (i < regions.Count) and (status = drNotFound) do |
| 286 | begin
|
| 287 | if TRegion(regions[i]).Name = regionName then |
| 288 | begin
|
| 289 | regions.Delete(i); |
| 290 | regions.Invalidate; |
| 291 | status := drDeleted; |
| 292 | end else |
| 293 | inc(i); |
| 294 | end;
|
| 295 | |
| 296 | AdminBroadcast(alAdministrator, |
| 297 | TDeleteRegionResponsePacket.Create(status, regionName)); |
| 298 | end;
|
| 299 | |
| 300 | procedure OnListRegionsPacket(ABuffer: TEnhancedMemoryStream;
|
| 301 | ANetState: TNetState); |
| 302 | begin
|
| 303 | CEDServerInstance.SendPacket(ANetState, |
| 304 | TCompressedPacket.Create(TRegionListPacket.Create)); |
| 305 | end;
|
| 306 | |
| 307 | { TModifyUserResponsePacket }
|
| 308 | |
| 309 | constructor TModifyUserResponsePacket.Create(AStatus: TModifyUserStatus;
|
| 310 | AAccount: TAccount); |
| 311 | var
|
| 312 | i: Integer; |
| 313 | begin
|
| 314 | inherited Create($03, 0); |
| 315 | FStream.WriteByte($05);
|
| 316 | FStream.WriteByte(Byte(AStatus)); |
| 317 | FStream.WriteStringNull(AAccount.Name); |
| 318 | if (AStatus = muAdded) or (AStatus = muModified) then |
| 319 | begin
|
| 320 | FStream.WriteByte(Byte(AAccount.AccessLevel)); |
| 321 | FStream.WriteByte(AAccount.Regions.Count); |
| 322 | for i := 0 to AAccount.Regions.Count - 1 do |
| 323 | FStream.WriteStringNull(AAccount.Regions[i]); |
| 324 | end;
|
| 325 | {TODO : check for client side modifications!}
|
| 326 | end;
|
| 327 | |
| 328 | { TDeleteUserResponsePacket }
|
| 329 | |
| 330 | constructor TDeleteUserResponsePacket.Create(AStatus: TDeleteUserStatus; AUsername: string); |
| 331 | begin
|
| 332 | inherited Create($03, 0); |
| 333 | FStream.WriteByte($06);
|
| 334 | FStream.WriteByte(Byte(AStatus)); |
| 335 | FStream.WriteStringNull(AUsername); |
| 336 | end;
|
| 337 | |
| 338 | { TUserListPacket }
|
| 339 | |
| 340 | constructor TUserListPacket.Create;
|
| 341 | var
|
| 342 | i, j: Integer; |
| 343 | account: TAccount; |
| 344 | begin
|
| 345 | inherited Create($03, 0); |
| 346 | FStream.WriteByte($07);
|
| 347 | FStream.WriteWord(Config.Accounts.Count); |
| 348 | for i := 0 to Config.Accounts.Count - 1 do |
| 349 | begin
|
| 350 | account := TAccount(Config.Accounts.Items[i]); |
| 351 | FStream.WriteStringNull(account.Name); |
| 352 | FStream.WriteByte(Byte(account.AccessLevel)); |
| 353 | FStream.WriteByte(account.Regions.Count); |
| 354 | for j := 0 to account.Regions.Count - 1 do |
| 355 | FStream.WriteStringNull(account.Regions[j]); |
| 356 | end;
|
| 357 | end;
|
| 358 | |
| 359 | { TModifyRegionResponsePacket }
|
| 360 | |
| 361 | constructor TModifyRegionResponsePacket.Create(AStatus: TModifyRegionStatus;
|
| 362 | ARegion: TRegion); |
| 363 | var
|
| 364 | i, areaCount: Integer; |
| 365 | begin
|
| 366 | inherited Create($03, 0); |
| 367 | FStream.WriteByte($08);
|
| 368 | FStream.WriteByte(Byte(AStatus)); |
| 369 | FStream.WriteStringNull(ARegion.Name); |
| 370 | if (AStatus = mrAdded) or (AStatus = mrModified) then |
| 371 | begin
|
| 372 | areaCount := ARegion.Areas.Count; |
| 373 | FStream.WriteByte(areaCount); |
| 374 | for i := 0 to areaCount - 1 do |
| 375 | with ARegion.Areas.Rects[i] do |
| 376 | begin
|
| 377 | FStream.WriteWord(Left); |
| 378 | FStream.WriteWord(Top); |
| 379 | FStream.WriteWord(Right); |
| 380 | FStream.WriteWord(Bottom); |
| 381 | end;
|
| 382 | end;
|
| 383 | end;
|
| 384 | |
| 385 | { TDeleteRegionResponsePacket }
|
| 386 | |
| 387 | constructor TDeleteRegionResponsePacket.Create(AStatus: TDeleteRegionStatus;
|
| 388 | ARegionName: string);
|
| 389 | begin
|
| 390 | inherited Create($03, 0); |
| 391 | FStream.WriteByte($09);
|
| 392 | FStream.WriteByte(Byte(AStatus)); |
| 393 | FStream.WriteStringNull(ARegionName); |
| 394 | end;
|
| 395 | |
| 396 | { TRegionListPacket }
|
| 397 | |
| 398 | constructor TRegionListPacket.Create;
|
| 399 | var
|
| 400 | i, j: Integer; |
| 401 | region: TRegion; |
| 402 | begin
|
| 403 | inherited Create($03, 0); |
| 404 | FStream.WriteByte($0A);
|
| 405 | FStream.WriteByte(Config.Regions.Count); |
| 406 | for i := 0 to Config.Regions.Count - 1 do |
| 407 | begin
|
| 408 | region := TRegion(Config.Regions.Items[i]); |
| 409 | FStream.WriteStringNull(region.Name); |
| 410 | FStream.WriteByte(region.Areas.Count); |
| 411 | for j := 0 to region.Areas.Count - 1 do |
| 412 | with region.Areas.Rects[j] do |
| 413 | begin
|
| 414 | FStream.WriteWord(Left); |
| 415 | FStream.WriteWord(Top); |
| 416 | FStream.WriteWord(Right); |
| 417 | FStream.WriteWord(Bottom); |
| 418 | end;
|
| 419 | end;
|
| 420 | end;
|
| 421 | |
| 422 | {$WARNINGS OFF}
|
| 423 | var
|
| 424 | i: Integer; |
| 425 | |
| 426 | initialization
|
| 427 | for i := 0 to $FF do |
| 428 | AdminPacketHandlers[i] := nil;
|
| 429 | AdminPacketHandlers[$01] := TPacketHandler.Create(0, @OnFlushPacket); |
| 430 | AdminPacketHandlers[$02] := TPacketHandler.Create(0, @OnQuitPacket); |
| 431 | AdminPacketHandlers[$05] := TPacketHandler.Create(0, @OnModifyUserPacket); |
| 432 | AdminPacketHandlers[$06] := TPacketHandler.Create(0, @OnDeleteUserPacket); |
| 433 | AdminPacketHandlers[$07] := TPacketHandler.Create(0, @OnListUsersPacket); |
| 434 | AdminPacketHandlers[$08] := TPacketHandler.Create(0, @OnModifyRegionPacket); |
| 435 | AdminPacketHandlers[$09] := TPacketHandler.Create(0, @OnDeleteRegionPacket); |
| 436 | AdminPacketHandlers[$0A] := TPacketHandler.Create(0, @OnListRegionsPacket); |
| 437 | finalization
|
| 438 | for i := 0 to $FF do |
| 439 | if AdminPacketHandlers[i] <> nil then |
| 440 | AdminPacketHandlers[i].Free; |
| 441 | {$WARNINGS ON}
|
| 442 | |
| 443 | end.
|
| 444 |