Core/PacketIO: Updated packets to 8.3.0

Port From (https://github.com/TrinityCore/TrinityCore/commit/462a10de17003631957b69e578e7e4c55ed1ef61)
This commit is contained in:
hondacrx
2020-02-21 18:21:19 -05:00
parent 96fd9b7a57
commit bcf199dba5
17 changed files with 1276 additions and 936 deletions
+11 -11
View File
@@ -107,19 +107,19 @@ namespace Framework.Constants
public const byte BagStart = 19;
public const byte BagEnd = 23;
public const byte ItemStart = 23;
public const byte ItemEnd = 47;
public const byte ItemEnd = 51;
public const byte BankItemStart = 47;
public const byte BankItemEnd = 75;
public const byte BankBagStart = 75;
public const byte BankBagEnd = 82;
public const byte BankItemStart = 51;
public const byte BankItemEnd = 79;
public const byte BankBagStart = 79;
public const byte BankBagEnd = 86;
public const byte BuyBackStart = 82;
public const byte BuyBackEnd = 94;
public const byte ReagentStart = 94;
public const byte ReagentEnd = 192;
public const byte ChildEquipmentStart = 192;
public const byte ChildEquipmentEnd = 195;
public const byte BuyBackStart = 86;
public const byte BuyBackEnd = 98;
public const byte ReagentStart = 98;
public const byte ReagentEnd = 196;
public const byte ChildEquipmentStart = 196;
public const byte ChildEquipmentEnd = 199;
public const byte Bag0 = 255;
public const byte DefaultSize = 16;
File diff suppressed because it is too large Load Diff
@@ -658,13 +658,13 @@ namespace Game.Entities
{
public UpdateField<uint> SpecializationID = new UpdateField<uint>(0, 1);
public UpdateField<uint> Enabled = new UpdateField<uint>(0, 2);
public UpdateFieldArray<uint> AzeriteEssenceID = new UpdateFieldArray<uint>(3, 3, 4);
public UpdateFieldArray<uint> AzeriteEssenceID = new UpdateFieldArray<uint>(4, 3, 4);
public SelectedAzeriteEssences() : base(7) { }
public SelectedAzeriteEssences() : base(8) { }
public override void WriteCreate(WorldPacket data, AzeriteItem owner, Player receiver)
{
for (int i = 0; i < 3; ++i)
for (int i = 0; i < 4; ++i)
{
data.WriteUInt32(AzeriteEssenceID[i]);
}
@@ -693,7 +693,7 @@ namespace Game.Entities
}
if (changesMask[3])
{
for (int i = 0; i < 3; ++i)
for (int i = 0; i < 4; ++i)
{
if (changesMask[4 + i])
{
@@ -1043,22 +1043,24 @@ namespace Game.Entities
public UpdateField<int> LookAtControllerID = new UpdateField<int>(96, 111);
public UpdateField<int> TaxiNodesID = new UpdateField<int>(96, 112);
public UpdateField<ObjectGuid> GuildGUID = new UpdateField<ObjectGuid>(96, 113);
public UpdateField<ObjectGuid>SkinningOwnerGUID = new UpdateField<ObjectGuid>(96, 114);
public UpdateFieldArray<uint> NpcFlags = new UpdateFieldArray<uint>(2, 114, 115);
public UpdateFieldArray<int> Power = new UpdateFieldArray<int>(6, 117, 118);
public UpdateFieldArray<uint> MaxPower = new UpdateFieldArray<uint>(6, 117, 124);
public UpdateFieldArray<float> PowerRegenFlatModifier = new UpdateFieldArray<float>(6, 117, 130);
public UpdateFieldArray<float> PowerRegenInterruptedFlatModifier = new UpdateFieldArray<float>(6, 117, 136);
public UpdateFieldArray<VisibleItem> VirtualItems = new UpdateFieldArray<VisibleItem>(3, 142, 143);
public UpdateFieldArray<uint> AttackRoundBaseTime = new UpdateFieldArray<uint>(2, 146, 147);
public UpdateFieldArray<int> Stats = new UpdateFieldArray<int>(4, 149, 150);
public UpdateFieldArray<int> StatPosBuff = new UpdateFieldArray<int>(4, 149, 154);
public UpdateFieldArray<int> StatNegBuff = new UpdateFieldArray<int>(4, 149, 158);
public UpdateFieldArray<int> Resistances = new UpdateFieldArray<int>(7, 162, 163);
public UpdateFieldArray<int> BonusResistanceMods = new UpdateFieldArray<int>(7, 162, 170);
public UpdateFieldArray<int> PowerCostModifier = new UpdateFieldArray<int>(7, 162, 177);
public UpdateFieldArray<float> PowerCostMultiplier = new UpdateFieldArray<float>(7, 162, 184);
public UnitData() : base(0, TypeId.Unit, 191) { }
public UpdateFieldArray<int>Power = new UpdateFieldArray<int>(6, 118, 119);
public UpdateFieldArray<uint>MaxPower = new UpdateFieldArray<uint>(6, 118, 125);
public UpdateFieldArray<float>PowerRegenFlatModifier = new UpdateFieldArray<float>(6, 118, 131);
public UpdateFieldArray<float>PowerRegenInterruptedFlatModifier = new UpdateFieldArray<float>(6, 118, 137);
public UpdateFieldArray<VisibleItem>VirtualItems = new UpdateFieldArray<VisibleItem>(3, 143, 144);
public UpdateFieldArray<uint>AttackRoundBaseTime = new UpdateFieldArray<uint>(2, 147, 148);
public UpdateFieldArray<int>Stats = new UpdateFieldArray<int>(4, 150, 151);
public UpdateFieldArray<int>StatPosBuff = new UpdateFieldArray<int>(4, 150, 155);
public UpdateFieldArray<int>StatNegBuff = new UpdateFieldArray<int>(4, 150, 159);
public UpdateFieldArray<int>Resistances = new UpdateFieldArray<int>(7, 163, 164);
public UpdateFieldArray<int>BonusResistanceMods = new UpdateFieldArray<int>(7, 163, 171);
public UpdateFieldArray<int>PowerCostModifier = new UpdateFieldArray<int>(7, 163, 178);
public UpdateFieldArray<float>PowerCostMultiplier = new UpdateFieldArray<float>(7, 163, 185);
public UnitData() : base(0, TypeId.Unit, 192) { }
public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver)
{
@@ -1234,6 +1236,8 @@ namespace Game.Entities
data.WriteInt32(PassiveSpells.Size());
data.WriteInt32(WorldEffects.Size());
data.WriteInt32(ChannelObjects.Size());
data.WritePackedGuid(SkinningOwnerGUID);
for (int i = 0; i < PassiveSpells.Size(); ++i)
PassiveSpells[i].WriteCreate(data, owner, receiver);
@@ -1246,7 +1250,7 @@ namespace Game.Entities
public override void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver)
{
UpdateMask allowedMaskForTarget = new UpdateMask(191, new uint[] { 0xFFFFEFFFu, 0xFC3FBFFFu, 0x0001EFFFu, 0xFFDFFFF9u, 0x001FC003u, 0x00000000u });
UpdateMask allowedMaskForTarget = new UpdateMask(192, new uint[] { 0xFFFFEFFFu, 0xFC3FBFFFu, 0x0001EFFFu, 0xFFBFFFF9u, 0x003F8007u, 0x00000000u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver);
}
@@ -1254,11 +1258,11 @@ namespace Game.Entities
public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags)
{
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner))
allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00001000u, 0x03C04000u, 0xFFFE1000u, 0x00200006u, 0xFFE03FFCu, 0x7FFFFFFFu });
allowedMaskForTarget |= new UpdateMask(192, new uint[] { 0x00001000u, 0x03C04000u, 0xFFFE1000u, 0x00400006u, 0xFFC07FF8u, 0xFFFFFFFFu });
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.UnitAll))
allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x00200000u, 0x00003FFCu, 0x00000000u });
allowedMaskForTarget |= new UpdateMask(192, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x00400000u, 0x00007FF8u, 0x00000000u });
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath))
allowedMaskForTarget |= new UpdateMask(191, new uint[] { 0x00000000u, 0x03C00000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000003FCu });
allowedMaskForTarget |= new UpdateMask(192, new uint[] { 0x00000000u, 0x03C00000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000007F8u });
}
public void WriteUpdate(WorldPacket data, UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver)
@@ -1762,94 +1766,98 @@ namespace Game.Entities
{
data.WritePackedGuid(GuildGUID);
}
if (changesMask[114])
{
data.WritePackedGuid(SkinningOwnerGUID);
}
}
if (changesMask[114])
if (changesMask[115])
{
for (int i = 0; i < 2; ++i)
{
if (changesMask[115 + i])
if (changesMask[116 + i])
{
data.WriteUInt32(GetViewerDependentNpcFlags(NpcFlags[i], i, owner, receiver));
}
}
}
if (changesMask[117])
if (changesMask[118])
{
for (int i = 0; i < 6; ++i)
{
if (changesMask[118 + i])
if (changesMask[119 + i])
{
data.WriteInt32(Power[i]);
}
if (changesMask[124 + i])
if (changesMask[125 + i])
{
data.WriteUInt32(MaxPower[i]);
}
if (changesMask[130 + i])
if (changesMask[131 + i])
{
data.WriteFloat(PowerRegenFlatModifier[i]);
}
if (changesMask[136 + i])
if (changesMask[137 + i])
{
data.WriteFloat(PowerRegenInterruptedFlatModifier[i]);
}
}
}
if (changesMask[142])
if (changesMask[143])
{
for (int i = 0; i < 3; ++i)
{
if (changesMask[143 + i])
if (changesMask[144 + i])
{
VirtualItems[i].WriteUpdate(data, owner, receiver);
}
}
}
if (changesMask[146])
if (changesMask[147])
{
for (int i = 0; i < 2; ++i)
{
if (changesMask[147 + i])
if (changesMask[148 + i])
{
data.WriteUInt32(AttackRoundBaseTime[i]);
}
}
}
if (changesMask[149])
if (changesMask[150])
{
for (int i = 0; i < 4; ++i)
{
if (changesMask[150 + i])
if (changesMask[151 + i])
{
data.WriteInt32(Stats[i]);
}
if (changesMask[154 + i])
if (changesMask[155 + i])
{
data.WriteInt32(StatPosBuff[i]);
}
if (changesMask[158 + i])
if (changesMask[159 + i])
{
data.WriteInt32(StatNegBuff[i]);
}
}
}
if (changesMask[162])
if (changesMask[163])
{
for (int i = 0; i < 7; ++i)
{
if (changesMask[163 + i])
if (changesMask[164 + i])
{
data.WriteInt32(Resistances[i]);
}
if (changesMask[170 + i])
if (changesMask[171 + i])
{
data.WriteInt32(BonusResistanceMods[i]);
}
if (changesMask[177 + i])
if (changesMask[178 + i])
{
data.WriteInt32(PowerCostModifier[i]);
}
if (changesMask[184 + i])
if (changesMask[185 + i])
{
data.WriteFloat(PowerCostMultiplier[i]);
}
@@ -1969,6 +1977,7 @@ namespace Game.Entities
ClearChangesMask(LookAtControllerID);
ClearChangesMask(TaxiNodesID);
ClearChangesMask(GuildGUID);
ClearChangesMask(SkinningOwnerGUID);
ClearChangesMask(NpcFlags);
ClearChangesMask(Power);
ClearChangesMask(MaxPower);
@@ -3097,32 +3106,31 @@ namespace Game.Entities
public UpdateField<int> PvpLastWeeksRewardClaimed = new UpdateField<int>(98, 101);
public UpdateField<byte> NumBankSlots = new UpdateField<byte>(98, 102);
public UpdateField<Optional<QuestSession>> QuestSession = new UpdateField<Optional<QuestSession>>(98, 103);
public UpdateFieldArray<ObjectGuid> InvSlots = new UpdateFieldArray<ObjectGuid>(195, 104, 105);
public UpdateFieldArray<uint> TrackResourceMask = new UpdateFieldArray<uint>(2, 300, 301);
public UpdateFieldArray<ulong> ExploredZones = new UpdateFieldArray<ulong>(192, 303, 304);
public UpdateFieldArray<RestInfo> RestInfo = new UpdateFieldArray<RestInfo>(2, 496, 497);
public UpdateFieldArray<int> ModDamageDonePos = new UpdateFieldArray<int>(7, 499, 500);
public UpdateFieldArray<int> ModDamageDoneNeg = new UpdateFieldArray<int>(7, 499, 507);
public UpdateFieldArray<float> ModDamageDonePercent = new UpdateFieldArray<float>(7, 499, 514);
public UpdateFieldArray<float> WeaponDmgMultipliers = new UpdateFieldArray<float>(3, 521, 522);
public UpdateFieldArray<float> WeaponAtkSpeedMultipliers = new UpdateFieldArray<float>(3, 521, 525);
public UpdateFieldArray<uint> BuybackPrice = new UpdateFieldArray<uint>(12, 528, 529);
public UpdateFieldArray<uint> BuybackTimestamp = new UpdateFieldArray<uint>(12, 528, 541);
public UpdateFieldArray<uint> CombatRatings = new UpdateFieldArray<uint>(32, 553, 554);
public UpdateFieldArray<PVPInfo> PvpInfo = new UpdateFieldArray<PVPInfo>(6, 586, 587);
public UpdateFieldArray<uint> NoReagentCostMask = new UpdateFieldArray<uint>(4, 593, 594);
public UpdateFieldArray<uint> ProfessionSkillLine = new UpdateFieldArray<uint>(2, 598, 599);
public UpdateFieldArray<uint> BagSlotFlags = new UpdateFieldArray<uint>(4, 601, 602);
public UpdateFieldArray<uint> BankBagSlotFlags = new UpdateFieldArray<uint>(7, 606, 607);
public UpdateFieldArray<ulong> QuestCompleted = new UpdateFieldArray<ulong>(875, 614, 615);
public UpdateFieldArray<ObjectGuid> InvSlots = new UpdateFieldArray<ObjectGuid>(199, 104, 105);
public UpdateFieldArray<uint> TrackResourceMask = new UpdateFieldArray<uint>(2, 304, 305);
public UpdateFieldArray<ulong> ExploredZones = new UpdateFieldArray<ulong>(192, 307, 308);
public UpdateFieldArray<RestInfo> RestInfo = new UpdateFieldArray<RestInfo>(2, 500, 501);
public UpdateFieldArray<int> ModDamageDonePos = new UpdateFieldArray<int>(7, 503, 504);
public UpdateFieldArray<int> ModDamageDoneNeg = new UpdateFieldArray<int>(7, 503, 511);
public UpdateFieldArray<float> ModDamageDonePercent = new UpdateFieldArray<float>(7, 503, 518);
public UpdateFieldArray<float> WeaponDmgMultipliers = new UpdateFieldArray<float>(3, 525, 526);
public UpdateFieldArray<float> WeaponAtkSpeedMultipliers = new UpdateFieldArray<float>(3, 525, 529);
public UpdateFieldArray<uint> BuybackPrice = new UpdateFieldArray<uint>(12, 532, 533);
public UpdateFieldArray<uint> BuybackTimestamp = new UpdateFieldArray<uint>(12, 532, 545);
public UpdateFieldArray<uint> CombatRatings = new UpdateFieldArray<uint>(32, 557, 558);
public UpdateFieldArray<PVPInfo> PvpInfo = new UpdateFieldArray<PVPInfo>(6, 590, 591);
public UpdateFieldArray<uint> NoReagentCostMask = new UpdateFieldArray<uint>(4, 597, 598);
public UpdateFieldArray<uint> ProfessionSkillLine = new UpdateFieldArray<uint>(2, 602, 603);
public UpdateFieldArray<uint> BagSlotFlags = new UpdateFieldArray<uint>(4, 605, 606);
public UpdateFieldArray<uint> BankBagSlotFlags = new UpdateFieldArray<uint>(7, 610, 611);
public UpdateFieldArray<ulong> QuestCompleted = new UpdateFieldArray<ulong>(875, 618, 619);
public ActivePlayerData() : base(0, TypeId.ActivePlayer, 1487) { }
public ActivePlayerData() : base(0, TypeId.ActivePlayer, 1494) { }
public override void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver)
{
for (int i = 0; i < 195; ++i)
for (int i = 0; i < 199; ++i)
{
data.WritePackedGuid(InvSlots[i]);
}
@@ -3997,7 +4005,7 @@ namespace Game.Entities
}
if (_changesMask[104])
{
for (int i = 0; i < 195; ++i)
for (int i = 0; i < 199; ++i)
{
if (_changesMask[105 + i])
{
@@ -4005,147 +4013,147 @@ namespace Game.Entities
}
}
}
if (_changesMask[300])
if (_changesMask[304])
{
for (int i = 0; i < 2; ++i)
{
if (_changesMask[301 + i])
if (_changesMask[305 + i])
{
data.WriteUInt32(TrackResourceMask[i]);
}
}
}
if (_changesMask[303])
if (_changesMask[307])
{
for (int i = 0; i < 192; ++i)
{
if (_changesMask[304 + i])
if (_changesMask[308 + i])
{
data.WriteUInt64(ExploredZones[i]);
}
}
}
if (_changesMask[496])
if (_changesMask[500])
{
for (int i = 0; i < 2; ++i)
{
if (_changesMask[497 + i])
if (_changesMask[501 + i])
{
RestInfo[i].WriteUpdate(data, owner, receiver);
}
}
}
if (_changesMask[499])
if (_changesMask[503])
{
for (int i = 0; i < 7; ++i)
{
if (_changesMask[500 + i])
if (_changesMask[504 + i])
{
data.WriteInt32(ModDamageDonePos[i]);
}
if (_changesMask[507 + i])
if (_changesMask[511 + i])
{
data.WriteInt32(ModDamageDoneNeg[i]);
}
if (_changesMask[514 + i])
if (_changesMask[518 + i])
{
data.WriteFloat(ModDamageDonePercent[i]);
}
}
}
if (_changesMask[521])
if (_changesMask[525])
{
for (int i = 0; i < 3; ++i)
{
if (_changesMask[522 + i])
if (_changesMask[526 + i])
{
data.WriteFloat(WeaponDmgMultipliers[i]);
}
if (_changesMask[525 + i])
if (_changesMask[529 + i])
{
data.WriteFloat(WeaponAtkSpeedMultipliers[i]);
}
}
}
if (_changesMask[528])
if (_changesMask[532])
{
for (int i = 0; i < 12; ++i)
{
if (_changesMask[529 + i])
if (_changesMask[533 + i])
{
data.WriteUInt32(BuybackPrice[i]);
}
if (_changesMask[541 + i])
if (_changesMask[545 + i])
{
data.WriteUInt32(BuybackTimestamp[i]);
}
}
}
if (_changesMask[553])
if (_changesMask[557])
{
for (int i = 0; i < 32; ++i)
{
if (_changesMask[554 + i])
if (_changesMask[558 + i])
{
data.WriteUInt32(CombatRatings[i]);
}
}
}
if (_changesMask[593])
if (_changesMask[597])
{
for (int i = 0; i < 4; ++i)
{
if (_changesMask[594 + i])
if (_changesMask[598 + i])
{
data.WriteUInt32(NoReagentCostMask[i]);
}
}
}
if (_changesMask[598])
if (_changesMask[602])
{
for (int i = 0; i < 2; ++i)
{
if (_changesMask[599 + i])
if (_changesMask[603 + i])
{
data.WriteUInt32(ProfessionSkillLine[i]);
}
}
}
if (_changesMask[601])
if (_changesMask[605])
{
for (int i = 0; i < 4; ++i)
{
if (_changesMask[602 + i])
if (_changesMask[606 + i])
{
data.WriteUInt32(BagSlotFlags[i]);
}
}
}
if (_changesMask[606])
if (_changesMask[610])
{
for (int i = 0; i < 7; ++i)
{
if (_changesMask[607 + i])
if (_changesMask[611 + i])
{
data.WriteUInt32(BankBagSlotFlags[i]);
}
}
}
if (_changesMask[614])
if (_changesMask[618])
{
for (int i = 0; i < 875; ++i)
{
if (_changesMask[615 + i])
if (_changesMask[619 + i])
{
data.WriteUInt64(QuestCompleted[i]);
}
}
}
if (_changesMask[586])
if (_changesMask[590])
{
for (int i = 0; i < 6; ++i)
{
if (_changesMask[587 + i])
if (_changesMask[591 + i])
{
PvpInfo[i].WriteUpdate(data, owner, receiver);
}
+79 -14
View File
@@ -437,35 +437,73 @@ namespace Game
oldMSTime = Time.GetMSTime();
_classExpansionRequirementStorage.Clear();
// 0 1
result = DB.World.Query("SELECT classID, expansion FROM `class_expansion_requirement`");
// 0 1 2 3
result = DB.World.Query("SELECT ClassID, RaceID, ActiveExpansionLevel, AccountExpansionLevel FROM `class_expansion_requirement`");
if (!result.IsEmpty())
{
Dictionary<byte, Dictionary<byte, Tuple<byte, byte>>> temp = new Dictionary<byte, Dictionary<byte, Tuple<byte, byte>>>();
uint count = 0;
do
{
byte classID = result.Read<byte>(0);
byte expansion = result.Read<byte>(1);
byte raceID = result.Read<byte>(1);
byte activeExpansionLevel = result.Read<byte>(2);
byte accountExpansionLevel = result.Read<byte>(3);
ChrClassesRecord classEntry = CliDB.ChrClassesStorage.LookupByKey(classID);
if (classEntry == null)
{
Log.outError(LogFilter.Sql, "Class {0} defined in `class_expansion_requirement` does not exists, skipped.", classID);
Log.outError(LogFilter.Sql, $"Class {classID} (race {raceID}) defined in `class_expansion_requirement` does not exists, skipped.");
continue;
}
if (expansion >= (int)Expansion.Max)
ChrRacesRecord raceEntry = CliDB.ChrRacesStorage.LookupByKey(raceID);
if (raceEntry == null)
{
Log.outError(LogFilter.Sql, "Class {0} defined in `class_expansion_requirement` has incorrect expansion {1}, skipped.", classID, expansion);
Log.outError(LogFilter.Sql, $"Race {raceID} (class {classID}) defined in `class_expansion_requirement` does not exists, skipped.");
continue;
}
_classExpansionRequirementStorage[classID] = expansion;
if (activeExpansionLevel >= (int)Expansion.Max)
{
Log.outError(LogFilter.Sql, $"Class {classID} Race {raceID} defined in `class_expansion_requirement` has incorrect ActiveExpansionLevel {activeExpansionLevel}, skipped.");
continue;
}
if (accountExpansionLevel >= (int)Expansion.MaxAccountExpansions)
{
Log.outError(LogFilter.Sql, $"Class {classID} Race {raceID} defined in `class_expansion_requirement` has incorrect AccountExpansionLevel {accountExpansionLevel}, skipped.");
continue;
}
if (!temp.ContainsKey(raceID))
temp[raceID] = new Dictionary<byte, Tuple<byte, byte>>();
temp[raceID][classID] = Tuple.Create(activeExpansionLevel, accountExpansionLevel);
++count;
}
while (result.NextRow());
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} class expansion requirements in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime));
foreach (var race in temp)
{
RaceClassAvailability raceClassAvailability = new RaceClassAvailability();
raceClassAvailability.RaceID = race.Key;
foreach (var class_ in race.Value)
{
ClassAvailability classAvailability = new ClassAvailability();
classAvailability.ClassID = class_.Key;
classAvailability.ActiveExpansionLevel = class_.Value.Item1;
classAvailability.AccountExpansionLevel = class_.Value.Item2;
raceClassAvailability.Classes.Add(classAvailability);
}
_classExpansionRequirementStorage.Add(raceClassAvailability);
}
Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} class expansion requirements in {Time.GetMSTimeDiffToNow(oldMSTime)} ms.");
}
else
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 class expansion requirements. DB table `class_expansion_requirement` is empty.");
@@ -533,12 +571,26 @@ namespace Game
}
public Dictionary<byte, RaceUnlockRequirement> GetRaceUnlockRequirements() { return _raceUnlockRequirementStorage; }
public RaceUnlockRequirement GetRaceUnlockRequirement(Race race) { return _raceUnlockRequirementStorage.LookupByKey((byte)race); }
public Dictionary<byte, byte> GetClassExpansionRequirements() { return _classExpansionRequirementStorage; }
public Expansion GetClassExpansionRequirement(Class class_)
public List<RaceClassAvailability> GetClassExpansionRequirements() { return _classExpansionRequirementStorage; }
public ClassAvailability GetClassExpansionRequirement(Race raceId, Class classId)
{
if (_classExpansionRequirementStorage.ContainsKey((byte)class_))
return (Expansion)_classExpansionRequirementStorage[(byte)class_];
return Expansion.Classic;
var raceClassAvailability = _classExpansionRequirementStorage.Find(raceClass =>
{
return raceClass.RaceID == (byte)raceId;
});
if (raceClassAvailability == null)
return null;
var classAvailability = raceClassAvailability.Classes.Find(availability =>
{
return availability.ClassID == (byte)classId;
});
if (classAvailability == null)
return null;
return classAvailability;
}
public PlayerChoice GetPlayerChoice(int choiceId)
{
@@ -9694,7 +9746,7 @@ namespace Game
Dictionary<uint, SceneTemplate> _sceneTemplateStorage = new Dictionary<uint, SceneTemplate>();
Dictionary<byte, RaceUnlockRequirement> _raceUnlockRequirementStorage = new Dictionary<byte, RaceUnlockRequirement>();
Dictionary<byte, byte> _classExpansionRequirementStorage = new Dictionary<byte, byte>();
List<RaceClassAvailability> _classExpansionRequirementStorage = new List<RaceClassAvailability>();
Dictionary<uint, string> _realmNameStorage = new Dictionary<uint, string>();
//Quest
@@ -10743,6 +10795,19 @@ namespace Game
public bool KeepOpenAfterChoice;
}
public class ClassAvailability
{
public byte ClassID;
public byte ActiveExpansionLevel;
public byte AccountExpansionLevel;
}
public class RaceClassAvailability
{
public byte RaceID;
public List<ClassAvailability> Classes = new List<ClassAvailability>();
}
public class RaceUnlockRequirement
{
public byte Expansion;
+3 -3
View File
@@ -61,7 +61,7 @@ namespace Game
AuctionHelloResponse packet = new AuctionHelloResponse();
packet.Guid = guid;
packet.OpenForBusiness = true; // 3.3.3: 1 - AH enabled, 0 - AH disabled
packet.OpenForBusiness = false; // 3.3.3: 1 - AH enabled, 0 - AH disabled
SendPacket(packet);
}
@@ -590,7 +590,7 @@ namespace Game
SendPacket(result);
}
[WorldPacketHandler(ClientOpcodes.AuctionListItems)]
//[WorldPacketHandler(ClientOpcodes.AuctionListItems)]
void HandleAuctionListItems(AuctionListItems packet)
{
Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None);
@@ -636,7 +636,7 @@ namespace Game
SendPacket(result);
}
[WorldPacketHandler(ClientOpcodes.AuctionListPendingSales)]
//[WorldPacketHandler(ClientOpcodes.AuctionListPendingSales)]
void HandleAuctionListPendingSales(AuctionListPendingSales packet)
{
AuctionListPendingSalesResult result = new AuctionListPendingSalesResult();
@@ -32,10 +32,10 @@ namespace Game
response.SuccessInfo.HasValue = true;
response.SuccessInfo.Value = new AuthResponse.AuthSuccessInfo();
response.SuccessInfo.Value.AccountExpansionLevel = (byte)GetAccountExpansion();
response.SuccessInfo.Value.ActiveExpansionLevel = (byte)GetExpansion();
response.SuccessInfo.Value.AccountExpansionLevel = (byte)GetAccountExpansion();
response.SuccessInfo.Value.VirtualRealmAddress = Global.WorldMgr.GetVirtualRealmAddress();
response.SuccessInfo.Value.Time = (uint)Time.UnixTime;
response.SuccessInfo.Value.Time = (uint)GameTime.GetGameTime();
var realm = Global.WorldMgr.GetRealm();
+10 -3
View File
@@ -246,10 +246,17 @@ namespace Game
//}
// prevent character creating Expansion class without Expansion account
var classExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirement(charCreate.CreateInfo.ClassId);
if (classExpansionRequirement > GetAccountExpansion())
ClassAvailability classExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirement(charCreate.CreateInfo.RaceId, charCreate.CreateInfo.ClassId);
if (classExpansionRequirement == null)
{
Log.outError(LogFilter.Network, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {classExpansionRequirement} class ({charCreate.CreateInfo.ClassId})");
Log.outError(LogFilter.Player, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character for race/class combination that is missing requirements in db ({charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId})");
SendCharCreate(ResponseCodes.CharCreateExpansionClass);
return;
}
if (classExpansionRequirement.ActiveExpansionLevel > (int)GetExpansion() || classExpansionRequirement.AccountExpansionLevel > (int)GetAccountExpansion())
{
Log.outError(LogFilter.Player, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {classExpansionRequirement.AccountExpansionLevel} race/class ({charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId})");
SendCharCreate(ResponseCodes.CharCreateExpansionClass);
return;
}
+1
View File
@@ -94,6 +94,7 @@ namespace Game
QueryGameObjectResponse response = new QueryGameObjectResponse();
response.GameObjectID = packet.GameObjectID;
response.Guid = packet.Guid;
SendPacket(response);
}
}
@@ -354,7 +354,7 @@ namespace Game.Network.Packets
class AuctionListPendingSalesResult : ServerPacket
{
public AuctionListPendingSalesResult() : base(ServerOpcodes.AuctionListPendingSalesResult) { }
public AuctionListPendingSalesResult() : base(ServerOpcodes.Unknown) { }
public override void Write()
{
@@ -132,10 +132,17 @@ namespace Game.Network.Packets
_worldPacket.WriteUInt32(SuccessInfo.Value.CurrencyID);
_worldPacket.WriteUInt32(SuccessInfo.Value.Time);
foreach (var klass in SuccessInfo.Value.AvailableClasses)
foreach (var raceClassAvailability in SuccessInfo.Value.AvailableClasses)
{
_worldPacket.WriteUInt8(klass.Key); // the current class
_worldPacket.WriteUInt8(klass.Value); // the required Expansion
_worldPacket.WriteUInt8(raceClassAvailability.RaceID);
_worldPacket.WriteInt32(raceClassAvailability.Classes.Count);
foreach (var classAvailability in raceClassAvailability.Classes)
{
_worldPacket.WriteUInt8(classAvailability.ClassID);
_worldPacket.WriteUInt8(classAvailability.ActiveExpansionLevel);
_worldPacket.WriteUInt8(classAvailability.AccountExpansionLevel);
}
}
_worldPacket.WriteBit(SuccessInfo.Value.IsExpansionTrial);
@@ -197,8 +204,8 @@ namespace Game.Network.Packets
public class AuthSuccessInfo
{
public byte AccountExpansionLevel; // the current expansion of this account, the possible values are in @ref Expansions
public byte ActiveExpansionLevel; // the current server expansion, the possible values are in @ref Expansions
public byte AccountExpansionLevel; // the current expansion of this account, the possible values are in @ref Expansions
public uint TimeRested; // affects the return value of the GetBillingTimeRested() client API call, it is the number of seconds you have left until the experience points and loot you receive from creatures and quests is reduced. It is only used in the Asia region in retail, it's not implemented in TC and will probably never be.
public uint VirtualRealmAddress; // a special identifier made from the Index, BattleGroup and Region. @todo implement
@@ -211,7 +218,7 @@ namespace Game.Network.Packets
public List<VirtualRealmInfo> VirtualRealms = new List<VirtualRealmInfo>(); // list of realms connected to this one (inclusive) @todo implement
public List<CharacterTemplate> Templates = new List<CharacterTemplate>(); // list of pre-made character templates. @todo implement
public Dictionary<byte, byte> AvailableClasses; // the minimum AccountExpansion required to select the classes
public List<RaceClassAvailability> AvailableClasses; // the minimum AccountExpansion required to select the classes
public bool IsExpansionTrial;
public bool ForceCharacterTemplate; // forces the client to always use a character template when creating a new character. @see Templates. @todo implement
@@ -219,12 +219,21 @@ namespace Game.Network.Packets
data.WriteUInt32(Unknown703);
data.WriteUInt32(LastLoginVersion);
data.WriteUInt32(Flags4);
data.WriteInt32(Unknown830.Count);
data.WriteBits(Name.GetByteCount(), 6);
data.WriteBit(FirstLogin);
data.WriteBit(BoostInProgress);
data.WriteBits(unkWod61x, 5);
foreach (string str in Unknown830)
data.WriteBits(str.GetByteCount() + 1, 6);
data.FlushBits();
foreach (string str in Unknown830)
if (!str.IsEmpty())
data.WriteCString(str);
data.WriteString(Name);
}
@@ -262,6 +271,8 @@ namespace Game.Network.Packets
public bool BoostInProgress; // @todo
public uint[] ProfessionIds = new uint[2]; // @todo
public VisualItemInfo[] VisualItems = new VisualItemInfo[InventorySlots.BagEnd];
public List<string> Unknown830 = new List<string>(); // Something with character names, same length limit as name,
// client accepts unlimited number of these in packet but only uses first 3
public struct VisualItemInfo
{
@@ -460,11 +460,13 @@ namespace Game.Network.Packets
public void Write(WorldPacket data)
{
data.WriteInt32(GarrTalentID);
data.WriteInt32(Rank);
data.WriteUInt32((uint)ResearchStartTime);
data.WriteInt32(Flags);
}
public int GarrTalentID;
public int Rank;
public long ResearchStartTime;
public int Flags;
}
@@ -496,18 +498,18 @@ namespace Game.Network.Packets
mission.Write(data);
foreach (List<GarrisonMissionReward> missionReward in MissionRewards)
{
data.WriteInt32(missionReward.Count);
foreach (List<GarrisonMissionReward> missionReward in MissionRewards)
foreach (GarrisonMissionReward missionRewardItem in missionReward)
missionRewardItem.Write(data);
}
foreach (List<GarrisonMissionReward> missionReward in MissionOvermaxRewards)
{
data.WriteInt32(missionReward.Count);
foreach (List<GarrisonMissionReward> missionReward in MissionOvermaxRewards)
foreach (GarrisonMissionReward missionRewardItem in missionReward)
missionRewardItem.Write(data);
}
foreach (GarrisonMissionBonusAbility areaBonus in MissionAreaBonuses)
areaBonus.Write(data);
@@ -274,6 +274,7 @@ namespace Game.Network.Packets
public override void Write()
{
_worldPacket.WriteUInt32(GameObjectID);
_worldPacket.WritePackedGuid(Guid);
_worldPacket.WriteBit(Allow);
_worldPacket.FlushBits();
@@ -307,6 +308,7 @@ namespace Game.Network.Packets
}
public uint GameObjectID;
public ObjectGuid Guid;
public bool Allow;
public GameObjectStats Stats;
}
@@ -32,6 +32,8 @@ namespace Game.Network.Packets
_worldPacket.WriteUInt32(SceneScriptPackageID);
_worldPacket.WritePackedGuid(TransportGUID);
_worldPacket.WriteXYZO(Location);
_worldPacket.WriteBit(PerformTactCallbacks);
_worldPacket.FlushBits();
}
public uint SceneID;
@@ -40,6 +42,7 @@ namespace Game.Network.Packets
public uint SceneScriptPackageID;
public ObjectGuid TransportGUID;
public Position Location;
public bool PerformTactCallbacks;
}
class CancelScene : ServerPacket
@@ -77,7 +77,6 @@ namespace Game.Network.Packets
_worldPacket.WriteBit(WillKickFromWorld);
_worldPacket.WriteBit(KioskModeEnabled);
_worldPacket.WriteBit(CompetitiveModeEnabled);
_worldPacket.WriteBit(RaceClassExpansionLevels.HasValue);
_worldPacket.WriteBit(TokenBalanceEnabled);
_worldPacket.WriteBit(WarModeFeatureEnabled);
_worldPacket.WriteBit(ClubsEnabled);
@@ -124,13 +123,6 @@ namespace Game.Network.Packets
_worldPacket.WriteInt32(SessionAlert.Value.DisplayTime);
}
if (RaceClassExpansionLevels.HasValue)
{
_worldPacket.WriteInt32(RaceClassExpansionLevels.Value.Count);
foreach (var level in RaceClassExpansionLevels.Value)
_worldPacket.WriteUInt8(level);
}
_worldPacket.WriteBit(VoiceChatManagerSettings.IsSquelched);
_worldPacket.WritePackedGuid(VoiceChatManagerSettings.BnetAccountGuid);
_worldPacket.WritePackedGuid(VoiceChatManagerSettings.GuildGuid);
@@ -192,7 +184,6 @@ namespace Game.Network.Packets
public bool IsMuted;
public bool ClubFinderEnabled;
public Optional<List<byte>> RaceClassExpansionLevels;
public SocialQueueConfig QuickJoinConfig;
public VoiceChatProxySettings VoiceChatManagerSettings;
public RafSystemFeatureInfo RAFSystem;
@@ -0,0 +1,7 @@
UPDATE `character_inventory` SET `slot`=`slot`+4 WHERE `slot`>=47 AND `bag`=0;
ALTER TABLE `item_instance_azerite`
ADD `selectedAzeriteEssences1azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0' AFTER `selectedAzeriteEssences1azeriteEssenceId3`,
ADD `selectedAzeriteEssences2azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0' AFTER `selectedAzeriteEssences2azeriteEssenceId3`,
ADD `selectedAzeriteEssences3azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0' AFTER `selectedAzeriteEssences3azeriteEssenceId3`,
ADD `selectedAzeriteEssences4azeriteEssenceId4` int(10) unsigned NULL DEFAULT '0' AFTER `selectedAzeriteEssences4azeriteEssenceId3`;
@@ -0,0 +1,223 @@
DROP TABLE IF EXISTS `class_expansion_requirement`;
CREATE TABLE `class_expansion_requirement` (
`ClassID` tinyint(3) unsigned NOT NULL,
`RaceID` tinyint(3) unsigned NOT NULL,
`ActiveExpansionLevel` tinyint(3) unsigned DEFAULT '0',
`AccountExpansionLevel` tinyint(3) unsigned DEFAULT '0',
PRIMARY KEY (`ClassID`,`RaceID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
--
-- Dumping data for table `class_expansion_requirement`
--
INSERT INTO `class_expansion_requirement` VALUES
(1,1,0,0),
(1,2,0,0),
(1,3,0,0),
(1,4,0,0),
(1,5,0,0),
(1,6,0,0),
(1,7,0,0),
(1,8,0,0),
(1,9,0,0),
(1,10,0,0),
(1,11,0,0),
(1,22,0,0),
(1,24,0,0),
(1,25,0,0),
(1,26,0,0),
(1,27,0,0),
(1,28,0,0),
(1,29,0,0),
(1,30,0,0),
(1,31,0,0),
(1,32,0,0),
(1,34,0,0),
(1,35,0,0),
(1,36,0,0),
(1,37,0,0),
(2,1,0,0),
(2,3,0,0),
(2,6,0,0),
(2,10,0,0),
(2,11,0,0),
(2,30,0,0),
(2,31,0,0),
(2,34,0,0),
(3,1,0,0),
(3,2,0,0),
(3,3,0,0),
(3,4,0,0),
(3,5,0,0),
(3,6,0,0),
(3,7,0,0),
(3,8,0,0),
(3,9,0,0),
(3,10,0,0),
(3,11,0,0),
(3,22,0,0),
(3,24,0,0),
(3,25,0,0),
(3,26,0,0),
(3,27,0,0),
(3,28,0,0),
(3,29,0,0),
(3,30,0,0),
(3,31,0,0),
(3,32,0,0),
(3,34,0,0),
(3,35,0,0),
(3,36,0,0),
(3,37,0,0),
(4,1,0,0),
(4,2,0,0),
(4,3,0,0),
(4,4,0,0),
(4,5,0,0),
(4,7,0,0),
(4,8,0,0),
(4,9,0,0),
(4,10,0,0),
(4,22,0,0),
(4,24,0,0),
(4,25,0,0),
(4,26,0,0),
(4,27,0,0),
(4,29,0,0),
(4,31,0,0),
(4,32,0,0),
(4,34,0,0),
(4,35,0,0),
(4,36,0,0),
(4,37,0,0),
(5,1,0,0),
(5,3,0,0),
(5,4,0,0),
(5,5,0,0),
(5,6,0,0),
(5,7,0,0),
(5,8,0,0),
(5,9,0,0),
(5,10,0,0),
(5,11,0,0),
(5,22,0,0),
(5,24,0,0),
(5,25,0,0),
(5,26,0,0),
(5,27,0,0),
(5,29,0,0),
(5,30,0,0),
(5,31,0,0),
(5,32,0,0),
(5,34,0,0),
(5,35,0,0),
(5,36,0,0),
(5,37,0,0),
(6,1,2,2),
(6,2,2,2),
(6,3,2,2),
(6,4,2,2),
(6,5,2,2),
(6,6,2,2),
(6,7,2,2),
(6,8,2,2),
(6,9,2,2),
(6,10,2,2),
(6,11,2,2),
(6,22,2,2),
(6,24,2,8),
(6,25,2,8),
(6,26,2,8),
(6,27,2,8),
(6,28,2,8),
(6,29,2,8),
(6,30,2,8),
(6,31,2,8),
(6,32,2,8),
(6,34,2,8),
(6,35,2,8),
(6,36,2,8),
(6,37,2,8),
(7,2,0,0),
(7,3,0,0),
(7,6,0,0),
(7,8,0,0),
(7,9,0,0),
(7,11,0,0),
(7,24,0,0),
(7,25,0,0),
(7,26,0,0),
(7,28,0,0),
(7,31,0,0),
(7,32,0,0),
(7,34,0,0),
(7,35,0,0),
(7,36,0,0),
(8,1,0,0),
(8,2,0,0),
(8,3,0,0),
(8,4,0,0),
(8,5,0,0),
(8,7,0,0),
(8,8,0,0),
(8,9,0,0),
(8,10,0,0),
(8,11,0,0),
(8,22,0,0),
(8,24,0,0),
(8,25,0,0),
(8,26,0,0),
(8,27,0,0),
(8,29,0,0),
(8,30,0,0),
(8,31,0,0),
(8,32,0,0),
(8,34,0,0),
(8,35,0,0),
(8,36,0,0),
(8,37,0,0),
(9,1,0,0),
(9,2,0,0),
(9,3,0,0),
(9,5,0,0),
(9,7,0,0),
(9,8,0,0),
(9,9,0,0),
(9,10,0,0),
(9,22,0,0),
(9,27,0,0),
(9,29,0,0),
(9,34,0,0),
(9,35,0,0),
(9,37,0,0),
(10,1,4,4),
(10,2,4,4),
(10,3,4,4),
(10,4,4,4),
(10,5,4,4),
(10,6,4,4),
(10,7,4,4),
(10,8,4,4),
(10,10,4,4),
(10,11,4,4),
(10,24,4,4),
(10,25,4,4),
(10,26,4,4),
(10,27,4,4),
(10,28,4,4),
(10,29,4,4),
(10,31,4,4),
(10,32,4,4),
(10,34,4,4),
(10,35,4,4),
(10,36,4,4),
(10,37,4,4),
(11,4,0,0),
(11,6,0,0),
(11,8,0,0),
(11,22,0,0),
(11,28,0,0),
(11,31,0,0),
(11,32,0,0),
(12,4,6,6),
(12,10,6,6);