* Enhanced UXmlHelper (enumerator)

* Added UMapManagement
* Fixed TCPServer to allow address reuse
This commit is contained in:
Andreas Schneider 2013-11-23 20:41:20 +01:00
parent 1791fd7494
commit b9a45bf43b
5 changed files with 221 additions and 7 deletions

View File

@ -113,6 +113,7 @@ begin
Config.Map.StaIdxFile, Config.Tiledata, Config.Radarcol, Config.Map.Width, Config.Map.StaIdxFile, Config.Tiledata, Config.Radarcol, Config.Map.Width,
Config.Map.Height, FValid); Config.Map.Height, FValid);
FTCPServer := TLTcp.Create(nil); FTCPServer := TLTcp.Create(nil);
FTCPServer.ReuseAddress := True;
FTCPServer.OnAccept := @OnAccept; FTCPServer.OnAccept := @OnAccept;
FTCPServer.OnCanSend := @OnCanSend; FTCPServer.OnCanSend := @OnCanSend;
FTCPServer.OnDisconnect := @OnDisconnect; FTCPServer.OnDisconnect := @OnDisconnect;

View File

@ -31,7 +31,7 @@ interface
uses uses
Classes, SysUtils, DOM, XMLRead, XMLWrite, Keyboard, UAccount, UXmlHelper, Classes, SysUtils, DOM, XMLRead, XMLWrite, Keyboard, UAccount, UXmlHelper,
UInterfaces, UEnums, URegions; UInterfaces, UEnums, URegions, UMapManagement;
type type
@ -78,6 +78,7 @@ type
FRadarcol: string; FRadarcol: string;
FRegions: TRegionList; FRegions: TRegionList;
FAccounts: TAccountList; FAccounts: TAccountList;
FMapStates: TMapStates;
FChanged: Boolean; FChanged: Boolean;
procedure SetPort(const AValue: Integer); procedure SetPort(const AValue: Integer);
procedure SetRadarcol(const AValue: string); procedure SetRadarcol(const AValue: string);
@ -89,6 +90,7 @@ type
property Radarcol: string read FRadarcol write SetRadarcol; property Radarcol: string read FRadarcol write SetRadarcol;
property Regions: TRegionList read FRegions; property Regions: TRegionList read FRegions;
property Accounts: TAccountList read FAccounts; property Accounts: TAccountList read FAccounts;
property MapStates: TMapStates read FMapStates;
procedure Flush; procedure Flush;
procedure Invalidate; procedure Invalidate;
end; end;
@ -210,7 +212,7 @@ begin
FPort := TXmlHelper.ReadInteger(xmlDoc.DocumentElement, 'Port', 2597); FPort := TXmlHelper.ReadInteger(xmlDoc.DocumentElement, 'Port', 2597);
xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Map')); xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Map'));
if not assigned(xmlElement) then if not Assigned(xmlElement) then
raise TInvalidConfigException.Create('Map information not found'); raise TInvalidConfigException.Create('Map information not found');
FMap := TMapInfo.Deserialize(Self, xmlElement); FMap := TMapInfo.Deserialize(Self, xmlElement);
@ -218,16 +220,22 @@ begin
FRadarcol := TXmlHelper.ReadString(xmlDoc.DocumentElement, 'Radarcol', 'radarcol.mul'); FRadarcol := TXmlHelper.ReadString(xmlDoc.DocumentElement, 'Radarcol', 'radarcol.mul');
xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Regions')); xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Regions'));
if assigned(xmlElement) then if Assigned(xmlElement) then
FRegions := TRegionList.Deserialize(Self, xmlElement) FRegions := TRegionList.Deserialize(Self, xmlElement)
else else
Fregions := TRegionList.Create(Self); FRegions := TRegionList.Create(Self);
xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Accounts')); xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('Accounts'));
if not assigned(xmlElement) then if not Assigned(xmlElement) then
raise TInvalidConfigException.Create('Account information not found'); raise TInvalidConfigException.Create('Account information not found');
FAccounts := TAccountList.Deserialize(Self, xmlElement); FAccounts := TAccountList.Deserialize(Self, xmlElement);
xmlElement := TDOMElement(xmlDoc.DocumentElement.FindNode('MapStates'));
if Assigned(xmlElement) then
FMapStates := TMapStates.Deserialize(Self, xmlElement)
else
FMapStates := TMapStates.Create(Self);
xmlDoc.Free; xmlDoc.Free;
FChanged := False; FChanged := False;
@ -243,6 +251,7 @@ begin
FMap := TMapInfo.Create(Self); FMap := TMapInfo.Create(Self);
FAccounts := TAccountList.Create(Self); FAccounts := TAccountList.Create(Self);
FRegions := TRegionList.Create(Self); FRegions := TRegionList.Create(Self);
FMapStates := TMapStates.Create(Self);
Writeln('Configuring Network'); Writeln('Configuring Network');
Writeln('==================='); Writeln('===================');
@ -303,6 +312,7 @@ begin
if Assigned(FMap) then FreeAndNil(FMap); if Assigned(FMap) then FreeAndNil(FMap);
if Assigned(FAccounts) then FreeAndNil(FAccounts); if Assigned(FAccounts) then FreeAndNil(FAccounts);
if Assigned(FRegions) then FreeAndNil(FRegions); if Assigned(FRegions) then FreeAndNil(FRegions);
if Assigned(FMapStates) then FreeAndNil(FMapStates);
inherited Destroy; inherited Destroy;
end; end;
@ -314,6 +324,7 @@ begin
TXmlHelper.WriteString(AElement, 'Radarcol', FRadarcol); TXmlHelper.WriteString(AElement, 'Radarcol', FRadarcol);
FAccounts.Serialize(TXmlHelper.AssureElement(AElement, 'Accounts')); FAccounts.Serialize(TXmlHelper.AssureElement(AElement, 'Accounts'));
FRegions.Serialize(TXmlHelper.AssureElement(AElement, 'Regions')); FRegions.Serialize(TXmlHelper.AssureElement(AElement, 'Regions'));
FMapStates.Serialize(TXmlHelper.AssureElement(AElement, 'MapStates'));
end; end;
procedure TConfig.SetPort(const AValue: Integer); procedure TConfig.SetPort(const AValue: Integer);

153
Server/UMapManagement.pas Normal file
View File

@ -0,0 +1,153 @@
(*
* 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 2013 Andreas Schneider
*)
unit UMapManagement;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, UPacket, UInterfaces, UXmlHelper,
DOM, fgl;
type
{ TMapState }
TMapState = class(TObject, IInvalidate, ISerializable)
private
FOwner: IInvalidate;
FName: String;
FPath: String;
FDescription: String;
public
constructor Create(AOwner: IInvalidate);
constructor Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
procedure Invalidate;
procedure Serialize(AElement: TDOMElement);
end;
{ TMapStates }
TMapStates = class(specialize TFPGObjectList<TMapState>, IInvalidate,
ISerializable)
private
FOwner: IInvalidate;
public
constructor Create(AOwner: IInvalidate);
constructor Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
procedure Invalidate;
procedure Serialize(AElement: TDOMElement);
function Add(const Item: TMapState): Integer;
function Remove(const Item: TMapState): Integer;
end;
implementation
{ TMapState }
constructor TMapState.Create(AOwner: IInvalidate);
begin
inherited Create;
FOwner := AOwner;
end;
constructor TMapState.Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
begin
inherited Create;
FOwner := AOwner;
FName := TXmlHelper.ReadString(AElement, 'Name', '');
FPath := TXmlHelper.ReadString(AElement, 'Path', '');
FDescription := TXmlHelper.ReadString(AElement, 'Description', '');
end;
procedure TMapState.Invalidate;
begin
FOwner.Invalidate;
end;
procedure TMapState.Serialize(AElement: TDOMElement);
begin
TXmlHelper.WriteString(AElement, 'Name', FName);
TXmlHelper.WriteString(AElement, 'Path', FPath);
TXmlHelper.WriteString(AElement, 'Description', FDescription);
end;
{ TMapStates }
constructor TMapStates.Create(AOwner: IInvalidate);
begin
inherited Create(True);
FOwner := AOwner;
end;
constructor TMapStates.Deserialize(AOwner: IInvalidate; AElement: TDOMElement);
var
nodeList: TDOMNodeList;
node: TDOMNode;
begin
inherited Create(True);
FOwner := AOwner;
for node in AElement.ChildNodes do
begin
if node.NodeName = 'MapState' then
Add(TMapState.Deserialize(Self, TDOMElement(node)));
end;
end;
procedure TMapStates.Invalidate;
begin
FOwner.Invalidate;
end;
procedure TMapStates.Serialize(AElement: TDOMElement);
var
mapState: TMapState;
childElement: TDOMElement;
begin
for mapState in Self do
begin
childElement := AElement.OwnerDocument.CreateElement('MapState');
AElement.AppendChild(childElement);
mapState.Serialize(childElement);
end;
end;
function TMapStates.Add(const Item: TMapState): Integer;
begin
Result := inherited Add(Item);
Invalidate;
end;
function TMapStates.Remove(const Item: TMapState): Integer;
begin
Result := inherited Remove(Item);
Invalidate;
end;
end.

View File

@ -173,7 +173,7 @@
<PackageName Value="lnetbase"/> <PackageName Value="lnetbase"/>
</Item2> </Item2>
</RequiredPackages> </RequiredPackages>
<Units Count="16"> <Units Count="18">
<Unit0> <Unit0>
<Filename Value="cedserver.lpr"/> <Filename Value="cedserver.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -254,6 +254,16 @@
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="UMap"/> <UnitName Value="UMap"/>
</Unit15> </Unit15>
<Unit16>
<Filename Value="UMapManagement.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="UMapManagement"/>
</Unit16>
<Unit17>
<Filename Value="URegions.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="URegions"/>
</Unit17>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -25,7 +25,7 @@
*) *)
unit UXmlHelper; unit UXmlHelper;
{$mode delphi}{$H+} {$mode objfpc}{$H+}
interface interface
@ -49,8 +49,47 @@ type
class function ReadCoords(AParent: TDOMElement; AName: string; out X, Y: Integer): Boolean; class function ReadCoords(AParent: TDOMElement; AName: string; out X, Y: Integer): Boolean;
end; end;
{ TDOMNodeListEnumerator }
TDOMNodeListEnumerator = class
private
FNodeList: TDOMNodeList;
FIndex: Integer;
function GetCurrent: TDOMNode;
public
constructor Create(const ANodeList: TDOMNodeList);
function MoveNext: Boolean;
property Current: TDOMNode read GetCurrent;
end;
operator Enumerator(const ANodeList: TDOMNodeList): TDOMNodeListEnumerator;
implementation implementation
operator Enumerator(const ANodeList: TDOMNodeList): TDOMNodeListEnumerator;
begin
Result := TDOMNodeListEnumerator.Create(ANodeList);
end;
{ TDOMNodeListEnumerator }
function TDOMNodeListEnumerator.GetCurrent: TDOMNode;
begin
Result := FNodeList[FIndex];
end;
constructor TDOMNodeListEnumerator.Create(const ANodeList: TDOMNodeList);
begin
FNodeList := ANodeList;
FIndex := -1;
end;
function TDOMNodeListEnumerator.MoveNext: Boolean;
begin
Inc(FIndex);
Result := FIndex < FNodeList.Count;
end;
{ TXmlHelper } { TXmlHelper }
class function TXmlHelper.FindChild(AParent: TDOMElement; AName: string): TDOMElement; class function TXmlHelper.FindChild(AParent: TDOMElement; AName: string): TDOMElement;