diff --git a/Client/Tools/UfrmHueSettings.lfm b/Client/Tools/UfrmHueSettings.lfm
index 74e9169..bbb9851 100644
--- a/Client/Tools/UfrmHueSettings.lfm
+++ b/Client/Tools/UfrmHueSettings.lfm
@@ -5,7 +5,6 @@ object frmHueSettings: TfrmHueSettings
Width = 217
HorzScrollBar.Page = 216
VertScrollBar.Page = 206
- ActiveControl = lbHue
BorderIcons = []
BorderStyle = bsToolWindow
Caption = 'Hue Settings'
@@ -15,14 +14,23 @@ object frmHueSettings: TfrmHueSettings
OnClose = FormClose
OnCreate = FormCreate
OnDeactivate = FormDeactivate
+ LCLVersion = '0.9.25'
object lblHue: TLabel
Left = 8
- Height = 16
+ Height = 12
Top = 12
- Width = 26
+ Width = 27
Caption = 'Hue:'
ParentColor = False
end
+ object edHue: TEdit
+ Left = 48
+ Height = 23
+ Top = 10
+ Width = 80
+ OnEditingDone = edHueEditingDone
+ TabOrder = 0
+ end
object lbHue: TListBox
Left = 8
Height = 160
@@ -32,14 +40,7 @@ object frmHueSettings: TfrmHueSettings
OnDrawItem = lbHueDrawItem
OnSelectionChange = lbHueSelectionChange
Style = lbOwnerDrawFixed
- TabOrder = 0
- end
- object edHue: TEdit
- Left = 48
- Height = 23
- Top = 10
- Width = 80
- OnEditingDone = edHueEditingDone
TabOrder = 1
+ TopIndex = -1
end
end
diff --git a/Client/Tools/UfrmHueSettings.pas b/Client/Tools/UfrmHueSettings.pas
index 2e773ef..8ff6d13 100644
--- a/Client/Tools/UfrmHueSettings.pas
+++ b/Client/Tools/UfrmHueSettings.pas
@@ -1,156 +1,156 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UfrmHueSettings;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
- LMessages, LCLIntf, UHue;
-
-type
-
- { TfrmHueSettings }
-
- TfrmHueSettings = class(TForm)
- edHue: TEdit;
- lblHue: TLabel;
- lbHue: TListBox;
- procedure edHueEditingDone(Sender: TObject);
- procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
- procedure FormCreate(Sender: TObject);
- procedure FormDeactivate(Sender: TObject);
- procedure lbHueDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
- State: TOwnerDrawState);
- procedure lbHueSelectionChange(Sender: TObject; User: boolean);
- protected
- procedure MouseLeave(var msg: TLMessage); message CM_MouseLeave;
- public
- class procedure DrawHue(AHue: THue; ACanvas: TCanvas; ARect: TRect;
- ACaption: string);
- end;
-
-var
- frmHueSettings: TfrmHueSettings;
-
-implementation
-
-uses
- UGameResources, UGraphicHelper;
-
-{ TfrmHueSettings }
-
-procedure TfrmHueSettings.FormClose(Sender: TObject;
- var CloseAction: TCloseAction);
-begin
- CloseAction := caHide;
-end;
-
-procedure TfrmHueSettings.edHueEditingDone(Sender: TObject);
-var
- hueID: Integer;
-begin
- if (not TryStrToInt(edHue.Text, hueID)) or (hueID >= lbHue.Items.Count) then
- begin
- edHue.Text := Format('$%x', [lbHue.ItemIndex]);
- MessageDlg('Invalid Hue', 'The hue you''ve entered is invalid.', mtWarning, [mbOK], 0);
- end else
- lbHue.ItemIndex := hueID;
-end;
-
-procedure TfrmHueSettings.FormCreate(Sender: TObject);
-var
- i: Integer;
- hue: THue;
-begin
- lbHue.Clear;
- lbHue.Items.Add('$0 (no hue)');
- for i := 1 to ResMan.Hue.Count do
- begin
- hue := ResMan.Hue.Hues[i-1];
- lbHue.Items.AddObject(Format('$%x (%s)', [i, hue.Name]), hue);
- end;
- lbHue.ItemIndex := 0;
-end;
-
-procedure TfrmHueSettings.FormDeactivate(Sender: TObject);
-begin
- Close;
-end;
-
-procedure TfrmHueSettings.lbHueDrawItem(Control: TWinControl; Index: Integer;
- ARect: TRect; State: TOwnerDrawState);
-var
- hue: THue;
-begin
- if Index > 0 then
- hue := ResMan.Hue.Hues[Index-1]
- else
- hue := nil;
- DrawHue(hue, lbHue.Canvas, ARect, lbHue.Items.Strings[Index]);
-end;
-
-procedure TfrmHueSettings.lbHueSelectionChange(Sender: TObject; User: boolean);
-begin
- edHue.Text := Format('$%x', [lbHue.ItemIndex]);
-end;
-
-procedure TfrmHueSettings.MouseLeave(var msg: TLMessage);
-begin
- try
- if not PtInRect(ClientRect, ScreenToClient(Mouse.CursorPos)) then
- Close;
- except
- Close;
- end;
-end;
-
-class procedure TfrmHueSettings.DrawHue(AHue: THue; ACanvas: TCanvas; ARect: TRect;
- ACaption: string);
-var
- hueColor: TColor;
- i: Integer;
-begin
- ACanvas.Pen.Color := clWhite;
- ACanvas.Rectangle(ARect);
- if AHue <> nil then
- for i := 0 to 31 do
- begin
- hueColor := ARGB2RGB(AHue.ColorTable[i]);
- ACanvas.Pen.Color := hueColor;
- ACanvas.MoveTo(ARect.Left + 2 + i, ARect.Top + 1);
- ACanvas.LineTo(ARect.Left + 2 + i, ARect.Bottom - 1);
- end;
- ACanvas.TextOut(ARect.Left + 36, ARect.Top, ACaption);
-end;
-
-initialization
- {$I UfrmHueSettings.lrs}
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Andreas Schneider
+ *)
+unit UfrmHueSettings;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
+ LMessages, LCLIntf, UHue;
+
+type
+
+ { TfrmHueSettings }
+
+ TfrmHueSettings = class(TForm)
+ edHue: TEdit;
+ lblHue: TLabel;
+ lbHue: TListBox;
+ procedure edHueEditingDone(Sender: TObject);
+ procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
+ procedure FormCreate(Sender: TObject);
+ procedure FormDeactivate(Sender: TObject);
+ procedure lbHueDrawItem(Control: TWinControl; Index: Integer; ARect: TRect;
+ State: TOwnerDrawState);
+ procedure lbHueSelectionChange(Sender: TObject; User: boolean);
+ protected
+ procedure MouseLeave(var msg: TLMessage); message CM_MouseLeave;
+ public
+ class procedure DrawHue(AHue: THue; ACanvas: TCanvas; ARect: TRect;
+ ACaption: string);
+ end;
+
+var
+ frmHueSettings: TfrmHueSettings;
+
+implementation
+
+uses
+ UGameResources, UGraphicHelper;
+
+{ TfrmHueSettings }
+
+procedure TfrmHueSettings.FormClose(Sender: TObject;
+ var CloseAction: TCloseAction);
+begin
+ CloseAction := caHide;
+end;
+
+procedure TfrmHueSettings.edHueEditingDone(Sender: TObject);
+var
+ hueID: Integer;
+begin
+ if (not TryStrToInt(edHue.Text, hueID)) or (hueID >= lbHue.Items.Count) then
+ begin
+ edHue.Text := Format('$%x', [lbHue.ItemIndex]);
+ MessageDlg('Invalid Hue', 'The hue you''ve entered is invalid.', mtWarning, [mbOK], 0);
+ end else
+ lbHue.ItemIndex := hueID;
+end;
+
+procedure TfrmHueSettings.FormCreate(Sender: TObject);
+var
+ i: Integer;
+ hue: THue;
+begin
+ lbHue.Clear;
+ lbHue.Items.Add('$0 (no hue)');
+ for i := 1 to ResMan.Hue.Count do
+ begin
+ hue := ResMan.Hue.Hues[i-1];
+ lbHue.Items.AddObject(Format('$%x (%s)', [i, hue.Name]), hue);
+ end;
+ lbHue.ItemIndex := 0;
+end;
+
+procedure TfrmHueSettings.FormDeactivate(Sender: TObject);
+begin
+ Close;
+end;
+
+procedure TfrmHueSettings.lbHueDrawItem(Control: TWinControl; Index: Integer;
+ ARect: TRect; State: TOwnerDrawState);
+var
+ hue: THue;
+begin
+ if Index > 0 then
+ hue := ResMan.Hue.Hues[Index-1]
+ else
+ hue := nil;
+ DrawHue(hue, lbHue.Canvas, ARect, lbHue.Items.Strings[Index]);
+end;
+
+procedure TfrmHueSettings.lbHueSelectionChange(Sender: TObject; User: boolean);
+begin
+ edHue.Text := Format('$%x', [lbHue.ItemIndex]);
+end;
+
+procedure TfrmHueSettings.MouseLeave(var msg: TLMessage);
+begin
+ try
+ if not PtInRect(ClientRect, ScreenToClient(Mouse.CursorPos)) then
+ Close;
+ except
+ Close;
+ end;
+end;
+
+class procedure TfrmHueSettings.DrawHue(AHue: THue; ACanvas: TCanvas; ARect: TRect;
+ ACaption: string);
+var
+ hueColor: TColor;
+ i: Integer;
+begin
+ ACanvas.Pen.Color := clWhite;
+ ACanvas.Rectangle(ARect);
+ if AHue <> nil then
+ for i := 0 to 31 do
+ begin
+ hueColor := ARGB2RGB(AHue.ColorTable[i]);
+ ACanvas.Pen.Color := hueColor;
+ ACanvas.MoveTo(ARect.Left + 2 + i, ARect.Top + 1);
+ ACanvas.LineTo(ARect.Left + 2 + i, ARect.Bottom - 1);
+ end;
+ ACanvas.TextOut(ARect.Left + 36, ARect.Top, ACaption);
+end;
+
+initialization
+ {$I UfrmHueSettings.lrs}
+
+end.
+
diff --git a/Client/ULandscape.pas b/Client/ULandscape.pas
index 8e36a1d..9082bcf 100644
--- a/Client/ULandscape.pas
+++ b/Client/ULandscape.pas
@@ -32,7 +32,7 @@ interface
uses
SysUtils, Classes, math, contnrs, LCLIntf, GL, GLU, ImagingOpenGL,
Imaging, ImagingClasses, ImagingTypes, ImagingUtility,
- UGenericIndex, UMap, UStatics, UArt, UTexture, UTileData, UHue, UWorldItem,
+ UGenericIndex, UMap, UStatics, UArt, UTexture, UTiledata, UHue, UWorldItem,
UMulBlock,
UListSort, UVector, UEnhancedMemoryStream,
UCacheManager, ULinkedList;
diff --git a/Client/UfrmLogin.lfm b/Client/UfrmLogin.lfm
index 212e1d9..9d89e6d 100644
--- a/Client/UfrmLogin.lfm
+++ b/Client/UfrmLogin.lfm
@@ -16,8 +16,8 @@ object frmLogin: TfrmLogin
Position = poScreenCenter
ShowInTaskBar = stAlways
object lblCopyright: TLabel
- Height = 17
- Top = 248
+ Height = 19
+ Top = 246
Width = 489
Align = alBottom
Alignment = taCenter
@@ -146,6 +146,7 @@ object frmLogin: TfrmLogin
233023312332233323342335517451745174222C0A2251745174517451745174
51745174517451745174517451745174517451745174227D3B0A
}
+ Transparent = False
end
object imgUsername: TImage
Left = 6
@@ -237,6 +238,7 @@ object frmLogin: TfrmLogin
233123322333233423355174517451745174222C0A2251745174517451745174
51745174517451745174517451745174517451745174227D3B0A
}
+ Transparent = False
end
object imgPassword: TImage
Left = 6
@@ -318,6 +320,7 @@ object frmLogin: TfrmLogin
5174222C0A2251742349234A236E234B51745174517451745174517451745174
517451745174227D3B0A
}
+ Transparent = False
end
object edHost: TEdit
Left = 101
@@ -433,103 +436,40 @@ object frmLogin: TfrmLogin
Width = 23
Color = clBtnFace
Glyph.Data = {
- 010C00002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203135332032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023333636424243222C0A222E2D2063202333363642
- 4242222C0A222E2A20632023333636414242222C0A222E612063202333393643
- 4243222C0A222E6220632023334236454244222C0A222E632063202333413644
- 4242222C0A222E6420632023333836424242222C0A222E652063202333453730
- 4242222C0A222E6620632023443145304636222C0A222E672063202344314530
- 4637222C0A222E6820632023463846424645222C0A222E692063202346374642
- 4645222C0A222E6A20632023463646394644222C0A222E6B2063202346304635
- 4643222C0A222E6C20632023454146304641222C0A222E6D2063202345444632
- 4642222C0A222E6E20632023463746414644222C0A222E6F2063202345424631
- 4642222C0A222E7020632023444645394638222C0A222E712063202342444430
- 4543222C0A222E7220632023354538394339222C0A222E732063202344314446
- 4636222C0A222E7420632023383041414539222C0A222E752063202346364641
- 4645222C0A222E7620632023463646414644222C0A222E772063202336343843
- 4338222C0A222E7820632023454546334642222C0A222E792063202345414631
- 4642222C0A222E7A20632023463246364643222C0A222E412063202346314636
- 4643222C0A222E4220632023453245434639222C0A222E432063202344424537
- 4638222C0A222E4420632023424144304545222C0A222E452063202344304446
- 4636222C0A222E4620632023374541384538222C0A222E472063202345394631
- 4641222C0A222E4820632023454546344642222C0A222E492063202345384630
- 4641222C0A222E4A20632023444445384638222C0A222E4B2063202344424536
- 4637222C0A222E4C20632023374141334531222C0A222E4D2063202343334435
- 4546222C0A222E4E20632023333536394237222C0A222E4F2063202343434444
- 4635222C0A222E5020632023374541384537222C0A222E512063202336363844
- 4339222C0A222E5220632023453946304641222C0A222E532063202346334638
- 4644222C0A222E5420632023463846414645222C0A222E552063202345464634
- 4643222C0A222E5620632023444645394639222C0A222E572063202344424537
- 4637222C0A222E5820632023443945354637222C0A222E592063202337384132
- 4530222C0A222E5A20632023413943324537222C0A222E302063202333353638
- 4236222C0A222E3120632023433944434634222C0A222E322063202337444137
- 4537222C0A222E3320632023453145434639222C0A222E342063202345334544
- 4639222C0A222E3520632023454546344643222C0A222E362063202346334637
- 4644222C0A222E3720632023453545444641222C0A222E382063202344384535
- 4636222C0A222E3920632023373741304445222C0A222E402063202341344245
- 4534222C0A222E2320632023333436374234222C0A222E3B2063202343374439
- 4634222C0A222E3A20632023374441364536222C0A222E3D2063202336353844
- 4339222C0A222E2B20632023363738454339222C0A222E252063202336433932
- 4342222C0A222E2420632023364439324342222C0A222E282063202336393930
- 4341222C0A222E2920632023363538434338222C0A222E5B2063202337343943
- 4441222C0A222E5D20632023394642414531222C0A222C2E2063202333343636
- 4233222C0A222C2C20632023433544384632222C0A222C2D2063202337424134
- 4533222C0A222C2A20632023374141334533222C0A222C612063202337414134
- 4533222C0A222C6220632023374241344532222C0A222C632063202337424133
- 4532222C0A222C6420632023374241334531222C0A222C652063202337394132
- 4531222C0A222C6620632023373741304446222C0A222C672063202337363946
- 4445222C0A222C6820632023373439454444222C0A222C692063202337323943
- 4442222C0A222C6A20632023373439444443222C0A222C6B2063202339414235
- 4444222C0A222C6C20632023333436354231222C0A222C6D2063202343324435
- 4632222C0A222C6E20632023373841314530222C0A222C6F2063202337353945
- 4445222C0A222C7020632023373339424441222C0A222C712063202337333942
- 4439222C0A222C7220632023393542304441222C0A222C732063202333333634
- 4146222C0A222C7420632023424544324630222C0A222C752063202337414133
- 4532222C0A222C7620632023373739464445222C0A222C772063202337363946
- 4444222C0A222C7820632023373239424439222C0A222C792063202337313939
- 4438222C0A222C7A20632023373039394436222C0A222C412063202338454142
- 4435222C0A222C4220632023333336334144222C0A222C432063202333363641
- 4241222C0A222C4420632023424244304546222C0A222C452063202337414132
- 4532222C0A222C4620632023364439364433222C0A222C472063202338414137
- 4432222C0A222C4820632023333236324142222C0A222C492063202342384345
- 4546222C0A222C4A20632023463746414645222C0A222C4B2063202338384330
- 3632222C0A222C4C20632023364139334346222C0A222C4D2063202338344133
- 4345222C0A222C4E20632023333236314141222C0A222C4F2063202333383643
- 4242222C0A222C5020632023423643434545222C0A222C512063202337414132
- 4531222C0A222C5220632023433244434246222C0A222C532063202336383930
- 4344222C0A222C5420632023383139454343222C0A222C552063202333323631
- 4138222C0A222C5620632023333736424241222C0A222C572063202342334341
- 4544222C0A222C5820632023374141324530222C0A222C592063202336353844
- 4341222C0A222C5A20632023374339424339222C0A222C302063202333313630
- 4137222C0A222C3120632023333536414241222C0A222C322063202341444336
- 4542222C0A222C3320632023414443354541222C0A222C342063202337433941
- 4338222C0A222C3520632023373939384337222C0A222C362063202333353639
- 4239222C0A222C3720632023333536394238222C0A222C382063202333353638
- 4237222C0A222C3920632023333536384235222C0A222C402063202333343636
- 4232222C0A222C2320632023333336354230222C0A222C3B2063202333333634
- 4145222C0A222C3A20632023333236334143222C0A222C3D2063202333323632
- 4141222C0A222C2B20632023333236314139222C0A222C252063202333313630
- 4138222C0A222C2420632023333136304136222C0A222C282063202333313631
- 4138222C0A222E2E2E2C2E2C2E2C2E2C2E2D2E2D2E2A2E2A2E612E622E632E64
- 2E652E2E2E2E222C0A222E2C2E662E672E682E692E6A2E6B2E6C2E6D2E6A2E6E
- 2E6F2E702E712E722E2E222C0A222E2C2E732E742E752E762E772E782E792E7A
- 2E682E412E422E432E442E712E65222C0A222E2C2E452E462E412E412E772E47
- 2E482E6E2E6A2E492E4A2E4B2E4C2E4D2E4E222C0A222E2C2E4F2E502E492E49
- 2E512E522E532E542E552E562E572E582E592E5A2E30222C0A222E2D2E312E32
- 2E332E332E342E352E6E2E362E372E572E582E382E392E402E23222C0A222E2D
- 2E3B2E3A2E772E3D2E2B2E252E242E282E292E772E772E772E5B2E5D2C2E222C
- 0A222E2A2C2C2C2D2C2A2C612C622C632C642C652C662C672C682C692C6A2C6B
- 2C6C222C0A222E2A2C6D2C2A2C2A2C632C632C622C652C6E2E392C6F2C6A2C70
- 2C712C722C73222C0A222E2A2C742C752C752E4C2C632C642C6E2C762C772C6A
- 2C782C792C7A2C412C42222C0A222C432C442C452E682E682E682E682E682E68
- 2E682E682E682E682C462C472C48222C0A222E642C492C652C4A2C4B2C4B2C4B
- 2C4B2C4B2C4B2C4B2C4B2E6A2C4C2C4D2C4E222C0A222C4F2C502C512C4A2C52
- 2C522C522C522C522C522C522C522E6A2C532C542C55222C0A222C562C572C58
- 2C4A2C4B2C4B2C4B2C4B2C4B2C4B2C4B2C4B2E6A2C592C5A2C30222C0A222C31
- 2C322C332E682E682E682E682E682E682E682E682E682E682C342C352C30222C
- 0A222C432C362C372C382C392E232C402C232C3B2C3A2C3D2C2B2C252C302C24
- 2C28227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000BA6A36FFB969
+ 35FFB86935FFB76835FFB56835FFB46734FFB26634FFB06533FFAE6433FFAC63
+ 32FFAA6232FFA96132FFA86031FFA76031FFA66031FFA86131FFBA6A35FFEBC6
+ ADFFEAC5ADFFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB
+ F8FFFEFBF8FFFEFBF8FFFEFBF8FFC89A7CFFC79879FFA76031FFBA6B37FFEDCA
+ B3FFE0A27AFFFEFAF7FF62C088FF62C088FF62C088FF62C088FF62C088FF62C0
+ 88FF62C088FF62C088FFFDF9F6FFCA8D65FFC99B7CFFA76031FFBB6C38FFEECC
+ B6FFE1A27AFFFEFAF7FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDCC2FFBFDC
+ C2FFBFDCC2FFBFDCC2FFFDF9F6FFCD9068FFCC9E81FFA86132FFBB6B38FFEFCE
+ B8FFE1A279FFFEFAF7FF62C088FF62C088FF62C088FF62C088FF62C088FF62C0
+ 88FF62C088FF62C088FFFDF9F6FFCF936AFFCEA384FFAA6132FFBA6A36FFEFD0
+ BBFFE2A27AFFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFBF8FFFEFB
+ F8FFFEFBF8FFFEFBF8FFFEFBF8FFD3966DFFD2A78AFFAB6232FFBB6A36FFF0D2
+ BEFFE2A37AFFE2A37AFFE1A37AFFE2A37BFFE1A37BFFE0A178FFDE9F77FFDD9F
+ 76FFDC9D74FFD99B72FFD89971FFD69970FFD5AB8EFFAD6333FFBB6A36FFF2D5
+ C2FFE3A37AFFE3A37AFFE2A37BFFE2A37BFFE2A47BFFE1A279FFE0A178FFDEA0
+ 77FFDE9E75FFDC9D74FFDA9B73FFD99B73FFDAB095FFAF6433FFBB6A36FFF2D8
+ C5FFE3A47BFFE3A37AFFE3A47AFFE2A47BFFE2A37BFFE1A37BFFE1A279FFDFA0
+ 77FFDE9F76FFDD9E74FFDB9C72FFDC9D74FFDDB59AFFB16534FFBB6B36FFF4D9
+ C7FFE6A67DFFC88C64FFC98D65FFC98E67FFCB926CFFCB926DFFCA9069FFC88C
+ 65FFC88C64FFC88C64FFC88C64FFDA9C74FFE1BA9FFFB36634FFBB6B36FFF4DC
+ C9FFE7A77DFFF9ECE1FFF9ECE1FFF9EDE3FFFCF4EEFFFDFAF7FFFDF7F3FFFAED
+ E5FFF7E7DBFFF7E5D9FFF6E5D8FFDEA077FFE4BEA4FFB46734FFBC6B36FFF5DD
+ CCFFE7A87EFFFAF0E8FFFAF0E8FFC98D66FFFAF0E9FFFDF8F3FFFEFAF8FFFCF4
+ EFFFF9E9DFFFF7E7DBFFF7E5D9FFE0A278FFE7C2A9FFB66835FFBC6B36FFF6DF
+ D0FFE8A87EFFFCF6F1FFFCF6F1FFC88C64FFFAF1E9FFFBF4EEFFFDFAF7FFFDF9
+ F6FFFAF0E8FFF8E8DDFFF7E6DBFFE1A37AFFEFD5C3FFB76935FFBC6B36FFF6DF
+ D1FFE9AA80FFFEFAF6FFFDFAF6FFC88C64FFFBF3EEFFFBF1EAFFFCF6F2FFFEFB
+ F8FFFCF6F1FFF9ECE2FFF8E7DBFFEED0BAFFECD0BDFFBB703EFFBC6B36FFF6E0
+ D1FFF7E0D1FFFEFBF8FFFEFBF7FFFDF9F6FFFCF5F0FFFAF0EAFFFBF2EDFFFDF9
+ F6FFFDFAF7FFFBF1EBFFF8E9DFFFECD0BDFFC9895EFF0000000000000000BC6B
+ 36FFBC6B36FFBC6B36FFBC6B36FFBB6B36FFBB6B36FFBB6A36FFBB6A36FFBC6C
+ 39FFBD6E3BFFBB6D3AFFBB6B38FFBB703EFF0000000000000000
}
NumGlyphs = 0
OnClick = btnSaveProfileClick
@@ -545,71 +485,40 @@ object frmLogin: TfrmLogin
Width = 23
Color = clBtnFace
Glyph.Data = {
- 100800002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A2231362031362039302032222C0A222E2E2063204E6F6E
- 65222C0A222E2C20632023464637373741222C0A222E2D206320234645373637
- 39222C0A222E2A20632023463836313634222C0A222E61206320234639363836
- 41222C0A222E6220632023463335313534222C0A222E63206320234646374538
- 31222C0A222E6420632023464537453831222C0A222E65206320234644373137
- 34222C0A222E6620632023463835463632222C0A222E67206320234642364436
- 46222C0A222E6820632023464637433745222C0A222E69206320234645373137
- 34222C0A222E6A20632023464537413744222C0A222E6B206320234646383738
- 41222C0A222E6C20632023464437393743222C0A222E6D206320234642363936
- 43222C0A222E6E20632023463835453631222C0A222E6F206320234641364336
- 45222C0A222E7020632023464637413744222C0A222E71206320234637354636
- 31222C0A222E7220632023463034363439222C0A222E73206320234643364236
- 45222C0A222E7420632023464437343737222C0A222E75206320234646383238
- 36222C0A222E7620632023464337333736222C0A222E77206320234638363236
- 34222C0A222E7820632023463735443630222C0A222E79206320234641364136
- 44222C0A222E7A20632023464637393742222C0A222E41206320234546343534
- 38222C0A222E4220632023463936333636222C0A222E43206320234642364437
- 30222C0A222E4420632023464637453830222C0A222E45206320234646374237
- 45222C0A222E4620632023464637393743222C0A222E47206320234646373737
- 39222C0A222E4820632023463735433545222C0A222E49206320234546343434
- 37222C0A222E4A20632023463635413544222C0A222E4B206320234646373937
- 44222C0A222E4C20632023464635423545222C0A222E4D206320234646353835
- 42222C0A222E4E20632023464637343736222C0A222E4F206320234546343334
- 36222C0A222E5020632023463735423544222C0A222E51206320234646373637
- 39222C0A222E5220632023464635363539222C0A222E53206320234646353435
- 37222C0A222E5420632023464637303732222C0A222E55206320234630343634
- 38222C0A222E5620632023463635413543222C0A222E57206320234641363436
- 37222C0A222E5820632023464637323734222C0A222E59206320234646373037
- 33222C0A222E5A20632023464636453730222C0A222E30206320234646364336
- 45222C0A222E3120632023463735353537222C0A222E32206320234545334433
- 46222C0A222E3320632023463635393542222C0A222E34206320234641363336
- 36222C0A222E3520632023464637313734222C0A222E36206320234636353835
- 41222C0A222E3720632023454534313433222C0A222E38206320234543334333
- 45222C0A222E3920632023463434443530222C0A222E40206320234646363736
- 38222C0A222E2320632023463534453530222C0A222E3B206320234542333433
- 36222C0A222E3A20632023463635383542222C0A222E3D206320234641363236
- 35222C0A222E2B20632023464637303731222C0A222E25206320234636353635
- 39222C0A222E2420632023454534303432222C0A222E28206320234539333233
- 35222C0A222E2920632023463234353437222C0A222E5B206320234646363236
- 33222C0A222E5D20632023463434383441222C0A222C2E206320234539324432
- 46222C0A222C2C20632023463535363538222C0A222C2D206320234641363136
- 33222C0A222C2A20632023463635353538222C0A222C61206320234544334634
- 31222C0A222C6220632023453632413243222C0A222C63206320234631334634
- 31222C0A222C6420632023463634413443222C0A222C65206320234541324633
- 31222C0A222C6620632023463234433446222C0A222C67206320234544334534
- 30222C0A222C6820632023453432323234222C0A222E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E
- 2E2E2E2E2C2E2D2E2E2E2E2E2E2E2E2E2E2E2E2E2A2E612E622E2E2E2E222C0A
- 222E2E2E2E2E2C2E632E642E652E2E2E2E2E2E2E2E2E662E672E682E662E2E2E
- 2E222C0A222E2E2E2E2E692E6A2E6B2E6C2E6D2E2E2E2E2E6E2E6F2E702E712E
- 722E2E2E2E222C0A222E2E2E2E2E2E2E732E742E752E762E772E782E792E7A2E
- 782E412E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E422E432E442E452E462E
- 472E482E492E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E4A2E4B2E
- 4C2E4D2E4E2E4F2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E
- 502E512E522E532E542E552E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E
- 2E2E562E572E582E592E5A2E302E312E322E2E2E2E2E2E2E2E222C0A222E2E2E
- 2E2E2E2E332E342E352E362E372E382E392E402E232E3B2E2E2E2E2E2E222C0A
- 222E2E2E2E2E3A2E3D2E2B2E252E242E2E2E2E2E282E292E5B2E5D2C2E2E2E2E
- 2E222C0A222E2E2E2E2C2C2C2D2C2A2C612E2E2E2E2E2E2E2E2C622C632C642C
- 652E2E2E2E222C0A222E2E2E2E2E2E2C662C672E2E2E2E2E2E2E2E2E2E2E2E2C
- 682C652E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000004F4CF2FF403EEDFF000000000000000000000000000000000000
+ 0000000000002422E4FF312FEAFF000000000000000000000000000000000000
+ 00005856F5FF6361FAFF5855F6FF413FEDFF0000000000000000000000000000
+ 00002C2AE6FF413FF1FF4C4AF6FF312FEAFF0000000000000000000000000000
+ 00005B58F6FF6562FAFF7170FFFF5956F6FF4240EEFF00000000000000003532
+ E9FF4745F2FF6362FFFF4A48F4FF2F2DE9FF0000000000000000000000000000
+ 0000000000005B59F6FF6663FAFF7471FFFF5A58F6FF4341EEFF3E3CECFF504D
+ F4FF6867FFFF504EF5FF3634EBFF000000000000000000000000000000000000
+ 000000000000000000005C5AF6FF6764FAFF7472FFFF7370FFFF706EFFFF6E6C
+ FFFF5755F7FF3F3DEEFF00000000000000000000000000000000000000000000
+ 00000000000000000000000000005D5BF7FF7976FFFF5956FFFF5754FFFF7270
+ FFFF4846F0FF0000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000005D5AF6FF7D79FFFF5E5BFFFF5B58FFFF7674
+ FFFF4643EFFF0000000000000000000000000000000000000000000000000000
+ 000000000000000000006663F9FF706DFBFF807EFFFF7E7BFFFF7C79FFFF7977
+ FFFF5E5CF7FF4744EFFF00000000000000000000000000000000000000000000
+ 0000000000006E6BFCFF7774FDFF8682FFFF7673FCFF6462F8FF605DF7FF6D6A
+ FAFF7B79FFFF605DF7FF4845EFFF000000000000000000000000000000000000
+ 00007471FEFF7D7AFEFF8A87FFFF7C79FDFF6C69FBFF0000000000000000615E
+ F8FF6E6CFAFF7D7AFFFF615FF7FF4946F0FF0000000000000000000000000000
+ 00007A77FFFF817EFFFF817EFEFF7471FDFF0000000000000000000000000000
+ 0000625FF8FF6F6DFBFF7E7CFFFF625FF8FF0000000000000000000000000000
+ 0000000000007A77FFFF7976FEFF000000000000000000000000000000000000
+ 0000000000006461F8FF6A68F9FF5451F3FF0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnDeleteProfileClick
diff --git a/Client/UfrmMain.lfm b/Client/UfrmMain.lfm
index deab9d9..bc62e60 100644
--- a/Client/UfrmMain.lfm
+++ b/Client/UfrmMain.lfm
@@ -260,86 +260,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- F10900002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203132302032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023383442363645222C0A222E2D2063202338304233
- 3641222C0A222E2A20632023374342313637222C0A222E612063202337374145
- 3633222C0A222E6220632023383742383731222C0A222E632063202341344345
- 3934222C0A222E6420632023434245364333222C0A222E652063202344344542
- 4346222C0A222E6620632023434545394339222C0A222E672063202342384444
- 4146222C0A222E6820632023374642393644222C0A222E692063202336394135
- 3538222C0A222E6A20632023383742383730222C0A222E6B2063202342424443
- 4146222C0A222E6C20632023453046324443222C0A222E6D2063202342444534
- 4236222C0A222E6E20632023413544423942222C0A222E6F2063202341304439
- 3936222C0A222E7020632023414644464135222C0A222E712063202343354538
- 4330222C0A222E7220632023384143323739222C0A222E732063202335463945
- 3530222C0A222E7420632023423744414141222C0A222E752063202344434631
- 4438222C0A222E7620632023394444383932222C0A222E772063202339334344
- 3838222C0A222E7820632023384543433834222C0A222E792063202339364434
- 3842222C0A222E7A20632023393544343841222C0A222E412063202338454432
- 3833222C0A222E4220632023423745304146222C0A222E432063202337444239
- 3642222C0A222E4420632023353639383438222C0A222E452063202339374337
- 3835222C0A222E4620632023443745454432222C0A222E472063202341304439
- 3935222C0A222E4820632023393444333841222C0A222E492063202338394338
- 3746222C0A222E4A20632023464646464646222C0A222E4B2063202338354344
- 3739222C0A222E4C20632023374343333642222C0A222E4D2063202337454337
- 3646222C0A222E4E20632023423544464143222C0A222E4F2063202335373945
- 3435222C0A222E5020632023383342353644222C0A222E512063202342364444
- 4143222C0A222E5220632023414644464136222C0A222E532063202338434342
- 3831222C0A222E5420632023383643393743222C0A222E552063202337394244
- 3645222C0A222E5620632023364141433542222C0A222E572063202337374243
- 3630222C0A222E5820632023373342413543222C0A222E592063202339394431
- 3842222C0A222E5A20632023393243353830222C0A222E302063202334373845
- 3343222C0A222E3120632023374542323639222C0A222E322063202342454532
- 4236222C0A222E3320632023393744353842222C0A222E342063202338364339
- 3741222C0A222E3520632023373042383539222C0A222E362063202337454331
- 3639222C0A222E3720632023414144343944222C0A222E382063202334323842
- 3338222C0A222E3920632023374141463635222C0A222E402063202342334444
- 4139222C0A222E2320632023384143463744222C0A222E3B2063202338314343
- 3735222C0A222E3A20632023374442453637222C0A222E3D2063202341424434
- 3943222C0A222E2B20632023334438383334222C0A222E252063202337354143
- 3631222C0A222E2420632023393843433841222C0A222E282063202339364433
- 3839222C0A222E2920632023374143363642222C0A222E5B2063202337304331
- 3633222C0A222E5D20632023363541423535222C0A222C2E2063202337324239
- 3542222C0A222C2C20632023393743433835222C0A222C2D2063202338444245
- 3742222C0A222C2A20632023333938353330222C0A222C612063202336384142
- 3533222C0A222C6220632023423444444141222C0A222C632063202337394331
- 3634222C0A222C6420632023373142453546222C0A222C652063202336454235
- 3538222C0A222C6620632023373442373543222C0A222C672063202342344441
- 4136222C0A222C6820632023343338463338222C0A222C692063202336364133
- 3536222C0A222C6A20632023374442393641222C0A222C6B2063202342324442
- 4138222C0A222C6C20632023364642353539222C0A222C6D2063202336464235
- 3538222C0A222C6E20632023373442373542222C0A222C6F2063202342334439
- 4135222C0A222C7020632023364341413541222C0A222C712063202333343832
- 3243222C0A222C7220632023354439433444222C0A222C732063202337384234
- 3634222C0A222C7420632023423544424138222C0A222C752063202339384343
- 3837222C0A222C7620632023374442433636222C0A222C772063202337434241
- 3634222C0A222C7820632023393843423836222C0A222C792063202342344439
- 4135222C0A222C7A20632023364241413538222C0A222C412063202333343831
- 3243222C0A222C4220632023353339363435222C0A222C432063202335303939
- 3431222C0A222C4420632023384643323744222C0A222C452063202341364430
- 3936222C0A222C4620632023413643463936222C0A222C472063202338394245
- 3738222C0A222C4820632023343238443336222C0A222C492063202334343843
- 3341222C0A222C4A20632023343038393336222C0A222C4B2063202333433837
- 3332222C0A222C4C20632023333738343246222C0A222E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2E2E2E2E2E2C2E2D2E2A2E612E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2E2E622E632E642E652E662E672E682E692E2E2E2E2E2E2E2E222C
- 0A222E2E2E2E2E2E2E6A2E6B2E6C2E6D2E6E2E6F2E702E712E722E732E2E2E2E
- 2E2E222C0A222E2E2E2E2E6A2E742E752E762E772E782E792E7A2E412E422E43
- 2E442E2E2E2E222C0A222E2E2E2E2E452E462E472E482E492E4A2E4A2E4B2E4C
- 2E4D2E4E2E4F2E2E2E2E222C0A222E2E2E502E512E522E532E542E552E4A2E4A
- 2E562E572E582E592E5A2E302E2E222C0A222E2E2E312E322E332E342E4A2E4A
- 2E4A2E4A2E4A2E4A2E352E362E372E382E2E222C0A222E2E2E392E402E232E3B
- 2E4A2E4A2E4A2E4A2E4A2E4A2E352E3A2E3D2E2B2E2E222C0A222E2E2E252E24
- 2E282E292E5B2E5D2E4A2E4A2E352E352C2E2C2C2C2D2C2A2E2E222C0A222E2E
- 2E2E2C612C622C632C642E572E4A2E4A2E352C652C662C672C682E2E2E2E222C
- 0A222E2E2E2E2C692C6A2C6B2E572E582E352C6C2C6D2C6E2C6F2C702C712E2E
- 2E2E222C0A222E2E2E2E2E2E2C722C732C742C752C762C772C782C792C7A2C41
- 2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2C422C432C442C452C462C472C48
- 2C412E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2C492C4A2C4B
- 2C4C2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003A8C44FF368940FF32873CFF2F84
+ 37FF000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000459653FF419950FF7DC28FFF96D0A6FF96CFA6FF78BE
+ 89FF368D42FF2C8134FF00000000000000000000000000000000000000000000
+ 0000000000004D9C5DFF64B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB
+ 98FFA5D9B4FF58AA6BFF2C8134FF000000000000000000000000000000000000
+ 000056A366FF6AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5
+ 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234FF0000000000000000000000000000
+ 000053AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8
+ 70FF58B56EFF5CB774FFA6DAB4FF388F43FF00000000000000000000000061AC
+ 75FF8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8
+ 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539FF000000000000000065AF
+ 7AFFA9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DFF000000000000000069B2
+ 7EFFB6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42FF00000000000000006DB5
+ 83FFACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC
+ 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47FF00000000000000000000
+ 000085C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD
+ 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF0000000000000000000000000000
+ 000070B887FFAADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4
+ 95FF83D28EFFAFE0B7FF6BB97DFF489856FF0000000000000000000000000000
+ 00000000000070B887FFAFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF
+ AFFFC0E8C5FF79C28AFF509E5FFF000000000000000000000000000000000000
+ 0000000000000000000071B887FF94CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD
+ B8FF6DB97FFF58A569FF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006EB684FF6AB380FF67B17CFF63AE
+ 77FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnAddRandomClick
@@ -353,83 +307,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- 810900002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203131332032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023444436413638222C0A222E2D2063202344433634
- 3633222C0A222E2A20632023444136343631222C0A222E612063202344393633
- 3544222C0A222E6220632023444636413641222C0A222E632063202345443933
- 3845222C0A222E6420632023463843334245222C0A222E652063202346394433
- 4343222C0A222E6620632023463943424334222C0A222E672063202346344234
- 4141222C0A222E6820632023453237303636222C0A222E692063202344313545
- 3533222C0A222E6A20632023453036393641222C0A222E6B2063202346324144
- 4141222C0A222E6C20632023464444434438222C0A222E6D2063202346414241
- 4145222C0A222E6E20632023464141333931222C0A222E6F2063202346413944
- 3842222C0A222E7020632023464241393943222C0A222E712063202346434337
- 4241222C0A222E7220632023453937423730222C0A222E732063202343433542
- 3443222C0A222E7420632023463341374133222C0A222E752063202346444442
- 4434222C0A222E7620632023464139413837222C0A222E772063202346303931
- 3746222C0A222E7820632023463138453741222C0A222E792063202346383934
- 3746222C0A222E7A20632023463939323745222C0A222E412063202346383843
- 3736222C0A222E4220632023463842364138222C0A222E432063202345333645
- 3633222C0A222E4420632023433735373435222C0A222E452063202345413833
- 3744222C0A222E4620632023464344344344222C0A222E472063202346373933
- 3745222C0A222E4820632023454538413735222C0A222E492063202346363834
- 3643222C0A222E4A20632023463337393633222C0A222E4B2063202346384146
- 4134222C0A222E4C20632023443034463345222C0A222E4D2063202344453641
- 3637222C0A222E4E20632023463541464135222C0A222E4F2063202346414142
- 3944222C0A222E5020632023463038433737222C0A222E512063202345433546
- 3534222C0A222E5220632023463237373633222C0A222E532063202346343845
- 3831222C0A222E5420632023453937463738222C0A222E552063202343303533
- 3341222C0A222E5620632023444236393634222C0A222E572063202346394239
- 4146222C0A222E5820632023464139333746222C0A222E592063202346303835
- 3730222C0A222E5A20632023464646464646222C0A222E302063202345393539
- 3444222C0A222E3120632023454536413545222C0A222E322063202346313944
- 3936222C0A222E3320632023424534463336222C0A222E342063202344413633
- 3546222C0A222E3520632023463741424131222C0A222E362063202346383836
- 3730222C0A222E3720632023463638323638222C0A222E382063202345413636
- 3543222C0A222E3920632023463139433936222C0A222E402063202342433530
- 3332222C0A222E2320632023443736323543222C0A222E3B2063202345453843
- 3831222C0A222E3A20632023463739313745222C0A222E3D2063202346333733
- 3544222C0A222E2B20632023453935423446222C0A222E252063202346303833
- 3742222C0A222E2420632023453237423735222C0A222E282063202342413442
- 3245222C0A222E2920632023444235363442222C0A222E5B2063202346364142
- 4132222C0A222E5D20632023463036343536222C0A222C2E2063202345453636
- 3532222C0A222C2C20632023453635383443222C0A222C2D2063202345363541
- 3532222C0A222C2A20632023463541333946222C0A222C612063202343343530
- 3334222C0A222C6220632023434636313533222C0A222C632063202345333642
- 3631222C0A222C6420632023463541434131222C0A222C652063202345413543
- 3530222C0A222C6620632023453635393445222C0A222C672063202345363536
- 3443222C0A222C6820632023453635363530222C0A222C692063202346344132
- 3945222C0A222C6A20632023443636303534222C0A222C6B2063202342383441
- 3241222C0A222C6C20632023434235393439222C0A222C6D2063202345303635
- 3543222C0A222C6E20632023463541364131222C0A222C6F2063202345463836
- 3745222C0A222C7020632023453936333542222C0A222C712063202345373544
- 3539222C0A222C7220632023454538343744222C0A222C732063202346344130
- 3945222C0A222C7420632023443735443531222C0A222C752063202342373441
- 3242222C0A222C7620632023433635353432222C0A222C772063202343433532
- 3343222C0A222C7820632023453837413735222C0A222C792063202345453932
- 3846222C0A222C7A20632023453437383731222C0A222C412063202343313444
- 3333222C0A222C4220632023424535333338222C0A222C432063202342443531
- 3335222C0A222C4420632023424334423330222C0A222C452063202342383445
- 3245222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2C2E2D2E2A2E612E2E
- 2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E622E632E642E652E66
- 2E672E682E692E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E6A2E6B2E6C2E6D
- 2E6E2E6F2E702E712E722E732E2E2E2E2E2E222C0A222E2E2E2E2E6A2E742E75
- 2E762E772E782E792E7A2E412E422E432E442E2E2E2E222C0A222E2E2E2E2E45
- 2E462E6F2E472E482E492E492E492E492E4A2E4B2E4C2E2E2E2E222C0A222E2E
- 2E4D2E4E2E4F2E502E512E512E512E512E512E512E522E532E542E552E2E222C
- 0A222E2E2E562E572E582E592E5A2E5A2E5A2E5A2E5A2E5A2E302E312E322E33
- 2E2E222C0A222E2E2E342E352E362E372E5A2E5A2E5A2E5A2E5A2E5A2E302E38
- 2E392E402E2E222C0A222E2E2E232E3B2E3A2E3D2E302E302E302E302E302E30
- 2E2B2E252E242E282E2E222C0A222E2E2E2E2E292E5B2E5D2C2E2E302E302E30
- 2E302C2C2C2D2C2A2C612E2E2E2E222C0A222E2E2E2E2C622C632C642E512C65
- 2E302C662C672C682C692C6A2C6B2E2E2E2E222C0A222E2E2E2E2E2E2C6C2C6D
- 2C6E2C6F2C702C712C722C732C742C752E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2C762C772C782C792C792C7A2C412C752E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2E2E2E2E2E2C422C432C442C452E2E2E2E2E2E2E2E2E2E2E2E222C
- 0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003853BEFF3551BDFF304BBCFF2E4E
+ B8FF000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000004255C6FF3C52CCFF757AE8FF8F92EEFF8F92EEFF7178
+ E4FF334DC1FF2B4AB7FF00000000000000000000000000000000000000000000
+ 0000000000004959CBFF5C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84
+ EEFF9EA0F4FF515DD7FF2B4AB7FF000000000000000000000000000000000000
+ 00005361CFFF616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56
+ E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8FF0000000000000000000000000000
+ 00004B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59
+ E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF0000000000000000000000005C62
+ D7FF818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59
+ E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBAFF00000000000000005F63
+ DAFFA1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCFF00000000000000006469
+ DBFFAFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEFF0000000000000000676A
+ DEFFA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F
+ ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0FF00000000000000000000
+ 00007D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84
+ F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF0000000000000000000000000000
+ 00006A69E0FFA3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92
+ F9FF768CF8FFA8B6F8FF636EE3FF4557C7FF0000000000000000000000000000
+ 0000000000006A69E0FFAAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9
+ FBFFBAC7FCFF707BE9FF4C5BCCFF000000000000000000000000000000000000
+ 000000000000000000006A6ADFFF8E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4
+ F4FF6670E2FF535ED1FF00000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000686ADDFF6364DCFF6164DAFF5D63
+ D9FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnDeleteRandomClick
@@ -443,78 +354,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- F10800002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203130342032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023464630303030222C0A222E2D2063202346443030
- 3030222C0A222E2A20632023464632423236222C0A222E612063202346463639
- 3543222C0A222E6220632023464636383542222C0A222E632063202346453637
- 3541222C0A222E6420632023464536353538222C0A222E652063202346453633
- 3536222C0A222E6620632023464536313534222C0A222E672063202346433237
- 3232222C0A222E6820632023464230303030222C0A222E692063202346463641
- 3544222C0A222E6A20632023464634373433222C0A222E6B2063202346453334
- 3334222C0A222E6C20632023464533323332222C0A222E6D2063202346443330
- 3330222C0A222E6E20632023464432443244222C0A222E6F2063202346433343
- 3338222C0A222E7020632023464335443446222C0A222E712063202346413235
- 3146222C0A222E7220632023463730303030222C0A222E732063202346463542
- 3538222C0A222E7420632023464643464346222C0A222E752063202346453532
- 3532222C0A222E7620632023464432463246222C0A222E772063202346443243
- 3243222C0A222E7820632023464334423442222C0A222E792063202346454343
- 4343222C0A222E7A20632023464234433438222C0A222E412063202346423537
- 3439222C0A222E4220632023463932333144222C0A222E432063202346353030
- 3030222C0A222E4420632023464534373433222C0A222E452063202346464633
- 4633222C0A222E4620632023464645444544222C0A222E472063202346433443
- 3443222C0A222E4820632023464334413441222C0A222E492063202346464543
- 4543222C0A222E4A20632023464646324632222C0A222E4B2063202346454341
- 4341222C0A222E4C20632023464132463241222C0A222E4D2063202346413531
- 3432222C0A222E4E20632023463330303030222C0A222E4F2063202346453333
- 3333222C0A222E5020632023464435303530222C0A222E512063202346454543
- 4543222C0A222E5220632023464133453345222C0A222E532063202346383137
- 3137222C0A222E5420632023463934453346222C0A222E552063202346313030
- 3030222C0A222E5620632023464536343537222C0A222E572063202346393344
- 3344222C0A222E5820632023463831363136222C0A222E592063202346373133
- 3133222C0A222E5A20632023463834423343222C0A222E302063202346453632
- 3535222C0A222E3120632023464332393239222C0A222E322063202346433438
- 3438222C0A222E3320632023463933413341222C0A222E342063202346373132
- 3132222C0A222E3520632023463630463046222C0A222E362063202346383438
- 3338222C0A222E3720632023464435463532222C0A222E382063202346433238
- 3238222C0A222E3920632023464334373437222C0A222E402063202346464631
- 4631222C0A222E2320632023464545414541222C0A222E3B2063202346373334
- 3334222C0A222E3A20632023463530423042222C0A222E3D2063202346383435
- 3335222C0A222E2B20632023454630303030222C0A222E252063202346443544
- 3446222C0A222E2420632023464233373332222C0A222E282063202346454342
- 4342222C0A222E2920632023464545424542222C0A222E5B2063202346393342
- 3342222C0A222E5D20632023463833393339222C0A222C2E2063202346454631
- 4631222C0A222C2C20632023464443354335222C0A222C2D2063202346363144
- 3138222C0A222C2A20632023463734333333222C0A222C612063202346393030
- 3030222C0A222C6220632023464235383441222C0A222C632063202346423437
- 3432222C0A222C6420632023464443394339222C0A222C652063202346363130
- 3130222C0A222C6620632023463733333333222C0A222C672063202346373335
- 3330222C0A222C6820632023463734343334222C0A222C692063202346323142
- 3134222C0A222C6A20632023454430303030222C0A222C6B2063202346413533
- 3434222C0A222C6C20632023463932393234222C0A222C6D2063202346353043
- 3043222C0A222C6E20632023463530393039222C0A222C6F2063202346353142
- 3136222C0A222C7020632023463131423134222C0A222C712063202346353230
- 3141222C0A222C7220632023463934433343222C0A222C732063202346383439
- 3341222C0A222C7420632023463834373338222C0A222C752063202346373433
- 3334222C0A222C7620632023463734323332222C0A222E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2E2C2E2C2E2C2E2C2E2D2E2D2E2D2E2D2E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2C2E2A2E612E622E632E642E652E662E672E682E2E2E2E2E2E222C
- 0A222E2E2E2E2E2C2E2A2E692E6A2E6B2E6C2E6D2E6E2E6F2E702E712E722E2E
- 2E2E222C0A222E2E2E2C2E2A2E692E732E742E752E762E772E782E792E7A2E41
- 2E422E432E2E222C0A222E2E2E2C2E622E442E742E452E462E472E482E492E4A
- 2E4B2E4C2E4D2E4E2E2E222C0A222E2E2E2C2E632E4F2E502E462E452E462E46
- 2E4A2E512E522E532E542E552E2E222C0A222E2E2E2D2E562E6D2E6E2E782E46
- 2E4A2E4A2E492E572E582E592E5A2E552E2E222C0A222E2E2E2D2E302E772E31
- 2E322E462E4A2E4A2E512E332E342E352E362E552E2E222C0A222E2E2E2D2E37
- 2E382E392E492E4A2E492E512E402E232E3B2E3A2E3D2E2B2E2E222C0A222E2E
- 2E682E252E242E282E4A2E292E5B2E5D2E232C2E2C2C2C2D2C2A2E2B2E2E222C
- 0A222E2E2C612E712C622C632C642E5B2E592C652C662C2C2C672C682C692C6A
- 2E2E222C0A222E2E2E2E2E722E422C6B2C6C2E342E352C6D2C6E2C6F2C2A2C70
- 2C6A2E2E2E2E222C0A222E2E2E2E2E2E2E432C712C722C732C742E3D2C752C76
- 2C702C6A2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E552E552E552E552E2B
- 2E2B2C6A2C6A2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000F1FF0000F1FF0000F1FF0000F1FF0000EFFF0000
+ EFFF0000EDFF0000EDFF00000000000000000000000000000000000000000000
+ 0000000000000000F5FF1A20F5FF3C4CF9FF3A49F8FF3847F8FF3545F8FF3443
+ F7FF3242F7FF141BF1FF0000EDFF000000000000000000000000000000000000
+ 00000000F7FF1D23F9FF4453FAFF2429F9FF1212F7FF0F0FF6FF0C0CF5FF0909
+ F5FF161BF5FF3343F7FF141BF1FF0000EDFF0000000000000000000000000000
+ F9FF1F25FAFF4A58FBFF4247FBFFC9C9FDFF3B3BF9FF1313F7FF1010F6FF3333
+ F7FFC5C5FDFF3035F7FF3444F7FF141BF2FF0000EDFF00000000000000000000
+ FBFF4F5DFDFF3237FBFFCBCBFEFFF2F2FFFFEBEBFEFF3B3BF9FF3939F8FFEAEA
+ FEFFF1F1FEFFC5C5FDFF181DF6FF3343F7FF0000EFFF00000000000000000000
+ FDFF525FFDFF2828FCFF4747FCFFECECFFFFF2F2FFFFECECFFFFECECFEFFF1F1
+ FFFFEAEAFEFF3434F7FF0B0BF5FF3545F8FF0000EFFF00000000000000000000
+ FDFF5562FEFF2C2CFDFF2929FCFF4848FCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC
+ FEFF3A3AF9FF1212F7FF0F0FF6FF3848F8FF0000F1FF00000000000000000000
+ FDFF5764FEFF3030FDFF2D2DFDFF4B4BFCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC
+ FFFF3D3DF9FF1616F8FF1313F7FF3C4BF8FF0000F1FF00000000000000000000
+ FFFF5A67FEFF3333FEFF5050FDFFEDEDFFFFF3F3FFFFEDEDFFFFEDEDFFFFF2F2
+ FFFFECECFEFF3E3EFAFF1717F8FF3F4EF9FF0000F1FF00000000000000000000
+ FFFF5B68FFFF4347FEFFCFCFFFFFF3F3FFFFEDEDFFFF4C4CFCFF4A4AFCFFECEC
+ FFFFF2F2FFFFCACAFEFF2A2FFAFF4251FAFF0000F3FF00000000000000000000
+ FFFF262BFFFF5D6AFFFF585BFFFFCFCFFFFF5252FEFF2F2FFDFF2C2CFDFF4B4B
+ FCFFCCCCFEFF484CFBFF4957FBFF1D23F9FF0000F5FF00000000000000000000
+ 00000000FFFF262BFFFF5D6AFFFF4347FFFF3434FEFF3232FEFF3030FDFF2D2D
+ FDFF383CFCFF4F5DFCFF1F25FAFF0000F7FF0000000000000000000000000000
+ 0000000000000000FFFF262BFFFF5C69FFFF5B68FFFF5A67FEFF5865FEFF5663
+ FEFF5461FEFF2227FCFF0000FBFF000000000000000000000000000000000000
+ 000000000000000000000000FFFF0000FFFF0000FFFF0000FFFF0000FDFF0000
+ FDFF0000FDFF0000FDFF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnClearRandomClick
@@ -540,125 +413,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- C10E00002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203139372032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023344438424338222C0A222E2D2063202334463843
- 4338222C0A222E2A20632023344638444338222C0A222E612063202334463843
- 4339222C0A222E6220632023344638424337222C0A222E632063202334423839
- 4335222C0A222E6420632023334237364334222C0A222E652063202334393835
- 4334222C0A222E6620632023454346324637222C0A222E672063202345454634
- 4638222C0A222E6820632023454446334638222C0A222E692063202345434632
- 4638222C0A222E6A20632023443745364632222C0A222E6B2063202337444232
- 4532222C0A222E6C20632023363539344442222C0A222E6D2063202334423838
- 4335222C0A222E6E20632023463246364641222C0A222E6F2063202343374530
- 4641222C0A222E7020632023433945324642222C0A222E712063202343384530
- 4642222C0A222E7220632023433544464639222C0A222E732063202343314442
- 4638222C0A222E7420632023423844364634222C0A222E752063202346384642
- 4646222C0A222E7620632023423444384636222C0A222E772063202337444230
- 4531222C0A222E7820632023363439324442222C0A222E792063202334433839
- 4336222C0A222E7A20632023463146354639222C0A222E412063202343444533
- 4643222C0A222E4220632023434445334642222C0A222E432063202343424532
- 4642222C0A222E4420632023433845304639222C0A222E452063202343324443
- 4638222C0A222E4620632023424144364635222C0A222E472063202346384642
- 4644222C0A222E4820632023434445364643222C0A222E492063202343394535
- 4641222C0A222E4A20632023383442364532222C0A222E4B2063202334323739
- 4246222C0A222E4C20632023344238394336222C0A222E4D2063202343464533
- 4643222C0A222E4E20632023434645344643222C0A222E4F2063202343414531
- 4641222C0A222E5020632023433444444639222C0A222E512063202342434439
- 4636222C0A222E5220632023444645394634222C0A222E532063202346334637
- 4642222C0A222E5420632023453945464635222C0A222E552063202334353745
- 4332222C0A222E5620632023463046344639222C0A222E572063202344334536
- 4643222C0A222E5820632023443345374644222C0A222E592063202344314534
- 4643222C0A222E5A20632023433845304641222C0A222E302063202342424436
- 4635222C0A222E3120632023423544344633222C0A222E322063202342334432
- 4631222C0A222E3320632023463046344638222C0A222E342063202334363832
- 4334222C0A222E3520632023344138384336222C0A222E362063202345464634
- 4639222C0A222E3720632023443745374645222C0A222E382063202344354537
- 4644222C0A222E3920632023443445364644222C0A222E402063202344324536
- 4643222C0A222E2320632023364539374434222C0A222E3B2063202337423945
- 4434222C0A222E3A20632023373139384430222C0A222E3D2063202338324134
- 4436222C0A222E2B20632023363838454344222C0A222E252063202336393930
- 4344222C0A222E2420632023373539414430222C0A222E282063202337333939
- 4431222C0A222E2920632023363238424338222C0A222E5B2063202334393838
- 4336222C0A222E5D20632023454446344639222C0A222C2E2063202344384538
- 4645222C0A222C2C20632023443745384645222C0A222C2D2063202344364537
- 4645222C0A222C2A20632023443345354644222C0A222C612063202336353844
- 4343222C0A222C6220632023423043444633222C0A222C632063202346464646
- 4646222C0A222C6420632023423343374533222C0A222C652063202341314246
- 4541222C0A222C6620632023363038394339222C0A222C672063202334373834
- 4336222C0A222C6820632023454346334639222C0A222C692063202344364538
- 4645222C0A222C6A20632023443645374644222C0A222C6B2063202335423836
- 4337222C0A222C6C20632023394543304546222C0A222C6D2063202336453933
- 4343222C0A222C6E20632023463746424646222C0A222C6F2063202346314638
- 4646222C0A222C7020632023384341464534222C0A222C712063202336313841
- 4337222C0A222C7220632023343538324335222C0A222C732063202345424632
- 4638222C0A222C7420632023443545364644222C0A222C752063202335443838
- 4338222C0A222C7620632023413142464546222C0A222C772063202346414643
- 4644222C0A222C7820632023464246434645222C0A222C792063202346444644
- 4645222C0A222C7A20632023464346444645222C0A222C412063202346414642
- 4644222C0A222C4220632023464246434644222C0A222C432063202338354138
- 4444222C0A222C4420632023353337464331222C0A222C452063202334303743
- 4334222C0A222C4620632023453646304637222C0A222C472063202335354234
- 4638222C0A222C4820632023353442354637222C0A222C492063202335334234
- 4638222C0A222C4A20632023353342324638222C0A222C4B2063202336353844
- 4341222C0A222C4C20632023393942384541222C0A222C4D2063202337454135
- 4444222C0A222C4E20632023383041364444222C0A222C4F2063202337434133
- 4442222C0A222C5020632023374141304439222C0A222C512063202337394130
- 4439222C0A222C5220632023373839464438222C0A222C532063202337383945
- 4438222C0A222C5420632023354438344246222C0A222C552063202333433738
- 4331222C0A222C5620632023453345444637222C0A222C572063202336454332
- 4644222C0A222C5820632023394544374646222C0A222C592063202339424436
- 4646222C0A222C5A20632023393844374646222C0A222C302063202336313842
- 4339222C0A222C3120632023393242354536222C0A222C322063202338314137
- 4532222C0A222C3320632023383141374531222C0A222C342063202337444133
- 4445222C0A222C3520632023374241314443222C0A222C362063202337393946
- 4442222C0A222C3720632023373739454439222C0A222C382063202337333941
- 4434222C0A222C3920632023353737454242222C0A222C402063202333383731
- 4246222C0A222C2320632023444645424635222C0A222C3B2063202336384246
- 4644222C0A222C3A20632023363542454642222C0A222C3D2063202336344245
- 4643222C0A222C2B20632023353438314334222C0A222C252063202339374236
- 4541222C0A222C2420632023454146334633222C0A222C282063202345364631
- 4544222C0A222C2920632023453646314546222C0A222C5B2063202345364630
- 4546222C0A222C5D20632023453546314544222C0A222D2E2063202345444635
- 4633222C0A222D2C20632023373939434435222C0A222D2D2063202334343730
- 4230222C0A222D2A20632023333336394243222C0A222D612063202345414631
- 4638222C0A222D6220632023444645434637222C0A222D632063202344454541
- 4636222C0A222D6420632023444345414636222C0A222D652063202335313746
- 4333222C0A222D6620632023394142364546222C0A222D672063202345384633
- 4541222C0A222D6820632023383442463531222C0A222D692063202339384339
- 3646222C0A222D6A20632023393943393731222C0A222D6B2063202338344246
- 3534222C0A222D6C20632023453946344534222C0A222D6D2063202337423943
- 4444222C0A222D6E20632023334136394141222C0A222D6F2063202333303635
- 4241222C0A222D7020632023333136364242222C0A222D712063202333303636
- 4241222C0A222D7220632023353538334336222C0A222D732063202342414345
- 4546222C0A222D7420632023464646464444222C0A222D752063202343374545
- 3837222C0A222D7620632023443746344132222C0A222D772063202344374636
- 4132222C0A222D7820632023433745453843222C0A222D792063202346464646
- 4530222C0A222D7A20632023383541324444222C0A222D412063202333453641
- 4142222C0A222D4220632023333336384241222C0A222D432063202335383834
- 4333222C0A222D4420632023363838424433222C0A222D452063202337303846
- 4531222C0A222D4620632023364338444443222C0A222D472063202336443842
- 4441222C0A222D4820632023364538414437222C0A222D492063202336433842
- 4344222C0A222D4A20632023343436444142222C0A222D4B2063202332453546
- 4136222C0A222E2E2E2C2E2D2E2D2E2D2E2A2E612E622E632E642E2E2E2E2E2E
- 2E2E2E2E2E2E222C0A222E652E662E672E682E682E682E692E662E6A2E6B2E6C
- 2E2E2E2E2E2E2E2E2E2E222C0A222E6D2E6E2E6F2E702E712E722E732E742E75
- 2E762E772E782E2E2E2E2E2E2E2E222C0A222E792E7A2E412E422E432E442E45
- 2E462E472E482E492E4A2E4B2E2E2E2E2E2E222C0A222E4C2E7A2E4D2E4E2E41
- 2E4F2E502E512E522E662E532E542E552E2E2E2E2E2E222C0A222E4C2E562E57
- 2E582E592E422E5A2E452E302E312E322E332E342E2E2E2E2E2E222C0A222E35
- 2E362E372E382E392E402E232E3B2E3A2E3D2E2B2E252E242E282E292E2E222C
- 0A222E5B2E5D2C2E2C2C2C2D2C2A2C612C622C632C642C632C632C632C632C65
- 2C66222C0A222C672C682C692C6A2C6A2E382C6B2C6C2C632C6D2C632C632C6E
- 2C6F2C702C71222C0A222C722C732C2D2C6A2C6A2C742C752C762C772C782C79
- 2C7A2C412C422C432C44222C0A222C452C462C472C482C492C4A2C4B2C4C2C4D
- 2C4E2C4F2C502C512C522C532C54222C0A222C552C562C572C582C592C5A2C30
- 2C312C322C332C342C352C362C372C382C39222C0A222C402C232C3B2C3A2C3D
- 2C3D2C2B2C252C242C282C292C5B2C5D2D2E2D2C2D2D222C0A222D2A2D612D62
- 2D632D642D642D652D662D672D682D692D6A2D6B2D6C2D6D2D6E222C0A222E2E
- 2D6F2D702D712D712D6F2D722D732D742D752D762D772D782D792D7A2D41222C
- 0A222E2E2E2E2E2E2E2E2E2E2E2E2D422D432D442D452D462D472D482D492D4A
- 2D4B227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 000000000000000000000000000000000000BA6833FFC38458FFD38B68FFE18F
+ 70FFDC8D6CFFDA8B6DFFD78A6EFFCD8B6CFFAB6D44FFA65F2EFF00000000BA65
+ 30FFBB6631FFBA6630FFBA6630FFBA6530FFC68355FFEFCEBAFFDDFFFFFF87EE
+ C7FFA2F4D7FFA2F6D7FF8CEEC7FFE0FFFFFFDDA285FFAB6A3EFFBC6933FFF8F1
+ EAFFF7ECDFFFF6EADEFFF6EADCFFF6EADCFFC37F51FFEFB69AFFEAF3E8FF51BF
+ 84FF6FC998FF71C999FF54BF84FFE4F4E9FFDD9C7BFFAA693AFFBF7138FFF5EB
+ DFFFFDBF68FFFBBE65FFFCBE64FFFCBE64FFC48154FFEAB697FFF3F3EAFFEDF1
+ E6FFEFF1E6FFEFF0E6FFEDF1E5FFF3F5EDFFD59C79FFB07044FFC1783CFFF7ED
+ E3FFFDC26EFFFFD79EFFFFD69BFFFFD798FFC98B61FFE6B592FFE2A781FFE1A7
+ 81FFDEA37DFFDCA17BFFDB9F79FFD99E77FFD49A73FFBB7E57FFC47C40FFF7F0
+ E6FFF8B455FFF7B554FFF8B453FFF8B253FFCA8D65FFEAB899FFDDA57EFFDDA6
+ 80FFDBA37CFFD9A07AFFD9A079FFD89F78FFD89E78FFBF845DFFC58245FFF8F2
+ EBFFFEE7D6FFFDE7D6FFFDE7D6FFFDE6D5FFC8885DFFEFBFA1FFFDFCFAFFFEFC
+ FBFFFEFDFDFFFEFDFCFFFDFBFAFFFDFCFBFFDDA885FFC17F53FFC68447FFF9F3
+ ECFFFEE8D6FFFDE7D6FFFDE7D6FFFDE7D5FFC7865BFFEFC09EFFFFFFFFFFCC93
+ 6EFFFFFFFFFFFFFFFFFFFFFBF7FFFFF8F1FFE4AF8CFFC78A61FFC68849FFF9F4
+ EDFFFEE8D8FFFEE8D7FFFEE7D6FFFDE5D3FFCC8D65FFF3CDB0FFFFFFFFFFE3C7
+ B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEABFA1FFC98960FFC6884AFFF9F4
+ EFFFFEE7D7FFFDE7D5FFFDE6D4FFFCE6D2FFD4976EFFD49E7BFFD09871FFD6A4
+ 82FFCD8E68FFCD9069FFD09A75FFD19973FFC88B62FF00000000C6894BFFF9F4
+ F0FFFCE6D3FFFDE7D3FFFCE4D1FFFBE3CDFFFAE0C8FFF8DCC2FFF5D6BBFFF3D4
+ B5FFF1D2B3FFF8F4F0FFC48246FF000000000000000000000000C6894BFFF9F5
+ F1FFFCE3CFFFFCE4CFFFFCE3CDFFFAE1CAFFF9DDC4FFF6D9BCFFF4E9DFFFF7F2
+ ECFFFBF7F3FFF5EFE9FFC27E45FF000000000000000000000000C6894CFFF9F5
+ F1FFFCE3CDFFFBE3CDFFFBE2CBFFF9E0C8FFF8DCC2FFF5D6BAFFFDFBF8FFFCE6
+ CDFFFAE5C9FFE2B684FFBF7942FF000000000000000000000000C5884BFFFAF6
+ F2FFFAE0C7FFFBE2C9FFFBE0C8FFF9DFC5FFF8DBC1FFF4D6B8FFFFFBF8FFF6D8
+ B4FFE1B07DFFDB9264FF00000000000000000000000000000000C48549FFF7F2
+ ECFFF8F4EEFFF8F3EDFFF8F3EDFFF8F3EDFFF8F2ECFFF7F2ECFFF2E6D7FFE2B2
+ 7DFFDB9465FF000000000000000000000000000000000000000000000000C88B
+ 4DFFC88C4FFFC88C4FFFC88C4FFFC88D4FFFC98C4FFFC78B4FFFC5894BFFC476
+ 3BFF000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnRandomPresetSaveClick
@@ -673,114 +461,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- 710D00002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203137362032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023344438424338222C0A222E2D2063202334463843
- 4338222C0A222E2A20632023344638444338222C0A222E612063202334463843
- 4339222C0A222E6220632023344638424337222C0A222E632063202334423839
- 4335222C0A222E6420632023334237364334222C0A222E652063202334393835
- 4334222C0A222E6620632023454346324637222C0A222E672063202345454634
- 4638222C0A222E6820632023454446344638222C0A222E692063202345444633
- 4638222C0A222E6A20632023454346324638222C0A222E6B2063202344374536
- 4632222C0A222E6C20632023374442324532222C0A222E6D2063202336353934
- 4442222C0A222E6E20632023344238384335222C0A222E6F2063202346324636
- 4641222C0A222E7020632023433745304641222C0A222E712063202343394531
- 4642222C0A222E7220632023433945324642222C0A222E732063202343384530
- 4642222C0A222E7420632023433544464639222C0A222E752063202343314442
- 4638222C0A222E7620632023423844364634222C0A222E772063202346384642
- 4646222C0A222E7820632023423444384636222C0A222E792063202337444230
- 4531222C0A222E7A20632023363439324442222C0A222E412063202334433839
- 4336222C0A222E4220632023463146354639222C0A222E432063202343444533
- 4643222C0A222E4420632023434545334642222C0A222E452063202343444533
- 4642222C0A222E4620632023434245324642222C0A222E472063202343384530
- 4639222C0A222E4820632023433244434638222C0A222E492063202342414436
- 4635222C0A222E4A20632023463846424644222C0A222E4B2063202343444536
- 4643222C0A222E4C20632023433945354641222C0A222E4D2063202338344236
- 4532222C0A222E4E20632023343237394246222C0A222E4F2063202334423839
- 4336222C0A222E5020632023434645334643222C0A222E512063202344304534
- 4642222C0A222E5220632023434645344643222C0A222E532063202343414531
- 4641222C0A222E5420632023433444444639222C0A222E552063202342434439
- 4636222C0A222E5620632023444645394634222C0A222E572063202346334637
- 4642222C0A222E5820632023453945464635222C0A222E592063202334353745
- 4332222C0A222E5A20632023463046344639222C0A222E302063202344334536
- 4643222C0A222E3120632023443445364643222C0A222E322063202344334537
- 4644222C0A222E3320632023443145344643222C0A222E342063202343384530
- 4641222C0A222E3520632023424244364635222C0A222E362063202342354434
- 4633222C0A222E3720632023423344324631222C0A222E382063202346304634
- 4638222C0A222E3920632023343638324334222C0A222E402063202334413838
- 4336222C0A222E2320632023454646344639222C0A222E3B2063202344374537
- 4645222C0A222E3A20632023443645374644222C0A222E3D2063202344354537
- 4644222C0A222E2B20632023443445364644222C0A222E252063202344324536
- 4643222C0A222E2420632023434345314642222C0A222E282063202343374446
- 4641222C0A222E2920632023424444414636222C0A222E5B2063202342424438
- 4636222C0A222E5D20632023454646344641222C0A222C2E2063202334363833
- 4336222C0A222C2C20632023343938384336222C0A222C2D2063202345444634
- 4639222C0A222C2A20632023443845384645222C0A222C612063202344374538
- 4645222C0A222C6220632023443645374645222C0A222C632063202344334535
- 4644222C0A222C6420632023433344444639222C0A222C652063202345444634
- 4641222C0A222C6620632023343538324336222C0A222C672063202334373834
- 4336222C0A222C6820632023454346334639222C0A222C692063202344364538
- 4645222C0A222C6A20632023434345334642222C0A222C6B2063202343364446
- 4641222C0A222C6C20632023454146324641222C0A222C6D2063202334323830
- 4336222C0A222C6E20632023343538324335222C0A222C6F2063202345424632
- 4638222C0A222C7020632023443545364644222C0A222C712063202343394131
- 3934222C0A222C7220632023433135453241222C0A222C732063202342433433
- 3035222C0A222C7420632023424635393146222C0A222C752063202337393632
- 3638222C0A222C7620632023343238304335222C0A222C772063202345384631
- 4638222C0A222C7820632023443545354645222C0A222C792063202344334535
- 4643222C0A222C7A20632023443137363344222C0A222C412063202346374235
- 3844222C0A222C4220632023464544364238222C0A222C432063202346354138
- 3732222C0A222C4420632023433936423246222C0A222C452063202334303743
- 4334222C0A222C4620632023453646304637222C0A222C472063202335354234
- 4638222C0A222C4820632023353642344637222C0A222C492063202335344235
- 4637222C0A222C4A20632023353342344638222C0A222C4B2063202335334232
- 4638222C0A222C4C20632023353242334637222C0A222C4D2063202341423533
- 3234222C0A222C4E20632023463642353844222C0A222C4F2063202346463932
- 3444222C0A222C5020632023464637373131222C0A222C512063202346463836
- 3231222C0A222C5220632023454238413430222C0A222C532063202342393434
- 3033222C0A222C5420632023334337384331222C0A222C552063202345334544
- 4637222C0A222C5620632023364543324644222C0A222C572063202341304438
- 4646222C0A222C5820632023394544374646222C0A222C592063202339424436
- 4646222C0A222C5A20632023393844374646222C0A222C302063202339364436
- 4646222C0A222C3120632023464543444145222C0A222C322063202346464646
- 4646222C0A222C3320632023454637463138222C0A222C342063202342433432
- 3034222C0A222C3520632023333837314246222C0A222C362063202344464542
- 4635222C0A222C3720632023363842464644222C0A222C382063202336374244
- 4643222C0A222C3920632023363542454642222C0A222C402063202336344245
- 4643222C0A222C2320632023363242444643222C0A222C3B2063202342303532
- 3145222C0A222C3A20632023463439443633222C0A222C3D2063202346463746
- 3138222C0A222C2B20632023463837363030222C0A222C252063202345453736
- 3030222C0A222C2420632023453136383033222C0A222C282063202342393435
- 3033222C0A222C2920632023333336394243222C0A222C5B2063202345414631
- 4638222C0A222C5D20632023444645434637222C0A222D2E2063202344454542
- 4636222C0A222D2C20632023444545414636222C0A222D2D2063202344434541
- 4636222C0A222D2A20632023454246334641222C0A222D612063202344374135
- 3841222C0A222D6220632023434136363238222C0A222D632063202345363737
- 3231222C0A222D6420632023454137393035222C0A222D652063202344443634
- 3031222C0A222D6620632023424234443036222C0A222D672063202333303635
- 4241222C0A222D6820632023333136364242222C0A222D692063202333303636
- 4241222C0A222D6A20632023324636354241222C0A222D6B2063202332453635
- 4239222C0A222D6C20632023373635453645222C0A222D6D2063202341383439
- 3139222C0A222D6E20632023424234323035222C0A222D6F2063202341443438
- 3133222C0A222D7020632023384634453339222C0A222E2E2E2E2E2C2E2D2E2D
- 2E2D2E2D2E2A2E612E622E632E642E2E2E2E2E2E2E2E222C0A222E2E2E652E66
- 2E672E682E692E692E692E6A2E662E6B2E6C2E6D2E2E2E2E2E2E222C0A222E2E
- 2E6E2E6F2E702E712E722E732E742E752E762E772E782E792E7A2E2E2E2E222C
- 0A222E2E2E412E422E432E442E452E462E472E482E492E4A2E4B2E4C2E4D2E4E
- 2E2E222C0A222E2E2E4F2E422E502E512E522E432E532E542E552E562E662E57
- 2E582E592E2E222C0A222E2E2E4F2E5A2E302E312E322E332E452E342E482E35
- 2E362E372E382E392E2E222C0A222E2E2E402E232E3B2E3A2E3D2E2B2E252E24
- 2E282E482E292E5B2E5D2C2E2E2E222C0A222E2E2C2C2C2D2C2A2C2A2C612C62
- 2C632E332E242E702C642E482C652C662E2E222C0A222E2E2C672C682C692C61
- 2E3A2E3A2E3D2C632E512C6A2E282C6B2C6C2C6D2E2E222C0A222E2E2C6E2C6F
- 2C622E3A2E3A2E3A2C702C632E332C712C722C732C742C752E2E222C0A222E2E
- 2C762C772C782C632C632C792C792E332C712C7A2C412C422C432C442E2E222C
- 0A222E2E2C452C462C472C482C492C4A2C4B2C4C2C4D2C4E2C4F2C502C512C52
- 2C53222C0A222E2E2C542C552C562C572C582C592C5A2C302C732C312C322C32
- 2C322C332C34222C0A222E2E2C352C362C372C382C392C402C402C232C3B2C3A
- 2C3D2C2B2C252C242C28222C0A222E2E2C292C5B2C5D2D2E2D2C2D2D2D2D2D2A
- 2D612D622D632D642D652D662E2E222C0A222E2E2E2E2D672D682D692D692D69
- 2D672D6A2D6B2D6C2D6D2D6E2D6F2D702E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000BA6530FFBB6631FFBA6630FFBA6630FFBA6630FFBA6530FFBA652FFFB965
+ 2EFF6E5E76FF1949A8FF0542BBFF1348ADFF394E8FFF0000000000000000BC69
+ 33FFF8F1EAFFF7ECDFFFF6EBDEFFF6EADEFFF6EADCFFF6EADCFFFAF3EBFF8AA5
+ D7FF2866CAFF2177E6FF0579EAFF0164DDFF064DBBFF0000000000000000BF71
+ 38FFF5EBDFFFFDBF68FFFCBD67FFFBBE65FFFCBE64FFFCBE64FFFCBD62FF1E52
+ B0FF639DF4FF187FFFFF0076F8FF0076EEFF0368E1FF0345B9FF00000000C178
+ 3CFFF7EDE3FFFDC26EFFFFD8A0FFFFD79EFFFFD69BFFFFD798FFFFD696FF0543
+ BCFFAECDFEFFFFFFFFFFFFFFFFFFFFFFFFFF187FEFFF0442BCFF00000000C47C
+ 40FFF7F0E6FFF8B455FFF7B456FFF7B554FFF8B453FFF8B253FFF7B352FF2453
+ ABFF8DB5F6FF4D92FFFF1177FFFF2186FFFF408AEBFF0344B9FF00000000C580
+ 42FFF8F1E8FFFEE5D5FFFDE5D3FFFDE5D3FFFCE5D3FFFCE5D3FFFCE4D1FF94A1
+ C9FF3D76D1FF8DB5F7FFB8D6FEFF72A8F5FF2F6BC9FF0000000000000000C582
+ 45FFF8F2EBFFFEE7D6FFFDE7D6FFFDE7D6FFFDE7D6FFFDE6D5FFFDE5D3FFFCE4
+ D1FF94A1C9FF2A5EC1FF0543BCFF1F59BFFF686279FF0000000000000000C684
+ 47FFF9F3ECFFFEE8D6FFFEE8D7FFFDE7D6FFFDE7D6FFFDE7D5FFFDE5D3FFFBE4
+ D0FFFBE3CCFFFADFC7FFFADFC6FFFAF2EAFFC68042FF0000000000000000C688
+ 49FFF9F4EDFFFEE8D8FFFEE8D8FFFEE8D7FFFEE7D6FFFDE5D3FFFCE4D1FFFBE1
+ CCFFFAE0C7FFF9DDC3FFF8DCC2FFFAF4EDFFC68245FF0000000000000000C688
+ 4AFFF9F4EFFFFEE7D7FFFDE7D6FFFDE7D5FFFDE6D4FFFCE6D2FFFBE1CCFFFADF
+ C7FFF8DCC2FFF6DABDFFF6D8BBFFFAF4EFFFC68346FF0000000000000000C689
+ 4BFFF9F4F0FFFCE6D3FFFCE6D4FFFDE7D3FFFCE4D1FFFBE3CDFFFAE0C8FFF8DC
+ C2FFF5D6BBFFF3D4B5FFF1D2B3FFF8F4F0FFC48246FF0000000000000000C689
+ 4BFFF9F5F1FFFCE3CFFFFBE4D0FFFCE4CFFFFCE3CDFFFAE1CAFFF9DDC4FFF6D9
+ BCFFF4E9DFFFF7F2ECFFFBF7F3FFF5EFE9FFC27E45FF0000000000000000C689
+ 4CFFF9F5F1FFFCE3CDFFFBE3CEFFFBE3CDFFFBE2CBFFF9E0C8FFF8DCC2FFF5D6
+ BAFFFDFBF8FFFCE6CDFFFAE5C9FFE2B684FFBF7942FF0000000000000000C588
+ 4BFFFAF6F2FFFAE0C7FFFBE1C9FFFBE2C9FFFBE0C8FFF9DFC5FFF8DBC1FFF4D6
+ B8FFFFFBF8FFF6D8B4FFE1B07DFFDB9264FF000000000000000000000000C485
+ 49FFF7F2ECFFF8F4EEFFF8F4EDFFF8F3EDFFF8F3EDFFF8F3EDFFF8F2ECFFF7F2
+ ECFFF2E6D7FFE2B27DFFDB9465FF000000000000000000000000000000000000
+ 0000C88B4DFFC88C4FFFC88C4FFFC88C4FFFC88C4FFFC88D4FFFC98C4FFFC78B
+ 4FFFC5894BFFC4763BFF00000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnRandomPresetDeleteClick
@@ -890,78 +604,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- F10800002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203130342032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023464630303030222C0A222E2D2063202346443030
- 3030222C0A222E2A20632023464632423236222C0A222E612063202346463639
- 3543222C0A222E6220632023464636383542222C0A222E632063202346453637
- 3541222C0A222E6420632023464536353538222C0A222E652063202346453633
- 3536222C0A222E6620632023464536313534222C0A222E672063202346433237
- 3232222C0A222E6820632023464230303030222C0A222E692063202346463641
- 3544222C0A222E6A20632023464634373433222C0A222E6B2063202346453334
- 3334222C0A222E6C20632023464533323332222C0A222E6D2063202346443330
- 3330222C0A222E6E20632023464432443244222C0A222E6F2063202346433343
- 3338222C0A222E7020632023464335443446222C0A222E712063202346413235
- 3146222C0A222E7220632023463730303030222C0A222E732063202346463542
- 3538222C0A222E7420632023464643464346222C0A222E752063202346453532
- 3532222C0A222E7620632023464432463246222C0A222E772063202346443243
- 3243222C0A222E7820632023464334423442222C0A222E792063202346454343
- 4343222C0A222E7A20632023464234433438222C0A222E412063202346423537
- 3439222C0A222E4220632023463932333144222C0A222E432063202346353030
- 3030222C0A222E4420632023464534373433222C0A222E452063202346464633
- 4633222C0A222E4620632023464645444544222C0A222E472063202346433443
- 3443222C0A222E4820632023464334413441222C0A222E492063202346464543
- 4543222C0A222E4A20632023464646324632222C0A222E4B2063202346454341
- 4341222C0A222E4C20632023464132463241222C0A222E4D2063202346413531
- 3432222C0A222E4E20632023463330303030222C0A222E4F2063202346453333
- 3333222C0A222E5020632023464435303530222C0A222E512063202346454543
- 4543222C0A222E5220632023464133453345222C0A222E532063202346383137
- 3137222C0A222E5420632023463934453346222C0A222E552063202346313030
- 3030222C0A222E5620632023464536343537222C0A222E572063202346393344
- 3344222C0A222E5820632023463831363136222C0A222E592063202346373133
- 3133222C0A222E5A20632023463834423343222C0A222E302063202346453632
- 3535222C0A222E3120632023464332393239222C0A222E322063202346433438
- 3438222C0A222E3320632023463933413341222C0A222E342063202346373132
- 3132222C0A222E3520632023463630463046222C0A222E362063202346383438
- 3338222C0A222E3720632023464435463532222C0A222E382063202346433238
- 3238222C0A222E3920632023464334373437222C0A222E402063202346464631
- 4631222C0A222E2320632023464545414541222C0A222E3B2063202346373334
- 3334222C0A222E3A20632023463530423042222C0A222E3D2063202346383435
- 3335222C0A222E2B20632023454630303030222C0A222E252063202346443544
- 3446222C0A222E2420632023464233373332222C0A222E282063202346454342
- 4342222C0A222E2920632023464545424542222C0A222E5B2063202346393342
- 3342222C0A222E5D20632023463833393339222C0A222C2E2063202346454631
- 4631222C0A222C2C20632023464443354335222C0A222C2D2063202346363144
- 3138222C0A222C2A20632023463734333333222C0A222C612063202346393030
- 3030222C0A222C6220632023464235383441222C0A222C632063202346423437
- 3432222C0A222C6420632023464443394339222C0A222C652063202346363130
- 3130222C0A222C6620632023463733333333222C0A222C672063202346373335
- 3330222C0A222C6820632023463734343334222C0A222C692063202346323142
- 3134222C0A222C6A20632023454430303030222C0A222C6B2063202346413533
- 3434222C0A222C6C20632023463932393234222C0A222C6D2063202346353043
- 3043222C0A222C6E20632023463530393039222C0A222C6F2063202346353142
- 3136222C0A222C7020632023463131423134222C0A222C712063202346353230
- 3141222C0A222C7220632023463934433343222C0A222C732063202346383439
- 3341222C0A222C7420632023463834373338222C0A222C752063202346373433
- 3334222C0A222C7620632023463734323332222C0A222E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2E2C2E2C2E2C2E2C2E2D2E2D2E2D2E2D2E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2C2E2A2E612E622E632E642E652E662E672E682E2E2E2E2E2E222C
- 0A222E2E2E2E2E2C2E2A2E692E6A2E6B2E6C2E6D2E6E2E6F2E702E712E722E2E
- 2E2E222C0A222E2E2E2C2E2A2E692E732E742E752E762E772E782E792E7A2E41
- 2E422E432E2E222C0A222E2E2E2C2E622E442E742E452E462E472E482E492E4A
- 2E4B2E4C2E4D2E4E2E2E222C0A222E2E2E2C2E632E4F2E502E462E452E462E46
- 2E4A2E512E522E532E542E552E2E222C0A222E2E2E2D2E562E6D2E6E2E782E46
- 2E4A2E4A2E492E572E582E592E5A2E552E2E222C0A222E2E2E2D2E302E772E31
- 2E322E462E4A2E4A2E512E332E342E352E362E552E2E222C0A222E2E2E2D2E37
- 2E382E392E492E4A2E492E512E402E232E3B2E3A2E3D2E2B2E2E222C0A222E2E
- 2E682E252E242E282E4A2E292E5B2E5D2E232C2E2C2C2C2D2C2A2E2B2E2E222C
- 0A222E2E2C612E712C622C632C642E5B2E592C652C662C2C2C672C682C692C6A
- 2E2E222C0A222E2E2E2E2E722E422C6B2C6C2E342E352C6D2C6E2C6F2C2A2C70
- 2C6A2E2E2E2E222C0A222E2E2E2E2E2E2E432C712C722C732C742E3D2C752C76
- 2C702C6A2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E552E552E552E552E2B
- 2E2B2C6A2C6A2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000F1FF0000F1FF0000F1FF0000F1FF0000EFFF0000
+ EFFF0000EDFF0000EDFF00000000000000000000000000000000000000000000
+ 0000000000000000F5FF1A20F5FF3C4CF9FF3A49F8FF3847F8FF3545F8FF3443
+ F7FF3242F7FF141BF1FF0000EDFF000000000000000000000000000000000000
+ 00000000F7FF1D23F9FF4453FAFF2429F9FF1212F7FF0F0FF6FF0C0CF5FF0909
+ F5FF161BF5FF3343F7FF141BF1FF0000EDFF0000000000000000000000000000
+ F9FF1F25FAFF4A58FBFF4247FBFFC9C9FDFF3B3BF9FF1313F7FF1010F6FF3333
+ F7FFC5C5FDFF3035F7FF3444F7FF141BF2FF0000EDFF00000000000000000000
+ FBFF4F5DFDFF3237FBFFCBCBFEFFF2F2FFFFEBEBFEFF3B3BF9FF3939F8FFEAEA
+ FEFFF1F1FEFFC5C5FDFF181DF6FF3343F7FF0000EFFF00000000000000000000
+ FDFF525FFDFF2828FCFF4747FCFFECECFFFFF2F2FFFFECECFFFFECECFEFFF1F1
+ FFFFEAEAFEFF3434F7FF0B0BF5FF3545F8FF0000EFFF00000000000000000000
+ FDFF5562FEFF2C2CFDFF2929FCFF4848FCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC
+ FEFF3A3AF9FF1212F7FF0F0FF6FF3848F8FF0000F1FF00000000000000000000
+ FDFF5764FEFF3030FDFF2D2DFDFF4B4BFCFFEDEDFFFFF2F2FFFFF2F2FFFFECEC
+ FFFF3D3DF9FF1616F8FF1313F7FF3C4BF8FF0000F1FF00000000000000000000
+ FFFF5A67FEFF3333FEFF5050FDFFEDEDFFFFF3F3FFFFEDEDFFFFEDEDFFFFF2F2
+ FFFFECECFEFF3E3EFAFF1717F8FF3F4EF9FF0000F1FF00000000000000000000
+ FFFF5B68FFFF4347FEFFCFCFFFFFF3F3FFFFEDEDFFFF4C4CFCFF4A4AFCFFECEC
+ FFFFF2F2FFFFCACAFEFF2A2FFAFF4251FAFF0000F3FF00000000000000000000
+ FFFF262BFFFF5D6AFFFF585BFFFFCFCFFFFF5252FEFF2F2FFDFF2C2CFDFF4B4B
+ FCFFCCCCFEFF484CFBFF4957FBFF1D23F9FF0000F5FF00000000000000000000
+ 00000000FFFF262BFFFF5D6AFFFF4347FFFF3434FEFF3232FEFF3030FDFF2D2D
+ FDFF383CFCFF4F5DFCFF1F25FAFF0000F7FF0000000000000000000000000000
+ 0000000000000000FFFF262BFFFF5C69FFFF5B68FFFF5A67FEFF5865FEFF5663
+ FEFF5461FEFF2227FCFF0000FBFF000000000000000000000000000000000000
+ 000000000000000000000000FFFF0000FFFF0000FFFF0000FFFF0000FDFF0000
+ FDFF0000FDFF0000FDFF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnClearLocationsClick
@@ -975,83 +651,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- 810900002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203131332032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023444436413638222C0A222E2D2063202344433634
- 3633222C0A222E2A20632023444136343631222C0A222E612063202344393633
- 3544222C0A222E6220632023444636413641222C0A222E632063202345443933
- 3845222C0A222E6420632023463843334245222C0A222E652063202346394433
- 4343222C0A222E6620632023463943424334222C0A222E672063202346344234
- 4141222C0A222E6820632023453237303636222C0A222E692063202344313545
- 3533222C0A222E6A20632023453036393641222C0A222E6B2063202346324144
- 4141222C0A222E6C20632023464444434438222C0A222E6D2063202346414241
- 4145222C0A222E6E20632023464141333931222C0A222E6F2063202346413944
- 3842222C0A222E7020632023464241393943222C0A222E712063202346434337
- 4241222C0A222E7220632023453937423730222C0A222E732063202343433542
- 3443222C0A222E7420632023463341374133222C0A222E752063202346444442
- 4434222C0A222E7620632023464139413837222C0A222E772063202346303931
- 3746222C0A222E7820632023463138453741222C0A222E792063202346383934
- 3746222C0A222E7A20632023463939323745222C0A222E412063202346383843
- 3736222C0A222E4220632023463842364138222C0A222E432063202345333645
- 3633222C0A222E4420632023433735373435222C0A222E452063202345413833
- 3744222C0A222E4620632023464344344344222C0A222E472063202346373933
- 3745222C0A222E4820632023454538413735222C0A222E492063202346363834
- 3643222C0A222E4A20632023463337393633222C0A222E4B2063202346384146
- 4134222C0A222E4C20632023443034463345222C0A222E4D2063202344453641
- 3637222C0A222E4E20632023463541464135222C0A222E4F2063202346414142
- 3944222C0A222E5020632023463038433737222C0A222E512063202345433546
- 3534222C0A222E5220632023463237373633222C0A222E532063202346343845
- 3831222C0A222E5420632023453937463738222C0A222E552063202343303533
- 3341222C0A222E5620632023444236393634222C0A222E572063202346394239
- 4146222C0A222E5820632023464139333746222C0A222E592063202346303835
- 3730222C0A222E5A20632023464646464646222C0A222E302063202345393539
- 3444222C0A222E3120632023454536413545222C0A222E322063202346313944
- 3936222C0A222E3320632023424534463336222C0A222E342063202344413633
- 3546222C0A222E3520632023463741424131222C0A222E362063202346383836
- 3730222C0A222E3720632023463638323638222C0A222E382063202345413636
- 3543222C0A222E3920632023463139433936222C0A222E402063202342433530
- 3332222C0A222E2320632023443736323543222C0A222E3B2063202345453843
- 3831222C0A222E3A20632023463739313745222C0A222E3D2063202346333733
- 3544222C0A222E2B20632023453935423446222C0A222E252063202346303833
- 3742222C0A222E2420632023453237423735222C0A222E282063202342413442
- 3245222C0A222E2920632023444235363442222C0A222E5B2063202346364142
- 4132222C0A222E5D20632023463036343536222C0A222C2E2063202345453636
- 3532222C0A222C2C20632023453635383443222C0A222C2D2063202345363541
- 3532222C0A222C2A20632023463541333946222C0A222C612063202343343530
- 3334222C0A222C6220632023434636313533222C0A222C632063202345333642
- 3631222C0A222C6420632023463541434131222C0A222C652063202345413543
- 3530222C0A222C6620632023453635393445222C0A222C672063202345363536
- 3443222C0A222C6820632023453635363530222C0A222C692063202346344132
- 3945222C0A222C6A20632023443636303534222C0A222C6B2063202342383441
- 3241222C0A222C6C20632023434235393439222C0A222C6D2063202345303635
- 3543222C0A222C6E20632023463541364131222C0A222C6F2063202345463836
- 3745222C0A222C7020632023453936333542222C0A222C712063202345373544
- 3539222C0A222C7220632023454538343744222C0A222C732063202346344130
- 3945222C0A222C7420632023443735443531222C0A222C752063202342373441
- 3242222C0A222C7620632023433635353432222C0A222C772063202343433532
- 3343222C0A222C7820632023453837413735222C0A222C792063202345453932
- 3846222C0A222C7A20632023453437383731222C0A222C412063202343313444
- 3333222C0A222C4220632023424535333338222C0A222C432063202342443531
- 3335222C0A222C4420632023424334423330222C0A222C452063202342383445
- 3245222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2C2E2D2E2A2E612E2E
- 2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E622E632E642E652E66
- 2E672E682E692E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E6A2E6B2E6C2E6D
- 2E6E2E6F2E702E712E722E732E2E2E2E2E2E222C0A222E2E2E2E2E6A2E742E75
- 2E762E772E782E792E7A2E412E422E432E442E2E2E2E222C0A222E2E2E2E2E45
- 2E462E6F2E472E482E492E492E492E492E4A2E4B2E4C2E2E2E2E222C0A222E2E
- 2E4D2E4E2E4F2E502E512E512E512E512E512E512E522E532E542E552E2E222C
- 0A222E2E2E562E572E582E592E5A2E5A2E5A2E5A2E5A2E5A2E302E312E322E33
- 2E2E222C0A222E2E2E342E352E362E372E5A2E5A2E5A2E5A2E5A2E5A2E302E38
- 2E392E402E2E222C0A222E2E2E232E3B2E3A2E3D2E302E302E302E302E302E30
- 2E2B2E252E242E282E2E222C0A222E2E2E2E2E292E5B2E5D2C2E2E302E302E30
- 2E302C2C2C2D2C2A2C612E2E2E2E222C0A222E2E2E2E2C622C632C642E512C65
- 2E302C662C672C682C692C6A2C6B2E2E2E2E222C0A222E2E2E2E2E2E2C6C2C6D
- 2C6E2C6F2C702C712C722C732C742C752E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2C762C772C782C792C792C7A2C412C752E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2E2E2E2E2E2C422C432C442C452E2E2E2E2E2E2E2E2E2E2E2E222C
- 0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003853BEFF3551BDFF304BBCFF2E4E
+ B8FF000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000004255C6FF3C52CCFF757AE8FF8F92EEFF8F92EEFF7178
+ E4FF334DC1FF2B4AB7FF00000000000000000000000000000000000000000000
+ 0000000000004959CBFF5C65E0FFA1A6F5FF7E86EFFF5B63E9FF595DE7FF7D84
+ EEFF9EA0F4FF515DD7FF2B4AB7FF000000000000000000000000000000000000
+ 00005361CFFF616BE3FFA1ACF5FF545FECFF505CEAFF4D59E9FF4E59E6FF4C56
+ E6FF5056E6FF9EA2F4FF5460D6FF2A4AB8FF0000000000000000000000000000
+ 00004B56DBFFA2ABF6FF5664F0FF5266EEFF4D59E9FF4D59E9FF4D59E9FF4D59
+ E9FF4C58E6FF525AE6FF9FA3F5FF3450C4FF0000000000000000000000005C62
+ D7FF818CEEFF7E91F7FF5D73F3FF4D59E9FF4D59E9FF4D59E9FF4D59E9FF4D59
+ E9FF4D59E9FF4F5BE9FF7B83F0FF757BE2FF2E4BBAFF00000000000000005F63
+ DAFFA1ABF7FF7086F8FF6882F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF4D59E9FF5C66EAFF969CF1FF3250BCFF00000000000000006469
+ DBFFAFB9F9FF7F93FAFF7085F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF4D59E9FF5E6AEEFF969DF1FF364FBEFF0000000000000000676A
+ DEFFA5AFF5FF9DABFAFF778CF0FF545FECFF545FECFF545FECFF545FECFF545F
+ ECFF545FECFF6377F2FF818EF4FF787FE9FF3A53C0FF00000000000000000000
+ 00007D83EAFFCDD4FCFF8B9DFAFF7E93F7FF758AEEFF6C84F6FF6C84F6FF6C84
+ F6FF6C84F6FF6379F3FFA4AFF8FF3E4FD0FF0000000000000000000000000000
+ 00006A69E0FFA3A7F3FFD4DBFDFF879AFAFF7F91F0FF7A8EF1FF7F94F8FF7E92
+ F9FF768CF8FFA8B6F8FF636EE3FF4557C7FF0000000000000000000000000000
+ 0000000000006A69E0FFAAADF2FFD8DCFDFFAEBAFAFF91A3FAFF8B9DFAFF9CA9
+ FBFFBAC7FCFF707BE9FF4C5BCCFF000000000000000000000000000000000000
+ 000000000000000000006A6ADFFF8E93EDFFBEC3F8FFCCD3F9FFC4CBF9FFAAB4
+ F4FF6670E2FF535ED1FF00000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000686ADDFF6364DCFF6164DAFF5D63
+ D9FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnDeleteLocationClick
@@ -1065,86 +698,40 @@ object frmMain: TfrmMain
Width = 23
Color = clBtnFace
Glyph.Data = {
- F10900002F2A2058504D202A2F0A7374617469632063686172202A6772617068
- 69635B5D203D207B0A223136203136203132302032222C0A222E2E2063204E6F
- 6E65222C0A222E2C20632023383442363645222C0A222E2D2063202338304233
- 3641222C0A222E2A20632023374342313637222C0A222E612063202337374145
- 3633222C0A222E6220632023383742383731222C0A222E632063202341344345
- 3934222C0A222E6420632023434245364333222C0A222E652063202344344542
- 4346222C0A222E6620632023434545394339222C0A222E672063202342384444
- 4146222C0A222E6820632023374642393644222C0A222E692063202336394135
- 3538222C0A222E6A20632023383742383730222C0A222E6B2063202342424443
- 4146222C0A222E6C20632023453046324443222C0A222E6D2063202342444534
- 4236222C0A222E6E20632023413544423942222C0A222E6F2063202341304439
- 3936222C0A222E7020632023414644464135222C0A222E712063202343354538
- 4330222C0A222E7220632023384143323739222C0A222E732063202335463945
- 3530222C0A222E7420632023423744414141222C0A222E752063202344434631
- 4438222C0A222E7620632023394444383932222C0A222E772063202339334344
- 3838222C0A222E7820632023384543433834222C0A222E792063202339364434
- 3842222C0A222E7A20632023393544343841222C0A222E412063202338454432
- 3833222C0A222E4220632023423745304146222C0A222E432063202337444239
- 3642222C0A222E4420632023353639383438222C0A222E452063202339374337
- 3835222C0A222E4620632023443745454432222C0A222E472063202341304439
- 3935222C0A222E4820632023393444333841222C0A222E492063202338394338
- 3746222C0A222E4A20632023464646464646222C0A222E4B2063202338354344
- 3739222C0A222E4C20632023374343333642222C0A222E4D2063202337454337
- 3646222C0A222E4E20632023423544464143222C0A222E4F2063202335373945
- 3435222C0A222E5020632023383342353644222C0A222E512063202342364444
- 4143222C0A222E5220632023414644464136222C0A222E532063202338434342
- 3831222C0A222E5420632023383643393743222C0A222E552063202337394244
- 3645222C0A222E5620632023364141433542222C0A222E572063202337374243
- 3630222C0A222E5820632023373342413543222C0A222E592063202339394431
- 3842222C0A222E5A20632023393243353830222C0A222E302063202334373845
- 3343222C0A222E3120632023374542323639222C0A222E322063202342454532
- 4236222C0A222E3320632023393744353842222C0A222E342063202338364339
- 3741222C0A222E3520632023373042383539222C0A222E362063202337454331
- 3639222C0A222E3720632023414144343944222C0A222E382063202334323842
- 3338222C0A222E3920632023374141463635222C0A222E402063202342334444
- 4139222C0A222E2320632023384143463744222C0A222E3B2063202338314343
- 3735222C0A222E3A20632023374442453637222C0A222E3D2063202341424434
- 3943222C0A222E2B20632023334438383334222C0A222E252063202337354143
- 3631222C0A222E2420632023393843433841222C0A222E282063202339364433
- 3839222C0A222E2920632023374143363642222C0A222E5B2063202337304331
- 3633222C0A222E5D20632023363541423535222C0A222C2E2063202337324239
- 3542222C0A222C2C20632023393743433835222C0A222C2D2063202338444245
- 3742222C0A222C2A20632023333938353330222C0A222C612063202336384142
- 3533222C0A222C6220632023423444444141222C0A222C632063202337394331
- 3634222C0A222C6420632023373142453546222C0A222C652063202336454235
- 3538222C0A222C6620632023373442373543222C0A222C672063202342344441
- 4136222C0A222C6820632023343338463338222C0A222C692063202336364133
- 3536222C0A222C6A20632023374442393641222C0A222C6B2063202342324442
- 4138222C0A222C6C20632023364642353539222C0A222C6D2063202336464235
- 3538222C0A222C6E20632023373442373542222C0A222C6F2063202342334439
- 4135222C0A222C7020632023364341413541222C0A222C712063202333343832
- 3243222C0A222C7220632023354439433444222C0A222C732063202337384234
- 3634222C0A222C7420632023423544424138222C0A222C752063202339384343
- 3837222C0A222C7620632023374442433636222C0A222C772063202337434241
- 3634222C0A222C7820632023393843423836222C0A222C792063202342344439
- 4135222C0A222C7A20632023364241413538222C0A222C412063202333343831
- 3243222C0A222C4220632023353339363435222C0A222C432063202335303939
- 3431222C0A222C4420632023384643323744222C0A222C452063202341364430
- 3936222C0A222C4620632023413643463936222C0A222C472063202338394245
- 3738222C0A222C4820632023343238443336222C0A222C492063202334343843
- 3341222C0A222C4A20632023343038393336222C0A222C4B2063202333433837
- 3332222C0A222C4C20632023333738343246222C0A222E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E
- 2E2E2E2E2E2E2E2C2E2D2E2A2E612E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E
- 2E2E2E2E2E2E2E622E632E642E652E662E672E682E692E2E2E2E2E2E2E2E222C
- 0A222E2E2E2E2E2E2E6A2E6B2E6C2E6D2E6E2E6F2E702E712E722E732E2E2E2E
- 2E2E222C0A222E2E2E2E2E6A2E742E752E762E772E782E792E7A2E412E422E43
- 2E442E2E2E2E222C0A222E2E2E2E2E452E462E472E482E492E4A2E4A2E4B2E4C
- 2E4D2E4E2E4F2E2E2E2E222C0A222E2E2E502E512E522E532E542E552E4A2E4A
- 2E562E572E582E592E5A2E302E2E222C0A222E2E2E312E322E332E342E4A2E4A
- 2E4A2E4A2E4A2E4A2E352E362E372E382E2E222C0A222E2E2E392E402E232E3B
- 2E4A2E4A2E4A2E4A2E4A2E4A2E352E3A2E3D2E2B2E2E222C0A222E2E2E252E24
- 2E282E292E5B2E5D2E4A2E4A2E352E352C2E2C2C2C2D2C2A2E2E222C0A222E2E
- 2E2E2C612C622C632C642E572E4A2E4A2E352C652C662C672C682E2E2E2E222C
- 0A222E2E2E2E2C692C6A2C6B2E572E582E352C6C2C6D2C6E2C6F2C702C712E2E
- 2E2E222C0A222E2E2E2E2E2E2C722C732C742C752C762C772C782C792C7A2C41
- 2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2C422C432C442C452C462C472C48
- 2C412E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2C492C4A2C4B
- 2C4C2E2E2E2E2E2E2E2E2E2E2E2E222C0A222E2E2E2E2E2E2E2E2E2E2E2E2E2E
- 2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E227D0A
+ 36040000424D3604000000000000360000002800000010000000100000000100
+ 2000000000000004000064000000640000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003A8C44FF368940FF32873CFF2F84
+ 37FF000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000459653FF419950FF7DC28FFF96D0A6FF96CFA6FF78BE
+ 89FF368D42FF2C8134FF00000000000000000000000000000000000000000000
+ 0000000000004D9C5DFF64B478FFA8DBB5FF87CC98FF66BC7DFF64BA7CFF86CB
+ 98FFA5D9B4FF58AA6BFF2C8134FF000000000000000000000000000000000000
+ 000056A366FF6AB97DFFA8DBB2FF60BC77FF5CBA73FF59B870FF59B56FFF58B5
+ 6FFF5BB774FFA5D9B3FF5AAA6CFF2C8234FF0000000000000000000000000000
+ 000053AB68FFAADDB4FF64C179FF5FBE71FF60BC77FFFFFFFFFFFFFFFFFF59B8
+ 70FF58B56EFF5CB774FFA6DAB4FF388F43FF00000000000000000000000061AC
+ 75FF8ACC98FF89D396FF6BC67AFF63C170FF55AB65FFFFFFFFFFFFFFFFFF59B8
+ 70FF59B870FF5BB972FF85CC97FF7BBE8DFF308539FF000000000000000065AF
+ 7AFFA9DDB3FF7DCF8AFF75CC81FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF59B870FF67BE7DFF9CD4ABFF34883DFF000000000000000069B2
+ 7EFFB6E2BEFF8BD597FF7AC986FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFF59B870FF69C17EFF9DD4AAFF388B42FF00000000000000006DB5
+ 83FFACDDB6FFA6DFAFFF81CB8CFF7CC986FF6EBD79FFFFFFFFFFFFFFFFFF5BAC
+ 6AFF60BC77FF5CBA73FF8BD199FF80C592FF3C8E47FF00000000000000000000
+ 000085C797FFD2EED7FF95D9A0FF8AD394FF7FC889FFFFFFFFFFFFFFFFFF79CD
+ 85FF6BC37CFF6FC77EFFACDFB5FF459E57FF0000000000000000000000000000
+ 000070B887FFAADAB7FFD8F1DCFF92D89DFF88CD93FF84CC8EFF8BD496FF8AD4
+ 95FF83D28EFFAFE0B7FF6BB97DFF489856FF0000000000000000000000000000
+ 00000000000070B887FFAFDCBBFFDCF2E0FFB6E4BDFF9BDBA5FF96D9A0FFA5DF
+ AFFFC0E8C5FF79C28AFF509E5FFF000000000000000000000000000000000000
+ 0000000000000000000071B887FF94CEA4FFC3E6CBFFCFEBD4FFC9E9CEFFAFDD
+ B8FF6DB97FFF58A569FF00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000006EB684FF6AB380FF67B17CFF63AE
+ 77FF000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000
}
NumGlyphs = 0
OnClick = btnAddLocationClick
diff --git a/Server/UAccount.pas b/Server/UAccount.pas
index cf102fc..b277cae 100644
--- a/Server/UAccount.pas
+++ b/Server/UAccount.pas
@@ -1,181 +1,213 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UAccount;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, md5, contnrs, math, UEnums;
-
-type
-
- { TAccount }
-
- TAccount = class(TObject)
- constructor Create(AAccountString: string);
- constructor Create(AName, APasswordHash: string; AAccessLevel: TAccessLevel);
- protected
- FName: string;
- FAccessLevel: TAccessLevel;
- FPasswordHash: string;
- FLastPos: TPoint;
- procedure SetAccessLevel(const AValue: TAccessLevel);
- procedure SetPasswordHash(const AValue: string);
- procedure SetLastPos(const AValue: TPoint);
- public
- property Name: string read FName;
- property AccessLevel: TAccessLevel read FAccessLevel write SetAccessLevel;
- property PasswordHash: string read FPasswordHash write SetPasswordHash;
- property LastPos: TPoint read FLastPos write SetLastPos;
- procedure Flush;
- end;
-
- { TAccountList }
-
- TAccountList = class(TObjectList)
- constructor Create; reintroduce;
- public
- function IndexOf(AName: string): Integer;
- function Find(AName: string): TAccount;
- procedure Delete(AName: string);
- end;
-
-implementation
-
-uses
- UCEDServer, UConfig;
-
-{ TAccount }
-
-constructor TAccount.Create(AAccountString: string);
-var
- i: Integer;
- attribs: TStringList;
-begin
- inherited Create;
- i := Pos('=', AAccountString);
- if i > 0 then
- FName := Trim(Copy(AAccountString, 1, i-1));
- AAccountString := Copy(AAccountString, i+1, Length(AAccountString));
-
- attribs := TStringList.Create;
- if ExtractStrings([':'], [' '], PChar(AAccountString), attribs) >= 2 then
- begin
- FAccessLevel := TAccessLevel(StrToInt(attribs.Strings[0]));
- FPasswordHash := attribs.Strings[1];
- end;
- if attribs.Count >= 4 then
- begin
- FLastPos.x := EnsureRange(StrToInt(attribs.Strings[2]), 0, Config.ReadInteger('Parameters', 'Width', 0) * 8 - 1);
- FLastPos.y := EnsureRange(StrToInt(attribs.Strings[3]), 0, Config.ReadInteger('Parameters', 'Height', 0) * 8 - 1);
- end else
- begin
- FLastPos.x := 0;
- FLastPos.y := 0;
- end;
- attribs.Free;
-end;
-
-constructor TAccount.Create(AName, APasswordHash: string;
- AAccessLevel: TAccessLevel);
-begin
- inherited Create;
- FName := AName;
- FPasswordHash := APasswordHash;
- FAccessLevel := AAccessLevel;
- Flush;
-end;
-
-procedure TAccount.SetAccessLevel(const AValue: TAccessLevel);
-begin
- FAccessLevel := AValue;
- Flush;
-end;
-
-procedure TAccount.SetPasswordHash(const AValue: string);
-begin
- FPasswordHash := AValue;
- Flush;
-end;
-
-procedure TAccount.SetLastPos(const AValue: TPoint);
-begin
- FLastPos.x := EnsureRange(AValue.x, 0, CEDServerInstance.Landscape.CellWidth - 1);
- FLastPos.y := EnsureRange(AValue.y, 0, CEDServerInstance.Landscape.CellHeight - 1);
- Flush;
-end;
-
-procedure TAccount.Flush;
-begin
- Config.WriteString('Accounts', FName, IntToStr(Byte(FAccessLevel)) + ':' +
- FPasswordHash + ':' + IntToStr(FLastPos.x) + ':' + IntToStr(FLastPos.y));
-end;
-
-{ TAccountList }
-
-constructor TAccountList.Create;
-begin
- inherited Create(True);
-end;
-
-function TAccountList.IndexOf(AName: string): Integer;
-var
- i: Integer;
-begin
- Result := -1;
- i := 0;
- while (i < Count) and (Result = -1) do
- begin
- if TAccount(Items[i]).Name = AName then
- Result := i;
- Inc(i);
- end;
-end;
-
-function TAccountList.Find(AName: string): TAccount;
-var
- i: Integer;
-begin
- i := IndexOf(AName);
- if i > -1 then
- Result := TAccount(Items[i])
- else
- Result := nil;
-end;
-
-procedure TAccountList.Delete(AName: string);
-var
- i: Integer;
-begin
- i := IndexOf(AName);
- if i > -1 then
- inherited Delete(i);
-end;
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2008 Andreas Schneider
+ *)
+unit UAccount;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, md5, contnrs, math, DOM, UXmlHelper, UInterfaces,
+ UEnums;
+
+type
+
+ { TAccount }
+
+ TAccount = class(TObject, ISerializable, IInvalidate)
+ constructor Create(AOwner: IInvalidate; AName, APasswordHash: string;
+ AAccessLevel: TAccessLevel);
+ constructor Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+ procedure Serialize(AElement: TDOMElement);
+ protected
+ FOwner: IInvalidate;
+ FName: string;
+ FAccessLevel: TAccessLevel;
+ FPasswordHash: string;
+ FLastPos: TPoint;
+ procedure SetAccessLevel(const AValue: TAccessLevel);
+ procedure SetPasswordHash(const AValue: string);
+ procedure SetLastPos(const AValue: TPoint);
+ public
+ property Name: string read FName;
+ property AccessLevel: TAccessLevel read FAccessLevel write SetAccessLevel;
+ property PasswordHash: string read FPasswordHash write SetPasswordHash;
+ property LastPos: TPoint read FLastPos write SetLastPos;
+ procedure Invalidate;
+ end;
+
+ { TAccountList }
+
+ TAccountList = class(TObjectList, ISerializable, IInvalidate)
+ constructor Create(AOwner: IInvalidate); reintroduce;
+ constructor Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+ procedure Serialize(AElement: TDOMElement);
+ protected
+ FOwner: IInvalidate;
+ public
+ function IndexOf(AName: string): Integer;
+ function Find(AName: string): TAccount;
+ procedure Delete(AName: string);
+ procedure Invalidate;
+ end;
+
+implementation
+
+uses
+ UCEDServer, UConfig;
+
+{ TAccount }
+
+constructor TAccount.Create(AOwner: IInvalidate; AName, APasswordHash: string;
+ AAccessLevel: TAccessLevel);
+begin
+ inherited Create;
+ FOwner := AOwner;
+ FName := AName;
+ FPasswordHash := APasswordHash;
+ FAccessLevel := AAccessLevel;
+end;
+
+constructor TAccount.Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+begin
+ inherited Create;
+ FOwner := AOwner;
+ FName := TXmlHelper.ReadString(AElement, 'Name', '');
+ FAccessLevel := TAccessLevel(TXmlHelper.ReadInteger(AElement, 'AccessLevel', 0));
+ FPasswordHash := TXmlHelper.ReadString(AElement, 'PasswordHash', '');
+ FLastPos := Point(0, 0);
+ TXmlHelper.ReadCoords(AElement, 'LastPos', FLastPos.X, FLastPos.Y);
+end;
+
+procedure TAccount.SetAccessLevel(const AValue: TAccessLevel);
+begin
+ FAccessLevel := AValue;
+ Invalidate;
+end;
+
+procedure TAccount.SetPasswordHash(const AValue: string);
+begin
+ FPasswordHash := AValue;
+ Invalidate;
+end;
+
+procedure TAccount.SetLastPos(const AValue: TPoint);
+begin
+ FLastPos.x := EnsureRange(AValue.x, 0, CEDServerInstance.Landscape.CellWidth - 1);
+ FLastPos.y := EnsureRange(AValue.y, 0, CEDServerInstance.Landscape.CellHeight - 1);
+ Invalidate;
+end;
+
+procedure TAccount.Invalidate;
+begin
+ FOwner.Invalidate;
+end;
+
+procedure TAccount.Serialize(AElement: TDOMElement);
+begin
+ TXmlHelper.WriteString(AElement, 'Name', FName);
+ TXmlHelper.WriteString(AElement, 'PasswordHash', FPasswordHash);
+ TXmlHelper.WriteInteger(AElement, 'AccessLevel', Integer(FAccessLevel));
+ TXmlHelper.WriteCoords(AElement, 'LastPos', FLastPos.X, FLastPos.Y);
+end;
+
+{ TAccountList }
+
+constructor TAccountList.Create(AOwner: IInvalidate);
+begin
+ inherited Create(True);
+ FOwner := AOwner;
+end;
+
+constructor TAccountList.Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+var
+ nodelist: TDOMNodeList;
+ i: Integer;
+begin
+ Create(AOwner);
+ nodeList := AElement.GetChildNodes;
+ for i := 0 to nodeList.Count - 1 do
+ begin
+ if nodeList.Item[i].NodeName = 'Account' then
+ Add(TAccount.Deserialize(Self, TDOMElement(nodeList.Item[i])));
+ end;
+ nodeList.Free;
+end;
+
+function TAccountList.IndexOf(AName: string): Integer;
+var
+ i: Integer;
+begin
+ Result := -1;
+ i := 0;
+ while (i < Count) and (Result = -1) do
+ begin
+ if TAccount(Items[i]).Name = AName then
+ Result := i;
+ Inc(i);
+ end;
+end;
+
+function TAccountList.Find(AName: string): TAccount;
+var
+ i: Integer;
+begin
+ i := IndexOf(AName);
+ if i > -1 then
+ Result := TAccount(Items[i])
+ else
+ Result := nil;
+end;
+
+procedure TAccountList.Delete(AName: string);
+var
+ i: Integer;
+begin
+ i := IndexOf(AName);
+ if i > -1 then
+ inherited Delete(i);
+end;
+
+procedure TAccountList.Invalidate;
+begin
+ FOwner.Invalidate;
+end;
+
+procedure TAccountList.Serialize(AElement: TDOMElement);
+var
+ i: Integer;
+ xmlAccount: TDOMElement;
+begin
+ for i := 0 to Count - 1 do
+ begin
+ xmlAccount := AElement.OwnerDocument.CreateElement('Account');
+ AElement.AppendChild(xmlAccount);
+ TAccount(Items[i]).Serialize(xmlAccount);
+ end;
+end;
+
+end.
+
diff --git a/Server/UAdminHandling.pas b/Server/UAdminHandling.pas
index 4312e16..a66d3bd 100644
--- a/Server/UAdminHandling.pas
+++ b/Server/UAdminHandling.pas
@@ -1,226 +1,229 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UAdminHandling;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
- UEnhancedMemoryStream, UEnums, lNet;
-
-type
-
- { TModifyUserResponsePacket }
-
- TModifyUserResponsePacket = class(TPacket)
- constructor Create(AStatus: TModifyUserStatus; AAccount: TAccount);
- end;
-
- { TDeleteUserResponsePacket }
-
- TDeleteUserResponsePacket = class(TPacket)
- constructor Create(AStatus: TDeleteUserStatus; AUsername: string);
- end;
-
- { TUserListPacket }
-
- TUserListPacket = class(TPacket)
- constructor Create;
- end;
-
-procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-
-var
- AdminPacketHandlers: array[0..$FF] of TPacketHandler;
-
-implementation
-
-uses
- md5, UCEDServer, UPackets, UClientHandling;
-
-procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-var
- packetHandler: TPacketHandler;
-begin
- if not ValidateAccess(ANetState, alAdministrator) then Exit;
- packetHandler := AdminPacketHandlers[ABuffer.ReadByte];
- if packetHandler <> nil then
- packetHandler.Process(ABuffer, ANetState);
-end;
-
-procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-begin
- CEDServerInstance.Landscape.Flush;
-end;
-
-procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-begin
- CEDServerInstance.Quit := True;
-end;
-
-procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-var
- account: TAccount;
- username, password: string;
- accessLevel: TAccessLevel;
- netState: TNetState;
-begin
- username := ABuffer.ReadStringNull;
- password := ABuffer.ReadStringNull;
- accessLevel := TAccessLevel(ABuffer.ReadByte);
- account := Accounts.Find(username);
- if account <> nil then
- begin
- if password <> '' then
- account.PasswordHash := MD5Print(MD5String(password));
- if account.AccessLevel <> accessLevel then
- begin
- account.AccessLevel := accessLevel;
- CEDServerInstance.TCPServer.IterReset;
- while CEDServerInstance.TCPServer.IterNext do
- begin
- netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
- if (netState <> nil) and (netState.Account = account) then
- begin
- CEDServerInstance.SendPacket(netState, TAccessLevelChangedPacket.Create(accessLevel));
- end;
- end;
- end;
- CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muModified, account));
- end else
- begin
- account := TAccount.Create(username, MD5Print(MD5String(password)), accessLevel);
- if (username = '') or (Pos('=', username) > 0) then
- begin
- CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muInvalidUsername, account));
- account.Free;
- Exit;
- end;
- Accounts.Add(account);
- CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muAdded, account));
- end;
-end;
-
-procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-var
- account: TAccount;
- username: string;
- netState: TNetState;
-begin
- username := ABuffer.ReadStringNull;
- account := Accounts.Find(username);
- if (account <> nil) and (account <> ANetState.Account) then
- begin
- Config.DeleteKey('Accounts', username);
- CEDServerInstance.TCPServer.IterReset;
- while CEDServerInstance.TCPServer.IterNext do
- begin
- netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
- if (netState <> nil) and (netState.Account = account) then
- begin
- CEDServerInstance.Disconnect(CEDServerInstance.TCPServer.Iterator);
- netState.Account := nil;
- end;
- end;
- Accounts.Remove(account);
- CEDServerInstance.SendPacket(ANetState, TDeleteUserResponsePacket.Create(duDeleted, username));
- end else
- CEDServerInstance.SendPacket(ANetState, TDeleteUserResponsePacket.Create(duNotFound, username));
-end;
-
-procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-begin
- CEDServerInstance.SendPacket(ANetState, TCompressedPacket.Create(TUserListPacket.Create));
-end;
-
-{ TModifyUserResponsePacket }
-
-constructor TModifyUserResponsePacket.Create(AStatus: TModifyUserStatus; AAccount: TAccount);
-begin
- inherited Create($03, 0);
- FStream.WriteByte($05);
- FStream.WriteByte(Byte(AStatus));
- FStream.WriteStringNull(AAccount.Name);
- FStream.WriteByte(Byte(AAccount.AccessLevel));
-end;
-
-{ TDeleteUserResponsePacket }
-
-constructor TDeleteUserResponsePacket.Create(AStatus: TDeleteUserStatus; AUsername: string);
-begin
- inherited Create($03, 0);
- FStream.WriteByte($06);
- FStream.WriteByte(Byte(AStatus));
- FStream.WriteStringNull(AUsername);
-end;
-
-{ TUserListPacket }
-
-constructor TUserListPacket.Create;
-var
- i: Integer;
- account: TAccount;
-begin
- inherited Create($03, 0);
- FStream.WriteByte($07);
- FStream.WriteWord(Accounts.Count);
- for i := 0 to Accounts.Count - 1 do
- begin
- account := TAccount(Accounts.Items[i]);
- FStream.WriteStringNull(account.Name);
- FStream.WriteByte(Byte(account.AccessLevel));
- end;
-end;
-
-{$WARNINGS OFF}
-var
- i: Integer;
-
-initialization
- for i := 0 to $FF do
- AdminPacketHandlers[i] := nil;
- AdminPacketHandlers[$01] := TPacketHandler.Create(0, @OnFlushPacket);
- AdminPacketHandlers[$02] := TPacketHandler.Create(0, @OnQuitPacket);
- AdminPacketHandlers[$05] := TPacketHandler.Create(0, @OnModifyUserPacket);
- AdminPacketHandlers[$06] := TPacketHandler.Create(0, @OnDeleteUserPacket);
- AdminPacketHandlers[$07] := TPacketHandler.Create(0, @OnListUsersPacket);
-finalization
- for i := 0 to $FF do
- if AdminPacketHandlers[i] <> nil then
- AdminPacketHandlers[i].Free;
-{$WARNINGS ON}
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2008 Andreas Schneider
+ *)
+unit UAdminHandling;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
+ UEnhancedMemoryStream, UEnums, lNet;
+
+type
+
+ { TModifyUserResponsePacket }
+
+ TModifyUserResponsePacket = class(TPacket)
+ constructor Create(AStatus: TModifyUserStatus; AAccount: TAccount);
+ end;
+
+ { TDeleteUserResponsePacket }
+
+ TDeleteUserResponsePacket = class(TPacket)
+ constructor Create(AStatus: TDeleteUserStatus; AUsername: string);
+ end;
+
+ { TUserListPacket }
+
+ TUserListPacket = class(TPacket)
+ constructor Create;
+ end;
+
+procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+
+var
+ AdminPacketHandlers: array[0..$FF] of TPacketHandler;
+
+implementation
+
+uses
+ md5, UCEDServer, UPackets, UClientHandling;
+
+procedure OnAdminHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+var
+ packetHandler: TPacketHandler;
+begin
+ if not ValidateAccess(ANetState, alAdministrator) then Exit;
+ packetHandler := AdminPacketHandlers[ABuffer.ReadByte];
+ if packetHandler <> nil then
+ packetHandler.Process(ABuffer, ANetState);
+end;
+
+procedure OnFlushPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+begin
+ CEDServerInstance.Landscape.Flush;
+ Config.Flush;
+end;
+
+procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+begin
+ CEDServerInstance.Quit := True;
+end;
+
+procedure OnModifyUserPacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+var
+ account: TAccount;
+ username, password: string;
+ accessLevel: TAccessLevel;
+ netState: TNetState;
+begin
+ username := ABuffer.ReadStringNull;
+ password := ABuffer.ReadStringNull;
+ accessLevel := TAccessLevel(ABuffer.ReadByte);
+ account := Config.Accounts.Find(username);
+ if account <> nil then
+ begin
+ if password <> '' then
+ account.PasswordHash := MD5Print(MD5String(password));
+ if account.AccessLevel <> accessLevel then
+ begin
+ account.AccessLevel := accessLevel;
+ CEDServerInstance.TCPServer.IterReset;
+ while CEDServerInstance.TCPServer.IterNext do
+ begin
+ netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
+ if (netState <> nil) and (netState.Account = account) then
+ begin
+ CEDServerInstance.SendPacket(netState, TAccessLevelChangedPacket.Create(accessLevel));
+ end;
+ end;
+ end;
+ CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muModified, account));
+ end else
+ begin
+ account := TAccount.Create(Config.Accounts, username,
+ MD5Print(MD5String(password)), accessLevel);
+ if (username = '') or (Pos('=', username) > 0) then
+ begin
+ CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muInvalidUsername, account));
+ account.Free;
+ Exit;
+ end;
+ Config.Accounts.Add(account);
+ Config.Invalidate;
+ CEDServerInstance.SendPacket(ANetState, TModifyUserResponsePacket.Create(muAdded, account));
+ end;
+end;
+
+procedure OnDeleteUserPacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+var
+ account: TAccount;
+ username: string;
+ netState: TNetState;
+begin
+ username := ABuffer.ReadStringNull;
+ account := Config.Accounts.Find(username);
+ if (account <> nil) and (account <> ANetState.Account) then
+ begin
+ CEDServerInstance.TCPServer.IterReset;
+ while CEDServerInstance.TCPServer.IterNext do
+ begin
+ netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
+ if (netState <> nil) and (netState.Account = account) then
+ begin
+ CEDServerInstance.Disconnect(CEDServerInstance.TCPServer.Iterator);
+ netState.Account := nil;
+ end;
+ end;
+ Config.Accounts.Remove(account);
+ Config.Invalidate;
+ CEDServerInstance.SendPacket(ANetState, TDeleteUserResponsePacket.Create(duDeleted, username));
+ end else
+ CEDServerInstance.SendPacket(ANetState, TDeleteUserResponsePacket.Create(duNotFound, username));
+end;
+
+procedure OnListUsersPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+begin
+ CEDServerInstance.SendPacket(ANetState, TCompressedPacket.Create(TUserListPacket.Create));
+end;
+
+{ TModifyUserResponsePacket }
+
+constructor TModifyUserResponsePacket.Create(AStatus: TModifyUserStatus; AAccount: TAccount);
+begin
+ inherited Create($03, 0);
+ FStream.WriteByte($05);
+ FStream.WriteByte(Byte(AStatus));
+ FStream.WriteStringNull(AAccount.Name);
+ FStream.WriteByte(Byte(AAccount.AccessLevel));
+end;
+
+{ TDeleteUserResponsePacket }
+
+constructor TDeleteUserResponsePacket.Create(AStatus: TDeleteUserStatus; AUsername: string);
+begin
+ inherited Create($03, 0);
+ FStream.WriteByte($06);
+ FStream.WriteByte(Byte(AStatus));
+ FStream.WriteStringNull(AUsername);
+end;
+
+{ TUserListPacket }
+
+constructor TUserListPacket.Create;
+var
+ i: Integer;
+ account: TAccount;
+begin
+ inherited Create($03, 0);
+ FStream.WriteByte($07);
+ FStream.WriteWord(Config.Accounts.Count);
+ for i := 0 to Config.Accounts.Count - 1 do
+ begin
+ account := TAccount(Config.Accounts.Items[i]);
+ FStream.WriteStringNull(account.Name);
+ FStream.WriteByte(Byte(account.AccessLevel));
+ end;
+end;
+
+{$WARNINGS OFF}
+var
+ i: Integer;
+
+initialization
+ for i := 0 to $FF do
+ AdminPacketHandlers[i] := nil;
+ AdminPacketHandlers[$01] := TPacketHandler.Create(0, @OnFlushPacket);
+ AdminPacketHandlers[$02] := TPacketHandler.Create(0, @OnQuitPacket);
+ AdminPacketHandlers[$05] := TPacketHandler.Create(0, @OnModifyUserPacket);
+ AdminPacketHandlers[$06] := TPacketHandler.Create(0, @OnDeleteUserPacket);
+ AdminPacketHandlers[$07] := TPacketHandler.Create(0, @OnListUsersPacket);
+finalization
+ for i := 0 to $FF do
+ if AdminPacketHandlers[i] <> nil then
+ AdminPacketHandlers[i].Free;
+{$WARNINGS ON}
+
+end.
+
diff --git a/Server/UCEDServer.pas b/Server/UCEDServer.pas
index eea56e5..f89b1ec 100644
--- a/Server/UCEDServer.pas
+++ b/Server/UCEDServer.pas
@@ -1,361 +1,358 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UCEDServer;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, lNet, UEnhancedMemoryStream, UConfig, ULandscape,
- UNetState, UPacket, dateutils,
- {$IFDEF Linux}BaseUnix,{$ENDIF}
- {$IFDEF Windows}Windows,{$ENDIF}
- UPacketHandlers, UConnectionHandling;
-
-type
-
- { TCEDServer }
-
- TCEDServer = class(TObject)
- constructor Create;
- destructor Destroy; override;
- protected
- FLandscape: TLandscape;
- FTCPServer: TLTcp;
- FQuit: Boolean;
- FLastFlush: TDateTime;
- FValid: Boolean;
- procedure OnAccept(ASocket: TLSocket);
- procedure OnCanSend(ASocket: TLSocket);
- procedure OnDisconnect(ASocket: TLSocket);
- procedure OnReceive(ASocket: TLSocket);
- procedure OnError(const AError: string; ASocket: TLSocket);
- procedure ProcessBuffer(ANetState: TNetState);
- procedure CheckNetStates;
- public
- property Landscape: TLandscape read FLandscape;
- property TCPServer: TLTcp read FTCPServer;
- property Quit: Boolean read FQuit write FQuit;
- procedure Run;
- procedure SendPacket(ANetState: TNetState; APacket: TPacket;
- AFreePacket: Boolean = True);
- procedure Disconnect(ASocket: TLSocket);
- end;
-
-var
- CEDServerInstance: TCEDServer;
-
-implementation
-
-uses
- UClientHandling;
-
-{$I version.inc}
-
-{$IFDEF Linux}
-procedure OnSigInt(ASignal: cint); cdecl;
-begin
- Writeln(TimeStamp, 'Killed');
- if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
-end;
-
-procedure OnSigSegv(ASignal: cint); cdecl;
-begin
- Writeln(TimeStamp, 'Internal error');
- Halt;
- //if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
-end;
-{$ENDIF}
-
-{$IFDEF Windows}
-function OnConsoleCtrlEvent(ACtrl: DWord): LongBool; stdcall; far;
-begin
- Result := False;
- if (ACtrl = CTRL_C_EVENT) or (ACtrl = CTRL_BREAK_EVENT) then
- begin
- Writeln(TimeStamp, 'Killed');
- if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
- Result := True;
- end;
-end;
-{$ENDIF}
-
-{ TCEDServer }
-
-constructor TCEDServer.Create;
-begin
- inherited Create;
- FLandscape := TLandscape.Create(Config.ReadString('Paths', 'map', 'map0.mul'),
- Config.ReadString('Paths', 'statics', 'statics0.mul'),
- Config.ReadString('Paths', 'staidx', 'staidx0.mul'),
- Config.ReadString('Paths', 'tiledata', 'tiledata.mul'),
- Config.ReadString('Paths', 'radarcol', 'radarcol.mul'),
- Config.ReadInteger('Parameters', 'Width', 0),
- Config.ReadInteger('Parameters', 'Height', 0),
- FValid);
- FTCPServer := TLTcp.Create(nil);
- FTCPServer.OnAccept := @OnAccept;
- FTCPServer.OnCanSend := @OnCanSend;
- FTCPServer.OnDisconnect := @OnDisconnect;
- FTCPServer.OnReceive := @OnReceive;
- FTCPServer.OnError := @OnError;
- FQuit := False;
- FLastFlush := Now;
-end;
-
-destructor TCEDServer.Destroy;
-begin
- if FTCPServer <> nil then
- begin
- FTCPServer.IterReset;
- if FTCPServer.Iterator <> nil then
- while FTCPServer.IterNext do
- begin
- FTCPServer.Iterator.Disconnect;
- if FTCPServer.Iterator.UserData <> nil then
- begin
- TObject(FTCPServer.Iterator.UserData).Free;
- FTCPServer.Iterator.UserData := nil;
- end;
- end;
- FreeAndNil(FTCPServer);
- end;
- if FLandscape <> nil then FreeAndNil(FLandscape);
- inherited Destroy;
-end;
-
-procedure TCEDServer.OnAccept(ASocket: TLSocket);
-begin
- writeln(TimeStamp, 'Connect: ', ASocket.PeerAddress);
- ASocket.UserData := TNetState.Create(ASocket);
- SendPacket(TNetState(ASocket.UserData), TProtocolVersionPacket.Create(ProtocolVersion));
-end;
-
-procedure TCEDServer.OnCanSend(ASocket: TLSocket);
-var
- netState: TNetState;
- size: Integer;
-begin
- //writeln('CanSend: ', ASocket.PeerAddress);
- netState := TNetState(ASocket.UserData);
- if netState = nil then Exit;
- while netState.SendQueue.Size > 0 do
- begin
- size := FTCPServer.Send(netState.SendQueue.Memory^, netState.SendQueue.Size, ASocket);
- if size > 0 then
- netState.SendQueue.Dequeue(size)
- else
- Break;
- end;
-end;
-
-procedure TCEDServer.OnDisconnect(ASocket: TLSocket);
-var
- netState: TNetState;
-begin
- writeln(TimeStamp, 'Disconnect: ', ASocket.PeerAddress);
- if ASocket.UserData <> nil then
- begin
- netState := TNetState(ASocket.UserData);
- ASocket.UserData := nil;
- if netState.Account <> nil then
- SendPacket(nil, TClientDisconnectedPacket.Create(netState.Account.Name));
- netState.Free;
- end;
-end;
-
-procedure TCEDServer.OnReceive(ASocket: TLSocket);
-var
- netState: TNetState;
- buffer: array[0..4095] of byte;
- size: Integer;
-begin
- netState := TNetState(ASocket.UserData);
- if netState <> nil then
- begin
- repeat
- size := FTCPServer.Get(buffer, 4096, ASocket);
- if size > 0 then
- netState.ReceiveQueue.Enqueue(buffer, size);
- until size <= 0;
- ProcessBuffer(netState);
- end;
-end;
-
-procedure TCEDServer.OnError(const AError: string; ASocket: TLSocket);
-begin
- writeln(TimeStamp, 'Error: ', ASocket.PeerAddress, ' :: ', AError);
- //OnDisconnect(ASocket);
-end;
-
-procedure TCEDServer.ProcessBuffer(ANetState: TNetState);
-var
- buffer: TEnhancedMemoryStream;
- packetID: Byte;
- packetHandler: TPacketHandler;
- size: Cardinal;
-begin
- try
- buffer := ANetState.ReceiveQueue;
- buffer.Position := 0;
- while (buffer.Size >= 1) and ANetState.Socket.Connected do
- begin
- packetID := buffer.ReadByte;
- packetHandler := PacketHandlers[packetID];
- if packetHandler <> nil then
- begin
- ANetState.LastAction := Now;
- size := packetHandler.PacketLength;
- if size = 0 then
- begin
- if buffer.Size > 5 then
- size := buffer.ReadCardinal
- else
- Break; //wait for more data
- end;
-
- if buffer.Size >= size then
- begin
- buffer.Lock(buffer.Position, size - buffer.Position); //prevent handler from reading too much
- packetHandler.Process(buffer, ANetState);
- buffer.Unlock;
- buffer.Dequeue(size);
- end else
- Break; //wait for more data
- end else
- begin
- Writeln(TimeStamp, 'Dropping client due to unknown packet [', packetID, ']: ', ANetState.Socket.PeerAddress);
- Disconnect(ANetState.Socket);
- buffer.Clear;
- end;
- end;
- ANetState.LastAction := Now;
- except
- Writeln(TimeStamp, 'Error processing buffer of client: ', ANetState.Socket.PeerAddress);
- end;
-end;
-
-procedure TCEDServer.CheckNetStates;
-var
- netState: TNetState;
-begin
- FTCPServer.IterReset;
- while FTCPServer.IterNext do
- begin
- netState := TNetState(FTCPServer.Iterator.UserData);
- if netState <> nil then
- begin
- if FTCPServer.Iterator.Connected then
- begin
- if (SecondsBetween(netState.LastAction, Now) > 120) then
- begin
- if netState.Account <> nil then
- Writeln(TimeStamp, 'Timeout: ', netState.Account.Name, ' (', netState.Socket.PeerAddress, ')')
- else
- Writeln(TimeStamp, 'Timeout: ', netState.Socket.PeerAddress);
- Disconnect(netState.Socket);
- end;
- end else {TODO : Unnecessary ...}
- begin
- OnDisconnect(FTCPServer.Iterator);
- end;
- end;
- end;
-end;
-
-procedure TCEDServer.Run;
-begin
- if not FValid then
- begin
- Writeln(TimeStamp, 'Invalid data. Check the map size and the files.');
- Exit;
- end;
-
- if FTCPServer.Listen(Config.ReadInteger('Network', 'Port', 2597)) then
- begin
- repeat
- FTCPServer.CallAction;
- CheckNetStates;
- if SecondsBetween(FLastFlush, Now) >= 60 then
- begin
- FLandscape.Flush;
- FLastFlush := Now;
- end;
- Sleep(1);
- until FQuit;
- end;
-end;
-
-procedure TCEDServer.SendPacket(ANetState: TNetState; APacket: TPacket;
- AFreePacket: Boolean = True);
-var
- netState: TNetState;
-begin
- if ANetState <> nil then
- begin
- ANetState.SendQueue.Seek(0, soFromEnd);
- ANetState.SendQueue.CopyFrom(APacket.Stream, 0);
- OnCanSend(ANetState.Socket);
- end else //broadcast
- begin
- FTCPServer.IterReset;
- while FTCPServer.IterNext do
- begin
- netState := TNetState(FTCPServer.Iterator.UserData);
- if (netState <> nil) and (FTCPServer.Iterator.Connected) then
- begin
- netState.SendQueue.Seek(0, soFromEnd);
- netState.SendQueue.CopyFrom(APacket.Stream, 0);
- OnCanSend(netState.Socket);
- end;
- end;
- end;
- if AFreePacket then
- APacket.Free;
-end;
-
-procedure TCEDServer.Disconnect(ASocket: TLSocket);
-begin
- if ASocket.Connected then
- begin
- ASocket.Disconnect;
- //OnDisconnect(ASocket);
- //Handling of the disconnect is done in CheckNetStates after each CallAction
- end;
-end;
-
-initialization
-{$IFDEF Linux}
- FpSignal(SIGINT, @OnSigInt);
- //FpSignal(SIGSEGV, @OnSigSegv);
-{$ENDIF}
-{$IFDEF Windows}
- SetConsoleCtrlHandler(@OnConsoleCtrlEvent, True);
-{$ENDIF}
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Andreas Schneider
+ *)
+unit UCEDServer;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, lNet, UEnhancedMemoryStream, UConfig, ULandscape,
+ UNetState, UPacket, dateutils,
+ {$IFDEF Linux}BaseUnix,{$ENDIF}
+ {$IFDEF Windows}Windows,{$ENDIF}
+ UPacketHandlers, UConnectionHandling;
+
+type
+
+ { TCEDServer }
+
+ TCEDServer = class(TObject)
+ constructor Create;
+ destructor Destroy; override;
+ protected
+ FLandscape: TLandscape;
+ FTCPServer: TLTcp;
+ FQuit: Boolean;
+ FLastFlush: TDateTime;
+ FValid: Boolean;
+ procedure OnAccept(ASocket: TLSocket);
+ procedure OnCanSend(ASocket: TLSocket);
+ procedure OnDisconnect(ASocket: TLSocket);
+ procedure OnReceive(ASocket: TLSocket);
+ procedure OnError(const AError: string; ASocket: TLSocket);
+ procedure ProcessBuffer(ANetState: TNetState);
+ procedure CheckNetStates;
+ public
+ property Landscape: TLandscape read FLandscape;
+ property TCPServer: TLTcp read FTCPServer;
+ property Quit: Boolean read FQuit write FQuit;
+ procedure Run;
+ procedure SendPacket(ANetState: TNetState; APacket: TPacket;
+ AFreePacket: Boolean = True);
+ procedure Disconnect(ASocket: TLSocket);
+ end;
+
+var
+ CEDServerInstance: TCEDServer;
+
+implementation
+
+uses
+ UClientHandling;
+
+{$I version.inc}
+
+{$IFDEF Linux}
+procedure OnSigInt(ASignal: cint); cdecl;
+begin
+ Writeln(TimeStamp, 'Killed');
+ if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
+end;
+
+procedure OnSigSegv(ASignal: cint); cdecl;
+begin
+ Writeln(TimeStamp, 'Internal error');
+ Halt;
+ //if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
+end;
+{$ENDIF}
+
+{$IFDEF Windows}
+function OnConsoleCtrlEvent(ACtrl: DWord): LongBool; stdcall; far;
+begin
+ Result := False;
+ if (ACtrl = CTRL_C_EVENT) or (ACtrl = CTRL_BREAK_EVENT) then
+ begin
+ Writeln(TimeStamp, 'Killed');
+ if CEDServerInstance <> nil then CEDServerInstance.Quit := True;
+ Result := True;
+ end;
+end;
+{$ENDIF}
+
+{ TCEDServer }
+
+constructor TCEDServer.Create;
+begin
+ inherited Create;
+ FLandscape := TLandscape.Create(Config.Map.MapFile, Config.Map.StaticsFile,
+ Config.Map.StaIdxFile, Config.Tiledata, Config.Radarcol, Config.Map.Width,
+ Config.Map.Height, FValid);
+ FTCPServer := TLTcp.Create(nil);
+ FTCPServer.OnAccept := @OnAccept;
+ FTCPServer.OnCanSend := @OnCanSend;
+ FTCPServer.OnDisconnect := @OnDisconnect;
+ FTCPServer.OnReceive := @OnReceive;
+ FTCPServer.OnError := @OnError;
+ FQuit := False;
+ FLastFlush := Now;
+end;
+
+destructor TCEDServer.Destroy;
+begin
+ if FTCPServer <> nil then
+ begin
+ FTCPServer.IterReset;
+ if FTCPServer.Iterator <> nil then
+ while FTCPServer.IterNext do
+ begin
+ FTCPServer.Iterator.Disconnect;
+ if FTCPServer.Iterator.UserData <> nil then
+ begin
+ TObject(FTCPServer.Iterator.UserData).Free;
+ FTCPServer.Iterator.UserData := nil;
+ end;
+ end;
+ FreeAndNil(FTCPServer);
+ end;
+ if FLandscape <> nil then FreeAndNil(FLandscape);
+ inherited Destroy;
+end;
+
+procedure TCEDServer.OnAccept(ASocket: TLSocket);
+begin
+ writeln(TimeStamp, 'Connect: ', ASocket.PeerAddress);
+ ASocket.UserData := TNetState.Create(ASocket);
+ SendPacket(TNetState(ASocket.UserData), TProtocolVersionPacket.Create(ProtocolVersion));
+end;
+
+procedure TCEDServer.OnCanSend(ASocket: TLSocket);
+var
+ netState: TNetState;
+ size: Integer;
+begin
+ //writeln('CanSend: ', ASocket.PeerAddress);
+ netState := TNetState(ASocket.UserData);
+ if netState = nil then Exit;
+ while netState.SendQueue.Size > 0 do
+ begin
+ size := FTCPServer.Send(netState.SendQueue.Memory^, netState.SendQueue.Size, ASocket);
+ if size > 0 then
+ netState.SendQueue.Dequeue(size)
+ else
+ Break;
+ end;
+end;
+
+procedure TCEDServer.OnDisconnect(ASocket: TLSocket);
+var
+ netState: TNetState;
+begin
+ writeln(TimeStamp, 'Disconnect: ', ASocket.PeerAddress);
+ if ASocket.UserData <> nil then
+ begin
+ netState := TNetState(ASocket.UserData);
+ ASocket.UserData := nil;
+ if netState.Account <> nil then
+ SendPacket(nil, TClientDisconnectedPacket.Create(netState.Account.Name));
+ netState.Free;
+ end;
+end;
+
+procedure TCEDServer.OnReceive(ASocket: TLSocket);
+var
+ netState: TNetState;
+ buffer: array[0..4095] of byte;
+ size: Integer;
+begin
+ netState := TNetState(ASocket.UserData);
+ if netState <> nil then
+ begin
+ repeat
+ size := FTCPServer.Get(buffer, 4096, ASocket);
+ if size > 0 then
+ netState.ReceiveQueue.Enqueue(buffer, size);
+ until size <= 0;
+ ProcessBuffer(netState);
+ end;
+end;
+
+procedure TCEDServer.OnError(const AError: string; ASocket: TLSocket);
+begin
+ writeln(TimeStamp, 'Error: ', ASocket.PeerAddress, ' :: ', AError);
+ //OnDisconnect(ASocket);
+end;
+
+procedure TCEDServer.ProcessBuffer(ANetState: TNetState);
+var
+ buffer: TEnhancedMemoryStream;
+ packetID: Byte;
+ packetHandler: TPacketHandler;
+ size: Cardinal;
+begin
+ try
+ buffer := ANetState.ReceiveQueue;
+ buffer.Position := 0;
+ while (buffer.Size >= 1) and ANetState.Socket.Connected do
+ begin
+ packetID := buffer.ReadByte;
+ packetHandler := PacketHandlers[packetID];
+ if packetHandler <> nil then
+ begin
+ ANetState.LastAction := Now;
+ size := packetHandler.PacketLength;
+ if size = 0 then
+ begin
+ if buffer.Size > 5 then
+ size := buffer.ReadCardinal
+ else
+ Break; //wait for more data
+ end;
+
+ if buffer.Size >= size then
+ begin
+ buffer.Lock(buffer.Position, size - buffer.Position); //prevent handler from reading too much
+ packetHandler.Process(buffer, ANetState);
+ buffer.Unlock;
+ buffer.Dequeue(size);
+ end else
+ Break; //wait for more data
+ end else
+ begin
+ Writeln(TimeStamp, 'Dropping client due to unknown packet [', packetID, ']: ', ANetState.Socket.PeerAddress);
+ Disconnect(ANetState.Socket);
+ buffer.Clear;
+ end;
+ end;
+ ANetState.LastAction := Now;
+ except
+ Writeln(TimeStamp, 'Error processing buffer of client: ', ANetState.Socket.PeerAddress);
+ end;
+end;
+
+procedure TCEDServer.CheckNetStates;
+var
+ netState: TNetState;
+begin
+ FTCPServer.IterReset;
+ while FTCPServer.IterNext do
+ begin
+ netState := TNetState(FTCPServer.Iterator.UserData);
+ if netState <> nil then
+ begin
+ if FTCPServer.Iterator.Connected then
+ begin
+ if (SecondsBetween(netState.LastAction, Now) > 120) then
+ begin
+ if netState.Account <> nil then
+ Writeln(TimeStamp, 'Timeout: ', netState.Account.Name, ' (', netState.Socket.PeerAddress, ')')
+ else
+ Writeln(TimeStamp, 'Timeout: ', netState.Socket.PeerAddress);
+ Disconnect(netState.Socket);
+ end;
+ end else {TODO : Unnecessary ...}
+ begin
+ OnDisconnect(FTCPServer.Iterator);
+ end;
+ end;
+ end;
+end;
+
+procedure TCEDServer.Run;
+begin
+ if not FValid then
+ begin
+ Writeln(TimeStamp, 'Invalid data. Check the map size and the files.');
+ Exit;
+ end;
+
+ if FTCPServer.Listen(Config.Port) then
+ begin
+ repeat
+ FTCPServer.CallAction;
+ CheckNetStates;
+ if SecondsBetween(FLastFlush, Now) >= 60 then
+ begin
+ FLandscape.Flush;
+ Config.Flush;
+ FLastFlush := Now;
+ end;
+ Sleep(1);
+ until FQuit;
+ end;
+end;
+
+procedure TCEDServer.SendPacket(ANetState: TNetState; APacket: TPacket;
+ AFreePacket: Boolean = True);
+var
+ netState: TNetState;
+begin
+ if ANetState <> nil then
+ begin
+ ANetState.SendQueue.Seek(0, soFromEnd);
+ ANetState.SendQueue.CopyFrom(APacket.Stream, 0);
+ OnCanSend(ANetState.Socket);
+ end else //broadcast
+ begin
+ FTCPServer.IterReset;
+ while FTCPServer.IterNext do
+ begin
+ netState := TNetState(FTCPServer.Iterator.UserData);
+ if (netState <> nil) and (FTCPServer.Iterator.Connected) then
+ begin
+ netState.SendQueue.Seek(0, soFromEnd);
+ netState.SendQueue.CopyFrom(APacket.Stream, 0);
+ OnCanSend(netState.Socket);
+ end;
+ end;
+ end;
+ if AFreePacket then
+ APacket.Free;
+end;
+
+procedure TCEDServer.Disconnect(ASocket: TLSocket);
+begin
+ if ASocket.Connected then
+ begin
+ ASocket.Disconnect;
+ //OnDisconnect(ASocket);
+ //Handling of the disconnect is done in CheckNetStates after each CallAction
+ end;
+end;
+
+initialization
+{$IFDEF Linux}
+ FpSignal(SIGINT, @OnSigInt);
+ FpSignal(SIGTERM, @OnSigInt); //SIGTERM should shutdown the server cleanly too
+ //FpSignal(SIGSEGV, @OnSigSegv);
+{$ENDIF}
+{$IFDEF Windows}
+ SetConsoleCtrlHandler(@OnConsoleCtrlEvent, True);
+{$ENDIF}
+
+end.
+
diff --git a/Server/UClientHandling.pas b/Server/UClientHandling.pas
index e09f628..6c70cdc 100644
--- a/Server/UClientHandling.pas
+++ b/Server/UClientHandling.pas
@@ -1,207 +1,207 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UClientHandling;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
- UEnhancedMemoryStream, UEnums, math;
-
-type
-
- { TClientConnectedPacket }
-
- TClientConnectedPacket = class(TPacket)
- constructor Create(AUsername: string);
- end;
-
- { TClientDisconnectedPacket }
-
- TClientDisconnectedPacket = class(TPacket)
- constructor Create(AUsername: string);
- end;
-
- { TClientListPacket }
-
- TClientListPacket = class(TPacket)
- constructor Create(AAvoid: TNetState = nil);
- end;
-
- { TSetClientPosPacket }
-
- TSetClientPosPacket = class(TPacket)
- constructor Create(APos: TPoint);
- end;
-
- { TChatMessagePacket }
-
- TChatMessagePacket = class(TPacket)
- constructor Create(ASender, AMessage: string);
- end;
-
- { TAccessLevelChangedPacket }
-
- TAccessLevelChangedPacket = class(TPacket)
- constructor Create(AAccessLevel: TAccessLevel);
- end;
-
-procedure OnClientHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnUpdateClientPosPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnChatMessagePacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnGotoClientPosPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-
-var
- ClientPacketHandlers: array[0..$FF] of TPacketHandler;
-
-implementation
-
-uses
- UCEDServer, UPackets;
-
-procedure OnClientHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-var
- packetHandler: TPacketHandler;
-begin
- if not ValidateAccess(ANetState, alView) then Exit;
- packetHandler := ClientPacketHandlers[ABuffer.ReadByte];
- if packetHandler <> nil then
- packetHandler.Process(ABuffer, ANetState);
-end;
-
-procedure OnUpdateClientPosPacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-var
- pos: TPoint;
-begin
- pos.x := ABuffer.ReadWord;
- pos.y := ABuffer.ReadWord;
- ANetState.Account.LastPos := pos;
-end;
-
-procedure OnChatMessagePacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-begin
- CEDServerInstance.SendPacket(nil, TCompressedPacket.Create(
- TChatMessagePacket.Create(ANetState.Account.Name, ABuffer.ReadStringNull)));
-end;
-
-procedure OnGotoClientPosPacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-var
- account: TAccount;
-begin
- account := Accounts.Find(ABuffer.ReadStringNull);
- if account <> nil then
- CEDServerInstance.SendPacket(ANetState, TSetClientPosPacket.Create(account.LastPos));
-end;
-
-{ TClientConnectedPacket }
-
-constructor TClientConnectedPacket.Create(AUsername: string);
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($01);
- FStream.WriteStringNull(AUsername);
-end;
-
-{ TClientDisconnectedPacket }
-
-constructor TClientDisconnectedPacket.Create(AUsername: string);
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($02);
- FStream.WriteStringNull(AUsername);
-end;
-
-{ TClientListPacket }
-
-constructor TClientListPacket.Create(AAvoid: TNetState = nil);
-var
- netState: TNetState;
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($03);
- CEDServerInstance.TCPServer.IterReset;
- if CEDServerInstance.TCPServer.Iterator <> nil then
- begin
- repeat
- netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
- if (netState <> nil) and (netState <> AAvoid) and (netState.Account <> nil) then
- FStream.WriteStringNull(netState.Account.Name);
- until not CEDServerInstance.TCPServer.IterNext;
- end;
-end;
-
-{ TSetClientPosPacket }
-
-constructor TSetClientPosPacket.Create(APos: TPoint);
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($04);
- FStream.WriteWord(EnsureRange(APos.x, 0, CEDServerInstance.Landscape.CellWidth - 1));
- FStream.WriteWord(EnsureRange(APos.y, 0, CEDServerInstance.Landscape.CellHeight - 1));
-end;
-
-{ TChatMessagePacket }
-
-constructor TChatMessagePacket.Create(ASender, AMessage: string);
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($05);
- FStream.WriteStringNull(ASender);
- FStream.WriteStringNull(AMessage);
-end;
-
-{ TAccessLevelChangedPacket }
-
-constructor TAccessLevelChangedPacket.Create(AAccessLevel: TAccessLevel);
-begin
- inherited Create($0C, 0);
- FStream.WriteByte($07);
- FStream.WriteByte(Byte(AAccessLevel));
-end;
-
-{$WARNINGS OFF}
-var
- i: Integer;
-
-initialization
- for i := 0 to $FF do
- ClientPacketHandlers[i] := nil;
- ClientPacketHandlers[$04] := TPacketHandler.Create(0, @OnUpdateClientPosPacket);
- ClientPacketHandlers[$05] := TPacketHandler.Create(0, @OnChatMessagePacket);
- ClientPacketHandlers[$06] := TPacketHandler.Create(0, @OnGotoClientPosPacket);
-finalization
- for i := 0 to $FF do
- if ClientPacketHandlers[i] <> nil then
- ClientPacketHandlers[i].Free;
-{$WARNINGS ON}
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Andreas Schneider
+ *)
+unit UClientHandling;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
+ UEnhancedMemoryStream, UEnums, math;
+
+type
+
+ { TClientConnectedPacket }
+
+ TClientConnectedPacket = class(TPacket)
+ constructor Create(AUsername: string);
+ end;
+
+ { TClientDisconnectedPacket }
+
+ TClientDisconnectedPacket = class(TPacket)
+ constructor Create(AUsername: string);
+ end;
+
+ { TClientListPacket }
+
+ TClientListPacket = class(TPacket)
+ constructor Create(AAvoid: TNetState = nil);
+ end;
+
+ { TSetClientPosPacket }
+
+ TSetClientPosPacket = class(TPacket)
+ constructor Create(APos: TPoint);
+ end;
+
+ { TChatMessagePacket }
+
+ TChatMessagePacket = class(TPacket)
+ constructor Create(ASender, AMessage: string);
+ end;
+
+ { TAccessLevelChangedPacket }
+
+ TAccessLevelChangedPacket = class(TPacket)
+ constructor Create(AAccessLevel: TAccessLevel);
+ end;
+
+procedure OnClientHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnUpdateClientPosPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnChatMessagePacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnGotoClientPosPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+
+var
+ ClientPacketHandlers: array[0..$FF] of TPacketHandler;
+
+implementation
+
+uses
+ UCEDServer, UPackets;
+
+procedure OnClientHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+var
+ packetHandler: TPacketHandler;
+begin
+ if not ValidateAccess(ANetState, alView) then Exit;
+ packetHandler := ClientPacketHandlers[ABuffer.ReadByte];
+ if packetHandler <> nil then
+ packetHandler.Process(ABuffer, ANetState);
+end;
+
+procedure OnUpdateClientPosPacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+var
+ pos: TPoint;
+begin
+ pos.x := ABuffer.ReadWord;
+ pos.y := ABuffer.ReadWord;
+ ANetState.Account.LastPos := pos;
+end;
+
+procedure OnChatMessagePacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+begin
+ CEDServerInstance.SendPacket(nil, TCompressedPacket.Create(
+ TChatMessagePacket.Create(ANetState.Account.Name, ABuffer.ReadStringNull)));
+end;
+
+procedure OnGotoClientPosPacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+var
+ account: TAccount;
+begin
+ account := Config.Accounts.Find(ABuffer.ReadStringNull);
+ if account <> nil then
+ CEDServerInstance.SendPacket(ANetState, TSetClientPosPacket.Create(account.LastPos));
+end;
+
+{ TClientConnectedPacket }
+
+constructor TClientConnectedPacket.Create(AUsername: string);
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($01);
+ FStream.WriteStringNull(AUsername);
+end;
+
+{ TClientDisconnectedPacket }
+
+constructor TClientDisconnectedPacket.Create(AUsername: string);
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($02);
+ FStream.WriteStringNull(AUsername);
+end;
+
+{ TClientListPacket }
+
+constructor TClientListPacket.Create(AAvoid: TNetState = nil);
+var
+ netState: TNetState;
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($03);
+ CEDServerInstance.TCPServer.IterReset;
+ if CEDServerInstance.TCPServer.Iterator <> nil then
+ begin
+ repeat
+ netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
+ if (netState <> nil) and (netState <> AAvoid) and (netState.Account <> nil) then
+ FStream.WriteStringNull(netState.Account.Name);
+ until not CEDServerInstance.TCPServer.IterNext;
+ end;
+end;
+
+{ TSetClientPosPacket }
+
+constructor TSetClientPosPacket.Create(APos: TPoint);
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($04);
+ FStream.WriteWord(EnsureRange(APos.x, 0, CEDServerInstance.Landscape.CellWidth - 1));
+ FStream.WriteWord(EnsureRange(APos.y, 0, CEDServerInstance.Landscape.CellHeight - 1));
+end;
+
+{ TChatMessagePacket }
+
+constructor TChatMessagePacket.Create(ASender, AMessage: string);
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($05);
+ FStream.WriteStringNull(ASender);
+ FStream.WriteStringNull(AMessage);
+end;
+
+{ TAccessLevelChangedPacket }
+
+constructor TAccessLevelChangedPacket.Create(AAccessLevel: TAccessLevel);
+begin
+ inherited Create($0C, 0);
+ FStream.WriteByte($07);
+ FStream.WriteByte(Byte(AAccessLevel));
+end;
+
+{$WARNINGS OFF}
+var
+ i: Integer;
+
+initialization
+ for i := 0 to $FF do
+ ClientPacketHandlers[i] := nil;
+ ClientPacketHandlers[$04] := TPacketHandler.Create(0, @OnUpdateClientPosPacket);
+ ClientPacketHandlers[$05] := TPacketHandler.Create(0, @OnChatMessagePacket);
+ ClientPacketHandlers[$06] := TPacketHandler.Create(0, @OnGotoClientPosPacket);
+finalization
+ for i := 0 to $FF do
+ if ClientPacketHandlers[i] <> nil then
+ ClientPacketHandlers[i].Free;
+{$WARNINGS ON}
+
+end.
+
diff --git a/Server/UConfig.pas b/Server/UConfig.pas
index 79b9a8e..499ec53 100644
--- a/Server/UConfig.pas
+++ b/Server/UConfig.pas
@@ -1,182 +1,357 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UConfig;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, IniFiles, md5, Keyboard, UAccount;
-
-
-var
- AppDir: string;
- Config: TIniFile;
- Accounts: TAccountList;
-
-procedure InitConfig;
-function LoadConfig: Boolean;
-function TimeStamp: string;
-
-implementation
-
-const
- CONFIGVERSION = 2;
-
-function QueryPassword: String;
-var
- pwChar: char;
-begin
- Result := '';
-
- InitKeyboard;
- try
- repeat
- pwChar := GetKeyEventChar(TranslateKeyEvent(GetKeyEvent));
- case pwChar of
- #8: Result := Copy(Result, 1, Length(Result) - 1);
- #13: break;
- else
- Result := Result + pwChar;
- end;
- until pwChar = #13;
- finally
- DoneKeyboard;
- end;
- writeln('');
-end;
-
-procedure InitConfig;
-var
- configFile: string;
- stringValue, password: string;
- intValue: Integer;
-begin
- configFile := ChangeFileExt(ParamStr(0), '.ini');
- DeleteFile(configFile);
- Config := TIniFile.Create(configFile);
- Config.WriteInteger('Config', 'Version', CONFIGVERSION);
-
- Writeln('Configuring Network');
- Writeln('===================');
- Write ('Port [2597]: ');
- Readln (stringValue);
- if not TryStrToInt(stringValue, intValue) then intValue := 2597;
- Config.WriteInteger('Network', 'Port', intValue);
- Writeln('');
-
- Writeln('Configuring Paths');
- Writeln('=================');
- Write ('map [map0.mul]: ');
- Readln (stringValue);
- if stringValue = '' then stringValue := 'map0.mul';
- Config.WriteString('Paths', 'map', stringValue);
- Write ('statics [statics0.mul]: ');
- Readln (stringValue);
- if stringValue = '' then stringValue := 'statics0.mul';
- Config.WriteString('Paths', 'statics', stringValue);
- Write ('staidx [staidx0.mul]: ');
- Readln (stringValue);
- if stringValue = '' then stringValue := 'staidx0.mul';
- Config.WriteString('Paths', 'staidx', stringValue);
- Write ('tiledata [tiledata.mul]: ');
- Readln (stringValue);
- if stringValue = '' then stringValue := 'tiledata.mul';
- Config.WriteString('Paths', 'tiledata', stringValue);
- Write ('radarcol [radarcol.mul]: ');
- Readln (stringValue);
- if stringValue = '' then stringValue := 'radarcol.mul';
- Config.WriteString('Paths', 'radarcol', stringValue);
- Writeln('');
-
- Writeln('Parameters');
- Writeln('==========');
- Write ('Map width [768]: ');
- Readln (stringValue);
- if not TryStrToInt(stringValue, intValue) then intValue := 768;
- Config.WriteInteger('Parameters', 'Width', intValue);
- Write ('Map height [512]: ');
- Readln (stringValue);
- if not TryStrToInt(stringValue, intValue) then intValue := 512;
- Config.WriteInteger('Parameters', 'Height', intValue);
- Writeln('');
-
- Writeln('Admin account');
- Writeln('=============');
- repeat
- Write('Account name: ');
- Readln(stringValue);
- until stringValue <> '';
- Write ('Password [hidden]: ');
- password := QueryPassword;
- Config.WriteString('Accounts', stringValue, '255:' + MD5Print(MD5String(password)));
-end;
-
-function LoadConfig: Boolean;
-var
- configFile: string;
- values: TStringList;
- i: Integer;
-begin
- configFile := ChangeFileExt(ParamStr(0), '.ini');
- if FileExists(configFile) then
- begin
- Config := TIniFile.Create(configFile);
- Result := (Config.ReadInteger('Config', 'Version', 0) = CONFIGVERSION);
- if Result then
- begin
- Accounts := TAccountList.Create;
- values := TStringList.Create;
- Config.ReadSectionRaw('Accounts', values);
- for i := 0 to values.Count - 1 do
- Accounts.Add(TAccount.Create(values.Strings[i]));
- values.Free;
- end;
- end else
- Result := False;
-end;
-
-function TimeStamp: string;
-begin
- Result := '[' + DateTimeToStr(Now) + '] ';
-end;
-
-initialization
-begin
- AppDir := ExtractFilePath(ParamStr(0));
- if AppDir[Length(AppDir)] <> PathDelim then
- AppDir := AppDir + PathDelim;
-end;
-
-finalization
-begin
- if Config <> nil then FreeAndNil(Config);
- if Accounts <> nil then FreeAndNil(Accounts);
-end;
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2008 Andreas Schneider
+ *)
+unit UConfig;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, DOM, XMLRead, XMLWrite, md5, Keyboard, UAccount,
+ UXmlHelper, UInterfaces, UEnums;
+
+type
+
+ TInvalidConfigVersionExeption = class(Exception);
+
+ { TMapInfo }
+
+ TMapInfo = class(TObject, ISerializable)
+ constructor Create(AOwner: IInvalidate);
+ constructor Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+ procedure Serialize(AElement: TDOMElement);
+ protected
+ FOwner: IInvalidate;
+ FMapFile: string;
+ FStaticsFile: string;
+ FStaIdxFile: string;
+ FWidth: Word;
+ FHeight: Word;
+ procedure SetHeight(const AValue: Word);
+ procedure SetMapFile(const AValue: string);
+ procedure SetStaIdxFile(const AValue: string);
+ procedure SetStaticsFile(const AValue: string);
+ procedure SetWidth(const AValue: Word);
+ public
+ property MapFile: string read FMapFile write SetMapFile;
+ property StaticsFile: string read FStaticsFile write SetStaticsFile;
+ property StaIdxFile: string read FStaIdxFile write SetStaIdxFile;
+ property Width: Word read FWidth write SetWidth;
+ property Height: Word read FHeight write SetHeight;
+ end;
+
+ { TConfig }
+
+ TConfig = class(TObject, ISerializable, IInvalidate)
+ constructor Create(AFilename: string);
+ constructor Init(AFilename: string);
+ destructor Destroy; override;
+ procedure Serialize(AElement: TDOMElement);
+ protected
+ FFilename: string;
+ FPort: Integer;
+ FMap: TMapInfo;
+ FTiledata: string;
+ FRadarcol: string;
+ FAccounts: TAccountList;
+ FChanged: Boolean;
+ procedure SetPort(const AValue: Integer);
+ procedure SetRadarcol(const AValue: string);
+ procedure SetTiledata(const AValue: string);
+ public
+ property Port: Integer read FPort write SetPort;
+ property Map: TMapInfo read FMap;
+ property Tiledata: string read FTiledata write SetTiledata;
+ property Radarcol: string read FRadarcol write SetRadarcol;
+ property Accounts: TAccountList read FAccounts;
+ procedure Flush;
+ procedure Invalidate;
+ end;
+
+var
+ AppDir: string;
+ ConfigFile: string;
+ Config: TConfig;
+
+function TimeStamp: string;
+
+implementation
+
+const
+ CONFIGVERSION = 3;
+
+function QueryPassword: String;
+var
+ pwChar: char;
+begin
+ Result := '';
+
+ InitKeyboard;
+ try
+ repeat
+ pwChar := GetKeyEventChar(TranslateKeyEvent(GetKeyEvent));
+ case pwChar of
+ #8: Result := Copy(Result, 1, Length(Result) - 1);
+ #13: break;
+ else
+ Result := Result + pwChar;
+ end;
+ until pwChar = #13;
+ finally
+ DoneKeyboard;
+ end;
+ writeln('');
+end;
+
+function TimeStamp: string;
+begin
+ Result := '[' + DateTimeToStr(Now) + '] ';
+end;
+
+{ TMapInfo }
+
+constructor TMapInfo.Create(AOwner: IInvalidate);
+begin
+ inherited Create;
+ FOwner := AOwner;
+end;
+
+constructor TMapInfo.Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
+begin
+ Create(AOwner);
+ FMapFile := TXmlHelper.ReadString(AElement, 'Map', 'map0.mul');
+ FStaIdxFile := TXmlHelper.ReadString(AElement, 'StaIdx', 'staidx0.mul');
+ FStaticsFile := TXmlHelper.ReadString(AElement, 'Statics', 'statics0.mul');
+ FWidth := TXmlHelper.ReadInteger(AElement, 'Width', 768);
+ FHeight := TXmlHelper.ReadInteger(AElement, 'Height', 512);
+end;
+
+procedure TMapInfo.Serialize(AElement: TDOMElement);
+begin
+ TXmlHelper.WriteString(AElement, 'Map', FMapFile);
+ TXmlHelper.WriteString(AElement, 'StaIdx', FStaIdxFile);
+ TXmlHelper.WriteString(AElement, 'Statics', FStaticsFile);
+ TXmlHelper.WriteInteger(AElement, 'Width', FWidth);
+ TXmlHelper.WriteInteger(AElement, 'Height', FHeight);
+end;
+
+procedure TMapInfo.SetHeight(const AValue: Word);
+begin
+ FHeight := AValue;
+ FOwner.Invalidate;
+end;
+
+procedure TMapInfo.SetMapFile(const AValue: string);
+begin
+ FMapFile := AValue;
+ FOwner.Invalidate;
+end;
+
+procedure TMapInfo.SetStaIdxFile(const AValue: string);
+begin
+ FStaIdxFile := AValue;
+ FOwner.Invalidate;
+end;
+
+procedure TMapInfo.SetStaticsFile(const AValue: string);
+begin
+ FStaticsFile := AValue;
+ FOwner.Invalidate;
+end;
+
+procedure TMapInfo.SetWidth(const AValue: Word);
+begin
+ FWidth := AValue;
+ FOwner.Invalidate;
+end;
+
+{ TConfig }
+
+constructor TConfig.Create(AFilename: string);
+var
+ xmlDoc: TXMLDocument;
+ version: Integer;
+ xmlElement: TDOMElement;
+begin
+ inherited Create;
+ FFilename := AFilename;
+ ReadXMLFile(xmlDoc, AFilename);
+ if not ((xmlDoc.DocumentElement.NodeName = 'CEDConfig') and
+ TryStrToInt(xmlDoc.DocumentElement.AttribStrings['Version'], version) and
+ (version = CONFIGVERSION)) then
+ raise TInvalidConfigVersionExeption.Create(Format('%d <> %d', [version, CONFIGVERSION]));
+
+ FPort := TXmlHelper.ReadInteger(xmlDoc.DocumentElement, 'Port', 2597);
+
+ xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Map'));
+ if not assigned(xmlElement) then
+ raise TInvalidConfigVersionExeption.Create('Map information not found');
+ FMap := TMapInfo.Deserialize(Self, xmlElement);
+
+ FTiledata := TXmlHelper.ReadString(xmlDoc.DocumentElement, 'Tiledata', 'tiledata.mul');
+ FRadarcol := TXmlHelper.ReadString(xmlDoc.DocumentElement, 'Radarcol', 'radarcol.mul');
+
+ xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Accounts'));
+ if not assigned(xmlElement) then
+ raise TInvalidConfigVersionExeption.Create('Account information not found');
+ FAccounts := TAccountList.Deserialize(Self, xmlElement);
+
+ xmlDoc.Free;
+
+ FChanged := False;
+end;
+
+constructor TConfig.Init(AFilename: string);
+var
+ stringValue, password: string;
+ intValue: Integer;
+begin
+ inherited Create;
+ FFilename := AFilename;
+ FMap := TMapInfo.Create(Self);
+ FAccounts := TAccountList.Create(Self);
+
+ Writeln('Configuring Network');
+ Writeln('===================');
+ Write ('Port [2597]: ');
+ Readln (stringValue);
+ if not TryStrToInt(stringValue, intValue) then intValue := 2597;
+ FPort := intValue;
+ Writeln('');
+
+ Writeln('Configuring Paths');
+ Writeln('=================');
+ Write ('map [map0.mul]: ');
+ Readln (FMap.MapFile);
+ if FMap.MapFile = '' then FMap.MapFile := 'map0.mul';
+ Write ('statics [statics0.mul]: ');
+ Readln (FMap.StaticsFile);
+ if FMap.StaticsFile = '' then FMap.StaticsFile := 'statics0.mul';
+ Write ('staidx [staidx0.mul]: ');
+ Readln (FMap.StaIdxFile);
+ if FMap.StaIdxFile = '' then FMap.StaIdxFile := 'staidx0.mul';
+ Write ('tiledata [tiledata.mul]: ');
+ Readln (FTiledata);
+ if FTiledata = '' then FTiledata := 'tiledata.mul';
+ Write ('radarcol [radarcol.mul]: ');
+ Readln (FRadarcol);
+ if FRadarcol = '' then FRadarcol := 'radarcol.mul';
+ Writeln('');
+
+ Writeln('Parameters');
+ Writeln('==========');
+ Write ('Map width [768]: ');
+ Readln (stringValue);
+ if not TryStrToInt(stringValue, intValue) then intValue := 768;
+ FMap.Width := intValue;
+ Write ('Map height [512]: ');
+ Readln (stringValue);
+ if not TryStrToInt(stringValue, intValue) then intValue := 512;
+ FMap.Height := intValue;
+ Writeln('');
+
+ Writeln('Admin account');
+ Writeln('=============');
+ repeat
+ Write('Account name: ');
+ Readln(stringValue);
+ until stringValue <> '';
+ Write ('Password [hidden]: ');
+ password := QueryPassword;
+ FAccounts.Add(TAccount.Create(FAccounts, stringValue,
+ MD5Print(MD5String(password)), alAdministrator));
+
+ FChanged := True;
+end;
+
+destructor TConfig.Destroy;
+begin
+ if Assigned(FMap) then FreeAndNil(FMap);
+ if Assigned(FAccounts) then FreeAndNil(FAccounts);
+ inherited Destroy;
+end;
+
+procedure TConfig.Serialize(AElement: TDOMElement);
+begin
+ TXmlHelper.WriteInteger(AElement, 'Port', FPort);
+ FMap.Serialize(TXmlHelper.AssureElement(AElement, 'Map'));
+ TXmlHelper.WriteString(AElement, 'Tiledata', FTiledata);
+ TXmlHelper.WriteString(AElement, 'Radarcol', FRadarcol);
+ FAccounts.Serialize(TXmlHelper.AssureElement(AElement, 'Accounts'));
+end;
+
+procedure TConfig.SetPort(const AValue: Integer);
+begin
+ FPort := AValue;
+ Invalidate;
+end;
+
+procedure TConfig.SetRadarcol(const AValue: string);
+begin
+ FRadarcol := AValue;
+ Invalidate;
+end;
+
+procedure TConfig.SetTiledata(const AValue: string);
+begin
+ FTiledata := AValue;
+ Invalidate;
+end;
+
+procedure TConfig.Flush;
+var
+ xmlDoc: TXMLDocument;
+begin
+ if FChanged then
+ begin
+ xmlDoc := TXMLDocument.Create;
+ xmlDoc.AppendChild(xmlDoc.CreateElement('CEDConfig'));
+ xmlDoc.DocumentElement.AttribStrings['Version'] := IntToStr(CONFIGVERSION);
+ Serialize(xmlDoc.DocumentElement);
+ WriteXMLFile(xmlDoc, FFilename);
+ xmlDoc.Free;
+ FChanged := False;
+ end;
+end;
+
+procedure TConfig.Invalidate;
+begin
+ FChanged := True;
+end;
+
+initialization
+begin
+ AppDir := ExtractFilePath(ParamStr(0));
+ if AppDir[Length(AppDir)] <> PathDelim then
+ AppDir := AppDir + PathDelim;
+
+ {TODO : add command line parameter to specify the config}
+ Config := nil;
+ ConfigFile := ChangeFileExt(ParamStr(0), '.xml');
+end;
+
+end.
+
diff --git a/Server/UConnectionHandling.pas b/Server/UConnectionHandling.pas
index 580a0f3..5845fb9 100644
--- a/Server/UConnectionHandling.pas
+++ b/Server/UConnectionHandling.pas
@@ -1,195 +1,198 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-unit UConnectionHandling;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
- UEnhancedMemoryStream, UEnums;
-
-type
-
- { TProtocolVersion }
-
- TProtocolVersionPacket = class(TPacket)
- constructor Create(AVersion: Cardinal);
- end;
-
- { TLoginResponsePacket }
-
- TLoginResponsePacket = class(TPacket)
- constructor Create(AState: TLoginState; AAccessLevel: TAccessLevel = alNone);
- end;
-
- { TServerStatePacket }
-
- TServerStatePacket = class(TPacket)
- constructor Create(AState: TServerState; AMessage: string = '');
- end;
-
-procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-
-var
- ConnectionPacketHandlers: array[0..$FF] of TPacketHandler;
-
-implementation
-
-uses
- md5, UCEDServer, UClientHandling, UPackets;
-
-procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-var
- packetHandler: TPacketHandler;
-begin
- packetHandler := ConnectionPacketHandlers[ABuffer.ReadByte];
- if packetHandler <> nil then
- packetHandler.Process(ABuffer, ANetState);
-end;
-
-procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream;
- ANetState: TNetState);
-var
- username, passwordHash: string;
- account: TAccount;
- pwHash: string;
- netState: TNetState;
- invalid: Boolean;
-begin
- username := ABuffer.ReadStringNull;
- passwordHash := MD5Print(MD5String(ABuffer.ReadStringNull));
- account := Accounts.Find(username);
- if account <> nil then
- begin
- if account.AccessLevel > alNone then
- begin
- if account.PasswordHash = passwordHash then
- begin
- invalid := False;
- CEDServerInstance.TCPServer.IterReset;
- if CEDServerInstance.TCPServer.Iterator <> nil then
- begin
- repeat
- netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
- if (netState <> nil) and (netState.Account = account) then
- begin
- CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsAlreadyLoggedIn));
- CEDServerInstance.Disconnect(ANetState.Socket);
- invalid := True;
- Break;
- end;
- until not CEDServerInstance.TCPServer.IterNext;
- end;
-
- if not invalid then
- begin
- Writeln(TimeStamp, 'Login (', username, '): ', ANetState.Socket.PeerAddress);
- ANetState.Account := account;
- CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsOK, account.AccessLevel));
- CEDServerInstance.SendPacket(ANetState, TCompressedPacket.Create(
- TClientListPacket.Create(ANetState)));
- CEDServerInstance.SendPacket(nil, TClientConnectedPacket.Create(username));
- CEDServerInstance.SendPacket(ANetState, TSetClientPosPacket.Create(account.LastPos));
- end;
- end else
- begin
- CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidPassword));
- CEDServerInstance.Disconnect(ANetState.Socket);
- end;
- end else
- begin
- CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsNoAccess));
- CEDServerInstance.Disconnect(ANetState.Socket);
- end;
- end else
- begin
- CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidUser));
- CEDServerInstance.Disconnect(ANetState.Socket);
- end;
-end;
-
-procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
-begin
- CEDServerInstance.Disconnect(ANetState.Socket);
-end;
-
-{ TProtocolVersionPacket }
-
-constructor TProtocolVersionPacket.Create(AVersion: Cardinal);
-begin
- inherited Create($02, 0);
- FStream.WriteByte($01);
- FStream.WriteCardinal(AVersion);
-end;
-
-{ TLoginResponsePacket }
-
-constructor TLoginResponsePacket.Create(AState: TLoginState;
- AAccessLevel: TAccessLevel = alNone);
-begin
- inherited Create($02, 0);
- FStream.WriteByte($03);
- FStream.WriteByte(Byte(AState));
- if AState = lsOK then
- begin
- FStream.WriteByte(Byte(AAccessLevel));
- FStream.WriteWord(Config.ReadInteger('Parameters', 'Width', 768));
- FStream.WriteWord(Config.ReadInteger('Parameters', 'Height', 512));
- end;
-end;
-
-{ TServerStatePacket }
-
-constructor TServerStatePacket.Create(AState: TServerState; AMessage: string = '');
-begin
- inherited Create($02, 0);
- FStream.WriteByte($04);
- FStream.WriteByte(Byte(AState));
- if AState = ssOther then
- FStream.WriteStringNull(AMessage);
-end;
-
-{$WARNINGS OFF}
-var
- i: Integer;
-
-initialization
- for i := 0 to $FF do
- ConnectionPacketHandlers[i] := nil;
- ConnectionPacketHandlers[$03] := TPacketHandler.Create(0, @OnLoginRequestPacket);
- ConnectionPacketHandlers[$05] := TPacketHandler.Create(0, @OnQuitPacket);
-finalization
- for i := 0 to $FF do
- if ConnectionPacketHandlers[i] <> nil then
- ConnectionPacketHandlers[i].Free;
-{$WARNINGS ON}
-
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2008 Andreas Schneider
+ *)
+unit UConnectionHandling;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, UPacket, UPacketHandlers, UConfig, UAccount, UNetState,
+ UEnhancedMemoryStream, UEnums;
+
+type
+
+ { TProtocolVersion }
+
+ TProtocolVersionPacket = class(TPacket)
+ constructor Create(AVersion: Cardinal);
+ end;
+
+ { TLoginResponsePacket }
+
+ TLoginResponsePacket = class(TPacket)
+ constructor Create(AState: TLoginState; AAccessLevel: TAccessLevel = alNone);
+ end;
+
+ { TServerStatePacket }
+
+ TServerStatePacket = class(TPacket)
+ constructor Create(AState: TServerState; AMessage: string = '');
+ end;
+
+procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+
+var
+ ConnectionPacketHandlers: array[0..$FF] of TPacketHandler;
+
+implementation
+
+uses
+ md5, UCEDServer, UClientHandling, UPackets;
+
+procedure OnConnectionHandlerPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+var
+ packetHandler: TPacketHandler;
+begin
+ packetHandler := ConnectionPacketHandlers[ABuffer.ReadByte];
+ if packetHandler <> nil then
+ packetHandler.Process(ABuffer, ANetState);
+end;
+
+procedure OnLoginRequestPacket(ABuffer: TEnhancedMemoryStream;
+ ANetState: TNetState);
+var
+ username, passwordHash: string;
+ account: TAccount;
+ pwHash: string;
+ netState: TNetState;
+ invalid: Boolean;
+begin
+ username := ABuffer.ReadStringNull;
+ passwordHash := MD5Print(MD5String(ABuffer.ReadStringNull));
+ account := Config.Accounts.Find(username);
+ if account <> nil then
+ begin
+ if account.AccessLevel > alNone then
+ begin
+ if account.PasswordHash = passwordHash then
+ begin
+ invalid := False;
+ CEDServerInstance.TCPServer.IterReset;
+ if CEDServerInstance.TCPServer.Iterator <> nil then
+ begin
+ repeat
+ netState := TNetState(CEDServerInstance.TCPServer.Iterator.UserData);
+ if (netState <> nil) and (netState.Account = account) then
+ begin
+ CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsAlreadyLoggedIn));
+ CEDServerInstance.Disconnect(ANetState.Socket);
+ invalid := True;
+ Break;
+ end;
+ until not CEDServerInstance.TCPServer.IterNext;
+ end;
+
+ if not invalid then
+ begin
+ Writeln(TimeStamp, 'Login (', username, '): ', ANetState.Socket.PeerAddress);
+ ANetState.Account := account;
+ CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsOK, account.AccessLevel));
+ CEDServerInstance.SendPacket(ANetState, TCompressedPacket.Create(
+ TClientListPacket.Create(ANetState)));
+ CEDServerInstance.SendPacket(nil, TClientConnectedPacket.Create(username));
+ CEDServerInstance.SendPacket(ANetState, TSetClientPosPacket.Create(account.LastPos));
+ end;
+ end else
+ begin
+ Writeln(TimeStamp, 'Invalid password for ', username);
+ CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidPassword));
+ CEDServerInstance.Disconnect(ANetState.Socket);
+ end;
+ end else
+ begin
+ Writeln(TimeStamp, 'Access denied for ', username);
+ CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsNoAccess));
+ CEDServerInstance.Disconnect(ANetState.Socket);
+ end;
+ end else
+ begin
+ Writeln(TimeStamp, 'Invalid account specified: ', ANetState.Socket.PeerAddress);
+ CEDServerInstance.SendPacket(ANetState, TLoginResponsePacket.Create(lsInvalidUser));
+ CEDServerInstance.Disconnect(ANetState.Socket);
+ end;
+end;
+
+procedure OnQuitPacket(ABuffer: TEnhancedMemoryStream; ANetState: TNetState);
+begin
+ CEDServerInstance.Disconnect(ANetState.Socket);
+end;
+
+{ TProtocolVersionPacket }
+
+constructor TProtocolVersionPacket.Create(AVersion: Cardinal);
+begin
+ inherited Create($02, 0);
+ FStream.WriteByte($01);
+ FStream.WriteCardinal(AVersion);
+end;
+
+{ TLoginResponsePacket }
+
+constructor TLoginResponsePacket.Create(AState: TLoginState;
+ AAccessLevel: TAccessLevel = alNone);
+begin
+ inherited Create($02, 0);
+ FStream.WriteByte($03);
+ FStream.WriteByte(Byte(AState));
+ if AState = lsOK then
+ begin
+ FStream.WriteByte(Byte(AAccessLevel));
+ FStream.WriteWord(Config.Map.Width);
+ FStream.WriteWord(Config.Map.Height);
+ end;
+end;
+
+{ TServerStatePacket }
+
+constructor TServerStatePacket.Create(AState: TServerState; AMessage: string = '');
+begin
+ inherited Create($02, 0);
+ FStream.WriteByte($04);
+ FStream.WriteByte(Byte(AState));
+ if AState = ssOther then
+ FStream.WriteStringNull(AMessage);
+end;
+
+{$WARNINGS OFF}
+var
+ i: Integer;
+
+initialization
+ for i := 0 to $FF do
+ ConnectionPacketHandlers[i] := nil;
+ ConnectionPacketHandlers[$03] := TPacketHandler.Create(0, @OnLoginRequestPacket);
+ ConnectionPacketHandlers[$05] := TPacketHandler.Create(0, @OnQuitPacket);
+finalization
+ for i := 0 to $FF do
+ if ConnectionPacketHandlers[i] <> nil then
+ ConnectionPacketHandlers[i].Free;
+{$WARNINGS ON}
+
+end.
+
diff --git a/Server/ULandscape.pas b/Server/ULandscape.pas
index 2a8b593..5b7062d 100644
--- a/Server/ULandscape.pas
+++ b/Server/ULandscape.pas
@@ -30,7 +30,7 @@ unit ULandscape;
interface
uses
- SysUtils, Classes, contnrs, UGenericIndex, UMap, UStatics, UTileData,
+ SysUtils, Classes, contnrs, UGenericIndex, UMap, UStatics, UTiledata,
UWorldItem, UMulBlock, math,
UTileDataProvider, URadarMap,
UListSort, UCacheManager, ULinkedList, UBufferedStreams,
diff --git a/Server/cedserver.lpi b/Server/cedserver.lpi
index 1c6eabe..73aecba 100644
--- a/Server/cedserver.lpi
+++ b/Server/cedserver.lpi
@@ -14,7 +14,6 @@
-
@@ -29,7 +28,7 @@
-
+
@@ -70,6 +69,11 @@
+
+
+
+
+
@@ -89,7 +93,7 @@
-
+
diff --git a/Server/cedserver.lpr b/Server/cedserver.lpr
index 2889d79..1562d89 100644
--- a/Server/cedserver.lpr
+++ b/Server/cedserver.lpr
@@ -1,75 +1,73 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-program cedserver;
-
-{$mode objfpc}{$H+}
-
-uses
- {$IFDEF UNIX}{$IFDEF UseCThreads}
- cthreads,
- {$ENDIF}{$ENDIF}
- SysUtils, Classes,
- lnetbase,
- UConfig, UCEDServer, URadarMap, ULargeScaleOperations;
-
-{$I version.inc}
-
-begin
- Writeln('UO CentrED Server Version ', ProductVersion);
- Writeln('Copyright ', Copyright);
- //Writeln('================================');
- Writeln('');
-
- {$IFDEF Windows}
- if not LoadConfig then
- begin
- InitConfig;
- Writeln('');
- end;
- {$ELSE}
- if ParamStr(1) = '--init' then
- begin
- InitConfig;
- Halt;
- end;
-
- if not LoadConfig then
- begin
- Writeln('No valid config file was found. Use --init to create one.');
- Halt;
- end;
- {$ENDIF}
-
- Write(TimeStamp, 'Initializing ... ');
- Randomize;
- CEDServerInstance := TCEDServer.Create;
- Writeln('Done');
- CEDServerInstance.Run;
- Write(TimeStamp, 'Terminating ... ');
- CEDServerInstance.Free;
- Writeln('Done');
-end.
-
+(*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * http://www.opensource.org/licenses/cddl1.php.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * http://www.opensource.org/licenses/cddl1.php. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2008 Andreas Schneider
+ *)
+program cedserver;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ SysUtils, Classes,
+ lnetbase,
+ UConfig, UCEDServer, URadarMap, ULargeScaleOperations;
+
+{$I version.inc}
+
+begin
+ Writeln('UO CentrED Server Version ', ProductVersion);
+ Writeln('Copyright ', Copyright);
+ //Writeln('================================');
+ Writeln('');
+
+ {$IFDEF Windows}
+ if FileExists(ConfigFile) then
+ Config := TConfig.Create(ConfigFile)
+ else
+ Config := TConfig.Init(ConfigFile);
+ {$ELSE}
+ if ParamStr(1) = '--init' then
+ Config := TConfig.Init(ConfigFile)
+ else if FileExists(ConfigFile) then
+ Config := TConfig.Create(ConfigFile)
+ else begin
+ Writeln('No valid config file was found. Use --init to create one.');
+ Halt;
+ end;
+ {$ENDIF}
+
+ Write(TimeStamp, 'Initializing ... ');
+ Randomize;
+ CEDServerInstance := TCEDServer.Create;
+ Writeln('Done');
+ CEDServerInstance.Run;
+ Write(TimeStamp, 'Terminating ... ');
+ FreeAndNil(CEDServerInstance);
+ Config.Flush;
+ FreeAndNil(Config);
+ Writeln('Done');
+end.
+
diff --git a/UIStream.pas b/UIStream.pas
deleted file mode 100644
index e38bc74..0000000
--- a/UIStream.pas
+++ /dev/null
@@ -1,75 +0,0 @@
-(*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * http://www.opensource.org/licenses/cddl1.php.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * http://www.opensource.org/licenses/cddl1.php. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying * information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Portions Copyright 2007 Andreas Schneider
- *)
-
-{This unit contains the interface for objects which offer read/write access and
-therefore streaming capability.
-
-@author(Andreas Schneider )
-@created(2007-07-08)
-@lastmod(2007-11-14)}
-unit UIStream;
-
-{$mode objfpc}{$H+}
-{$interfaces corba}
-
-interface
-
-uses
- Classes;
-
-type
- {@abstract(The @name interface is used in objects which offer read/write access and
- therefore streaming capability.)}
- IStream = interface
- function ReadBoolean: Boolean; // = class(TObject{, IStream})
{@abstract(@name implements @link(IStream) and offers a bunch of functions to
ease reading and writing special types (like @link(Integer)s or @link(String)s.))}
- TStreamWrapper = class(TObject, IStream)
+ TStreamWrapper = class(TObject)
constructor Create(AStream: TStreamType; AOwnsStream: Boolean = True); //