Fixed crashes and errors when loading into world.

This commit is contained in:
hondacrx
2022-06-21 14:56:22 -04:00
parent be8e18450e
commit 63cbd18350
12 changed files with 79 additions and 31 deletions
+2 -2
View File
@@ -47,7 +47,7 @@ namespace Game.AI
SmartEscortState _escortState; SmartEscortState _escortState;
uint _escortNPCFlags; uint _escortNPCFlags;
uint _escortInvokerCheckTimer; uint _escortInvokerCheckTimer;
WaypointPath _path; WaypointPath _path = new();
uint _currentWaypointNode; uint _currentWaypointNode;
bool _waypointReached; bool _waypointReached;
uint _waypointPauseTimer; uint _waypointPauseTimer;
@@ -132,7 +132,6 @@ namespace Game.AI
return false; return false;
} }
_path = new WaypointPath();
_path.id = path.id; _path.id = path.id;
_path.nodes.AddRange(path.nodes); _path.nodes.AddRange(path.nodes);
foreach (WaypointNode waypoint in _path.nodes) foreach (WaypointNode waypoint in _path.nodes)
@@ -802,6 +801,7 @@ namespace Game.AI
{ {
me.SetWalk(!run); me.SetWalk(!run);
_run = run; _run = run;
foreach (var node in _path.nodes) foreach (var node in _path.nodes)
node.moveType = run ? WaypointMoveType.Run : WaypointMoveType.Walk; node.moveType = run ? WaypointMoveType.Run : WaypointMoveType.Walk;
} }
@@ -2435,7 +2435,7 @@ namespace Game.AI
} }
} }
public class SmartScriptHolder : IComparer<SmartScriptHolder> public class SmartScriptHolder : IComparable<SmartScriptHolder>
{ {
public const uint DefaultPriority = uint.MaxValue; public const uint DefaultPriority = uint.MaxValue;
@@ -2478,17 +2478,17 @@ namespace Game.AI
return $"Entry {EntryOrGuid} SourceType {GetScriptType()} Event {EventId} Action {GetActionType()}"; return $"Entry {EntryOrGuid} SourceType {GetScriptType()} Event {EventId} Action {GetActionType()}";
} }
public int Compare(SmartScriptHolder left, SmartScriptHolder right) public int CompareTo(SmartScriptHolder other)
{ {
int result = left.Priority.CompareTo(right.Priority); int result = Priority.CompareTo(other.Priority);
if (result == 0) if (result == 0)
result = left.EntryOrGuid.CompareTo(right.EntryOrGuid); result = EntryOrGuid.CompareTo(other.EntryOrGuid);
if (result == 0) if (result == 0)
result = left.SourceType.CompareTo(right.SourceType); result = SourceType.CompareTo(other.SourceType);
if (result == 0) if (result == 0)
result = left.EventId.CompareTo(right.EventId); result = EventId.CompareTo(other.EventId);
if (result == 0) if (result == 0)
result = left.Link.CompareTo(right.Link); result = Link.CompareTo(other.Link);
return result; return result;
} }
+1 -1
View File
@@ -370,7 +370,7 @@ namespace Game.DataStorage
foreach (var entry in TaxiPathNodeStorage.Values) foreach (var entry in TaxiPathNodeStorage.Values)
TaxiPathNodesByPath[entry.PathID][entry.NodeIndex] = entry; TaxiPathNodesByPath[entry.PathID][entry.NodeIndex] = entry;
var taxiMaskSize = TaxiNodesStorage.GetNumRows() + 1; var taxiMaskSize = ((TaxiNodesStorage.GetNumRows() - 1) / 8) + 1;
TaxiNodesMask = new byte[taxiMaskSize]; TaxiNodesMask = new byte[taxiMaskSize];
OldContinentsNodesMask = new byte[taxiMaskSize]; OldContinentsNodesMask = new byte[taxiMaskSize];
HordeTaxiNodesMask = new byte[taxiMaskSize]; HordeTaxiNodesMask = new byte[taxiMaskSize];
@@ -3559,7 +3559,7 @@ namespace Game.Entities
uint _stateChangeProgress; uint _stateChangeProgress;
List<uint> _stopFrames = new(); List<uint> _stopFrames = new();
bool _autoCycleBetweenStopFrames; bool _autoCycleBetweenStopFrames;
TimeTracker _positionUpdateTimer; TimeTracker _positionUpdateTimer = new();
List<WorldObject> _passengers = new(); List<WorldObject> _passengers = new();
static TimeSpan PositionUpdateInterval = TimeSpan.FromMilliseconds(50); static TimeSpan PositionUpdateInterval = TimeSpan.FromMilliseconds(50);
@@ -382,7 +382,7 @@ namespace Game.Entities
public void ClearChangesMask<U>(OptionalUpdateField<U> updateField) where U : new() public void ClearChangesMask<U>(OptionalUpdateField<U> updateField) where U : new()
{ {
if (typeof(IHasChangesMask).IsAssignableFrom(typeof(U))) if (typeof(IHasChangesMask).IsAssignableFrom(typeof(U)) && updateField.HasValue())
((IHasChangesMask)updateField._value).ClearChangesMask(); ((IHasChangesMask)updateField._value).ClearChangesMask();
} }
+2 -2
View File
@@ -2981,9 +2981,9 @@ namespace Game.Entities
public bool IsPermanentWorldObject() { return m_isWorldObject; } public bool IsPermanentWorldObject() { return m_isWorldObject; }
public ITransport GetTransport() { return m_transport; } public ITransport GetTransport() { return m_transport; }
public T GetTransport<T>() where T : ITransport public T GetTransport<T>() where T : class, ITransport
{ {
return (T)m_transport; return m_transport as T;
} }
public float GetTransOffsetX() { return m_movementInfo.transport.pos.GetPositionX(); } public float GetTransOffsetX() { return m_movementInfo.transport.pos.GetPositionX(); }
public float GetTransOffsetY() { return m_movementInfo.transport.pos.GetPositionY(); } public float GetTransOffsetY() { return m_movementInfo.transport.pos.GetPositionY(); }
@@ -33,6 +33,8 @@ namespace Game.Entities
public void InitTaxiNodesForLevel(Race race, Class chrClass, uint level) public void InitTaxiNodesForLevel(Race race, Class chrClass, uint level)
{ {
m_taximask = new byte[((CliDB.TaxiNodesStorage.GetNumRows() - 1) / 8) + 1];
// class specific initial known nodes // class specific initial known nodes
if (chrClass == Class.Deathknight) if (chrClass == Class.Deathknight)
{ {
@@ -105,6 +107,8 @@ namespace Game.Entities
public void LoadTaxiMask(string data) public void LoadTaxiMask(string data)
{ {
m_taximask = new byte[((CliDB.TaxiNodesStorage.GetNumRows() - 1) / 8) + 1];
var split = new StringArray(data, ' '); var split = new StringArray(data, ' ');
int index = 0; int index = 0;
+5 -5
View File
@@ -127,11 +127,11 @@ namespace Game
public static void ChooseCreatureFlags(CreatureTemplate cInfo, out ulong npcFlag, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, out uint dynamicFlags, CreatureData data = null) public static void ChooseCreatureFlags(CreatureTemplate cInfo, out ulong npcFlag, out uint unitFlags, out uint unitFlags2, out uint unitFlags3, out uint dynamicFlags, CreatureData data = null)
{ {
npcFlag = data?.npcflag != 0 ? data.npcflag : cInfo.Npcflag; npcFlag = data != null && data.npcflag != 0 ? data.npcflag : cInfo.Npcflag;
unitFlags = data?.unit_flags != 0 ? data.unit_flags : (uint)cInfo.UnitFlags; unitFlags = data != null && data.unit_flags != 0 ? data.unit_flags : (uint)cInfo.UnitFlags;
unitFlags2 = data?.unit_flags2 != 0 ? data.unit_flags2 : cInfo.UnitFlags2; unitFlags2 = data != null && data.unit_flags2 != 0 ? data.unit_flags2 : cInfo.UnitFlags2;
unitFlags3 = data?.unit_flags3 != 0 ? data.unit_flags3 : cInfo.UnitFlags3; unitFlags3 = data != null && data.unit_flags3 != 0 ? data.unit_flags3 : cInfo.UnitFlags3;
dynamicFlags = data?.dynamicflags != 0 ? data.dynamicflags : cInfo.DynamicFlags; dynamicFlags = data != null && data.dynamicflags != 0 ? data.dynamicflags : cInfo.DynamicFlags;
} }
public static ResponseCodes CheckPlayerName(string name, Locale locale, bool create = false) public static ResponseCodes CheckPlayerName(string name, Locale locale, bool create = false)
+12 -9
View File
@@ -212,7 +212,7 @@ namespace Game.Maps
for (; pauseItr < pauses.Count; ++pauseItr) for (; pauseItr < pauses.Count; ++pauseItr)
{ {
var pausePointIndex = pathPoints.IndexOf(pauses[pauseItr]); var pausePointIndex = pathPoints.IndexOf(pauses[pauseItr]);
if (pausePointIndex == -1) // last point is a "fake" spline point, its position can never be reached so transport cannot stop there if (pausePointIndex == pathPoints.Count - 1) // last point is a "fake" spline point, its position can never be reached so transport cannot stop there
break; break;
for (; eventItr < events.Count; ++eventItr) for (; eventItr < events.Count; ++eventItr)
@@ -254,10 +254,11 @@ namespace Game.Maps
movementTime = legTimeAccel(length1); movementTime = legTimeAccel(length1);
leg.Duration += movementTime; leg.Duration += movementTime;
var segment = leg.Segments[pauseItr]; TransportPathSegment segment = new();
segment.SegmentEndArrivalTimestamp = leg.Duration + delaySum; segment.SegmentEndArrivalTimestamp = leg.Duration + delaySum;
segment.Delay = pathPoints[pausePointIndex].Delay * Time.InMilliseconds; segment.Delay = pathPoints[pausePointIndex].Delay * Time.InMilliseconds;
segment.DistanceFromLegStartAtEnd = splineLengthToCurrentNode; segment.DistanceFromLegStartAtEnd = splineLengthToCurrentNode;
leg.Segments.Add(segment);
delaySum += pathPoints[pausePointIndex].Delay * Time.InMilliseconds; delaySum += pathPoints[pausePointIndex].Delay * Time.InMilliseconds;
splineLengthToPreviousNode = splineLengthToCurrentNode; splineLengthToPreviousNode = splineLengthToCurrentNode;
} }
@@ -304,10 +305,11 @@ namespace Game.Maps
leg.StartTimestamp = totalTime; leg.StartTimestamp = totalTime;
leg.Duration += splineTime + delaySum; leg.Duration += splineTime + delaySum;
var pauseSegment = leg.Segments[pauseItr]; TransportPathSegment pauseSegment = new();
pauseSegment.SegmentEndArrivalTimestamp = leg.Duration; pauseSegment.SegmentEndArrivalTimestamp = leg.Duration;
pauseSegment.Delay = 0; pauseSegment.Delay = 0;
pauseSegment.DistanceFromLegStartAtEnd = leg.Spline.Length(); pauseSegment.DistanceFromLegStartAtEnd = leg.Spline.Length();
leg.Segments.Add(pauseSegment);
totalTime += leg.Segments[pauseItr].SegmentEndArrivalTimestamp + leg.Segments[pauseItr].Delay; totalTime += leg.Segments[pauseItr].SegmentEndArrivalTimestamp + leg.Segments[pauseItr].Delay;
for (var i = 0; i < leg.Segments.Count; ++i) for (var i = 0; i < leg.Segments.Count; ++i)
@@ -378,13 +380,14 @@ namespace Game.Maps
public void AddPathNodeToTransport(uint transportEntry, uint timeSeg, TransportAnimationRecord node) public void AddPathNodeToTransport(uint transportEntry, uint timeSeg, TransportAnimationRecord node)
{ {
TransportAnimation animNode = new(); if (!_transportAnimations.ContainsKey(transportEntry))
_transportAnimations[transportEntry] = new();
TransportAnimation animNode = _transportAnimations[transportEntry];
if (animNode.TotalTime < timeSeg) if (animNode.TotalTime < timeSeg)
animNode.TotalTime = timeSeg; animNode.TotalTime = timeSeg;
animNode.Path[timeSeg] = node; animNode.Path[timeSeg] = node;
_transportAnimations[transportEntry] = animNode;
} }
public void AddPathRotationToTransport(uint transportEntry, uint timeSeg, TransportRotationRecord node) public void AddPathRotationToTransport(uint transportEntry, uint timeSeg, TransportRotationRecord node)
@@ -531,7 +534,7 @@ namespace Game.Maps
public List<TransportPathLeg> PathLegs = new(); public List<TransportPathLeg> PathLegs = new();
public List<TransportPathEvent> Events = new(); public List<TransportPathEvent> Events = new();
public List<uint> MapIds = new(); public HashSet<uint> MapIds = new();
public bool InInstance; public bool InInstance;
public Position ComputePosition(uint time, out TransportMovementState moveState, out int legIndex) public Position ComputePosition(uint time, out TransportMovementState moveState, out int legIndex)
@@ -708,10 +711,10 @@ namespace Game.Maps
return null; return null;
List<uint> lKeys = Path.Keys.ToList(); List<uint> lKeys = Path.Keys.ToList();
int reqIndex = lKeys.IndexOf(time) - 1; int reqIndex = lKeys.IndexOf(time);
if (reqIndex != -1) if (reqIndex != -1)
return Path[lKeys[reqIndex]]; return Path[lKeys[reqIndex - 1]];
return Path.LastOrDefault().Value; return Path.LastOrDefault().Value;
} }
@@ -1244,7 +1244,7 @@ namespace Game.Networking.Packets
public override void Read() public override void Read()
{ {
_worldPacket.WriteUInt32(Ticks); Ticks = _worldPacket.ReadUInt32();
} }
} }
+41
View File
@@ -268,6 +268,47 @@ namespace Game
} }
while (result.NextRow()); while (result.NextRow());
// Now check for circular reference
// All pool_ids are in pool_template
foreach (var (id, poolData) in mPoolTemplate)
{
List<uint> checkedPools = new();
var poolItr = mPoolSearchMap.LookupByKey(id);
while (poolItr != 0)
{
if (poolData.MapId != -1)
{
if (mPoolTemplate[poolItr].MapId == -1)
mPoolTemplate[poolItr].MapId = poolData.MapId;
if (mPoolTemplate[poolItr].MapId != poolData.MapId)
{
Log.outError(LogFilter.Sql, $"`pool_pool` has child pools on multiple maps in pool id ({poolItr}), skipped.");
mPoolPoolGroups[poolItr].RemoveOneRelation(id);
mPoolSearchMap.Remove(poolItr);
--count;
break;
}
}
checkedPools.Add(id);
if (checkedPools.Contains(poolItr))
{
string ss = "The pool(s) ";
foreach (var itr in checkedPools)
ss += $"{itr} ";
ss += $"create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool {id} and child pool {poolItr}";
Log.outError(LogFilter.Sql, ss);
mPoolPoolGroups[poolItr].RemoveOneRelation(id);
mPoolSearchMap.Remove(poolItr);
--count;
break;
}
poolItr = mPoolSearchMap.LookupByKey(poolItr);
}
}
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} pools in mother pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); Log.outInfo(LogFilter.ServerLoading, "Loaded {0} pools in mother pools in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
} }
} }
+1 -1
View File
@@ -90,7 +90,7 @@ namespace Game.Spells
case AuraType.Transform: case AuraType.Transform:
case AuraType.ModRoot2: case AuraType.ModRoot2:
m_canBeRecalculated = false; m_canBeRecalculated = false;
if (!m_spellInfo.ProcFlags) if (m_spellInfo.ProcFlags == null)
break; break;
amount = (int)(GetBase().GetUnitOwner().CountPctFromMaxHealth(10)); amount = (int)(GetBase().GetUnitOwner().CountPctFromMaxHealth(10));
break; break;