Fix login
This commit is contained in:
@@ -883,7 +883,6 @@ namespace Framework.Constants
|
|||||||
WorldPortResponse = 0x350025,
|
WorldPortResponse = 0x350025,
|
||||||
WrapItem = 0x320000,
|
WrapItem = 0x320000,
|
||||||
|
|
||||||
Max = 0x5040,
|
|
||||||
Unknown = 0xbadd
|
Unknown = 0xbadd
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2100,7 +2099,6 @@ namespace Framework.Constants
|
|||||||
CompressedPacket = 0x3E000A,
|
CompressedPacket = 0x3E000A,
|
||||||
MultiplePackets = 0x3E0009,
|
MultiplePackets = 0x3E0009,
|
||||||
|
|
||||||
Max = 0x5040,
|
|
||||||
Unknown = 0xbadd,
|
Unknown = 0xbadd,
|
||||||
None = 0
|
None = 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ namespace Framework.Database
|
|||||||
fileName = @"/sql/base/characters_database.sql";
|
fileName = @"/sql/base/characters_database.sql";
|
||||||
break;
|
break;
|
||||||
case "WorldDatabase":
|
case "WorldDatabase":
|
||||||
fileName = @"/sql/TDB_full_world_1027.24051_2024_05_11.sql";
|
fileName = @"/sql/TDB_full_world_1102.24092_2024_09_23.sql";
|
||||||
break;
|
break;
|
||||||
case "HotfixDatabase":
|
case "HotfixDatabase":
|
||||||
fileName = @"/sql/TDB_full_hotfixes_1027.24051_2024_05_11.sql";
|
fileName = @"/sql/TDB_full_hotfixes_1102.24092_2024_09_23.sql";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace Framework.Database
|
|||||||
|
|
||||||
// AreaTable.db2
|
// AreaTable.db2
|
||||||
PrepareStatement(HotfixStatements.SEL_AREA_TABLE, "SELECT ID, ZoneName, AreaName, ContinentID, ParentAreaID, AreaBit, SoundProviderPref, " +
|
PrepareStatement(HotfixStatements.SEL_AREA_TABLE, "SELECT ID, ZoneName, AreaName, ContinentID, ParentAreaID, AreaBit, SoundProviderPref, " +
|
||||||
|
"SoundProviderPrefUnderwater, AmbienceID, UwAmbience, ZoneMusic, UwZoneMusic, IntroSound, UwIntroSound, FactionGroupMask, AmbientMultiplier, " +
|
||||||
"SoundProviderPrefUnderwater, AmbienceID, UwAmbience, ZoneMusic, UwZoneMusic, IntroSound, UwIntroSound, FactionGroupMask, AmbientMultiplier, " +
|
"SoundProviderPrefUnderwater, AmbienceID, UwAmbience, ZoneMusic, UwZoneMusic, IntroSound, UwIntroSound, FactionGroupMask, AmbientMultiplier, " +
|
||||||
"MountFlags, PvpCombatWorldStateID, WildBattlePetLevelMin, WildBattlePetLevelMax, WindSettingsID, ContentTuningID, Flags1, Flags2, " +
|
"MountFlags, PvpCombatWorldStateID, WildBattlePetLevelMin, WildBattlePetLevelMax, WindSettingsID, ContentTuningID, Flags1, Flags2, " +
|
||||||
"LiquidTypeID1, LiquidTypeID2, LiquidTypeID3, LiquidTypeID4 FROM area_table WHERE (`VerifiedBuild` > 0) = ?");
|
"LiquidTypeID1, LiquidTypeID2, LiquidTypeID3, LiquidTypeID4 FROM area_table WHERE (`VerifiedBuild` > 0) = ?");
|
||||||
@@ -782,7 +783,7 @@ namespace Framework.Database
|
|||||||
|
|
||||||
// ItemModifiedAppearance.db2
|
// ItemModifiedAppearance.db2
|
||||||
PrepareStatement(HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ID, ItemID, ItemAppearanceModifierID, ItemAppearanceID, OrderIndex, " +
|
PrepareStatement(HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ID, ItemID, ItemAppearanceModifierID, ItemAppearanceID, OrderIndex, " +
|
||||||
"TransmogSourceTypeEnum Flags, FROM item_modified_appearance WHERE (`VerifiedBuild` > 0) = ?");
|
"TransmogSourceTypeEnum, Flags FROM item_modified_appearance WHERE (`VerifiedBuild` > 0) = ?");
|
||||||
|
|
||||||
// ItemModifiedAppearanceExtra.db2
|
// ItemModifiedAppearanceExtra.db2
|
||||||
PrepareStatement(HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE_EXTRA, "SELECT ID, IconFileDataID, UnequippedIconFileDataID, SheatheType, " +
|
PrepareStatement(HotfixStatements.SEL_ITEM_MODIFIED_APPEARANCE_EXTRA, "SELECT ID, IconFileDataID, UnequippedIconFileDataID, SheatheType, " +
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ namespace Framework.ClientBuild
|
|||||||
build.HotfixVersion = hotfixVersion.ToCharArray();
|
build.HotfixVersion = hotfixVersion.ToCharArray();
|
||||||
|
|
||||||
build.Build = result.Read<uint>(4);
|
build.Build = result.Read<uint>(4);
|
||||||
|
|
||||||
|
_builds.Add(build);
|
||||||
}
|
}
|
||||||
while (result.NextRow());
|
while (result.NextRow());
|
||||||
}
|
}
|
||||||
@@ -169,11 +171,31 @@ namespace Framework.ClientBuild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClientBuildVariantId
|
public struct ClientBuildVariantId
|
||||||
{
|
{
|
||||||
public int Platform;
|
public int Platform;
|
||||||
public int Arch;
|
public int Arch;
|
||||||
public int Type;
|
public int Type;
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Platform.GetHashCode() ^ Arch.GetHashCode() ^ Type.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return this == (ClientBuildVariantId)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(ClientBuildVariantId left, ClientBuildVariantId right)
|
||||||
|
{
|
||||||
|
return left.Platform == right.Platform && left.Arch == right.Arch && left.Type == right.Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(ClientBuildVariantId left, ClientBuildVariantId right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClientBuildAuthKey
|
public class ClientBuildAuthKey
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace Framework.Realm
|
|||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return new { Site, Region, Index }.GetHashCode();
|
return new { Index }.GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public class RealmManager : Singleton<RealmManager>
|
|||||||
}
|
}
|
||||||
|
|
||||||
var realm = new Realm();
|
var realm = new Realm();
|
||||||
|
realm.Name = name;
|
||||||
realm.Addresses.Add(externalAddress);
|
realm.Addresses.Add(externalAddress);
|
||||||
realm.Addresses.Add(localAddress);
|
realm.Addresses.Add(localAddress);
|
||||||
realm.Port = result.Read<ushort>(4);
|
realm.Port = result.Read<ushort>(4);
|
||||||
@@ -127,7 +128,7 @@ public class RealmManager : Singleton<RealmManager>
|
|||||||
|
|
||||||
if (_currentRealmId.HasValue)
|
if (_currentRealmId.HasValue)
|
||||||
{
|
{
|
||||||
var realm = _realms.LookupByKey(_currentRealmId.Value);
|
var realm = _realms.LookupByKey(_currentRealmId);
|
||||||
if (realm != null)
|
if (realm != null)
|
||||||
_currentRealmId = realm.Id; // fill other fields of realm id
|
_currentRealmId = realm.Id; // fill other fields of realm id
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,8 +191,8 @@ namespace Game.Collision
|
|||||||
if (iLoadedModelFiles.TryGetValue(filename, out worldmodel))
|
if (iLoadedModelFiles.TryGetValue(filename, out worldmodel))
|
||||||
return worldmodel.Model;
|
return worldmodel.Model;
|
||||||
|
|
||||||
var model = new ManagedModel(filename);
|
worldmodel = new ManagedModel(filename);
|
||||||
if (!model.Model.ReadFile(VMapPath + filename))
|
if (!worldmodel.Model.ReadFile(VMapPath + filename))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Server, $"VMapManager: could not load '{filename}'");
|
Log.outError(LogFilter.Server, $"VMapManager: could not load '{filename}'");
|
||||||
return null;
|
return null;
|
||||||
@@ -200,10 +200,8 @@ namespace Game.Collision
|
|||||||
|
|
||||||
Log.outDebug(LogFilter.Maps, $"VMapManager: loading file '{filename}'");
|
Log.outDebug(LogFilter.Maps, $"VMapManager: loading file '{filename}'");
|
||||||
|
|
||||||
model = worldmodel;
|
iLoadedModelFiles.Add(filename, worldmodel);
|
||||||
|
return worldmodel.Model;
|
||||||
iLoadedModelFiles.Add(filename, model);
|
|
||||||
return model.Model;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +269,7 @@ namespace Game.Collision
|
|||||||
|
|
||||||
public class ManagedModel
|
public class ManagedModel
|
||||||
{
|
{
|
||||||
public WorldModel Model;
|
public WorldModel Model = new();
|
||||||
string _name; // valid only while model is held in VMapManager2::iLoadedModelFiles
|
string _name; // valid only while model is held in VMapManager2::iLoadedModelFiles
|
||||||
|
|
||||||
public ManagedModel(string name)
|
public ManagedModel(string name)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace Game.Collision
|
|||||||
LoadResult result = LoadResult.FileNotFound;
|
LoadResult result = LoadResult.FileNotFound;
|
||||||
|
|
||||||
TileFileOpenResult fileResult = OpenMapTileFile(VMapManager.VMapPath, iMapID, tileX, tileY, vm);
|
TileFileOpenResult fileResult = OpenMapTileFile(VMapManager.VMapPath, iMapID, tileX, tileY, vm);
|
||||||
if (fileResult.TileFile != null)
|
if (fileResult.TileFile != null && fileResult.SpawnIndicesFile != null)
|
||||||
{
|
{
|
||||||
result = LoadResult.Success;
|
result = LoadResult.Success;
|
||||||
using BinaryReader reader = new(fileResult.TileFile);
|
using BinaryReader reader = new(fileResult.TileFile);
|
||||||
@@ -127,7 +127,7 @@ namespace Game.Collision
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iTreeValues[referencedVal].GetWorldModel() == null)
|
if (iTreeValues[referencedVal]?.GetWorldModel() == null)
|
||||||
iTreeValues[referencedVal] = new ModelInstance(spawn, model);
|
iTreeValues[referencedVal] = new ModelInstance(spawn, model);
|
||||||
|
|
||||||
iTreeValues[referencedVal].AddTileReference();
|
iTreeValues[referencedVal].AddTileReference();
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ namespace Game.DataStorage
|
|||||||
if (fieldIndex >= _fieldMeta.Length)
|
if (fieldIndex >= _fieldMeta.Length)
|
||||||
{
|
{
|
||||||
if (_refId != -1)
|
if (_refId != -1)
|
||||||
f.SetValue(obj, (uint)_refId);
|
f.SetValue(obj, Convert.ChangeType(_refId, f.FieldType));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,7 +443,12 @@ namespace Game.DataStorage
|
|||||||
|
|
||||||
foreach (var (_, pathProperty) in CliDB.PathPropertyStorage)
|
foreach (var (_, pathProperty) in CliDB.PathPropertyStorage)
|
||||||
if (CliDB.PathStorage.HasRecord(pathProperty.PathID))
|
if (CliDB.PathStorage.HasRecord(pathProperty.PathID))
|
||||||
|
{
|
||||||
|
if (!_paths.ContainsKey(pathProperty.PathID))
|
||||||
|
_paths[pathProperty.PathID] = new();
|
||||||
|
|
||||||
_paths[pathProperty.PathID].Properties.Add(pathProperty);
|
_paths[pathProperty.PathID].Properties.Add(pathProperty);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var group in PhaseXPhaseGroupStorage.Values)
|
foreach (var group in PhaseXPhaseGroupStorage.Values)
|
||||||
{
|
{
|
||||||
@@ -594,9 +599,9 @@ namespace Game.DataStorage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<Tuple<uint, int>, UiMapLinkRecord> uiMapLinks = new();
|
Dictionary<Tuple<uint, uint>, UiMapLinkRecord> uiMapLinks = new();
|
||||||
foreach (UiMapLinkRecord uiMapLink in UiMapLinkStorage.Values)
|
foreach (UiMapLinkRecord uiMapLink in UiMapLinkStorage.Values)
|
||||||
uiMapLinks[Tuple.Create(uiMapLink.ParentUiMapID, uiMapLink.ChildUiMapID)] = uiMapLink;
|
uiMapLinks[Tuple.Create(uiMapLink.ParentUiMapID, (uint)uiMapLink.ChildUiMapID)] = uiMapLink;
|
||||||
|
|
||||||
foreach (UiMapRecord uiMap in UiMapStorage.Values)
|
foreach (UiMapRecord uiMap in UiMapStorage.Values)
|
||||||
{
|
{
|
||||||
@@ -2361,7 +2366,7 @@ namespace Game.DataStorage
|
|||||||
Dictionary<uint, List<NameGenRecord>[]> _nameGenData = new();
|
Dictionary<uint, List<NameGenRecord>[]> _nameGenData = new();
|
||||||
List<string>[] _nameValidators = new List<string>[(int)Locale.Total + 1];
|
List<string>[] _nameValidators = new List<string>[(int)Locale.Total + 1];
|
||||||
Dictionary<uint, ParagonReputationRecord> _paragonReputations = new();
|
Dictionary<uint, ParagonReputationRecord> _paragonReputations = new();
|
||||||
Dictionary<uint, PathDb2> _paths;
|
Dictionary<uint, PathDb2> _paths = new();
|
||||||
MultiMap<uint, uint> _phasesByGroup = new();
|
MultiMap<uint, uint> _phasesByGroup = new();
|
||||||
Dictionary<PowerType, PowerTypeRecord> _powerTypes = new();
|
Dictionary<PowerType, PowerTypeRecord> _powerTypes = new();
|
||||||
Dictionary<uint, byte> _pvpItemBonus = new();
|
Dictionary<uint, byte> _pvpItemBonus = new();
|
||||||
|
|||||||
@@ -46,10 +46,11 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
packet = new UpdateObject();
|
packet = new UpdateObject();
|
||||||
|
|
||||||
packet.NumObjUpdates = BlockCount;
|
|
||||||
packet.MapID = (ushort)MapId;
|
|
||||||
|
|
||||||
WorldPacket buffer = new();
|
WorldPacket buffer = new();
|
||||||
|
buffer.WriteUInt16((ushort)MapId);
|
||||||
|
buffer.WriteUInt32(BlockCount);
|
||||||
|
buffer.WriteBit(true); // unk
|
||||||
|
|
||||||
if (buffer.WriteBit(!outOfRangeGUIDs.Empty() || !destroyGUIDs.Empty()))
|
if (buffer.WriteBit(!outOfRangeGUIDs.Empty() || !destroyGUIDs.Empty()))
|
||||||
{
|
{
|
||||||
buffer.WriteUInt16((ushort)destroyGUIDs.Count);
|
buffer.WriteUInt16((ushort)destroyGUIDs.Count);
|
||||||
|
|||||||
@@ -4337,7 +4337,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public class TraitSubTreeCache
|
public class TraitSubTreeCache
|
||||||
{
|
{
|
||||||
public List<TraitEntry> Entries;
|
public List<TraitEntry> Entries = new();
|
||||||
public int TraitSubTreeID;
|
public int TraitSubTreeID;
|
||||||
public uint Active;
|
public uint Active;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ namespace Game.Entities
|
|||||||
public const byte CGObjectActiveMask = 0x1;
|
public const byte CGObjectActiveMask = 0x1;
|
||||||
public const byte CGObjectChangedMask = 0x2;
|
public const byte CGObjectChangedMask = 0x2;
|
||||||
public const byte CGObjectUpdateMask = CGObjectActiveMask | CGObjectChangedMask;
|
public const byte CGObjectUpdateMask = CGObjectActiveMask | CGObjectChangedMask;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EntityFragmentsHolder
|
public class EntityFragmentsHolder
|
||||||
@@ -75,15 +74,16 @@ namespace Game.Entities
|
|||||||
|
|
||||||
(int, bool) insertSorted(ref EntityFragment[] arr, ref byte count, EntityFragment f)
|
(int, bool) insertSorted(ref EntityFragment[] arr, ref byte count, EntityFragment f)
|
||||||
{
|
{
|
||||||
//auto where = std::ranges::lower_bound(arr.begin(), arr.begin() + count, f);
|
var whereIndex = Array.IndexOf(arr, f);
|
||||||
var where = Array.IndexOf(arr, f);
|
if (whereIndex != -1)
|
||||||
if (where != -1)
|
return (whereIndex, false);
|
||||||
return (where, false);
|
|
||||||
|
|
||||||
arr.SetValue(f, where);
|
whereIndex = Array.IndexOf(arr, EntityFragment.End);
|
||||||
arr = arr[^1..^0].Concat(arr[..^1]).ToArray();
|
|
||||||
|
arr.SetValue(f, whereIndex);
|
||||||
|
Array.Sort(arr);
|
||||||
++count;
|
++count;
|
||||||
return (where, true);
|
return (whereIndex, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!insertSorted(ref Ids, ref Count, fragment).Item2)
|
if (!insertSorted(ref Ids, ref Count, fragment).Item2)
|
||||||
@@ -120,7 +120,7 @@ namespace Game.Entities
|
|||||||
if (where != -1)
|
if (where != -1)
|
||||||
{
|
{
|
||||||
arr.SetValue(EntityFragment.End, where);
|
arr.SetValue(EntityFragment.End, where);
|
||||||
arr = arr[^1..^0].Concat(arr[..^1]).ToArray();
|
Array.Sort(arr);
|
||||||
--count;
|
--count;
|
||||||
return (where, true);
|
return (where, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,11 +172,13 @@ namespace Game.Entities
|
|||||||
UpdateFieldFlag fieldFlags = GetUpdateFieldFlagsFor(target);
|
UpdateFieldFlag fieldFlags = GetUpdateFieldFlagsFor(target);
|
||||||
|
|
||||||
WorldPacket tempBuffer = new();
|
WorldPacket tempBuffer = new();
|
||||||
|
tempBuffer.WriteUInt8((byte)fieldFlags);
|
||||||
|
BuildEntityFragments(tempBuffer, m_entityFragments.GetIds());
|
||||||
|
tempBuffer.WriteUInt8(1); // IndirectFragmentActive: CGObject
|
||||||
BuildValuesCreate(tempBuffer, fieldFlags, target);
|
BuildValuesCreate(tempBuffer, fieldFlags, target);
|
||||||
|
|
||||||
|
|
||||||
buffer.WriteUInt32(tempBuffer.GetSize());
|
buffer.WriteUInt32(tempBuffer.GetSize());
|
||||||
buffer.WriteUInt8((byte)fieldFlags);
|
|
||||||
BuildEntityFragments(buffer, m_entityFragments.GetIds());
|
|
||||||
buffer.WriteUInt8(1); // IndirectFragmentActive: CGObject
|
|
||||||
buffer.WriteBytes(tempBuffer);
|
buffer.WriteBytes(tempBuffer);
|
||||||
|
|
||||||
data.AddUpdateBlock(buffer);
|
data.AddUpdateBlock(buffer);
|
||||||
@@ -3879,7 +3881,7 @@ namespace Game.Entities
|
|||||||
public TypeMask ObjectTypeMask { get; set; }
|
public TypeMask ObjectTypeMask { get; set; }
|
||||||
protected TypeId ObjectTypeId { get; set; }
|
protected TypeId ObjectTypeId { get; set; }
|
||||||
protected CreateObjectBits m_updateFlag;
|
protected CreateObjectBits m_updateFlag;
|
||||||
public EntityFragmentsHolder m_entityFragments;
|
public EntityFragmentsHolder m_entityFragments = new();
|
||||||
ObjectGuid m_guid;
|
ObjectGuid m_guid;
|
||||||
bool _isNewObject;
|
bool _isNewObject;
|
||||||
bool _isDestroyedObject;
|
bool _isDestroyedObject;
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ namespace Game.Entities
|
|||||||
AdvFlyingRateTypeSingle.SurfaceFriction => (ServerOpcodes.MoveSetAdvFlyingSurfaceFriction, flightCapabilityEntry.SurfaceFriction, AuraType.None),
|
AdvFlyingRateTypeSingle.SurfaceFriction => (ServerOpcodes.MoveSetAdvFlyingSurfaceFriction, flightCapabilityEntry.SurfaceFriction, AuraType.None),
|
||||||
AdvFlyingRateTypeSingle.OverMaxDeceleration => (ServerOpcodes.MoveSetAdvFlyingOverMaxDeceleration, flightCapabilityEntry.OverMaxDeceleration, AuraType.ModAdvFlyingOverMaxDeceleration),
|
AdvFlyingRateTypeSingle.OverMaxDeceleration => (ServerOpcodes.MoveSetAdvFlyingOverMaxDeceleration, flightCapabilityEntry.OverMaxDeceleration, AuraType.ModAdvFlyingOverMaxDeceleration),
|
||||||
AdvFlyingRateTypeSingle.LaunchSpeedCoefficient => (ServerOpcodes.MoveSetAdvFlyingLaunchSpeedCoefficient, flightCapabilityEntry.LaunchSpeedCoefficient, AuraType.None),
|
AdvFlyingRateTypeSingle.LaunchSpeedCoefficient => (ServerOpcodes.MoveSetAdvFlyingLaunchSpeedCoefficient, flightCapabilityEntry.LaunchSpeedCoefficient, AuraType.None),
|
||||||
_ => (ServerOpcodes.Max, 0, AuraType.None)
|
_ => (ServerOpcodes.Unknown, 0, AuraType.None)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (rateAura != AuraType.None)
|
if (rateAura != AuraType.None)
|
||||||
@@ -239,7 +239,7 @@ namespace Game.Entities
|
|||||||
AdvFlyingRateTypeRange.PitchingRateDown => (ServerOpcodes.MoveSetAdvFlyingPitchingRateDown, flightCapabilityEntry.PitchingRateDownMin, flightCapabilityEntry.PitchingRateDownMax, AuraType.ModAdvFlyingPitchingRateDown),
|
AdvFlyingRateTypeRange.PitchingRateDown => (ServerOpcodes.MoveSetAdvFlyingPitchingRateDown, flightCapabilityEntry.PitchingRateDownMin, flightCapabilityEntry.PitchingRateDownMax, AuraType.ModAdvFlyingPitchingRateDown),
|
||||||
AdvFlyingRateTypeRange.PitchingRateUp => (ServerOpcodes.MoveSetAdvFlyingPitchingRateUp, flightCapabilityEntry.PitchingRateUpMin, flightCapabilityEntry.PitchingRateUpMax, AuraType.ModAdvFlyingPitchingRateUp),
|
AdvFlyingRateTypeRange.PitchingRateUp => (ServerOpcodes.MoveSetAdvFlyingPitchingRateUp, flightCapabilityEntry.PitchingRateUpMin, flightCapabilityEntry.PitchingRateUpMax, AuraType.ModAdvFlyingPitchingRateUp),
|
||||||
AdvFlyingRateTypeRange.TurnVelocityThreshold => (ServerOpcodes.MoveSetAdvFlyingTurnVelocityThreshold, flightCapabilityEntry.TurnVelocityThresholdMin, flightCapabilityEntry.TurnVelocityThresholdMax, AuraType.None),
|
AdvFlyingRateTypeRange.TurnVelocityThreshold => (ServerOpcodes.MoveSetAdvFlyingTurnVelocityThreshold, flightCapabilityEntry.TurnVelocityThresholdMin, flightCapabilityEntry.TurnVelocityThresholdMax, AuraType.None),
|
||||||
_ => (ServerOpcodes.Max, 0, 0, AuraType.None)
|
_ => (ServerOpcodes.Unknown, 0, 0, AuraType.None)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (rateAura != AuraType.None)
|
if (rateAura != AuraType.None)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
public Unit(bool isWorldObject) : base(isWorldObject)
|
public Unit(bool isWorldObject) : base(isWorldObject)
|
||||||
{
|
{
|
||||||
|
m_unitData = new UnitData();
|
||||||
MoveSpline = new MoveSpline();
|
MoveSpline = new MoveSpline();
|
||||||
i_motionMaster = new MotionMaster(this);
|
i_motionMaster = new MotionMaster(this);
|
||||||
m_combatManager = new CombatManager(this);
|
m_combatManager = new CombatManager(this);
|
||||||
@@ -74,7 +75,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
m_serverSideVisibility.SetValue(ServerSideVisibilityType.Ghost, GhostVisibilityType.Alive);
|
m_serverSideVisibility.SetValue(ServerSideVisibilityType.Ghost, GhostVisibilityType.Alive);
|
||||||
|
|
||||||
m_unitData = new UnitData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
|
|||||||
@@ -3675,12 +3675,12 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, $"Table `creature_template` lists creature (Entry: {cInfo.Entry}) with disallowed `unit_flags2` {disallowedUnitFlags2}, removing incorrect flag.");
|
Log.outError(LogFilter.Sql, $"Table `creature_template` lists creature (Entry: {cInfo.Entry}) with disallowed `unit_flags2` {disallowedUnitFlags2}, removing incorrect flag.");
|
||||||
data.unit_flags2 = data.unit_flags2 & (uint)UnitFlags2.Allowed;
|
data.unit_flags2 = data.unit_flags2 & (uint)UnitFlags2.Allowed;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((data.unit_flags2.Value & (uint)UnitFlags2.FeignDeath) != 0 && (!data.unit_flags.HasValue || (data.unit_flags.Value & (uint)(UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc)) == 0))
|
if ((data.unit_flags2.Value & (uint)UnitFlags2.FeignDeath) != 0 && (!data.unit_flags.HasValue || (data.unit_flags.Value & (uint)(UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc)) == 0))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid} Entry: {data.Id}) has UNIT_FLAG2_FEIGN_DEATH set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.");
|
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid} Entry: {data.Id}) has UNIT_FLAG2_FEIGN_DEATH set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.");
|
||||||
data.unit_flags2 = data.unit_flags2 & ~(uint)UnitFlags2.FeignDeath;
|
data.unit_flags2 = data.unit_flags2 & ~(uint)UnitFlags2.FeignDeath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.unit_flags3.HasValue)
|
if (data.unit_flags3.HasValue)
|
||||||
@@ -3691,12 +3691,12 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, $"Table `creature_template` lists creature (Entry: {cInfo.Entry}) with disallowed `unit_flags3` {disallowedUnitFlags3}, removing incorrect flag.");
|
Log.outError(LogFilter.Sql, $"Table `creature_template` lists creature (Entry: {cInfo.Entry}) with disallowed `unit_flags3` {disallowedUnitFlags3}, removing incorrect flag.");
|
||||||
data.unit_flags3 = data.unit_flags3 & (uint)UnitFlags3.Allowed;
|
data.unit_flags3 = data.unit_flags3 & (uint)UnitFlags3.Allowed;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((data.unit_flags3.Value & (uint)UnitFlags3.FakeDead) != 0 && (data.unit_flags.Value & (uint)(UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc)) == 0)
|
if ((data.unit_flags3.Value & (uint)UnitFlags3.FakeDead) != 0 && (data.unit_flags.Value & (uint)(UnitFlags.ImmuneToPc | UnitFlags.ImmuneToNpc)) == 0)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid} Entry: {data.Id}) has UNIT_FLAG3_FAKE_DEAD set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.");
|
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid} Entry: {data.Id}) has UNIT_FLAG3_FAKE_DEAD set without IMMUNE_TO_PC | IMMUNE_TO_NPC, removing incorrect flag.");
|
||||||
data.unit_flags3 = data.unit_flags3 & ~(uint)UnitFlags3.FakeDead;
|
data.unit_flags3 = data.unit_flags3 & ~(uint)UnitFlags3.FakeDead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint healthPct = Math.Clamp(data.curHealthPct, 1, 100);
|
uint healthPct = Math.Clamp(data.curHealthPct, 1, 100);
|
||||||
|
|||||||
@@ -70,7 +70,10 @@ namespace Game
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
EnumCharactersResult.CharacterInfoBasic charInfo = new(result.GetFields());
|
charResult.Characters.Add(new EnumCharactersResult.CharacterInfo(result.GetFields()));
|
||||||
|
|
||||||
|
|
||||||
|
EnumCharactersResult.CharacterInfoBasic charInfo = charResult.Characters.Last().Basic;
|
||||||
|
|
||||||
var customizationsForChar = customizations.LookupByKey(charInfo.Guid.GetCounter());
|
var customizationsForChar = customizations.LookupByKey(charInfo.Guid.GetCounter());
|
||||||
if (!customizationsForChar.Empty())
|
if (!customizationsForChar.Empty())
|
||||||
@@ -105,8 +108,6 @@ namespace Game
|
|||||||
Global.CharacterCacheStorage.AddCharacterCacheEntry(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.SexId, charInfo.RaceId, (byte)charInfo.ClassId, charInfo.ExperienceLevel, false);
|
Global.CharacterCacheStorage.AddCharacterCacheEntry(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.SexId, charInfo.RaceId, (byte)charInfo.ClassId, charInfo.ExperienceLevel, false);
|
||||||
|
|
||||||
charResult.MaxCharacterLevel = Math.Max(charResult.MaxCharacterLevel, charInfo.ExperienceLevel);
|
charResult.MaxCharacterLevel = Math.Max(charResult.MaxCharacterLevel, charInfo.ExperienceLevel);
|
||||||
|
|
||||||
charResult.Characters.Add(charInfo);
|
|
||||||
}
|
}
|
||||||
while (result.NextRow() && charResult.Characters.Count < 200);
|
while (result.NextRow() && charResult.Characters.Count < 200);
|
||||||
}
|
}
|
||||||
@@ -149,14 +150,14 @@ namespace Game
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
EnumCharactersResult.CharacterInfoBasic charInfo = new(result.GetFields());
|
charEnum.Characters.Add(new EnumCharactersResult.CharacterInfo(result.GetFields()));
|
||||||
|
|
||||||
|
EnumCharactersResult.CharacterInfoBasic charInfo = charEnum.Characters.Last().Basic;
|
||||||
|
|
||||||
Log.outInfo(LogFilter.Network, "Loading undeleted char guid {0} from account {1}.", charInfo.Guid.ToString(), GetAccountId());
|
Log.outInfo(LogFilter.Network, "Loading undeleted char guid {0} from account {1}.", charInfo.Guid.ToString(), GetAccountId());
|
||||||
|
|
||||||
if (!Global.CharacterCacheStorage.HasCharacterCacheEntry(charInfo.Guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
|
if (!Global.CharacterCacheStorage.HasCharacterCacheEntry(charInfo.Guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
|
||||||
Global.CharacterCacheStorage.AddCharacterCacheEntry(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.SexId, charInfo.RaceId, (byte)charInfo.ClassId, charInfo.ExperienceLevel, true);
|
Global.CharacterCacheStorage.AddCharacterCacheEntry(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.SexId, charInfo.RaceId, (byte)charInfo.ClassId, charInfo.ExperienceLevel, true);
|
||||||
|
|
||||||
charEnum.Characters.Add(charInfo);
|
|
||||||
}
|
}
|
||||||
while (result.NextRow());
|
while (result.NextRow());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Game.Movement
|
|||||||
public class WaypointMovementGenerator : MovementGeneratorMedium<Creature>
|
public class WaypointMovementGenerator : MovementGeneratorMedium<Creature>
|
||||||
{
|
{
|
||||||
uint _pathId;
|
uint _pathId;
|
||||||
WaypointPath _path;
|
WaypointPath _path = new();
|
||||||
int _currentNode;
|
int _currentNode;
|
||||||
|
|
||||||
TimeTracker _duration;
|
TimeTracker _duration;
|
||||||
@@ -28,8 +28,8 @@ namespace Game.Movement
|
|||||||
bool _repeating;
|
bool _repeating;
|
||||||
bool _generatePath;
|
bool _generatePath;
|
||||||
|
|
||||||
TimeTracker _moveTimer;
|
TimeTracker _moveTimer = new();
|
||||||
TimeTracker _nextMoveTime;
|
TimeTracker _nextMoveTime = new();
|
||||||
List<int> _waypointTransitionSplinePoints = new();
|
List<int> _waypointTransitionSplinePoints = new();
|
||||||
int _waypointTransitionSplinePointsIndex;
|
int _waypointTransitionSplinePointsIndex;
|
||||||
bool _isReturningToStart;
|
bool _isReturningToStart;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace Game
|
|||||||
|
|
||||||
var oldMSTime = Time.GetMSTime();
|
var oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
// 0 1 2
|
// 0 1 2 3
|
||||||
SQLResult result = DB.World.Query("SELECT PathId, MoveType, Flags FROM waypoint_path");
|
SQLResult result = DB.World.Query("SELECT PathId, MoveType, Flags, Velocity FROM waypoint_path");
|
||||||
if (result.IsEmpty())
|
if (result.IsEmpty())
|
||||||
{
|
{
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 waypoint paths. DB table `waypoint_path` is empty!");
|
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 waypoint paths. DB table `waypoint_path` is empty!");
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ namespace Game.Networking
|
|||||||
|
|
||||||
public ConnectionType GetConnection() { return connectionType; }
|
public ConnectionType GetConnection() { return connectionType; }
|
||||||
|
|
||||||
|
public bool IsValidOpcode()
|
||||||
|
{
|
||||||
|
return _worldPacket.IsValidOpcode();
|
||||||
|
}
|
||||||
|
|
||||||
byte[] buffer;
|
byte[] buffer;
|
||||||
ConnectionType connectionType;
|
ConnectionType connectionType;
|
||||||
protected WorldPacket _worldPacket;
|
protected WorldPacket _worldPacket;
|
||||||
@@ -209,6 +214,48 @@ namespace Game.Networking
|
|||||||
public DateTime GetReceivedTime() { return m_receivedTime; }
|
public DateTime GetReceivedTime() { return m_receivedTime; }
|
||||||
public void SetReceiveTime(DateTime receivedTime) { m_receivedTime = receivedTime; }
|
public void SetReceiveTime(DateTime receivedTime) { m_receivedTime = receivedTime; }
|
||||||
|
|
||||||
|
public bool IsValidOpcode()
|
||||||
|
{
|
||||||
|
int opcodeArrayIndex = GetOpcodeArrayIndex(opcode);
|
||||||
|
return opcodeArrayIndex >= 0 && opcodeArrayIndex < 1699;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetOpcodeArrayIndex(uint opcode)
|
||||||
|
{
|
||||||
|
int idInGroup = (int)(opcode & 0xFFFF);
|
||||||
|
switch (opcode >> 16)
|
||||||
|
{
|
||||||
|
case 0x2A: return idInGroup < 26 ? idInGroup + 0 : -1;
|
||||||
|
case 0x2C: return idInGroup < 47 ? idInGroup + 26 : -1;
|
||||||
|
case 0x2D: return idInGroup < 3 ? idInGroup + 73 : -1;
|
||||||
|
case 0x2E: return idInGroup < 33 ? idInGroup + 76 : -1;
|
||||||
|
case 0x30: return idInGroup < 739 ? idInGroup + 109 : -1;
|
||||||
|
case 0x31: return idInGroup < 298 ? idInGroup + 848 : -1;
|
||||||
|
case 0x32: return idInGroup < 12 ? idInGroup + 1146 : -1;
|
||||||
|
case 0x33: return idInGroup < 130 ? idInGroup + 1158 : -1;
|
||||||
|
case 0x35: return idInGroup < 396 ? idInGroup + 1288 : -1;
|
||||||
|
case 0x36: return idInGroup < 15 ? idInGroup + 1684 : -1;
|
||||||
|
case 0x37: return idInGroup < 831 ? idInGroup + 0 : -1;
|
||||||
|
case 0x38: return idInGroup < 10 ? idInGroup + 831 : -1;
|
||||||
|
case 0x3B: return idInGroup < 18 ? idInGroup + 841 : -1;
|
||||||
|
case 0x3C: return idInGroup < 33 ? idInGroup + 859 : -1;
|
||||||
|
case 0x3D: return idInGroup < 49 ? idInGroup + 892 : -1;
|
||||||
|
case 0x3E: return idInGroup < 11 ? idInGroup + 941 : -1;
|
||||||
|
case 0x3F: return idInGroup < 12 ? idInGroup + 952 : -1;
|
||||||
|
case 0x41: return idInGroup < 82 ? idInGroup + 964 : -1;
|
||||||
|
case 0x43: return idInGroup < 67 ? idInGroup + 1046 : -1;
|
||||||
|
case 0x45: return idInGroup < 32 ? idInGroup + 1113 : -1;
|
||||||
|
case 0x47: return idInGroup < 1 ? idInGroup + 1145 : -1;
|
||||||
|
case 0x48: return idInGroup < 118 ? idInGroup + 1146 : -1;
|
||||||
|
case 0x4A: return idInGroup < 46 ? idInGroup + 1264 : -1;
|
||||||
|
case 0x4B: return idInGroup < 41 ? idInGroup + 1310 : -1;
|
||||||
|
case 0x4D: return idInGroup < 85 ? idInGroup + 1351 : -1;
|
||||||
|
case 0x4E: return idInGroup < 8 ? idInGroup + 1436 : -1;
|
||||||
|
case 0x50: return idInGroup < 1 ? idInGroup + 1444 : -1;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint opcode;
|
uint opcode;
|
||||||
DateTime m_receivedTime; // only set for a specific set of opcodes, for performance reasons.
|
DateTime m_receivedTime; // only set for a specific set of opcodes, for performance reasons.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace Game.Networking.Packets
|
|||||||
foreach (WarbandGroup warbandGroup in WarbandGroups)
|
foreach (WarbandGroup warbandGroup in WarbandGroups)
|
||||||
warbandGroup.Write(_worldPacket);
|
warbandGroup.Write(_worldPacket);
|
||||||
|
|
||||||
foreach (CharacterInfoBasic charInfo in Characters)
|
foreach (CharacterInfo charInfo in Characters)
|
||||||
charInfo.Write(_worldPacket);
|
charInfo.Write(_worldPacket);
|
||||||
|
|
||||||
foreach (RegionwideCharacterListEntry charInfo in RegionwideCharacters)
|
foreach (RegionwideCharacterListEntry charInfo in RegionwideCharacters)
|
||||||
@@ -77,7 +77,7 @@ namespace Game.Networking.Packets
|
|||||||
public int MaxCharacterLevel = 1;
|
public int MaxCharacterLevel = 1;
|
||||||
public uint? DisabledClassesMask = new();
|
public uint? DisabledClassesMask = new();
|
||||||
|
|
||||||
public List<CharacterInfoBasic> Characters = new(); // all characters on the list
|
public List<CharacterInfo> Characters = new(); // all characters on the list
|
||||||
public List<RegionwideCharacterListEntry> RegionwideCharacters = new();
|
public List<RegionwideCharacterListEntry> RegionwideCharacters = new();
|
||||||
public List<RaceUnlock> RaceUnlockData = new();
|
public List<RaceUnlock> RaceUnlockData = new();
|
||||||
public List<UnlockedConditionalAppearance> UnlockedConditionalAppearances = new();
|
public List<UnlockedConditionalAppearance> UnlockedConditionalAppearances = new();
|
||||||
@@ -260,7 +260,7 @@ namespace Game.Networking.Packets
|
|||||||
public uint PetCreatureFamilyId;
|
public uint PetCreatureFamilyId;
|
||||||
public uint[] ProfessionIds = new uint[2]; // @todo
|
public uint[] ProfessionIds = new uint[2]; // @todo
|
||||||
public VisualItemInfo[] VisualItems = new VisualItemInfo[19];
|
public VisualItemInfo[] VisualItems = new VisualItemInfo[19];
|
||||||
public CustomTabardInfo PersonalTabard;
|
public CustomTabardInfo PersonalTabard = new();
|
||||||
|
|
||||||
public struct VisualItemInfo
|
public struct VisualItemInfo
|
||||||
{
|
{
|
||||||
@@ -332,7 +332,7 @@ namespace Game.Networking.Packets
|
|||||||
public struct CharacterInfo
|
public struct CharacterInfo
|
||||||
{
|
{
|
||||||
public CharacterInfoBasic Basic;
|
public CharacterInfoBasic Basic;
|
||||||
public CharacterRestrictionAndMailData RestrictionsAndMails;
|
public CharacterRestrictionAndMailData RestrictionsAndMails = new();
|
||||||
|
|
||||||
public CharacterInfo(SQLFields fields)
|
public CharacterInfo(SQLFields fields)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ namespace Game.Networking.Packets
|
|||||||
|
|
||||||
public override void Write()
|
public override void Write()
|
||||||
{
|
{
|
||||||
_worldPacket.WriteUInt16(MapID);
|
|
||||||
_worldPacket.WriteUInt32(NumObjUpdates);
|
|
||||||
_worldPacket.WriteBit(true); // unk
|
|
||||||
_worldPacket.WriteBytes(Data);
|
_worldPacket.WriteBytes(Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ namespace Game.Networking
|
|||||||
WorldPacket packet = new(_packetBuffer.GetData());
|
WorldPacket packet = new(_packetBuffer.GetData());
|
||||||
_packetBuffer.Reset();
|
_packetBuffer.Reset();
|
||||||
|
|
||||||
if (packet.GetOpcode() >= (int)ClientOpcodes.Max)
|
if (!packet.IsValidOpcode())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): client {GetRemoteIpAddress()} sent wrong opcode (opcode: {packet.GetOpcode()})");
|
Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): client {GetRemoteIpAddress()} sent wrong opcode (opcode: {packet.GetOpcode()})");
|
||||||
Log.outError(LogFilter.Network, $"Header: {_headerBuffer.GetData().ToHexString()} Data: {_packetBuffer.GetData().ToHexString()}");
|
Log.outError(LogFilter.Network, $"Header: {_headerBuffer.GetData().ToHexString()} Data: {_packetBuffer.GetData().ToHexString()}");
|
||||||
@@ -361,7 +361,7 @@ namespace Game.Networking
|
|||||||
int packetSize = data.Length;
|
int packetSize = data.Length;
|
||||||
if (packetSize > 0x400 && _worldCrypt.IsInitialized)
|
if (packetSize > 0x400 && _worldCrypt.IsInitialized)
|
||||||
{
|
{
|
||||||
buffer.WriteInt32(packetSize + 2);
|
buffer.WriteInt32(packetSize + 4);
|
||||||
buffer.WriteUInt32(ZLib.adler32(ZLib.adler32(0x9827D8F1, BitConverter.GetBytes((uint)opcode), 4), data, (uint)packetSize));
|
buffer.WriteUInt32(ZLib.adler32(ZLib.adler32(0x9827D8F1, BitConverter.GetBytes((uint)opcode), 4), data, (uint)packetSize));
|
||||||
|
|
||||||
byte[] compressedData;
|
byte[] compressedData;
|
||||||
|
|||||||
@@ -385,9 +385,10 @@ namespace Game
|
|||||||
if (packet == null)
|
if (packet == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (packet.GetOpcode() == ServerOpcodes.Unknown || packet.GetOpcode() == ServerOpcodes.Max)
|
if (!packet.IsValidOpcode())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Network, "Prevented sending of UnknownOpcode to {0}", GetPlayerInfo());
|
string specialName = packet.GetOpcode() == ServerOpcodes.Unknown ? "UNKNOWN_OPCODE" : "INVALID_OPCODE";
|
||||||
|
Log.outError(LogFilter.Network, $"Prevented sending of {specialName} (0x{packet.GetOpcode():04X}) to {GetPlayerInfo()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace WorldServer
|
|||||||
ExitNow();
|
ExitNow();
|
||||||
|
|
||||||
// Set server offline (not connectable)
|
// Set server offline (not connectable)
|
||||||
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag | {LegacyRealmFlags.Offline} WHERE id = '{realmId}'");
|
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag | {(uint)LegacyRealmFlags.Offline} WHERE id = '{realmId}'");
|
||||||
|
|
||||||
if (!Global.WorldMgr.SetInitialWorldSettings())
|
if (!Global.WorldMgr.SetInitialWorldSettings())
|
||||||
ExitNow();
|
ExitNow();
|
||||||
@@ -94,7 +94,7 @@ namespace WorldServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set server online (allow connecting now)
|
// set server online (allow connecting now)
|
||||||
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag & ~{LegacyRealmFlags.Offline}, population = 0 WHERE id = '{realmId}'");
|
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag & ~{(uint)LegacyRealmFlags.Offline}, population = 0 WHERE id = '{realmId}'");
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
@@ -129,7 +129,7 @@ namespace WorldServer
|
|||||||
Global.ScriptMgr.Unload();
|
Global.ScriptMgr.Unload();
|
||||||
|
|
||||||
// set server offline
|
// set server offline
|
||||||
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag | {LegacyRealmFlags.Offline} WHERE id = '{realmId}'");
|
DB.Login.DirectExecute($"UPDATE realmlist SET flag = flag | {(uint)LegacyRealmFlags.Offline} WHERE id = '{realmId}'");
|
||||||
Global.RealmMgr.Close();
|
Global.RealmMgr.Close();
|
||||||
|
|
||||||
ClearOnlineAccounts(realmId);
|
ClearOnlineAccounts(realmId);
|
||||||
|
|||||||
Reference in New Issue
Block a user