- Added client side visualization of area restrictions

- Added an icon to the "Region control" menu item
- Changed the former TAccessLevelChangedPacket and the TLoginResponsePacket to add informations about the writeable areas
- Changed OnModifyUserPacket to update clients according to new accesslevel/area restrictions
- Changed OnModifyRegionPacket to update clients using that particular region
- Fixed UPacketHandlers.ValidateAccess to check the region bounds according to the PtInRect function
This commit is contained in:
2008-08-26 22:48:48 +02:00
parent 91af86a294
commit 1c3d624949
10 changed files with 274 additions and 60 deletions

View File

@@ -31,7 +31,8 @@ interface
uses
Classes, SysUtils, LResources, Forms, Controls, Dialogs, lNetComponents, lNet,
UEnhancedMemoryStream, UPacket, UEnums, ExtCtrls, dateutils;
UEnhancedMemoryStream, UPacket, UEnums, ExtCtrls, dateutils, URectList,
LCLIntf;
type
@@ -56,6 +57,7 @@ type
FAccessLevel: TAccessLevel;
FDataDir: string;
FLastPacket: TDateTime;
FWriteMap: TRectList;
procedure OnCanSend(ASocket: TLSocket);
procedure OnConnectionHandlingPacket(ABuffer: TEnhancedMemoryStream);
procedure ProcessQueue;
@@ -63,9 +65,11 @@ type
public
property Username: string read FUsername;
property AccessLevel: TAccessLevel read FAccessLevel write FAccessLevel;
function CanWrite(AX, AY: Word): Boolean;
procedure Send(APacket: TPacket);
procedure Disconnect;
procedure CheckClose(ASender: TForm);
procedure UpdateWriteMap(AStream: TEnhancedMemoryStream);
end;
var
@@ -98,6 +102,7 @@ begin
if FSendQueue <> nil then FreeAndNil(FSendQueue);
if FReceiveQueue <> nil then FreeAndNil(FReceiveQueue);
if PacketHandlers[$02] <> nil then FreeAndNil(PacketHandlers[$02]);
if FWriteMap <> nil then FreeAndNil(FWriteMap);
end;
procedure TdmNetwork.TCPClientConnect(aSocket: TLSocket);
@@ -194,6 +199,12 @@ begin
width := ABuffer.ReadWord;
height := ABuffer.ReadWord;
ResMan.InitLandscape(width, height);
{FWriteMap := TBits.Create(ResMan.Landscape.CellWidth * ResMan.Landscape.CellHeight);
FWriteMap.XorBits(FWriteMap); //set all to 1}
FWriteMap := TRectList.Create;
UpdateWriteMap(ABuffer);
frmMain := TfrmMain.Create(dmNetwork);
frmRadarMap := TfrmRadarMap.Create(frmMain);
frmLargeScaleCommand := TfrmLargeScaleCommand.Create(frmMain);
@@ -309,6 +320,7 @@ begin
frmMain.ApplicationProperties1.OnIdle := nil;
FreeAndNil(frmMain);
end;
if FWriteMap <> nil then FreeAndNil(FWriteMap);
if GameResourceManager <> nil then FreeAndNil(GameResourceManager);
frmInitialize.Hide;
while frmLogin.ShowModal = mrOK do
@@ -328,6 +340,21 @@ begin
FreeAndNil(frmLogin);
end;
function TdmNetwork.CanWrite(AX, AY: Word): Boolean;
var
i: Integer;
pt: TPoint;
begin
if FWriteMap.Count = 0 then Exit(True); //TODO : still too slow
pt := Point(AX, AY);
for i := 0 to FWriteMap.Count - 1 do
if PtInRect(FWriteMap.Rects[i], pt) then
Exit(True);
Result := False;
end;
procedure TdmNetwork.Send(APacket: TPacket);
var
source: TEnhancedMemoryStream;
@@ -357,6 +384,23 @@ begin
end;
end;
procedure TdmNetwork.UpdateWriteMap(AStream: TEnhancedMemoryStream);
var
x1, y1, x2, y2: Word;
i, areaCount: Integer;
begin
FWriteMap.Clear;
areaCount := AStream.ReadWord;
for i := 0 to areaCount - 1 do
begin
x1 := AStream.ReadWord;
y1 := AStream.ReadWord;
x2 := AStream.ReadWord;
y2 := AStream.ReadWord;
FWriteMap.Add(x1, y1, x2, y2);
end;
end;
initialization
{$I UdmNetwork.lrs}

View File

@@ -1028,6 +1028,7 @@ object frmMain: TfrmMain
TreeOptions.MiscOptions = [toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
TreeOptions.PaintOptions = [toHideSelection, toShowButtons, toShowDropmark, toThemeAware, toUseBlendedImages]
OnClick = vstChatClick
OnFreeNode = vstChatFreeNode
OnGetText = vstChatGetText
OnPaintText = vstChatPaintText
Columns = <
@@ -1253,6 +1254,7 @@ object frmMain: TfrmMain
end
object mnuRegionControl: TMenuItem
Caption = '&Region Management'
ImageIndex = 19
OnClick = mnuRegionControlClick
end
object mnuLargeScaleCommands: TMenuItem
@@ -1309,7 +1311,7 @@ object frmMain: TfrmMain
left = 264
top = 32
Bitmap = {
4C69130000001000000010000000000000000000000000000000000000000000
4C69140000001000000010000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000D9A781FFD39E76FF00000000000000000000000000000000000000000000
0000000000000000000000000000ECBEA1FFE7BB9DFFE4B697FFE0B292FFDAAE
@@ -1917,7 +1919,39 @@ object frmMain: TfrmMain
000000000000000000FF000000FF000000FF000000FF00000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000FF000000FF0000000000000000000000000000
0000000000000000000000000000
0000000000000000000000000000536876FF5C6A5DFF5F6D60FF5F6D60FF5F6D
60FF5F6D60FF5F6D61FF5F6D61FF5F6D61FF5F6D61FF606D61FF606D62FF606D
62FF606D63FF5E6A5FFF454E46FF5C6A5DFFFBFCFBFFFCFEFCFFF7FCF8FFF7FC
F8FFF7FCF8FFF8FCF8FFF7FCF9FFF8FCF8FFF8FCF8FFECF7EEFFEDF7EEFFEFF6
EDFFEEF4ECFFEBF4EBFF5E6A5FFF5F6D60FFF7FCF8FF9DF9F9FF6CB4EDFF6271
FEFF80E7E9FF8CF4F4FF52CDCDFFECC2A4FFDDAD8AFFEBBA97FFDDA780FFE2AB
83FFDAA075FFD9EAD4FF616E64FF5F6D60FFF7FCF8FF8AEAEAFF72DDDEFF5665
F0FF569FDFFF73E8E8FF46C1C1FFBBBBA5FFD0A483FFDEB08EFFD19E7AFFD6A2
7AFFCF9871FFD7EBD5FF626E64FF5F6D61FFF7FCF8FF9FF9F9FF85E9EAFF84D3
FAFF525AF0FF87F2F7FF60DAD7FF98D5CAFFE0B79CFFEDC7A9FFE0B394FFE6B8
98FFDEAE8CFFD7ECD6FF636E64FF5F6D61FFF8FCF8FF90EAEAFF78DDDEFF81E9
EAFF4E6BE2FF639DEEFF5ED7D7FF5BCBC9FFD4B097FFE2BA9FFFA1ADA9FF58A5
D8FF85B1DBFF469DD0FF4E7C8CFF5F6D61FFF8FCF8FFA6F9F9FF8BE9EAFF99F8
FAFF78D3EBFF656BFFFF77DCEAFF70DFDEFFC1C5B5FFA8C8C8FF77BEE7FFB4D2
F0FFE5F3FFFFACD2EFFF4A89BEFF606D61FFF8FCF8FF9FF1F1FF81DDDFFF8AEA
EBFF75DEDEFF6591EEFF557EE2FF68DCDDFF5BBCC5FF80D5EDFFB2E3F9FF8BC0
E7FFAED3F6FFC4E0FCFF669DD0FF606D62FFF8FCF8FFAFFAFAFF94EBEBFFA2F9
FAFF8AEAEBFF95EDF3FF595FEBFF6BCFE5FF7CD4EEFFC4F6FDFF6CDDF6FF6DCA
EDFF63A3D7FF66A1D3FF617474FF606D63FFF8FCF8FFA4EBEDFF8DDFDFFF97EB
EBFF72CFB7FF74CA99FF4790BDFF79D3EEFFC7F7FDFF5FDCF5FF5BE2F7FF7AD6
F2FF4399DFFFB1D4D9FF646F66FF616E63FFF8FCF9FFBCFBFBFF9DE7DFFF93E1
BBFF77C997FF63BDAEFF77CBE7FFC7F7FDFF5EDCF5FF5AE1F7FF7BD4F1FF4395
DDFF589BC3FFD0E9DBFF646F66FF616E63FFF7FBF8FF9BDEC4FF73C393FF80CF
9FFF53AD9CFF73B9D5FFC2F6FDFF63DFF7FF5DE2F8FF79D3F0FF4395DAFF6CB8
A4FF74C38FFFD7EFDAFF646F66FF616E64FFECF7EEFF96DBAFFF7FC99AFF63AD
A5FF7AB6D5FF90B7D1FF55C9E4FF5BDFF5FF78D0EDFF4696D9FF76C1A1FF87D0
A0FF80CA9AFFD6EEDAFF646F66FF626E64FFEEF8EFFFA4DBBCFF8CCAA6FF4389
AAFFE0F2FFFF549AD8FF1A7ABEFF4998C5FF3B86BFFF6074E7FF81C5A3FF8CD0
A6FF85CAA0FFD2E9D7FF646F67FF5F6A60FFEBF5ECFFD4EDD7FFD4EED7FF2E67
84FF94C7F9FF91C9F9FF4185C9FF256BACFFB7D9D4FFD4E2ECFFCFE5D6FFD5ED
D9FFD8EFDCFFD5EDD9FF616C63FF454D47FF5F6A61FF636F64FF646F64FF143F
56FF295F86FF4988BCFF4A86A7FF5D7070FF646F66FF646F66FF646F67FF646F
67FF647067FF616C63FF474E48FF
}
end
object pmTileList: TPopupMenu

View File

@@ -247,6 +247,7 @@ type
Y: Integer);
procedure vdtTilesScroll(Sender: TBaseVirtualTree; DeltaX, DeltaY: Integer);
procedure vstChatClick(Sender: TObject);
procedure vstChatFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
procedure vstChatGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
procedure vstChatPaintText(Sender: TBaseVirtualTree;
@@ -283,6 +284,8 @@ type
procedure SetY(const AValue: Integer);
procedure SetCurrentTile(const AValue: TWorldItem);
procedure SetSelectedTile(const AValue: TWorldItem);
procedure SetNormalLights; inline;
procedure SetDarkLights; inline;
procedure InitRender;
procedure InitSize;
procedure Render;
@@ -1373,6 +1376,15 @@ begin
edChat.SetFocus;
end;
procedure TfrmMain.vstChatFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
chatInfo: PChatInfo;
begin
chatInfo := Sender.GetNodeData(Node);
chatInfo^.Sender := '';
chatInfo^.Msg := '';
end;
procedure TfrmMain.vstChatGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
@@ -1557,11 +1569,27 @@ begin
FSelectedTile.OnDestroy.RegisterEvent(@TileRemoved);
end;
procedure TfrmMain.SetNormalLights;
const
specular: TGLArrayf4 = (2, 2, 2, 1);
ambient: TGLArrayf4 = (1, 1, 1, 1);
begin
glLightfv(GL_LIGHT0, GL_AMBIENT, @specular);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @ambient);
end;
procedure TfrmMain.SetDarkLights;
const
specularDark: TGLArrayf4 = (0.5, 0.5, 0.5, 1);
ambientDark: TGLArrayf4 = (0.25, 0.25, 0.25, 1);
begin
glLightfv(GL_LIGHT0, GL_AMBIENT, @specularDark);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @ambientDark);
end;
procedure TfrmMain.InitRender;
const
lightPosition: TGLArrayf4 = (-1, -1, 0.5, 0);
specular: TGLArrayf4 = (2, 2, 2, 1);
ambient: TGLArrayf4 = (1, 1, 1, 1);
begin
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.1);
@@ -1574,8 +1602,6 @@ begin
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, @lightPosition);
glLightfv(GL_LIGHT0, GL_AMBIENT, @specular);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @ambient);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
end;
@@ -1612,6 +1638,8 @@ var
tileRect: TRect;
virtualTile: TVirtualTile;
staticsFilter: TStaticFilter;
editing: Boolean;
intensity: GLfloat;
procedure GetMapDrawOffset(x, y: Integer; out drawX, drawY: Single);
begin
@@ -1667,7 +1695,19 @@ begin
(CurrentTile <> SelectedTile) and
PtInRect(tileRect, Point(FX + offsetX, FY + offsetY));
if acDraw.Checked and (singleTarget or multiTarget) then
if acSelect.Checked or dmNetwork.CanWrite(FX + offsetX, FY + offsetY) then
begin
editing := True;
intensity := 1.0;
SetNormalLights;
end else
begin
editing := False;
intensity := 0.5;
SetDarkLights;
end;
if editing and acDraw.Checked and (singleTarget or multiTarget) then
begin
ghostTile := FGhostTile;
if (ghostTile is TMapCell) and (not frmDrawSettings.cbForceAltitude.Checked) then
@@ -1691,7 +1731,9 @@ begin
for i := 0 to draw.Count - 1 do
begin
if TObject(draw[i]) = virtualTile then
if not editing then
highlight := False
else if TObject(draw[i]) = virtualTile then
highlight := False
else if acDelete.Checked and multiTarget and (TObject(draw[i]) is TStaticItem) then
highlight := True
@@ -1715,8 +1757,8 @@ begin
z := 0
else
z := TWorldItem(draw[i]).Z;
glColor4f(1.0, 1.0, 1.0, 1.0);
glColor4f(intensity, intensity, intensity, 1.0);
if TObject(draw[i]) = virtualTile then
begin
@@ -1734,7 +1776,7 @@ begin
cell := TMapCell(draw[i]);
{if ResMan.Tiledata.LandTiles[cell.TileID].HasFlag(tdfTranslucent) then
glColor4f(1.0, 1.0, 1.0, 0.5);} //Possible, but probably not like the OSI client
glColor4f(intensity, intensity, intensity, 0.5);} //Possible, but probably not like the OSI client
mat := nil;
@@ -1773,6 +1815,7 @@ begin
(TObject(draw[i]) = ghostTile) then //when we have a ghosttile, only draw that, but still store the real one
begin
glBindTexture(GL_TEXTURE_2D, mat.Texture);
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glEnable(GL_LIGHTING);
normals := FLandscape.Normals[offsetX, offsetY];
@@ -1790,6 +1833,7 @@ begin
glNormal3f(normals[3].X, normals[3].Y, normals[3].Z);
glTexCoord2f(0, 1); glVertex2d(drawX - 22, drawY + 22 - west * 4);
glEnd;
//if (not cell.Selected) and (intensity = 1.0) then
if not cell.Selected then
glDisable(GL_LIGHTING);
end;
@@ -1814,7 +1858,7 @@ begin
hue := nil;
if staticTileData.HasFlag(tdfTranslucent) then
glColor4f(1.0, 1.0, 1.0, 0.5);
glColor4f(intensity, intensity, intensity, 0.5);
mat := FTextureManager.GetArtMaterial($4000 + staticItem.TileID, hue, (staticTileData.Flags and tdfPartialHue) = tdfPartialHue);
south := mat.RealHeight;
@@ -2090,6 +2134,7 @@ procedure TfrmMain.OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream);
var
sender, msg: string;
i: Integer;
accessLevel: TAccessLevel;
begin
case ABuffer.ReadByte of
$01: //client connected
@@ -2124,21 +2169,27 @@ begin
msg := ABuffer.ReadStringNull;
WriteChatMessage(sender, msg);
end;
$07: //access level changed
$07: //access changed
begin
dmNetwork.AccessLevel := TAccessLevel(ABuffer.ReadByte);
if dmNetwork.AccessLevel = alNone then
accessLevel := TAccessLevel(ABuffer.ReadByte);
dmNetwork.UpdateWriteMap(ABuffer);
if accessLevel <> dmNetwork.AccessLevel then
begin
MessageDlg('AccessLevel change', 'Your account has been locked.', mtWarning, [mbOK], 0);
mnuDisconnectClick(nil);
end else
begin
ProcessAccessLevel;
MessageDlg('AccessLevel change', Format('Your accesslevel has been changed to %s.', [GetAccessLevelString(dmNetwork.AccessLevel)]), mtWarning, [mbOK], 0);
dmNetwork.AccessLevel := accessLevel;
if accessLevel = alNone then
begin
MessageDlg('AccessLevel change', 'Your account has been locked.', mtWarning, [mbOK], 0);
mnuDisconnectClick(nil);
end else
begin
ProcessAccessLevel;
MessageDlg('AccessLevel change', Format('Your accesslevel has been changed to %s.', [GetAccessLevelString(accessLevel)]), mtWarning, [mbOK], 0);
end;
end;
for i := Low(FAccessChangedListeners) to High(FAccessChangedListeners) do
FAccessChangedListeners[i](dmNetwork.AccessLevel);
FAccessChangedListeners[i](accessLevel);
end;
end;
end;
@@ -2189,7 +2240,8 @@ end;
function TfrmMain.CanBeModified(ATile: TWorldItem): Boolean;
begin
Result := not (ATile is TVirtualTile);
Result := (not (ATile is TVirtualTile)) and
dmNetwork.CanWrite(ATile.X, ATile.Y);
end;
initialization

View File

@@ -122,7 +122,7 @@ implementation
uses
UGameResources, UfrmRadar, UfrmMain, UdmNetwork, UPacket, UGUIPlatformUtils,
UAdminHandling, UPacketHandlers, UConsts;
UAdminHandling, UPacketHandlers;
type
{ TModifyRegionPacket }