Skip to content

Commit caf15c4

Browse files
committed
Refactor output of movement into protobuf based
1 parent 852fea1 commit caf15c4

File tree

7 files changed

+259
-151
lines changed

7 files changed

+259
-151
lines changed

Diff for: WowPacketParser.Proto/PacketStructures/structures.proto

+1-11
Original file line numberDiff line numberDiff line change
@@ -344,15 +344,6 @@ enum UniversalSplineFlag {
344344
Steering = 0x40000000;
345345
}
346346

347-
enum CreatureMovementFlags {
348-
NormalPathfinding = 0; // pathfinding
349-
ExactPath = 1; // sent fully
350-
ExactPathFlying = 2; // sent fully + flying flag
351-
ExactPathFlyingCyclic = 3; // sent fully + flying flag + cyclic flag
352-
ExactPathAndJump = 4; // sent fully + parabolic movement at the end
353-
CombatMovement = 100;
354-
}
355-
356347
message PacketMonsterMove {
357348
UniversalGuid mover = 1;
358349
Vec3 position = 2;
@@ -371,8 +362,7 @@ message PacketMonsterMove {
371362
repeated Vec3 points = 13;
372363
repeated Vec3 packedPoints = 14;
373364
optional SplineJump jump = 15;
374-
optional CreatureMovementFlags creatureMovementFlags = 16;
375-
bool creationSpline = 17;
365+
bool creationSpline = 16;
376366
}
377367

378368
message SplineJump {

Diff for: WowPacketParser/PacketStructures/ProtoExtensions.cs

+96
Original file line numberDiff line numberDiff line change
@@ -256,5 +256,101 @@ public static CreateObjectType ToCreateObjectType(this UpdateTypeCataclysm updat
256256
return CreateObjectType.Spawn;
257257
throw new ArgumentOutOfRangeException();
258258
}
259+
260+
public static ObjectType ToObjectType(this UniversalHighGuid highGuid)
261+
{
262+
switch (highGuid)
263+
{
264+
case UniversalHighGuid.Player:
265+
return ObjectType.Player;
266+
case UniversalHighGuid.DynamicObject:
267+
return ObjectType.DynamicObject;
268+
case UniversalHighGuid.Item:
269+
return ObjectType.Item;
270+
case UniversalHighGuid.GameObject:
271+
case UniversalHighGuid.Transport:
272+
return ObjectType.GameObject;
273+
case UniversalHighGuid.Vehicle:
274+
case UniversalHighGuid.Creature:
275+
case UniversalHighGuid.Pet:
276+
return ObjectType.Unit;
277+
case UniversalHighGuid.AreaTrigger:
278+
return ObjectType.AreaTrigger;
279+
default:
280+
return ObjectType.Object;
281+
}
282+
}
283+
284+
public static string ToWowParserString(this UniversalGuid guid)
285+
{
286+
if (guid.KindCase == UniversalGuid.KindOneofCase.Guid128 && (guid.Guid128.High != 0 || guid.Guid128.Low != 0))
287+
{
288+
var guid128 = new WowGuid128(guid.Guid128.Low, guid.Guid128.High);
289+
return guid128.ToString();
290+
}
291+
else if (guid.KindCase == UniversalGuid.KindOneofCase.Guid64 && (guid.Guid64.High != 0 || guid.Guid64.Low != 0))
292+
{
293+
var guid64 = new WowGuid64(guid.Guid64.Low);
294+
return guid64.ToString();
295+
}
296+
297+
return "Full: 0x0";
298+
}
299+
300+
public static uint GetLow(this UniversalGuid guid)
301+
{
302+
if (guid.KindCase == UniversalGuid.KindOneofCase.Guid128)
303+
return (uint)(guid.Guid128.Low & 0xFFFFFFFFFF);
304+
else if (guid.KindCase == UniversalGuid.KindOneofCase.Guid64)
305+
{
306+
switch (guid.Type)
307+
{
308+
case UniversalHighGuid.Player:
309+
case UniversalHighGuid.DynamicObject:
310+
case UniversalHighGuid.RaidGroup:
311+
case UniversalHighGuid.Item:
312+
return (uint)(guid.Guid64.Low & 0x000FFFFFFFFFFFFF);
313+
case UniversalHighGuid.GameObject:
314+
case UniversalHighGuid.Transport:
315+
//case HighGuidType.MOTransport: ??
316+
case UniversalHighGuid.Vehicle:
317+
case UniversalHighGuid.Creature:
318+
case UniversalHighGuid.Pet:
319+
return (uint)(guid.Guid64.Low & 0x00000000FFFFFFFFul);
320+
}
321+
322+
return (uint)(guid.Guid64.Low & 0x00000000FFFFFFFFul);
323+
}
324+
325+
return 0;
326+
}
327+
328+
public static uint GetEntry(this UniversalGuid128 guid)
329+
{
330+
return (uint)((guid.High >> 6) & 0x7FFFFF);
331+
}
332+
333+
public static byte GetSubType(this UniversalGuid128 guid) => (byte)(guid.High & 0x3F);
334+
335+
public static ushort GetRealmId(this UniversalGuid128 guid) => (ushort)((guid.High >> 42) & 0x1FFF);
336+
337+
public static uint GetServerId(this UniversalGuid128 guid) => (uint)((guid.Low >> 40) & 0xFFFFFF);
338+
339+
public static ushort GetMapId(this UniversalGuid128 guid) => (ushort)((guid.High >> 29) & 0x1FFF);
340+
341+
public static bool HasEntry(this UniversalGuid guid)
342+
{
343+
switch (guid.Type)
344+
{
345+
case UniversalHighGuid.Creature:
346+
case UniversalHighGuid.GameObject:
347+
case UniversalHighGuid.Pet:
348+
case UniversalHighGuid.Vehicle:
349+
case UniversalHighGuid.AreaTrigger:
350+
return true;
351+
default:
352+
return false;
353+
}
354+
}
259355
}
260356
}

Diff for: WowPacketParser/SQL/Builders/Movement.cs

+155-81
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,189 @@
1-
using System;
2-
using WowPacketParser.Enums;
1+
using WowPacketParser.Enums;
32
using WowPacketParser.Misc;
4-
using WowPacketParser.Store;
5-
using WowPacketParser.SQL;
6-
using System.Linq;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
using WowPacketParser.Parsing.Proto;
6+
using WowPacketParser.Proto;
7+
using WowPacketParser.PacketStructures;
8+
using System.IO;
9+
using Org.BouncyCastle.Crypto.Digests;
710

811
namespace WowPacketParser.SQL.Builders
912
{
10-
[BuilderClass]
11-
public static class Movement
13+
[ProtoBuilderClass]
14+
public class Movement : BaseProtoQueryBuilder
1215
{
13-
[BuilderMethod]
14-
public static string MovementData()
16+
private struct Waypoint
1517
{
16-
if (!Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_movement))
17-
return string.Empty;
18+
public Vec3 Position { get; init; }
19+
public float Orientation { get; init; }
20+
public bool Point { get; init; }
21+
}
1822

19-
string output = "SET @MOVID = 0;\n";
20-
int pathIdCounter = 0;
21-
if (Settings.TargetedProject == TargetedProject.Cmangos)
22-
{
23-
string nodeSql = "INSERT INTO waypoint_path (PathId, Point, PositionX, PositionY, PositionZ, Orientation, WaitTime, ScriptId, Comment) VALUES\n";
24-
foreach (var data in Storage.CreatureMovement.ToList())
25-
{
26-
var creatureMovement = data.Item1;
27-
if (creatureMovement.Waypoints.Count == 0)
28-
continue;
23+
public enum PathType
24+
{
25+
None = 0, // pathfinding
26+
ExactPath = 1, // sent fully
27+
ExactPathFlying = 2, // sent fully + flying flag
28+
ExactPathFlyingCyclic = 3, // sent fully + flying flag + cyclic flag
29+
ExactPathAndJump = 4, // sent fully + parabolic movement at the end
30+
Invalid = 100,
31+
}
2932

30-
string creatureName = SQLUtil.EscapeString(StoreGetters.GetName(Utilities.ObjectTypeToStore(creatureMovement.GUID.GetObjectType()), (int)creatureMovement.GUID.GetEntry()));
31-
output += "-- " + $"GUID: {creatureMovement.GUID} PathType: {creatureMovement.Type}" + "\n" + $"INSERT INTO waypoint_path_name(PathId, Name) VALUES(@MOVID + {pathIdCounter},'{creatureName}');\n" + nodeSql;
33+
private class AggregatedPaths
34+
{
35+
public List<Path> Paths { get; set; } = new();
36+
public int PointCount { get; set; } = 0;
37+
}
3238

33-
int pointIdCounter = 1;
34-
int actualPoint = 1;
35-
foreach (var node in creatureMovement.Waypoints)
36-
{
37-
bool finalP = creatureMovement.Destination == null && creatureMovement.Waypoints.Count == actualPoint;
38-
++actualPoint;
39-
float ori = finalP ? (creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f) : 100f;
40-
if (node.Point == false)
41-
{
42-
if (Settings.SkipIntermediatePoints == true)
43-
continue;
44-
output += "-- ";
45-
}
39+
private class Path
40+
{
41+
public List<Waypoint> Waypoints { get; init; }
42+
public PathType Type { get; init; }
43+
}
4644

47-
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{ori}', '0', '0', NULL)";
48-
49-
if (!finalP)
50-
output += ",\n";
51-
else
52-
output += ";\n\n";
53-
54-
++pointIdCounter;
55-
}
45+
private Dictionary<UniversalGuid, AggregatedPaths> pathsPerGuid = new();
5646

57-
if (creatureMovement.Destination != null)
58-
{
59-
float ori = creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f;
60-
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{creatureMovement.Destination.Position.X}', '{creatureMovement.Destination.Position.Y}', '{creatureMovement.Destination.Position.Z}', '{ori}', '0', '0', NULL);\n";
61-
}
47+
public override bool IsEnabled() => Settings.SQLOutputFlag.HasAnyFlagBit(SQLOutput.creature_movement) &&
48+
Settings.TargetedProject is TargetedProject.Cmangos or TargetedProject.TrinityCore;
6249

63-
++pathIdCounter;
64-
}
50+
private PathType GetMovementType(PacketMonsterMove packet)
51+
{
52+
PathType flags = PathType.None;
53+
if (packet.Flags.HasFlag(UniversalSplineFlag.EnterCycle) || packet.Flags.HasFlag(UniversalSplineFlag.Cyclic))
54+
flags = PathType.ExactPathFlyingCyclic;
55+
else if (packet.Flags.HasFlag(UniversalSplineFlag.Flying))
56+
flags = PathType.ExactPathFlying;
57+
else if (packet.Flags.HasFlag(UniversalSplineFlag.UncompressedPath))
58+
flags = PathType.ExactPath;
59+
else if (packet.LookTarget != null)
60+
flags = PathType.Invalid;
61+
else if (packet.Jump != null && packet.Jump.StartTime > 0)
62+
flags = PathType.ExactPathAndJump;
63+
return flags;
64+
}
65+
66+
protected override VoidType Process(PacketBase basePacket, PacketMonsterMove packet)
67+
{
68+
if (packet.PackedPoints.Count == 0 && packet.Points.Count == 0)
69+
return default;
70+
71+
var movementType = GetMovementType(packet);
72+
if (movementType == PathType.Invalid)
73+
return default;
74+
75+
Path path = new Path()
76+
{
77+
Waypoints = new List<Waypoint>(),
78+
Type = movementType
79+
};
80+
81+
for (var index = 0; index < packet.PackedPoints.Count; index++)
82+
{
83+
var node = packet.PackedPoints[index];
84+
bool finalP = packet.Destination == null && packet.PackedPoints.Count - 1 != index;
85+
path.Waypoints.Add(new Waypoint()
86+
{
87+
Position = node,
88+
Orientation = 100,
89+
Point = false
90+
});
91+
}
92+
93+
for (var index = 0; index < packet.Points.Count; index++)
94+
{
95+
var node = packet.Points[index];
96+
path.Waypoints.Add(new Waypoint()
97+
{
98+
Position = node,
99+
Orientation = 100,
100+
Point = true
101+
});
65102
}
66-
else if (Settings.TargetedProject == TargetedProject.TrinityCore)
103+
104+
bool dest = false;
105+
if (packet.Destination != null && !(packet.Destination.X == 0 && packet.Destination.Y == 0 && packet.Destination.Z == 0))
67106
{
68-
string nodeSql = "INSERT INTO waypoint_path_node (PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay) VALUES\n";
69-
foreach (var data in Storage.CreatureMovement.ToList())
107+
float ori = packet.HasLookOrientation ? packet.LookOrientation : 100f;
108+
path.Waypoints.Add(new Waypoint()
70109
{
71-
var creatureMovement = data.Item1;
72-
if (creatureMovement.Waypoints.Count == 0)
73-
continue;
110+
Position = packet.Destination,
111+
Orientation = ori,
112+
Point = true
113+
});
114+
dest = true;
115+
}
74116

75-
string commentInformation = $"GUID: {creatureMovement.GUID} PathType: {creatureMovement.Type}";
76-
output += "-- " + commentInformation + "\n";
77-
output += nodeSql;
117+
if (!pathsPerGuid.TryGetValue(packet.Mover, out var pathList))
118+
{
119+
pathList = new AggregatedPaths();
120+
pathsPerGuid.Add(packet.Mover, pathList);
121+
}
122+
pathList.Paths.Add(path);
123+
if (Settings.SkipIntermediatePoints == true)
124+
pathList.PointCount += packet.Points.Count + (dest ? 1 : 0);
125+
else
126+
pathList.PointCount += path.Waypoints.Count;
78127

79-
int pointIdCounter = 1;
80-
int actualPoint = 1;
81-
foreach (var node in creatureMovement.Waypoints)
128+
return default;
129+
}
130+
131+
protected override string GenerateQuery()
132+
{
133+
StringBuilder output = new();
134+
output.AppendLine("SET @MOVID = 0;");
135+
int pathIdCounter = 0;
136+
foreach (var (mover, paths) in pathsPerGuid)
137+
{
138+
string commentInformation = $"GUID: {mover.ToWowParserString()}";
139+
output.AppendLine("-- " + commentInformation);
140+
if (Settings.TargetedProject == TargetedProject.Cmangos)
141+
{
142+
output.AppendLine($"INSERT INTO waypoint_path_name(PathId, Name) VALUES(@MOVID + {pathIdCounter},'{SQLUtil.EscapeString(StoreGetters.GetName(Utilities.ObjectTypeToStore(mover.Type.ToObjectType()), (int)mover.Entry))}');");
143+
output.AppendLine("INSERT INTO waypoint_path (PathId, Point, PositionX, PositionY, PositionZ, Orientation, WaitTime, ScriptId, Comment) VALUES");
144+
}
145+
else if (Settings.TargetedProject == TargetedProject.TrinityCore)
146+
{
147+
output.AppendLine("INSERT INTO waypoint_path_node (PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay) VALUES");
148+
}
149+
int pointIdCounter = 1;
150+
foreach (var path in paths.Paths)
151+
{
152+
foreach (var node in path.Waypoints)
82153
{
83-
bool finalP = creatureMovement.Destination == null && creatureMovement.Waypoints.Count == actualPoint;
84-
++actualPoint;
85-
float ori = finalP ? (creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f) : 100f;
86154
if (node.Point == false)
87155
{
88156
if (Settings.SkipIntermediatePoints == true)
89157
continue;
90-
output += "-- ";
158+
output.Append("-- ");
91159
}
92-
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{ori}')";
93160

94-
if (!finalP)
95-
output += ",\n";
161+
var isLast = pointIdCounter == paths.PointCount;
162+
if (Settings.TargetedProject == TargetedProject.Cmangos)
163+
output.Append($"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{node.Orientation}', '0', '0', NULL)");
164+
else if (Settings.TargetedProject == TargetedProject.TrinityCore)
165+
output.Append($"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{node.Position.X}', '{node.Position.Y}', '{node.Position.Z}', '{node.Orientation}')");
166+
167+
if (!isLast)
168+
output.Append(",");
96169
else
97-
output += ";\n\n";
170+
output.Append(";");
98171

99-
++pointIdCounter;
100-
}
172+
if (pointIdCounter == 1)
173+
output.Append($" -- PathType: {path.Type}");
101174

102-
if (creatureMovement.Destination != null)
103-
{
104-
float ori = creatureMovement.FinalOrientation != null ? creatureMovement.FinalOrientation.Value : 100f;
105-
output += $"(@MOVID + {pathIdCounter}, '{pointIdCounter}', '{creatureMovement.Destination.Position.X}', '{creatureMovement.Destination.Position.Y}', '{creatureMovement.Destination.Position.Z}', '{ori}', '0', '0', NULL);\n\n";
175+
if (isLast)
176+
output.AppendLine();
177+
178+
++pointIdCounter;
106179
}
107180

108-
++pathIdCounter;
181+
output.AppendLine();
109182
}
110-
}
111183

112-
return output;
184+
++pathIdCounter;
185+
}
186+
return output.ToString();
113187
}
114188
}
115189
}

0 commit comments

Comments
 (0)