Core: Update to 10.2.0
Port From (https://github.com/TrinityCore/TrinityCore/commit/1eea1d11b14d2ae065ab0f1888fba3b1ef03874f)
This commit is contained in:
@@ -153,6 +153,7 @@ namespace Game.Achievements
|
||||
case CriteriaType.DamageDealt:
|
||||
case CriteriaType.HealingDone:
|
||||
case CriteriaType.EarnArtifactXPForAzeriteItem:
|
||||
case CriteriaType.GainLevels:
|
||||
SetCriteriaProgress(criteria, miscValue1, referencePlayer, ProgressType.Accumulate);
|
||||
break;
|
||||
case CriteriaType.KillCreature:
|
||||
@@ -458,7 +459,7 @@ namespace Game.Achievements
|
||||
}
|
||||
else
|
||||
_startedCriteria[key] -= timeDiff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCriteria(CriteriaStartEvent startEvent, uint entry, TimeSpan timeLost = default)
|
||||
@@ -799,6 +800,7 @@ namespace Game.Achievements
|
||||
case CriteriaType.CompleteAnyReplayQuest:
|
||||
case CriteriaType.BuyItemsFromVendors:
|
||||
case CriteriaType.SellItemsToVendors:
|
||||
case CriteriaType.GainLevels:
|
||||
return progress.Counter >= requiredAmount;
|
||||
case CriteriaType.EarnAchievement:
|
||||
case CriteriaType.CompleteQuest:
|
||||
@@ -932,6 +934,7 @@ namespace Game.Achievements
|
||||
case CriteriaType.CompleteAnyReplayQuest:
|
||||
case CriteriaType.BuyItemsFromVendors:
|
||||
case CriteriaType.SellItemsToVendors:
|
||||
case CriteriaType.GainLevels:
|
||||
if (miscValue1 == 0)
|
||||
return false;
|
||||
break;
|
||||
@@ -3291,6 +3294,15 @@ namespace Game.Achievements
|
||||
case 149: // Shadowlands Season 2 End
|
||||
// timestamp = unknown
|
||||
break;
|
||||
case 349: // Dragonflight Season 3 Start (pre-season)
|
||||
eventTimestamp = 1699340400L; // November 7, 2023 8:00
|
||||
break;
|
||||
case 350: // Dragonflight Season 3 Start
|
||||
eventTimestamp = 1699945200L; // November 14, 2023 8:00
|
||||
break;
|
||||
case 352: // Dragonflight Season 3 End
|
||||
// eventTimestamp = time_t(); unknown
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3668,6 +3680,13 @@ namespace Game.Achievements
|
||||
if (referencePlayer.GetPositionZ() >= reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType.PlayerIsOnMapWithExpansion: // 380
|
||||
{
|
||||
var mapEntry = referencePlayer.GetMap().GetEntry();
|
||||
if (mapEntry.ExpansionID != reqValue)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -3706,8 +3725,8 @@ namespace Game.Achievements
|
||||
MultiMap<uint, Criteria>[] _scenarioCriteriasByTypeAndScenarioId = new MultiMap<uint, Criteria>[(int)CriteriaType.Count];
|
||||
MultiMap<CriteriaType, Criteria> _questObjectiveCriteriasByType = new();
|
||||
|
||||
MultiMap<int, Criteria>[] _criteriasByStartEvent = new MultiMap<int, Criteria>[(int)CriteriaStartEvent.Max];
|
||||
MultiMap<int, Criteria>[] _criteriasByFailEvent = new MultiMap<int, Criteria>[(int)CriteriaFailEvent.Max];
|
||||
MultiMap<int, Criteria>[] _criteriasByStartEvent = new MultiMap<int, Criteria>[(int)CriteriaStartEvent.Count];
|
||||
MultiMap<int, Criteria>[] _criteriasByFailEvent = new MultiMap<int, Criteria>[(int)CriteriaFailEvent.Count];
|
||||
|
||||
CriteriaManager()
|
||||
{
|
||||
@@ -3717,10 +3736,10 @@ namespace Game.Achievements
|
||||
_scenarioCriteriasByTypeAndScenarioId[i] = new MultiMap<uint, Criteria>();
|
||||
}
|
||||
|
||||
for (var i = 0; i < (int)CriteriaStartEvent.Max; ++i)
|
||||
for (var i = 0; i < (int)CriteriaStartEvent.Count; ++i)
|
||||
_criteriasByStartEvent[i] = new();
|
||||
|
||||
for (var i = 0; i < (int)CriteriaFailEvent.Max; ++i)
|
||||
for (var i = 0; i < (int)CriteriaFailEvent.Count; ++i)
|
||||
_criteriasByFailEvent[i] = new();
|
||||
|
||||
}
|
||||
@@ -3836,7 +3855,7 @@ namespace Game.Achievements
|
||||
_criteriaTreeByCriteria.Add(pair.Value.Entry.CriteriaID, pair.Value);
|
||||
}
|
||||
|
||||
for (var i = 0; i < (int)CriteriaFailEvent.Max; ++i)
|
||||
for (var i = 0; i < (int)CriteriaFailEvent.Count; ++i)
|
||||
_criteriasByFailEvent[i] = new MultiMap<int, Criteria>();
|
||||
|
||||
// Load criteria
|
||||
@@ -3846,10 +3865,9 @@ namespace Game.Achievements
|
||||
uint questObjectiveCriterias = 0;
|
||||
foreach (CriteriaRecord criteriaEntry in CliDB.CriteriaStorage.Values)
|
||||
{
|
||||
Cypher.Assert(criteriaEntry.Type < CriteriaType.Count,
|
||||
$"CRITERIA_TYPE_TOTAL must be greater than or equal to {criteriaEntry.Type + 1} but is currently equal to {CriteriaType.Count}");
|
||||
Cypher.Assert(criteriaEntry.StartEvent < (byte)CriteriaStartEvent.Max, $"CRITERIA_TYPE_TOTAL must be greater than or equal to {criteriaEntry.StartEvent + 1} but is currently equal to {CriteriaStartEvent.Max}");
|
||||
Cypher.Assert(criteriaEntry.FailEvent < (byte)CriteriaFailEvent.Max, $"CRITERIA_CONDITION_MAX must be greater than or equal to {criteriaEntry.FailEvent + 1} but is currently equal to {CriteriaFailEvent.Max}");
|
||||
Cypher.Assert(criteriaEntry.Type < CriteriaType.Count, $"CriteriaType.Count must be greater than or equal to {criteriaEntry.Type + 1} but is currently equal to {CriteriaType.Count}");
|
||||
Cypher.Assert(criteriaEntry.StartEvent < (byte)CriteriaStartEvent.Count, $"CriteriaStartEvent.Count must be greater than or equal to {criteriaEntry.StartEvent + 1} but is currently equal to {CriteriaStartEvent.Count}");
|
||||
Cypher.Assert(criteriaEntry.FailEvent < (byte)CriteriaFailEvent.Count, $"CriteriaFailEvent.Count must be greater than or equal to {criteriaEntry.FailEvent + 1} but is currently equal to {CriteriaFailEvent.Count}");
|
||||
|
||||
var treeList = _criteriaTreeByCriteria.LookupByKey(criteriaEntry.Id);
|
||||
if (treeList.Empty())
|
||||
@@ -4086,7 +4104,7 @@ namespace Game.Achievements
|
||||
{
|
||||
return _criteriasByFailEvent[(int)failEvent].LookupByKey(asset);
|
||||
}
|
||||
|
||||
|
||||
public List<Criteria> GetGuildCriteriaByType(CriteriaType type)
|
||||
{
|
||||
return _guildCriteriasByType.LookupByKey(type);
|
||||
|
||||
@@ -281,6 +281,7 @@ namespace Game.DataStorage
|
||||
SceneScriptGlobalTextStorage = ReadDB2<SceneScriptGlobalTextRecord>("SceneScriptGlobalText.db2", HotfixStatements.SEL_SCENE_SCRIPT_GLOBAL_TEXT);
|
||||
SceneScriptPackageStorage = ReadDB2<SceneScriptPackageRecord>("SceneScriptPackage.db2", HotfixStatements.SEL_SCENE_SCRIPT_PACKAGE);
|
||||
SceneScriptTextStorage = ReadDB2<SceneScriptTextRecord>("SceneScriptText.db2", HotfixStatements.SEL_SCENE_SCRIPT_TEXT);
|
||||
ServerMessagesStorage = ReadDB2<ServerMessagesRecord>("ServerMessages.db2", HotfixStatements.SEL_SERVER_MESSAGES, HotfixStatements.SEL_SERVER_MESSAGES_LOCALE);
|
||||
SkillLineStorage = ReadDB2<SkillLineRecord>("SkillLine.db2", HotfixStatements.SEL_SKILL_LINE, HotfixStatements.SEL_SKILL_LINE_LOCALE);
|
||||
SkillLineAbilityStorage = ReadDB2<SkillLineAbilityRecord>("SkillLineAbility.db2", HotfixStatements.SEL_SKILL_LINE_ABILITY);
|
||||
SkillLineXTraitTreeStorage = ReadDB2<SkillLineXTraitTreeRecord>("SkillLineXTraitTree.db2", HotfixStatements.SEL_SKILL_LINE_X_TRAIT_TREE);
|
||||
@@ -715,6 +716,7 @@ namespace Game.DataStorage
|
||||
public static DB6Storage<SceneScriptGlobalTextRecord> SceneScriptGlobalTextStorage;
|
||||
public static DB6Storage<SceneScriptPackageRecord> SceneScriptPackageStorage;
|
||||
public static DB6Storage<SceneScriptTextRecord> SceneScriptTextStorage;
|
||||
public static DB6Storage<ServerMessagesRecord> ServerMessagesStorage;
|
||||
public static DB6Storage<SkillLineRecord> SkillLineStorage;
|
||||
public static DB6Storage<SkillLineAbilityRecord> SkillLineAbilityStorage;
|
||||
public static DB6Storage<SkillLineXTraitTreeRecord> SkillLineXTraitTreeStorage;
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Game.DataStorage
|
||||
public Vector3 Pos;
|
||||
public uint Id;
|
||||
public ushort ContinentID;
|
||||
public sbyte PhaseUseFlags;
|
||||
public int PhaseUseFlags;
|
||||
public ushort PhaseID;
|
||||
public ushort PhaseGroupID;
|
||||
public float Radius;
|
||||
|
||||
@@ -163,6 +163,7 @@ namespace Game.DataStorage
|
||||
public uint DisplayID;
|
||||
public float BarberShopMinCameraDistance;
|
||||
public float BarberShopHeightOffset;
|
||||
public float BarberShopCameraZoomOffset;
|
||||
}
|
||||
|
||||
public sealed class ChrCustomizationElementRecord
|
||||
@@ -180,6 +181,7 @@ namespace Game.DataStorage
|
||||
public int ChrCustomizationVoiceID;
|
||||
public int AnimKitID;
|
||||
public int ParticleColorID;
|
||||
public int ChrCustGeoComponentLinkID;
|
||||
}
|
||||
|
||||
public sealed class ChrCustomizationOptionRecord
|
||||
@@ -422,6 +424,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public uint BroadcastTextID;
|
||||
public uint Unused1020;
|
||||
public uint SpellVisualKitID;
|
||||
public int AdditionalDuration;
|
||||
public ushort NextConversationLineID;
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace Game.DataStorage
|
||||
public byte KeyID;
|
||||
public uint AudioFileDataID;
|
||||
public uint SubtitleFileDataID;
|
||||
public int SubtitleFileFormat;
|
||||
public uint SubtitleFileFormat;
|
||||
}
|
||||
|
||||
public sealed class MythicPlusSeasonRecord
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Game.DataStorage
|
||||
public int MaxAvgItemLevel;
|
||||
public ushort MinAvgEquippedItemLevel;
|
||||
public ushort MaxAvgEquippedItemLevel;
|
||||
public byte PhaseUseFlags;
|
||||
public int PhaseUseFlags;
|
||||
public ushort PhaseID;
|
||||
public uint PhaseGroupID;
|
||||
public int Flags;
|
||||
|
||||
@@ -68,6 +68,12 @@ namespace Game.DataStorage
|
||||
public string Script;
|
||||
}
|
||||
|
||||
public sealed class ServerMessagesRecord
|
||||
{
|
||||
public uint Id;
|
||||
public LocalizedString Text;
|
||||
}
|
||||
|
||||
public sealed class SkillLineRecord
|
||||
{
|
||||
public LocalizedString DisplayName;
|
||||
@@ -544,6 +550,7 @@ namespace Game.DataStorage
|
||||
{
|
||||
public uint Id;
|
||||
public string Name;
|
||||
public uint CreatureDisplayID;
|
||||
public sbyte CreatureType;
|
||||
public SpellShapeshiftFormFlags Flags;
|
||||
public int AttackIconFileID;
|
||||
@@ -551,7 +558,6 @@ namespace Game.DataStorage
|
||||
public ushort CombatRoundTime;
|
||||
public float DamageVariance;
|
||||
public ushort MountTypeID;
|
||||
public uint[] CreatureDisplayID = new uint[4];
|
||||
public uint[] PresetSpellID = new uint[SpellConst.MaxShapeshift];
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Game.DataStorage
|
||||
public uint Id;
|
||||
public int ParentUiMapID;
|
||||
public int Flags;
|
||||
public byte System;
|
||||
public sbyte System;
|
||||
public UiMapType Type;
|
||||
public int BountySetID;
|
||||
public uint BountyDisplayLocation;
|
||||
|
||||
@@ -127,15 +127,16 @@ namespace Game.Entities
|
||||
if (!Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.ConversationLine, line.Id, creator))
|
||||
continue;
|
||||
|
||||
var convoLine = CliDB.ConversationLineStorage.LookupByKey(line.Id); // never null for conversationTemplate->Lines
|
||||
|
||||
ConversationLine lineField = new();
|
||||
lineField.ConversationLineID = line.Id;
|
||||
lineField.BroadcastTextID = convoLine.BroadcastTextID;
|
||||
lineField.UiCameraID = line.UiCameraID;
|
||||
lineField.ActorIndex = line.ActorIdx;
|
||||
lineField.Flags = line.Flags;
|
||||
lineField.ChatType = line.ChatType;
|
||||
|
||||
ConversationLineRecord convoLine = CliDB.ConversationLineStorage.LookupByKey(line.Id); // never null for conversationTemplate->Lines
|
||||
|
||||
for (Locale locale = Locale.enUS; locale < Locale.Total; locale = locale + 1)
|
||||
{
|
||||
if (locale == Locale.None)
|
||||
|
||||
@@ -126,6 +126,43 @@ namespace Game.Entities
|
||||
public bool HasValue() { return _hasValue; }
|
||||
}
|
||||
|
||||
public class UpdateFieldArrayString
|
||||
{
|
||||
public string[] _values;
|
||||
public int FirstElementBit;
|
||||
public int Bit;
|
||||
|
||||
public UpdateFieldArrayString(uint size, int bit, int firstElementBit)
|
||||
{
|
||||
_values = new string[size];
|
||||
for (var i = 0; i < size; ++i)
|
||||
_values[i] = "";
|
||||
|
||||
Bit = bit;
|
||||
FirstElementBit = firstElementBit;
|
||||
}
|
||||
|
||||
public string this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _values[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
_values[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSize() { return _values.Length; }
|
||||
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
{
|
||||
foreach (var obj in _values)
|
||||
yield return obj;
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateFieldArray<T> where T : new()
|
||||
{
|
||||
public T[] _values;
|
||||
@@ -404,6 +441,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearChangesMask(UpdateFieldArrayString updateField) { }
|
||||
|
||||
public void ClearChangesMask<U>(DynamicUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
if (typeof(IHasChangesMask).IsAssignableFrom(typeof(U)))
|
||||
@@ -421,24 +460,30 @@ namespace Game.Entities
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public OptionalUpdateField<U> ModifyValue<U>(OptionalUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public UpdateFieldString ModifyValue(UpdateFieldString updateField)
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public OptionalUpdateField<U> ModifyValue<U>(OptionalUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public ref U ModifyValue<U>(UpdateFieldArray<U> updateField, int index) where U : new()
|
||||
{
|
||||
MarkChanged(updateField, index);
|
||||
return ref updateField._values[index];
|
||||
}
|
||||
|
||||
public ref string ModifyValue(UpdateFieldArrayString updateField, int index)
|
||||
{
|
||||
MarkChanged(updateField, index);
|
||||
return ref updateField._values[index];
|
||||
}
|
||||
|
||||
public DynamicUpdateField<U> ModifyValue<U>(DynamicUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
@@ -486,6 +531,12 @@ namespace Game.Entities
|
||||
_changesMask.Set(updateField.FirstElementBit + index);
|
||||
}
|
||||
|
||||
public void MarkChanged(UpdateFieldArrayString updateField, int index)
|
||||
{
|
||||
_changesMask.Set(updateField.Bit);
|
||||
_changesMask.Set(updateField.FirstElementBit + index);
|
||||
}
|
||||
|
||||
public void WriteCompleteDynamicFieldUpdateMask(int size, WorldPacket data, int bitsForSize = 32)
|
||||
{
|
||||
data.WriteBits(size, bitsForSize);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -832,6 +832,15 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUpdateFieldValue(ref string value, string newValue)
|
||||
{
|
||||
if (!newValue.Equals(value))
|
||||
{
|
||||
value = newValue;
|
||||
AddToObjectUpdateIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUpdateFieldValue<T>(DynamicUpdateField<T> updateField, int index, T newValue) where T : new()
|
||||
{
|
||||
if (!newValue.Equals(updateField[index]))
|
||||
|
||||
@@ -465,7 +465,7 @@ namespace Game.Entities
|
||||
do
|
||||
{
|
||||
var spell = m_spells.LookupByKey(favoritesResult.Read<uint>(0));
|
||||
if (spell !=null)
|
||||
if (spell != null)
|
||||
spell.Favorite = true;
|
||||
} while (favoritesResult.NextRow());
|
||||
}
|
||||
@@ -1388,9 +1388,9 @@ namespace Game.Entities
|
||||
if (result.IsEmpty())
|
||||
return;
|
||||
|
||||
_declinedname = new DeclinedName();
|
||||
for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
|
||||
_declinedname.name[i] = result.Read<string>(i);
|
||||
DeclinedNames declinedNames = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.DeclinedNames);
|
||||
for (int i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
|
||||
SetUpdateFieldValue(ref declinedNames.ModifyValue(declinedNames.Name, i), result.Read<string>(i));
|
||||
}
|
||||
void _LoadArenaTeamInfo(SQLResult result)
|
||||
{
|
||||
@@ -2047,7 +2047,7 @@ namespace Game.Entities
|
||||
void _SaveActions(SQLTransaction trans)
|
||||
{
|
||||
int traitConfigId = 0;
|
||||
|
||||
|
||||
TraitConfig traitConfig = GetTraitConfig((int)(uint)m_activePlayerData.ActiveCombatTraitConfigID);
|
||||
if (traitConfig != null)
|
||||
{
|
||||
@@ -2430,7 +2430,7 @@ namespace Game.Entities
|
||||
|
||||
m_traitConfigStates.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void _SaveMail(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt;
|
||||
@@ -2863,7 +2863,11 @@ namespace Game.Entities
|
||||
PlayerRestState honorRestState = (PlayerRestState)result.Read<byte>(fieldIndex++);
|
||||
float honorRestBonus = result.Read<float>(fieldIndex++);
|
||||
byte numRespecs = result.Read<byte>(fieldIndex++);
|
||||
|
||||
int personalTabardEmblemStyle = result.Read<int>(fieldIndex++);
|
||||
int personalTabardEmblemColor = result.Read<int>(fieldIndex++);
|
||||
int personalTabardBorderStyle = result.Read<int>(fieldIndex++);
|
||||
int personalTabardBorderColor = result.Read<int>(fieldIndex++);
|
||||
int personalTabardBackgroundColor = result.Read<int>(fieldIndex++);
|
||||
|
||||
// check if the character's account in the db and the logged in account match.
|
||||
// player should be able to load/delete character only with correct account!
|
||||
@@ -2895,9 +2899,10 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.Name), GetName());
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.WowAccount), GetSession().GetAccountGUID());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BnetAccount), GetSession().GetBattlenetAccountGUID());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.BnetAccount), GetSession().GetBattlenetAccountGUID());
|
||||
|
||||
if (gender >= Gender.None)
|
||||
{
|
||||
@@ -3099,7 +3104,7 @@ namespace Game.Entities
|
||||
transport = transportOnMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (transport != null)
|
||||
{
|
||||
float x = trans_x;
|
||||
@@ -3217,7 +3222,7 @@ namespace Game.Entities
|
||||
else if (map.IsDungeon()) // if map is dungeon...
|
||||
{
|
||||
TransferAbortParams denyReason = map.CannotEnter(this); // ... and can't enter map, then look for entry point.
|
||||
if (denyReason != null)
|
||||
if (denyReason != null)
|
||||
{
|
||||
SendTransferAborted(map.GetId(), denyReason.Reason, denyReason.Arg, denyReason.MapDifficultyXConditionId);
|
||||
areaTrigger = Global.ObjectMgr.GetGoBackTrigger(mapId);
|
||||
@@ -3460,6 +3465,8 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
SetPersonalTabard(personalTabardEmblemStyle, personalTabardEmblemColor, personalTabardBorderStyle, personalTabardBorderColor, personalTabardBackgroundColor);
|
||||
|
||||
Log.outDebug(LogFilter.Player, "The value of player {0} after load item and aura is: ", GetName());
|
||||
|
||||
// GM state
|
||||
|
||||
@@ -237,7 +237,6 @@ namespace Game.Entities
|
||||
TimeTracker m_groupUpdateTimer;
|
||||
|
||||
ulong m_GuildIdInvited;
|
||||
DeclinedName _declinedname;
|
||||
Runes m_runes = new();
|
||||
uint m_hostileReferenceCheckTimer;
|
||||
uint m_drunkTimer;
|
||||
|
||||
@@ -138,7 +138,6 @@ namespace Game.Entities
|
||||
PlayerTalkClass.ClearMenus();
|
||||
ItemSetEff.Clear();
|
||||
|
||||
_declinedname = null;
|
||||
m_runes = null;
|
||||
m_achievementSys = null;
|
||||
reputationMgr = null;
|
||||
@@ -816,7 +815,7 @@ namespace Game.Entities
|
||||
_session.SendPacket(data);
|
||||
}
|
||||
|
||||
public DeclinedName GetDeclinedNames() { return _declinedname; }
|
||||
public DeclinedNames GetDeclinedNames() { return m_playerData.DeclinedNames.HasValue() ? m_playerData.DeclinedNames.GetValue() : null; }
|
||||
|
||||
public void CreateGarrison(uint garrSiteId)
|
||||
{
|
||||
@@ -1040,7 +1039,7 @@ namespace Game.Entities
|
||||
if (!m_activePlayerData.PetStable.HasValue())
|
||||
return ObjectGuid.Empty;
|
||||
|
||||
return m_activePlayerData.PetStable.GetValue().StableMaster;
|
||||
return m_activePlayerData.PetStable.GetValue().StableMaster;
|
||||
}
|
||||
|
||||
public void SetStableMaster(ObjectGuid stableMaster)
|
||||
@@ -1051,7 +1050,7 @@ namespace Game.Entities
|
||||
StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
SetUpdateFieldValue(stableInfo.ModifyValue(stableInfo.StableMaster), stableMaster);
|
||||
}
|
||||
|
||||
|
||||
// last used pet number (for BG's)
|
||||
public uint GetLastPetNumber() { return m_lastpetnumber; }
|
||||
public void SetLastPetNumber(uint petnumber) { m_lastpetnumber = petnumber; }
|
||||
@@ -1059,7 +1058,7 @@ namespace Game.Entities
|
||||
public void SetTemporaryUnsummonedPetNumber(uint petnumber) { m_temporaryUnsummonedPetNumber = petnumber; }
|
||||
|
||||
public ReactStates? GetTemporaryPetReactState() { return m_temporaryPetReactState; }
|
||||
|
||||
|
||||
public void DisablePetControlsOnMount(ReactStates reactState, CommandStates commandState)
|
||||
{
|
||||
Pet pet = GetPet();
|
||||
@@ -2667,11 +2666,12 @@ namespace Game.Entities
|
||||
case GossipOptionNpc.Binder:
|
||||
case GossipOptionNpc.Banker:
|
||||
case GossipOptionNpc.PetitionVendor:
|
||||
case GossipOptionNpc.TabardVendor:
|
||||
case GossipOptionNpc.GuildTabardVendor:
|
||||
case GossipOptionNpc.Auctioneer:
|
||||
case GossipOptionNpc.Mailbox:
|
||||
case GossipOptionNpc.Transmogrify:
|
||||
case GossipOptionNpc.AzeriteRespec:
|
||||
case GossipOptionNpc.PersonalTabardVendor:
|
||||
break; // No checks
|
||||
case GossipOptionNpc.CemeterySelect:
|
||||
canTalk = false; // Deprecated
|
||||
@@ -2887,7 +2887,7 @@ namespace Game.Entities
|
||||
{
|
||||
PlayerInteractionType.None, PlayerInteractionType.Vendor, PlayerInteractionType.TaxiNode,
|
||||
PlayerInteractionType.Trainer, PlayerInteractionType.SpiritHealer, PlayerInteractionType.Binder,
|
||||
PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.TabardVendor,
|
||||
PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.GuildTabardVendor,
|
||||
PlayerInteractionType.BattleMaster, PlayerInteractionType.Auctioneer, PlayerInteractionType.TalentMaster,
|
||||
PlayerInteractionType.StableMaster, PlayerInteractionType.None, PlayerInteractionType.GuildBanker,
|
||||
PlayerInteractionType.None, PlayerInteractionType.None, PlayerInteractionType.None,
|
||||
@@ -2902,7 +2902,8 @@ namespace Game.Entities
|
||||
PlayerInteractionType.LegendaryCrafting, PlayerInteractionType.NewPlayerGuide, PlayerInteractionType.LegendaryCrafting,
|
||||
PlayerInteractionType.Renown, PlayerInteractionType.BlackMarketAuctioneer, PlayerInteractionType.PerksProgramVendor,
|
||||
PlayerInteractionType.ProfessionsCraftingOrder, PlayerInteractionType.Professions, PlayerInteractionType.ProfessionsCustomerOrder,
|
||||
PlayerInteractionType.TraitSystem, PlayerInteractionType.BarbersChoice, PlayerInteractionType.MajorFactionRenown
|
||||
PlayerInteractionType.TraitSystem, PlayerInteractionType.BarbersChoice, PlayerInteractionType.MajorFactionRenown,
|
||||
PlayerInteractionType.PersonalTabardVendor
|
||||
};
|
||||
|
||||
PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[(int)gossipOptionNpc];
|
||||
@@ -4313,9 +4314,9 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
ObjectGuid GetSpiritHealerGUID() { return _areaSpiritHealerGUID; }
|
||||
|
||||
|
||||
public bool CanAcceptAreaSpiritHealFrom(Unit spiritHealer) { return spiritHealer.GetGUID() == _areaSpiritHealerGUID; }
|
||||
|
||||
|
||||
public void SetAreaSpiritHealer(Creature creature)
|
||||
{
|
||||
if (creature == null)
|
||||
@@ -4349,7 +4350,7 @@ namespace Game.Entities
|
||||
areaSpiritHealerTime.TimeLeft = (uint)timeLeft;
|
||||
SendPacket(areaSpiritHealerTime);
|
||||
}
|
||||
|
||||
|
||||
public void KillPlayer()
|
||||
{
|
||||
if (IsFlying() && GetTransport() == null)
|
||||
@@ -5254,7 +5255,7 @@ namespace Game.Entities
|
||||
if (guildId != 0)
|
||||
{
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.GuildGUID), ObjectGuid.Create(HighGuid.Guild, guildId));
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.GuildClubMemberID), GetGUID().GetCounter());
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_playerData.GuildClubMemberID), GetGUID().GetCounter());
|
||||
SetPlayerFlag(PlayerFlags.GuildLevelEnabled);
|
||||
}
|
||||
else
|
||||
@@ -5376,6 +5377,8 @@ namespace Game.Entities
|
||||
StartCriteria(CriteriaStartEvent.ReachLevel, level);
|
||||
UpdateCriteria(CriteriaType.ReachLevel);
|
||||
UpdateCriteria(CriteriaType.ActivelyReachLevel, level);
|
||||
if (level > oldLevel)
|
||||
UpdateCriteria(CriteriaType.GainLevels, level - oldLevel);
|
||||
|
||||
PushQuests();
|
||||
|
||||
@@ -7691,10 +7694,10 @@ namespace Game.Entities
|
||||
public void RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
||||
|
||||
public void SetTransportServerTime(int transportServerTime) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TransportServerTime), transportServerTime); }
|
||||
|
||||
|
||||
public void SetRequiredMountCapabilityFlag(byte flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flag); }
|
||||
public void ReplaceAllRequiredMountCapabilityFlags(byte flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flags); }
|
||||
|
||||
|
||||
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
||||
|
||||
void SendAttackSwingCantAttack() { SendPacket(new AttackSwingError(AttackSwingErr.CantAttack)); }
|
||||
@@ -7874,5 +7877,15 @@ namespace Game.Entities
|
||||
|
||||
//Clears the Menu
|
||||
public void ClearGossipMenu() { PlayerTalkClass.ClearMenus(); }
|
||||
|
||||
public void SetPersonalTabard(int style, int color, int borderStyle, int borderColor, int backgroundColor)
|
||||
{
|
||||
CustomTabardInfo personalTabard = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.PersonalTabard);
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.EmblemStyle), style);
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.EmblemColor), color);
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.BorderStyle), borderStyle);
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.BorderColor), borderColor);
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.BackgroundColor), backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -566,7 +566,14 @@ namespace Game.Entities
|
||||
public class DeclinedName
|
||||
{
|
||||
public StringArray name = new(SharedConst.MaxDeclinedNameCases);
|
||||
}
|
||||
|
||||
public DeclinedName() { }
|
||||
public DeclinedName(DeclinedNames uf)
|
||||
{
|
||||
for (var i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
|
||||
name[i] = uf.Name[i];
|
||||
}
|
||||
}
|
||||
|
||||
struct PositionUpdateInfo
|
||||
{
|
||||
|
||||
@@ -1495,27 +1495,11 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
uint modelid = 0;
|
||||
SpellShapeshiftFormRecord formEntry = CliDB.SpellShapeshiftFormStorage.LookupByKey(form);
|
||||
if (formEntry != null && formEntry.CreatureDisplayID[0] != 0)
|
||||
{
|
||||
// Take the alliance modelid as default
|
||||
if (GetTypeId() != TypeId.Player)
|
||||
return formEntry.CreatureDisplayID[0];
|
||||
else
|
||||
{
|
||||
if (Player.TeamForRace(GetRace()) == Team.Alliance)
|
||||
modelid = formEntry.CreatureDisplayID[0];
|
||||
else
|
||||
modelid = formEntry.CreatureDisplayID[1];
|
||||
if (formEntry != null && formEntry.CreatureDisplayID != 0)
|
||||
return formEntry.CreatureDisplayID;
|
||||
|
||||
// If the player is horde but there are no values for the horde modelid - take the alliance modelid
|
||||
if (modelid == 0 && Player.TeamForRace(GetRace()) == Team.Horde)
|
||||
modelid = formEntry.CreatureDisplayID[0];
|
||||
}
|
||||
}
|
||||
|
||||
return modelid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Totem ToTotem() { return IsTotem() ? (this as Totem) : null; }
|
||||
|
||||
@@ -3539,9 +3539,14 @@ namespace Game.Guilds
|
||||
|
||||
public bool ValidateEmblemColors()
|
||||
{
|
||||
return CliDB.GuildColorBackgroundStorage.ContainsKey(m_backgroundColor) &&
|
||||
CliDB.GuildColorBorderStorage.ContainsKey(m_borderColor) &&
|
||||
CliDB.GuildColorEmblemStorage.ContainsKey(m_color);
|
||||
return ValidateEmblemColors(m_style, m_color, m_borderStyle, m_borderColor, m_backgroundColor);
|
||||
}
|
||||
|
||||
public static bool ValidateEmblemColors(uint style, uint color, uint borderStyle, uint borderColor, uint backgroundColor)
|
||||
{
|
||||
return CliDB.GuildColorBackgroundStorage.ContainsKey(backgroundColor) &&
|
||||
CliDB.GuildColorBorderStorage.ContainsKey(borderColor) &&
|
||||
CliDB.GuildColorEmblemStorage.ContainsKey(color);
|
||||
}
|
||||
|
||||
public bool LoadFromDB(SQLFields field)
|
||||
|
||||
@@ -607,8 +607,17 @@ namespace Game
|
||||
{
|
||||
// This packet is completely irrelevant, it triggers PVP_TYPES_ENABLED lua event but that is not handled in interface code as of 6.1.2
|
||||
PVPOptionsEnabled pvpOptionsEnabled = new();
|
||||
pvpOptionsEnabled.RatedBattlegrounds = false;
|
||||
pvpOptionsEnabled.PugBattlegrounds = true;
|
||||
SendPacket(new PVPOptionsEnabled());
|
||||
pvpOptionsEnabled.WargameBattlegrounds = false;
|
||||
pvpOptionsEnabled.WargameArenas = false;
|
||||
pvpOptionsEnabled.RatedArenas = false;
|
||||
pvpOptionsEnabled.ArenaSkirmish = false;
|
||||
pvpOptionsEnabled.SoloShuffle = false;
|
||||
pvpOptionsEnabled.RatedSoloShuffle = false;
|
||||
pvpOptionsEnabled.BattlegroundBlitz = false;
|
||||
pvpOptionsEnabled.RatedBattlegroundBlitz = false;
|
||||
SendPacket(pvpOptionsEnabled);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.RequestPvpRewards, Processing = PacketProcessing.Inplace)]
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace Game
|
||||
CalendarSendCalendar packet = new();
|
||||
packet.ServerTime = currTime;
|
||||
|
||||
var invites = Global.CalendarMgr.GetPlayerInvites(guid);
|
||||
foreach (var invite in invites)
|
||||
var playerInvites = Global.CalendarMgr.GetPlayerInvites(guid);
|
||||
foreach (var invite in playerInvites)
|
||||
{
|
||||
CalendarSendCalendarInviteInfo inviteInfo = new();
|
||||
inviteInfo.EventID = invite.EventId;
|
||||
@@ -45,7 +45,7 @@ namespace Game
|
||||
var playerEvents = Global.CalendarMgr.GetPlayerEvents(guid);
|
||||
foreach (var calendarEvent in playerEvents)
|
||||
{
|
||||
CalendarSendCalendarEventInfo eventInfo;
|
||||
CalendarSendCalendarEventInfo eventInfo = new();
|
||||
eventInfo.EventID = calendarEvent.EventId;
|
||||
eventInfo.Date = calendarEvent.Date;
|
||||
eventInfo.EventClubID = calendarEvent.GuildId;
|
||||
@@ -61,7 +61,6 @@ namespace Game
|
||||
foreach (InstanceLock instanceLock in Global.InstanceLockMgr.GetInstanceLocksForPlayer(_player.GetGUID()))
|
||||
{
|
||||
CalendarSendCalendarRaidLockoutInfo lockoutInfo = new();
|
||||
|
||||
lockoutInfo.MapID = (int)instanceLock.GetMapId();
|
||||
lockoutInfo.DifficultyID = (uint)instanceLock.GetDifficultyId();
|
||||
lockoutInfo.ExpireTime = (int)Math.Max((instanceLock.GetEffectiveExpiryTime() - GameTime.GetSystemTime()).TotalSeconds, 0);
|
||||
|
||||
@@ -111,8 +111,6 @@ namespace Game
|
||||
while (result.NextRow() && charResult.Characters.Count < 200);
|
||||
}
|
||||
|
||||
charResult.IsAlliedRacesCreationAllowed = CanAccessAlliedRaces();
|
||||
|
||||
foreach (var requirement in Global.ObjectMgr.GetRaceUnlockRequirements())
|
||||
{
|
||||
EnumCharactersResult.RaceUnlock raceUnlock = new();
|
||||
@@ -811,9 +809,8 @@ namespace Game
|
||||
|
||||
SendFeatureSystemStatus();
|
||||
|
||||
MOTD motd = new();
|
||||
motd.Text = Global.WorldMgr.GetMotd();
|
||||
SendPacket(motd);
|
||||
foreach (var motdLine in Global.WorldMgr.GetMotd())
|
||||
Global.WorldMgr.SendServerMessage(ServerMessageType.String, motdLine, pCurrChar);
|
||||
|
||||
SendSetTimeZoneInformation();
|
||||
|
||||
@@ -2544,6 +2541,29 @@ namespace Game
|
||||
GetPlayer().SetStandState(packet.StandState);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SavePersonalEmblem)]
|
||||
void HandleSavePersonalEmblem(SavePersonalEmblem savePersonalEmblem)
|
||||
{
|
||||
if (_player.GetNPCIfCanInteractWith(savePersonalEmblem.Vendor, NPCFlags.None, NPCFlags2.PersonalTabardDesigner) == null)
|
||||
{
|
||||
SendPacket(new PlayerSavePersonalEmblem(GuildEmblemError.InvalidVendor));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Guild.EmblemInfo.ValidateEmblemColors((uint)savePersonalEmblem.PersonalTabard.EmblemStyle, (uint)savePersonalEmblem.PersonalTabard.EmblemColor,
|
||||
(uint)savePersonalEmblem.PersonalTabard.BorderStyle, (uint)savePersonalEmblem.PersonalTabard.BorderColor, (uint)savePersonalEmblem.PersonalTabard.BackgroundColor))
|
||||
{
|
||||
SendPacket(new PlayerSavePersonalEmblem(GuildEmblemError.InvalidTabardColors));
|
||||
return;
|
||||
}
|
||||
|
||||
_player.SetPersonalTabard(savePersonalEmblem.PersonalTabard.EmblemStyle, savePersonalEmblem.PersonalTabard.EmblemColor,
|
||||
savePersonalEmblem.PersonalTabard.BorderStyle, savePersonalEmblem.PersonalTabard.BorderColor,
|
||||
savePersonalEmblem.PersonalTabard.BackgroundColor);
|
||||
|
||||
SendPacket(new PlayerSavePersonalEmblem(GuildEmblemError.Success));
|
||||
}
|
||||
|
||||
void SendCharCreate(ResponseCodes result, ObjectGuid guid = default)
|
||||
{
|
||||
CreateChar response = new();
|
||||
|
||||
@@ -17,27 +17,44 @@ namespace Game
|
||||
public partial class WorldSession
|
||||
{
|
||||
[WorldPacketHandler(ClientOpcodes.TabardVendorActivate, Processing = PacketProcessing.Inplace)]
|
||||
void HandleTabardVendorActivate(Hello packet)
|
||||
void HandleTabardVendorActivate(TabardVendorActivate tabardVendorActivate)
|
||||
{
|
||||
Creature unit = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.TabardDesigner, NPCFlags2.None);
|
||||
Creature unit = GetPlayer().GetNPCIfCanInteractWith(tabardVendorActivate.Vendor, NPCFlags.TabardDesigner, NPCFlags2.None);
|
||||
if (unit == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WORLD: HandleTabardVendorActivateOpcode - {0} not found or you can not interact with him.", packet.Unit.ToString());
|
||||
Log.outDebug(LogFilter.Network, $"WORLD: HandleTabardVendorActivateOpcode - {tabardVendorActivate.Vendor} not found or you can not interact with him.");
|
||||
return;
|
||||
}
|
||||
|
||||
TabardVendorType type = (TabardVendorType)tabardVendorActivate.Type;
|
||||
if (type != TabardVendorType.Guild && type != TabardVendorType.Personal)
|
||||
return;
|
||||
|
||||
// remove fake death
|
||||
if (GetPlayer().HasUnitState(UnitState.Died))
|
||||
GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
|
||||
|
||||
SendTabardVendorActivate(packet.Unit);
|
||||
SendTabardVendorActivate(tabardVendorActivate.Vendor, type);
|
||||
}
|
||||
|
||||
public void SendTabardVendorActivate(ObjectGuid guid)
|
||||
public void SendTabardVendorActivate(ObjectGuid guid, TabardVendorType type)
|
||||
{
|
||||
NPCInteractionOpenResult npcInteraction = new();
|
||||
npcInteraction.Npc = guid;
|
||||
npcInteraction.InteractionType = PlayerInteractionType.TabardVendor;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TabardVendorType.Guild:
|
||||
npcInteraction.InteractionType = PlayerInteractionType.GuildTabardVendor;
|
||||
break;
|
||||
case TabardVendorType.Personal:
|
||||
npcInteraction.InteractionType = PlayerInteractionType.PersonalTabardVendor;
|
||||
break;
|
||||
default:
|
||||
Log.outFatal(LogFilter.Server, $"Unsupported tabard vendor type {type}");
|
||||
break;
|
||||
}
|
||||
|
||||
npcInteraction.Success = true;
|
||||
SendPacket(npcInteraction);
|
||||
}
|
||||
@@ -345,7 +362,7 @@ namespace Game
|
||||
|
||||
_player.SetPetSlot(setPetSlot.PetNumber, (PetSaveMode)setPetSlot.DestSlot);
|
||||
}
|
||||
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.RepairItem, Processing = PacketProcessing.Inplace)]
|
||||
void HandleRepairItem(RepairItem packet)
|
||||
{
|
||||
|
||||
@@ -310,15 +310,23 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(WargameArenas);
|
||||
_worldPacket.WriteBit(RatedArenas);
|
||||
_worldPacket.WriteBit(ArenaSkirmish);
|
||||
_worldPacket.WriteBit(SoloShuffle);
|
||||
_worldPacket.WriteBit(RatedSoloShuffle);
|
||||
_worldPacket.WriteBit(BattlegroundBlitz);
|
||||
_worldPacket.WriteBit(RatedBattlegroundBlitz);
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
|
||||
public bool RatedBattlegrounds;
|
||||
public bool PugBattlegrounds;
|
||||
public bool WargameBattlegrounds;
|
||||
public bool WargameArenas;
|
||||
public bool RatedArenas;
|
||||
public bool WargameBattlegrounds;
|
||||
public bool ArenaSkirmish;
|
||||
public bool PugBattlegrounds;
|
||||
public bool RatedBattlegrounds;
|
||||
public bool SoloShuffle;
|
||||
public bool RatedSoloShuffle;
|
||||
public bool BattlegroundBlitz;
|
||||
public bool RatedBattlegroundBlitz; // solo rbg
|
||||
}
|
||||
|
||||
class RequestBattlefieldStatus : ClientPacket
|
||||
@@ -510,7 +518,7 @@ namespace Game.Networking.Packets
|
||||
|
||||
PVPMatchState State;
|
||||
}
|
||||
|
||||
|
||||
class PVPMatchComplete : ServerPacket
|
||||
{
|
||||
public PVPMatchComplete() : base(ServerOpcodes.PvpMatchComplete, ConnectionType.Instance) { }
|
||||
|
||||
@@ -149,12 +149,12 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteInt32(Events.Count);
|
||||
_worldPacket.WriteInt32(RaidLockouts.Count);
|
||||
|
||||
foreach (var invite in Invites)
|
||||
invite.Write(_worldPacket);
|
||||
|
||||
foreach (var lockout in RaidLockouts)
|
||||
lockout.Write(_worldPacket);
|
||||
|
||||
foreach (var invite in Invites)
|
||||
invite.Write(_worldPacket);
|
||||
|
||||
foreach (var Event in Events)
|
||||
Event.Write(_worldPacket);
|
||||
}
|
||||
@@ -822,6 +822,8 @@ namespace Game.Networking.Packets
|
||||
data.WriteUInt8((byte)Moderator);
|
||||
data.WriteUInt8(InviteType);
|
||||
data.WritePackedGuid(InviterGuid);
|
||||
data.WriteBit(IgnoreFriendAndGuildRestriction);
|
||||
data.FlushBits();
|
||||
}
|
||||
|
||||
public ulong EventID;
|
||||
@@ -830,6 +832,7 @@ namespace Game.Networking.Packets
|
||||
public CalendarInviteStatus Status;
|
||||
public CalendarModerationRank Moderator;
|
||||
public byte InviteType;
|
||||
public bool IgnoreFriendAndGuildRestriction;
|
||||
}
|
||||
struct CalendarSendCalendarRaidLockoutInfo
|
||||
{
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(IsNewPlayer);
|
||||
_worldPacket.WriteBit(IsTrialAccountRestricted);
|
||||
_worldPacket.WriteBit(DisabledClassesMask.HasValue);
|
||||
_worldPacket.WriteBit(IsAlliedRacesCreationAllowed);
|
||||
_worldPacket.WriteInt32(Characters.Count);
|
||||
_worldPacket.WriteInt32(MaxCharacterLevel);
|
||||
_worldPacket.WriteInt32(RaceUnlockData.Count);
|
||||
@@ -62,7 +61,6 @@ namespace Game.Networking.Packets
|
||||
public bool IsNewPlayerRestricted; // forbids using level boost and class trials
|
||||
public bool IsNewPlayer; // forbids hero classes and allied races
|
||||
public bool IsTrialAccountRestricted;
|
||||
public bool IsAlliedRacesCreationAllowed;
|
||||
|
||||
public int MaxCharacterLevel = 1;
|
||||
public uint? DisabledClassesMask = new();
|
||||
@@ -105,7 +103,7 @@ namespace Game.Networking.Packets
|
||||
if (fields.Read<uint>(18) != 0)
|
||||
Flags |= CharacterFlags.LockedByBilling;
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.DeclinedNamesUsed) && !string.IsNullOrEmpty(fields.Read<string>(23)))
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.DeclinedNamesUsed) && !string.IsNullOrEmpty(fields.Read<string>(28)))
|
||||
Flags |= CharacterFlags.Declined;
|
||||
|
||||
if (atLoginFlags.HasAnyFlag(AtLoginFlags.Customize))
|
||||
@@ -145,6 +143,12 @@ namespace Game.Networking.Packets
|
||||
|
||||
LastLoginVersion = fields.Read<int>(22);
|
||||
|
||||
PersonalTabard.EmblemStyle = fields.Read<int>(23);
|
||||
PersonalTabard.EmblemColor = fields.Read<int>(24);
|
||||
PersonalTabard.BorderStyle = fields.Read<int>(25);
|
||||
PersonalTabard.BorderColor = fields.Read<int>(26);
|
||||
PersonalTabard.BackgroundColor = fields.Read<int>(27);
|
||||
|
||||
int equipmentFieldsPerSlot = 5;
|
||||
|
||||
for (var slot = 0; slot < VisualItems.Length && (slot + 1) * equipmentFieldsPerSlot <= equipment.Length; ++slot)
|
||||
@@ -194,6 +198,7 @@ namespace Game.Networking.Packets
|
||||
data.WriteInt32(MailSenders.Count);
|
||||
data.WriteInt32(MailSenderTypes.Count);
|
||||
data.WriteUInt32(OverrideSelectScreenFileDataID);
|
||||
PersonalTabard.Write(data);
|
||||
|
||||
foreach (ChrCustomizationChoice customization in Customizations)
|
||||
{
|
||||
@@ -208,6 +213,8 @@ namespace Game.Networking.Packets
|
||||
data.WriteBit(FirstLogin);
|
||||
data.WriteBit(BoostInProgress);
|
||||
data.WriteBits(unkWod61x, 5);
|
||||
data.WriteBit(RpeResetAvailable);
|
||||
data.WriteBit(RpeResetQuestClearAvailable);
|
||||
|
||||
foreach (string str in MailSenders)
|
||||
data.WriteBits(str.GetByteCount() + 1, 6);
|
||||
@@ -228,7 +235,7 @@ namespace Game.Networking.Packets
|
||||
public byte RaceId;
|
||||
public Class ClassId;
|
||||
public byte SexId;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
public byte ExperienceLevel;
|
||||
public uint ZoneId;
|
||||
public uint MapId;
|
||||
@@ -253,6 +260,9 @@ namespace Game.Networking.Packets
|
||||
public VisualItemInfo[] VisualItems = new VisualItemInfo[InventorySlots.ReagentBagEnd];
|
||||
public List<string> MailSenders = new();
|
||||
public List<uint> MailSenderTypes = new();
|
||||
public bool RpeResetAvailable = false;
|
||||
public bool RpeResetQuestClearAvailable = false;
|
||||
public CustomTabardInfo PersonalTabard = new();
|
||||
|
||||
public struct VisualItemInfo
|
||||
{
|
||||
@@ -288,6 +298,7 @@ namespace Game.Networking.Packets
|
||||
data.WriteBit(HasExpansion);
|
||||
data.WriteBit(HasAchievement);
|
||||
data.WriteBit(HasHeritageArmor);
|
||||
data.WriteBit(IsLocked);
|
||||
data.FlushBits();
|
||||
}
|
||||
|
||||
@@ -295,6 +306,7 @@ namespace Game.Networking.Packets
|
||||
public bool HasExpansion;
|
||||
public bool HasAchievement;
|
||||
public bool HasHeritageArmor;
|
||||
public bool IsLocked;
|
||||
}
|
||||
|
||||
public struct UnlockedConditionalAppearance
|
||||
@@ -329,7 +341,7 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
|
||||
class CheckCharacterNameAvailability : ClientPacket
|
||||
{
|
||||
{
|
||||
public uint SequenceIndex;
|
||||
public string Name;
|
||||
|
||||
@@ -359,7 +371,7 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteUInt32((uint)Result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CreateCharacter : ClientPacket
|
||||
{
|
||||
public CreateCharacter(WorldPacket packet) : base(packet) { }
|
||||
@@ -570,7 +582,7 @@ namespace Game.Networking.Packets
|
||||
public string Name;
|
||||
public byte SexID;
|
||||
public byte RaceID;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,7 +895,7 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
|
||||
public byte NewSex;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
public int CustomizedRace;
|
||||
public int CustomizedChrModelID;
|
||||
}
|
||||
@@ -952,7 +964,7 @@ namespace Game.Networking.Packets
|
||||
FactionIndex = _worldPacket.ReadUInt8();
|
||||
}
|
||||
|
||||
public byte FactionIndex;
|
||||
public ushort FactionIndex;
|
||||
}
|
||||
|
||||
class SetFactionNotAtWar : ClientPacket
|
||||
@@ -964,7 +976,7 @@ namespace Game.Networking.Packets
|
||||
FactionIndex = _worldPacket.ReadUInt8();
|
||||
}
|
||||
|
||||
public byte FactionIndex;
|
||||
public ushort FactionIndex;
|
||||
}
|
||||
|
||||
class SetFactionInactive : ClientPacket
|
||||
@@ -1089,6 +1101,35 @@ namespace Game.Networking.Packets
|
||||
public DeclinedNameResult ResultCode;
|
||||
}
|
||||
|
||||
class SavePersonalEmblem : ClientPacket
|
||||
{
|
||||
public ObjectGuid Vendor;
|
||||
public CustomTabardInfo PersonalTabard = new();
|
||||
|
||||
public SavePersonalEmblem(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Vendor = _worldPacket.ReadPackedGuid();
|
||||
PersonalTabard.Read(_worldPacket);
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerSavePersonalEmblem : ServerPacket
|
||||
{
|
||||
public GuildEmblemError Error;
|
||||
|
||||
public PlayerSavePersonalEmblem(GuildEmblemError error) : base(ServerOpcodes.PlayerSavePersonalEmblem)
|
||||
{
|
||||
Error = error;
|
||||
}
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteInt32((int)Error);
|
||||
}
|
||||
}
|
||||
|
||||
//Structs
|
||||
public class CharacterCreateInfo
|
||||
{
|
||||
@@ -1096,7 +1137,7 @@ namespace Game.Networking.Packets
|
||||
public Race RaceId = Race.None;
|
||||
public Class ClassId = Class.None;
|
||||
public Gender Sex = Gender.None;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
public uint? TemplateSet;
|
||||
public bool IsTrialBoost;
|
||||
public bool UseNPE;
|
||||
@@ -1117,7 +1158,7 @@ namespace Game.Networking.Packets
|
||||
public ObjectGuid CharGUID;
|
||||
public Gender SexID = Gender.None;
|
||||
public string CharName;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
}
|
||||
|
||||
public class CharRaceOrFactionChangeInfo
|
||||
@@ -1128,15 +1169,42 @@ namespace Game.Networking.Packets
|
||||
public ObjectGuid Guid;
|
||||
public bool FactionChange;
|
||||
public string Name;
|
||||
public Array<ChrCustomizationChoice> Customizations = new(125);
|
||||
public Array<ChrCustomizationChoice> Customizations = new(250);
|
||||
}
|
||||
|
||||
public class CharacterUndeleteInfo
|
||||
{ // User specified variables
|
||||
public ObjectGuid CharacterGuid; // Guid of the character to restore
|
||||
public int ClientToken = 0; // @todo: research
|
||||
public int ClientToken; // @todo: research
|
||||
|
||||
// Server side data
|
||||
public string Name;
|
||||
}
|
||||
|
||||
public class CustomTabardInfo
|
||||
{
|
||||
public int EmblemStyle = -1;
|
||||
public int EmblemColor = -1;
|
||||
public int BorderStyle = -1;
|
||||
public int BorderColor = -1;
|
||||
public int BackgroundColor = -1;
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteInt32(EmblemStyle);
|
||||
data.WriteInt32(EmblemColor);
|
||||
data.WriteInt32(BorderStyle);
|
||||
data.WriteInt32(BorderColor);
|
||||
data.WriteInt32(BackgroundColor);
|
||||
}
|
||||
|
||||
public void Read(WorldPacket data)
|
||||
{
|
||||
EmblemStyle = data.ReadInt32();
|
||||
EmblemColor = data.ReadInt32();
|
||||
BorderStyle = data.ReadInt32();
|
||||
BorderColor = data.ReadInt32();
|
||||
BackgroundColor = data.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(FirstCraftOperationID.HasValue);
|
||||
_worldPacket.WriteBit(NextRechargeTime.HasValue);
|
||||
_worldPacket.WriteBit(RechargeCycleStartTime.HasValue);
|
||||
_worldPacket.WriteBit(OverflownCurrencyID.HasValue);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
if (WeeklyQuantity.HasValue)
|
||||
@@ -139,6 +140,9 @@ namespace Game.Networking.Packets
|
||||
|
||||
if (RechargeCycleStartTime.HasValue)
|
||||
_worldPacket.WriteInt64(RechargeCycleStartTime.Value);
|
||||
|
||||
if (OverflownCurrencyID.HasValue)
|
||||
_worldPacket.WriteInt32(OverflownCurrencyID.Value);
|
||||
}
|
||||
|
||||
public uint Type;
|
||||
@@ -155,6 +159,7 @@ namespace Game.Networking.Packets
|
||||
public uint? FirstCraftOperationID;
|
||||
public long? NextRechargeTime;
|
||||
public long? RechargeCycleStartTime;
|
||||
public int? OverflownCurrencyID; // what currency was originally changed but couldn't be incremented because of a cap
|
||||
public bool SuppressChatLog;
|
||||
}
|
||||
|
||||
@@ -1442,17 +1447,17 @@ namespace Game.Networking.Packets
|
||||
{
|
||||
public PhaseShiftDataPhase(uint phaseFlags, uint id)
|
||||
{
|
||||
PhaseFlags = (ushort)phaseFlags;
|
||||
PhaseFlags = phaseFlags;
|
||||
Id = (ushort)id;
|
||||
}
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt16(PhaseFlags);
|
||||
data.WriteUInt32(PhaseFlags);
|
||||
data.WriteUInt16(Id);
|
||||
}
|
||||
|
||||
public ushort PhaseFlags;
|
||||
public uint PhaseFlags;
|
||||
public ushort Id;
|
||||
}
|
||||
|
||||
|
||||
@@ -1497,7 +1497,6 @@ namespace Game.Networking.Packets
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt32(Id);
|
||||
data.WriteVector3(Destination);
|
||||
data.WriteBit(CrzTeleport);
|
||||
data.WriteBits(StopDistanceTolerance, 3);
|
||||
|
||||
@@ -1505,7 +1504,6 @@ namespace Game.Networking.Packets
|
||||
}
|
||||
|
||||
public uint Id;
|
||||
public Vector3 Destination;
|
||||
public bool CrzTeleport;
|
||||
public byte StopDistanceTolerance; // Determines how far from spline destination the mover is allowed to stop in place 0, 0, 3.0, 2.76, numeric_limits<float>::max, 1.1, float(INT_MAX); default before this field existed was distance 3.0 (index 2)
|
||||
public MovementSpline Move;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Game.Networking.Packets
|
||||
public PlayerInteractionType InteractionType;
|
||||
public bool Success = true;
|
||||
}
|
||||
|
||||
|
||||
public class GossipMessagePkt : ServerPacket
|
||||
{
|
||||
public GossipMessagePkt() : base(ServerOpcodes.GossipMessage) { }
|
||||
@@ -122,7 +122,7 @@ namespace Game.Networking.Packets
|
||||
public int GossipNpcOptionID;
|
||||
public int? FriendshipFactionID;
|
||||
}
|
||||
|
||||
|
||||
public class GossipComplete : ServerPacket
|
||||
{
|
||||
public bool SuppressSound;
|
||||
@@ -230,6 +230,20 @@ namespace Game.Networking.Packets
|
||||
public ObjectGuid Healer;
|
||||
}
|
||||
|
||||
class TabardVendorActivate : ClientPacket
|
||||
{
|
||||
public ObjectGuid Vendor;
|
||||
public int Type;
|
||||
|
||||
public TabardVendorActivate(WorldPacket packet) : base(packet) { }
|
||||
|
||||
public override void Read()
|
||||
{
|
||||
Vendor = _worldPacket.ReadPackedGuid();
|
||||
Type = _worldPacket.ReadInt32();
|
||||
}
|
||||
}
|
||||
|
||||
class TrainerBuySpell : ClientPacket
|
||||
{
|
||||
public TrainerBuySpell(WorldPacket packet) : base(packet) { }
|
||||
@@ -238,7 +252,7 @@ namespace Game.Networking.Packets
|
||||
{
|
||||
TrainerGUID = _worldPacket.ReadPackedGuid();
|
||||
TrainerID = _worldPacket.ReadUInt32();
|
||||
SpellID= _worldPacket.ReadUInt32();
|
||||
SpellID = _worldPacket.ReadUInt32();
|
||||
}
|
||||
|
||||
public ObjectGuid TrainerGUID;
|
||||
@@ -289,7 +303,7 @@ namespace Game.Networking.Packets
|
||||
public uint PetNumber;
|
||||
public byte DestSlot;
|
||||
}
|
||||
|
||||
|
||||
//Structs
|
||||
public struct TreasureItem
|
||||
{
|
||||
@@ -406,7 +420,7 @@ namespace Game.Networking.Packets
|
||||
data.WriteBit(DoNotFilterOnVendor);
|
||||
data.WriteBit(Refundable);
|
||||
data.FlushBits();
|
||||
|
||||
|
||||
Item.Write(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1042,17 +1042,17 @@ namespace Game.Networking.Packets
|
||||
{
|
||||
public PartyMemberPhase(uint flags, uint id)
|
||||
{
|
||||
Flags = (ushort)flags;
|
||||
Flags = flags;
|
||||
Id = (ushort)id;
|
||||
}
|
||||
|
||||
public void Write(WorldPacket data)
|
||||
{
|
||||
data.WriteUInt16(Flags);
|
||||
data.WriteUInt32(Flags);
|
||||
data.WriteUInt16(Id);
|
||||
}
|
||||
|
||||
public ushort Flags;
|
||||
public uint Flags;
|
||||
public ushort Id;
|
||||
}
|
||||
|
||||
|
||||
@@ -601,9 +601,9 @@ namespace Game.Networking.Packets
|
||||
ClassID = player.GetClass();
|
||||
Level = (byte)player.GetLevel();
|
||||
|
||||
DeclinedName names = player.GetDeclinedNames();
|
||||
DeclinedNames names = player.GetDeclinedNames();
|
||||
if (names != null)
|
||||
DeclinedNames = names;
|
||||
DeclinedNames = new(names);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Game.Networking.Packets
|
||||
{
|
||||
public class InitializeFactions : ServerPacket
|
||||
{
|
||||
const ushort FactionCount = 443;
|
||||
const ushort FactionCount = 1000;
|
||||
|
||||
public InitializeFactions() : base(ServerOpcodes.InitializeFactions, ConnectionType.Instance) { }
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Game.Networking.Packets
|
||||
public override void Read()
|
||||
{
|
||||
uint nameLength = _worldPacket.ReadBits<uint>(9);
|
||||
uint noteslength = _worldPacket.ReadBits<uint>(10);
|
||||
uint noteslength = _worldPacket.ReadBits<uint>(9);
|
||||
Name = _worldPacket.ReadString(nameLength);
|
||||
Notes = _worldPacket.ReadString(noteslength);
|
||||
}
|
||||
|
||||
@@ -83,9 +83,13 @@ namespace Game.Networking.Packets
|
||||
_worldPacket.WriteBit(ChatDisabledByPlayer);
|
||||
_worldPacket.WriteBit(LFGListCustomRequiresAuthenticator);
|
||||
_worldPacket.WriteBit(AddonsDisabled);
|
||||
_worldPacket.WriteBit(Unused1000);
|
||||
_worldPacket.WriteBit(WarGamesEnabled);
|
||||
_worldPacket.WriteBit(ContentTrackingEnabled);
|
||||
_worldPacket.WriteBit(IsSellAllJunkEnabled);
|
||||
_worldPacket.WriteBit(IsGroupFinderEnabled);
|
||||
_worldPacket.WriteBit(IsLFDEnabled);
|
||||
_worldPacket.WriteBit(IsLFREnabled);
|
||||
_worldPacket.WriteBit(IsPremadeGroupEnabled);
|
||||
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
@@ -177,9 +181,13 @@ namespace Game.Networking.Packets
|
||||
public bool ChatDisabledByPlayer;
|
||||
public bool LFGListCustomRequiresAuthenticator;
|
||||
public bool AddonsDisabled;
|
||||
public bool Unused1000;
|
||||
public bool WarGamesEnabled; // classic only
|
||||
public bool ContentTrackingEnabled;
|
||||
public bool IsSellAllJunkEnabled;
|
||||
public bool IsGroupFinderEnabled = true; // classic only
|
||||
public bool IsLFDEnabled = true; // classic only
|
||||
public bool IsLFREnabled = true; // classic only
|
||||
public bool IsPremadeGroupEnabled = true; // classic only
|
||||
|
||||
public SocialQueueConfig QuickJoinConfig;
|
||||
public SquelchInfo Squelch;
|
||||
@@ -361,26 +369,6 @@ namespace Game.Networking.Packets
|
||||
public string RealmHiddenAlert;
|
||||
}
|
||||
|
||||
public class MOTD : ServerPacket
|
||||
{
|
||||
public MOTD() : base(ServerOpcodes.Motd) { }
|
||||
|
||||
public override void Write()
|
||||
{
|
||||
_worldPacket.WriteBits(Text.Count, 4);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
foreach (var line in Text)
|
||||
{
|
||||
_worldPacket.WriteBits(line.GetByteCount(), 7);
|
||||
_worldPacket.FlushBits();
|
||||
_worldPacket.WriteString(line);
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> Text;
|
||||
}
|
||||
|
||||
public class SetTimeZoneInformation : ServerPacket
|
||||
{
|
||||
public SetTimeZoneInformation() : base(ServerOpcodes.SetTimeZoneInformation) { }
|
||||
|
||||
@@ -42,9 +42,11 @@ namespace Game.Networking.Packets
|
||||
public override void Read()
|
||||
{
|
||||
uint areasCount = _worldPacket.ReadBits<uint>(4);
|
||||
IsFromAddOn = _worldPacket.HasBit();
|
||||
|
||||
Request.Read(_worldPacket);
|
||||
RequestID = _worldPacket.ReadUInt32();
|
||||
Origin = _worldPacket.ReadUInt8();
|
||||
|
||||
for (int i = 0; i < areasCount; ++i)
|
||||
Areas.Add(_worldPacket.ReadInt32());
|
||||
@@ -52,6 +54,8 @@ namespace Game.Networking.Packets
|
||||
|
||||
public WhoRequest Request = new();
|
||||
public uint RequestID;
|
||||
public byte Origin; // 1 = Social, 2 = Chat, 3 = Item
|
||||
public bool IsFromAddOn;
|
||||
public List<int> Areas= new();
|
||||
}
|
||||
|
||||
|
||||
@@ -1899,9 +1899,13 @@ namespace Game
|
||||
|
||||
public void SendServerMessage(ServerMessageType messageID, string stringParam = "", Player player = null)
|
||||
{
|
||||
ServerMessagesRecord serverMessage = CliDB.ServerMessagesStorage.LookupByKey(messageID);
|
||||
if (serverMessage == null)
|
||||
return;
|
||||
|
||||
ChatServerMessage packet = new();
|
||||
packet.MessageID = (int)messageID;
|
||||
if (messageID <= ServerMessageType.String)
|
||||
if (serverMessage.Text[player != null ? player.GetSession().GetSessionDbcLocale() : GetDefaultDbcLocale()].Contains("%s"))
|
||||
packet.StringParam = stringParam;
|
||||
|
||||
if (player != null)
|
||||
|
||||
Reference in New Issue
Block a user