Skip to content

Commit 5934947

Browse files
committed
fix(982): expire dashes based on end time in case packets are delayed
1 parent 475bc73 commit 5934947

File tree

5 files changed

+129
-60
lines changed

5 files changed

+129
-60
lines changed

Intersect (Core)/Network/Packets/Server/EntityDashPacket.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ public EntityDashPacket()
1111
{
1212
}
1313

14-
public EntityDashPacket(Guid entityId, Guid endMapId, byte endX, byte endY, int dashTime, Direction direction)
14+
public EntityDashPacket(Guid entityId, Guid endMapId, int endX, int endY, long dashEndMilliseconds, int dashLengthMilliseconds, Direction direction)
1515
{
1616
EntityId = entityId;
1717
EndMapId = endMapId;
18-
EndX = endX;
19-
EndY = endY;
20-
DashTime = dashTime;
18+
EndX = (byte)endX;
19+
EndY = (byte)endY;
20+
DashEndMilliseconds = dashEndMilliseconds;
21+
DashLengthMilliseconds = dashLengthMilliseconds;
2122
Direction = direction;
2223
}
2324

@@ -34,9 +35,12 @@ public EntityDashPacket(Guid entityId, Guid endMapId, byte endX, byte endY, int
3435
public byte EndY { get; set; }
3536

3637
[Key(4)]
37-
public int DashTime { get; set; }
38+
public long DashEndMilliseconds { get; set; }
3839

3940
[Key(5)]
41+
public int DashLengthMilliseconds { get; set; }
42+
43+
[Key(6)]
4044
public Direction Direction { get; set; }
4145

4246
}
Lines changed: 69 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
using Intersect.Client.Framework.Entities;
22
using Intersect.Client.Maps;
3+
using Intersect.Core;
34
using Intersect.Enums;
45
using Intersect.Utilities;
6+
using Microsoft.Extensions.Logging;
57

68
namespace Intersect.Client.Entities;
79

810
public partial class Dash : IDash
911
{
1012
private readonly Direction mChangeDirection = Direction.None;
1113

12-
private readonly int mDashTime;
14+
private readonly long _serverDashEndMilliseconds;
15+
16+
private readonly long _dashLengthMilliseconds;
17+
18+
private long _dashEndMilliseconds;
1319

1420
private readonly Guid mEndMapId;
1521

@@ -31,75 +37,99 @@ public partial class Dash : IDash
3137

3238
public float OffsetY => GetYOffset();
3339

34-
public Dash(Guid endMapId, byte endX, byte endY, int dashTime, Direction changeDirection = Direction.None)
40+
public Dash(
41+
Guid endMapId,
42+
byte endX,
43+
byte endY,
44+
long dashEndMilliseconds,
45+
long dashLengthMilliseconds,
46+
Direction changeDirection = Direction.None
47+
)
3548
{
3649
mChangeDirection = changeDirection;
3750
mEndMapId = endMapId;
3851
mEndX = endX;
3952
mEndY = endY;
40-
mDashTime = dashTime;
53+
_serverDashEndMilliseconds = dashEndMilliseconds;
54+
_dashLengthMilliseconds = dashLengthMilliseconds;
4155
}
4256

43-
public void Start(Entity en)
57+
public void Start(Entity entity)
4458
{
45-
if (MapInstance.Get(en.MapId) == null ||
46-
MapInstance.Get(mEndMapId) == null ||
47-
mEndMapId == en.MapId && mEndX == en.X && mEndY == en.Y)
59+
var now = Timing.Global.Milliseconds;
60+
61+
if (_serverDashEndMilliseconds < now)
62+
{
63+
ApplicationContext.CurrentContext.Logger.LogDebug("Skipping already-expired dash");
64+
entity.Dashing = null;
65+
return;
66+
}
67+
68+
if (mEndMapId == entity.MapId && mEndX == entity.X && mEndY == entity.Y)
69+
{
70+
entity.Dashing = null;
71+
return;
72+
}
73+
74+
if (!MapInstance.TryGet(entity.MapId, out var currentMap) || !MapInstance.TryGet(mEndMapId, out var targetMap))
4875
{
49-
en.Dashing = null;
76+
entity.Dashing = null;
77+
return;
5078
}
51-
else
79+
80+
mStartTime = now;
81+
_dashEndMilliseconds = Math.Min(_serverDashEndMilliseconds, mStartTime + _dashLengthMilliseconds);
82+
83+
ApplicationContext.CurrentContext.Logger.LogDebug(
84+
"Starting dash that is {DashLength}ms long, and there are {RemainingTime}ms before it is completed on the server",
85+
_dashLengthMilliseconds,
86+
_serverDashEndMilliseconds - now
87+
);
88+
89+
mStartXCoord = entity.X;
90+
mStartYCoord = entity.Y;
91+
mEndXCoord = targetMap.X + mEndX * Options.Instance.Map.TileWidth - (currentMap.X + entity.X * Options.Instance.Map.TileWidth);
92+
mEndYCoord = targetMap.Y + mEndY * Options.Instance.Map.TileHeight - (currentMap.Y + entity.Y * Options.Instance.Map.TileHeight);
93+
if (mChangeDirection > Direction.None)
5294
{
53-
var startMap = MapInstance.Get(en.MapId);
54-
var endMap = MapInstance.Get(mEndMapId);
55-
mStartTime = Timing.Global.Milliseconds;
56-
mStartXCoord = en.OffsetX;
57-
mStartYCoord = en.OffsetY;
58-
mEndXCoord = endMap.X + mEndX * Options.Instance.Map.TileWidth - (startMap.X + en.X * Options.Instance.Map.TileWidth);
59-
mEndYCoord = endMap.Y + mEndY * Options.Instance.Map.TileHeight - (startMap.Y + en.Y * Options.Instance.Map.TileHeight);
60-
if (mChangeDirection > Direction.None)
61-
{
62-
en.Dir = mChangeDirection;
63-
}
95+
entity.Dir = mChangeDirection;
6496
}
6597
}
6698

6799
public float GetXOffset()
68100
{
69-
if (Timing.Global.Milliseconds > mStartTime + mDashTime)
101+
if (Timing.Global.Milliseconds > mStartTime + _dashLengthMilliseconds)
70102
{
71103
return mEndXCoord;
72104
}
73-
else
74-
{
75-
return (mEndXCoord - mStartXCoord) * ((Timing.Global.Milliseconds - mStartTime) / (float)mDashTime);
76-
}
105+
106+
return (mEndXCoord - mStartXCoord) * ((Timing.Global.Milliseconds - mStartTime) / (float)_dashLengthMilliseconds);
77107
}
78108

79109
public float GetYOffset()
80110
{
81-
if (Timing.Global.Milliseconds > mStartTime + mDashTime)
111+
if (Timing.Global.Milliseconds > mStartTime + _dashLengthMilliseconds)
82112
{
83113
return mEndYCoord;
84114
}
85-
else
86-
{
87-
return (mEndYCoord - mStartYCoord) * ((Timing.Global.Milliseconds - mStartTime) / (float)mDashTime);
88-
}
115+
116+
return (mEndYCoord - mStartYCoord) * ((Timing.Global.Milliseconds - mStartTime) / (float)_dashLengthMilliseconds);
89117
}
90118

91-
public bool Update(Entity en)
119+
public bool Update(Entity entity)
92120
{
93-
if (Timing.Global.Milliseconds > mStartTime + mDashTime)
121+
if (Timing.Global.Milliseconds <= _dashEndMilliseconds)
94122
{
95-
en.Dashing = null;
96-
en.OffsetX = 0;
97-
en.OffsetY = 0;
98-
en.MapId = mEndMapId;
99-
en.X = mEndX;
100-
en.Y = mEndY;
123+
return entity.Dashing != null;
101124
}
102125

103-
return en.Dashing != null;
126+
ApplicationContext.CurrentContext.Logger.LogDebug("Dash finished");
127+
entity.Dashing = null;
128+
entity.OffsetX = 0;
129+
entity.OffsetY = 0;
130+
entity.MapId = mEndMapId;
131+
entity.X = mEndX;
132+
entity.Y = mEndY;
133+
return false;
104134
}
105135
}

Intersect.Client.Core/Networking/PacketHandler.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,16 +1838,21 @@ public void HandlePacket(IPacketSender packetSender, GameObjectPacket packet)
18381838
//EntityDashPacket
18391839
public void HandlePacket(IPacketSender packetSender, EntityDashPacket packet)
18401840
{
1841-
if (Globals.Entities.ContainsKey(packet.EntityId))
1841+
if (!Globals.Entities.TryGetValue(packet.EntityId, out var value))
18421842
{
1843-
Globals.Entities[packet.EntityId]
1844-
.DashQueue.Enqueue(
1845-
new Dash(
1846-
packet.EndMapId, packet.EndX, packet.EndY,
1847-
packet.DashTime, packet.Direction
1848-
)
1849-
);
1843+
return;
18501844
}
1845+
1846+
value.DashQueue.Enqueue(
1847+
new Dash(
1848+
packet.EndMapId,
1849+
packet.EndX,
1850+
packet.EndY,
1851+
packet.DashEndMilliseconds,
1852+
packet.DashLengthMilliseconds,
1853+
packet.Direction
1854+
)
1855+
);
18511856
}
18521857

18531858
//MapGridPacket

Intersect.Server.Core/Entities/Combat/Dash.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public partial class Dash
1717
public int Range;
1818

1919
public Dash(
20-
Entity en,
20+
Entity entity,
2121
int range,
2222
Direction direction,
2323
bool blockPass = false,
@@ -27,20 +27,30 @@ public Dash(
2727
)
2828
{
2929
Direction = direction;
30-
Facing = en.Dir;
30+
Facing = entity.Dir;
3131

32-
CalculateRange(en, range, blockPass, activeResourcePass, deadResourcePass, zdimensionPass);
32+
CalculateRange(entity, range, blockPass, activeResourcePass, deadResourcePass, zdimensionPass);
3333
if (Range <= 0)
3434
{
3535
return;
3636
} //Remove dash instance if no where to dash
3737

38+
var endX = entity.X;
39+
var endY = entity.Y;
40+
41+
var dashLengthMilliseconds = (int)(Options.Instance.Combat.MaxDashSpeed);// * (Range / 10f));
42+
var dashEndMilliseconds = Timing.Global.Milliseconds + dashLengthMilliseconds;
43+
entity.MoveTimer = dashEndMilliseconds;
44+
3845
PacketSender.SendEntityDash(
39-
en, en.MapId, (byte) en.X, (byte) en.Y, (int) (Options.Instance.Combat.MaxDashSpeed * (Range / 10f)),
46+
entity,
47+
entity.MapId,
48+
endX,
49+
endY,
50+
dashEndMilliseconds,
51+
dashLengthMilliseconds,
4052
Direction == Facing ? Direction : Direction.None
4153
);
42-
43-
en.MoveTimer = Timing.Global.Milliseconds + Options.Instance.Combat.MaxDashSpeed;
4454
}
4555

4656
public void CalculateRange(

Intersect.Server.Core/Networking/PacketSender.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,9 +1922,29 @@ public static void SendOpenEditor(Client client, GameObjectType type)
19221922
}
19231923

19241924
//EntityDashPacket
1925-
public static void SendEntityDash(Entity en, Guid endMapId, byte endX, byte endY, int dashTime, Direction direction)
1925+
public static void SendEntityDash(
1926+
Entity en,
1927+
Guid endMapId,
1928+
int endX,
1929+
int endY,
1930+
long dashEndMilliseconds,
1931+
int dashLengthMilliseconds,
1932+
Direction direction
1933+
)
19261934
{
1927-
SendDataToProximityOnMapInstance(en.MapId, en.MapInstanceId, new EntityDashPacket(en.Id, endMapId, endX, endY, dashTime, direction));
1935+
SendDataToProximityOnMapInstance(
1936+
en.MapId,
1937+
en.MapInstanceId,
1938+
new EntityDashPacket(
1939+
en.Id,
1940+
endMapId,
1941+
endX,
1942+
endY,
1943+
dashEndMilliseconds,
1944+
dashLengthMilliseconds,
1945+
direction
1946+
)
1947+
);
19281948
}
19291949

19301950
/// <summary>

0 commit comments

Comments
 (0)