Ported .Net Core commits:
hondacrx: - Initial commit: Switch to .Net Core 2.0 - Fix build and removed not needed files Fabi: - Updated solution platforms. - Changed folder structure. - Change library target framework to netstandard2.0. - Updated solution platforms again... - Removed windows specific kernel32 function usage (Ctrl-C handler).
This commit is contained in:
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.IO;
|
||||
using Game.BattleGrounds;
|
||||
using Game.DataStorage;
|
||||
using Game.Entities;
|
||||
using Game.Groups;
|
||||
using Game.Guilds;
|
||||
using Game.Maps;
|
||||
using Game.Network;
|
||||
using Game.Network.Packets;
|
||||
using Game.PvP;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public partial class WorldSession
|
||||
{
|
||||
[WorldPacketHandler(ClientOpcodes.RequestAccountData, Status = SessionStatus.Authed)]
|
||||
void HandleRequestAccountData(RequestAccountData request)
|
||||
{
|
||||
if (request.DataType > AccountDataTypes.Max)
|
||||
return;
|
||||
|
||||
AccountData adata = GetAccountData(request.DataType);
|
||||
if (adata.Data == null)
|
||||
return;
|
||||
|
||||
UpdateAccountData data = new UpdateAccountData();
|
||||
data.Player = GetPlayer() ? GetPlayer().GetGUID() : ObjectGuid.Empty;
|
||||
data.Time = (uint)adata.Time;
|
||||
data.Size = (uint)adata.Data.Length;
|
||||
data.DataType = request.DataType;
|
||||
data.CompressedData = new ByteBuffer(ZLib.Compress(Encoding.UTF8.GetBytes(adata.Data)));
|
||||
|
||||
SendPacket(data);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.UpdateAccountData, Status = SessionStatus.Authed)]
|
||||
void HandleUpdateAccountData(UserClientUpdateAccountData packet)
|
||||
{
|
||||
if (packet.DataType > AccountDataTypes.Max)
|
||||
return;
|
||||
|
||||
if (packet.Size == 0)
|
||||
{
|
||||
SetAccountData(packet.DataType, 0, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.Size > 0xFFFF)
|
||||
{
|
||||
Log.outError(LogFilter.Network, "UpdateAccountData: Account data packet too big, size {0}", packet.Size);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] data = ZLib.Decompress(packet.CompressedData.GetData(), packet.Size);
|
||||
SetAccountData(packet.DataType, packet.Time, Encoding.Default.GetString(data));
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetSelection)]
|
||||
void HandleSetSelection(SetSelection packet)
|
||||
{
|
||||
GetPlayer().SetSelection(packet.Selection);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ObjectUpdateFailed)]
|
||||
void HandleObjectUpdateFailed(ObjectUpdateFailed objectUpdateFailed)
|
||||
{
|
||||
Log.outError(LogFilter.Network, "Object update failed for {0} for player {1} ({2})", objectUpdateFailed.ObjectGUID.ToString(), GetPlayerName(), GetPlayer().GetGUID().ToString());
|
||||
|
||||
// If create object failed for current player then client will be stuck on loading screen
|
||||
if (GetPlayer().GetGUID() == objectUpdateFailed.ObjectGUID)
|
||||
{
|
||||
LogoutPlayer(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pretend we've never seen this object
|
||||
GetPlayer().m_clientGUIDs.Remove(objectUpdateFailed.ObjectGUID);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ObjectUpdateRescued, Processing = PacketProcessing.Inplace)]
|
||||
void HandleObjectUpdateRescued(ObjectUpdateRescued objectUpdateRescued)
|
||||
{
|
||||
Log.outError(LogFilter.Network, "Object update rescued for {0} for player {1} ({2})", objectUpdateRescued.ObjectGUID.ToString(), GetPlayerName(), GetPlayer().GetGUID().ToString());
|
||||
|
||||
// Client received values update after destroying object
|
||||
// re-register object in m_clientGUIDs to send DestroyObject on next visibility update
|
||||
GetPlayer().m_clientGUIDs.Add(objectUpdateRescued.ObjectGUID);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetActionButton)]
|
||||
void HandleSetActionButton(SetActionButton packet)
|
||||
{
|
||||
uint action = packet.GetButtonAction();
|
||||
uint type = packet.GetButtonType();
|
||||
|
||||
if (packet.Action == 0)
|
||||
GetPlayer().RemoveActionButton(packet.Index);
|
||||
else
|
||||
GetPlayer().AddActionButton(packet.Index, action, type);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetActionBarToggles)]
|
||||
void HandleSetActionBarToggles(SetActionBarToggles packet)
|
||||
{
|
||||
if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
|
||||
{
|
||||
if (packet.Mask != 0)
|
||||
Log.outError(LogFilter.Network, "WorldSession.HandleSetActionBarToggles in not logged state with value: {0}, ignored", packet.Mask);
|
||||
return;
|
||||
}
|
||||
|
||||
GetPlayer().SetByteValue(PlayerFields.FieldBytes, PlayerFieldOffsets.FieldBytesOffsetActionBarToggles, packet.Mask);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.CompleteCinematic)]
|
||||
void HandleCompleteCinematic(CompleteCinematic packet)
|
||||
{
|
||||
// If player has sight bound to visual waypoint NPC we should remove it
|
||||
GetPlayer().GetCinematicMgr().EndCinematic();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.NextCinematicCamera)]
|
||||
void HandleNextCinematicCamera(NextCinematicCamera packet)
|
||||
{
|
||||
// Sent by client when cinematic actually begun. So we begin the server side process
|
||||
GetPlayer().GetCinematicMgr().BeginCinematic();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.CompleteMovie)]
|
||||
void HandleCompleteMovie(CompleteMovie packet)
|
||||
{
|
||||
uint movie = _player.GetMovie();
|
||||
if (movie == 0)
|
||||
return;
|
||||
|
||||
_player.SetMovie(0);
|
||||
Global.ScriptMgr.OnMovieComplete(_player, movie);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ViolenceLevel, Processing = PacketProcessing.Inplace, Status = SessionStatus.Authed)]
|
||||
void HandleViolenceLevel(ViolenceLevel violenceLevel)
|
||||
{
|
||||
// do something?
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.AreaTrigger)]
|
||||
void HandleAreaTrigger(AreaTriggerPkt packet)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
if (player.IsInFlight())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) in flight, ignore Area Trigger ID:{2}",
|
||||
player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
|
||||
return;
|
||||
}
|
||||
|
||||
AreaTriggerRecord atEntry = CliDB.AreaTriggerStorage.LookupByKey(packet.AreaTriggerID);
|
||||
if (atEntry == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' (GUID: {1}) send unknown (by DBC) Area Trigger ID:{2}",
|
||||
player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.Entered && !player.IsInAreaTriggerRadius(atEntry))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "HandleAreaTriggerOpcode: Player '{0}' ({1}) too far, ignore Area Trigger ID: {2}",
|
||||
player.GetName(), player.GetGUID().ToString(), packet.AreaTriggerID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isDebugAreaTriggers)
|
||||
player.SendSysMessage(packet.Entered ? CypherStrings.DebugAreatriggerEntered : CypherStrings.DebugAreatriggerLeft, packet.AreaTriggerID);
|
||||
|
||||
if (Global.ScriptMgr.OnAreaTrigger(player, atEntry, packet.Entered))
|
||||
return;
|
||||
|
||||
if (player.IsAlive())
|
||||
{
|
||||
List<uint> quests = Global.ObjectMgr.GetQuestsForAreaTrigger(packet.AreaTriggerID);
|
||||
if (quests != null)
|
||||
{
|
||||
foreach (uint questId in quests)
|
||||
{
|
||||
Quest qInfo = Global.ObjectMgr.GetQuestTemplate(questId);
|
||||
if (qInfo != null && player.GetQuestStatus(questId) == QuestStatus.Incomplete)
|
||||
{
|
||||
foreach (QuestObjective obj in qInfo.Objectives)
|
||||
{
|
||||
if (obj.Type == QuestObjectiveType.AreaTrigger && !player.IsQuestObjectiveComplete(obj))
|
||||
{
|
||||
player.SetQuestObjectiveData(obj, 1);
|
||||
player.SendQuestUpdateAddCreditSimple(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (player.CanCompleteQuest(questId))
|
||||
player.CompleteQuest(questId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Global.ObjectMgr.IsTavernAreaTrigger(packet.AreaTriggerID))
|
||||
{
|
||||
// set resting flag we are in the inn
|
||||
player.GetRestMgr().SetRestFlag(RestFlag.Tavern, atEntry.Id);
|
||||
|
||||
if (Global.WorldMgr.IsFFAPvPRealm())
|
||||
player.RemoveByteFlag(UnitFields.Bytes2, UnitBytes2Offsets.PvpFlag, UnitBytes2Flags.FFAPvp);
|
||||
|
||||
return;
|
||||
}
|
||||
Battleground bg = player.GetBattleground();
|
||||
if (bg)
|
||||
bg.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered);
|
||||
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null)
|
||||
{
|
||||
if (pvp.HandleAreaTrigger(player, packet.AreaTriggerID, packet.Entered))
|
||||
return;
|
||||
}
|
||||
|
||||
AreaTriggerStruct at = Global.ObjectMgr.GetAreaTrigger(packet.AreaTriggerID);
|
||||
if (at == null)
|
||||
return;
|
||||
|
||||
bool teleported = false;
|
||||
if (player.GetMapId() != at.target_mapId)
|
||||
{
|
||||
EnterState denyReason = Global.MapMgr.PlayerCannotEnter(at.target_mapId, player, false);
|
||||
if (denyReason != 0)
|
||||
{
|
||||
bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
|
||||
switch (denyReason)
|
||||
{
|
||||
case EnterState.CannotEnterNoEntry:
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter map with id {1} which has no entry", player.GetName(), at.target_mapId);
|
||||
break;
|
||||
case EnterState.CannotEnterUninstancedDungeon:
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter dungeon map {1} but no instance template was found", player.GetName(), at.target_mapId);
|
||||
break;
|
||||
case EnterState.CannotEnterDifficultyUnavailable:
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' attempted to enter instance map {1} but the requested difficulty was not found", player.GetName(), at.target_mapId);
|
||||
MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
|
||||
if (entry != null)
|
||||
player.SendTransferAborted(entry.Id, TransferAbortReason.Difficulty, (byte)player.GetDifficultyID(entry));
|
||||
}
|
||||
break;
|
||||
case EnterState.CannotEnterNotInRaid:
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' must be in a raid group to enter map {1}", player.GetName(), at.target_mapId);
|
||||
player.SendRaidGroupOnlyMessage(RaidGroupReason.Only, 0);
|
||||
reviveAtTrigger = true;
|
||||
break;
|
||||
case EnterState.CannotEnterCorpseInDifferentInstance:
|
||||
player.SendPacket(new AreaTriggerNoCorpse());
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' does not have a corpse in instance map {1} and cannot enter", player.GetName(), at.target_mapId);
|
||||
break;
|
||||
case EnterState.CannotEnterInstanceBindMismatch:
|
||||
{
|
||||
MapRecord entry = CliDB.MapStorage.LookupByKey(at.target_mapId);
|
||||
if (entry != null)
|
||||
{
|
||||
string mapName = entry.MapName[player.GetSession().GetSessionDbcLocale()];
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map '{1}' because their permanent bind is incompatible with their group's", player.GetName(), mapName);
|
||||
// is there a special opcode for this?
|
||||
// @todo figure out how to get player localized difficulty string (e.g. "10 player", "Heroic" etc)
|
||||
player.SendSysMessage(CypherStrings.InstanceBindMismatch, mapName);
|
||||
}
|
||||
reviveAtTrigger = true;
|
||||
}
|
||||
break;
|
||||
case EnterState.CannotEnterTooManyInstances:
|
||||
player.SendTransferAborted(at.target_mapId, TransferAbortReason.TooManyInstances);
|
||||
Log.outDebug(LogFilter.Maps, "MAP: Player '{0}' cannot enter instance map {1} because he has exceeded the maximum number of instances per hour.", player.GetName(), at.target_mapId);
|
||||
reviveAtTrigger = true;
|
||||
break;
|
||||
case EnterState.CannotEnterMaxPlayers:
|
||||
player.SendTransferAborted(at.target_mapId, TransferAbortReason.MaxPlayers);
|
||||
reviveAtTrigger = true;
|
||||
break;
|
||||
case EnterState.CannotEnterZoneInCombat:
|
||||
player.SendTransferAborted(at.target_mapId, TransferAbortReason.ZoneInCombat);
|
||||
reviveAtTrigger = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
|
||||
{
|
||||
if (!player.IsAlive() && player.HasCorpse())
|
||||
{
|
||||
if (player.GetCorpseLocation().GetMapId() == at.target_mapId)
|
||||
{
|
||||
player.ResurrectPlayer(0.5f);
|
||||
player.SpawnCorpseBones();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = player.GetGroup();
|
||||
if (group)
|
||||
if (group.isLFGGroup() && player.GetMap().IsDungeon())
|
||||
teleported = player.TeleportToBGEntryPoint();
|
||||
}
|
||||
|
||||
if (!teleported)
|
||||
{
|
||||
WorldSafeLocsRecord entranceLocation = null;
|
||||
InstanceSave instanceSave = player.GetInstanceSave(at.target_mapId);
|
||||
if (instanceSave != null)
|
||||
{
|
||||
// Check if we can contact the instancescript of the instance for an updated entrance location
|
||||
Map map = Global.MapMgr.FindMap(at.target_mapId, player.GetInstanceSave(at.target_mapId).GetInstanceId());
|
||||
if (map)
|
||||
{
|
||||
InstanceMap instanceMap = map.ToInstanceMap();
|
||||
if (instanceMap != null)
|
||||
{
|
||||
InstanceScript instanceScript = instanceMap.GetInstanceScript();
|
||||
if (instanceScript != null)
|
||||
entranceLocation = CliDB.WorldSafeLocsStorage.LookupByKey(instanceScript.GetEntranceLocation());
|
||||
}
|
||||
}
|
||||
|
||||
// Finally check with the instancesave for an entrance location if we did not get a valid one from the instancescript
|
||||
if (entranceLocation == null)
|
||||
entranceLocation = CliDB.WorldSafeLocsStorage.LookupByKey(instanceSave.GetEntranceLocation());
|
||||
}
|
||||
|
||||
if (entranceLocation != null)
|
||||
player.TeleportTo(entranceLocation.MapID, entranceLocation.Loc.X, entranceLocation.Loc.Y, entranceLocation.Loc.Z, (float)(entranceLocation.Facing * Math.PI / 180), TeleportToOptions.NotLeaveTransport);
|
||||
else
|
||||
player.TeleportTo(at.target_mapId, at.target_X, at.target_Y, at.target_Z, at.target_Orientation, TeleportToOptions.NotLeaveTransport);
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.RequestPlayedTime)]
|
||||
void HandlePlayedTime(RequestPlayedTime packet)
|
||||
{
|
||||
PlayedTime playedTime = new PlayedTime();
|
||||
playedTime.TotalTime = GetPlayer().GetTotalPlayedTime();
|
||||
playedTime.LevelTime = GetPlayer().GetLevelPlayedTime();
|
||||
playedTime.TriggerEvent = packet.TriggerScriptEvent; // 0-1 - will not show in chat frame
|
||||
SendPacket(playedTime);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SaveCufProfiles, Processing = PacketProcessing.Inplace)]
|
||||
void HandleSaveCUFProfiles(SaveCUFProfiles packet)
|
||||
{
|
||||
if (packet.CUFProfiles.Count > PlayerConst.MaxCUFProfiles)
|
||||
{
|
||||
Log.outError(LogFilter.Player, "HandleSaveCUFProfiles - {0} tried to save more than {1} CUF profiles. Hacking attempt?", GetPlayerName(), PlayerConst.MaxCUFProfiles);
|
||||
return;
|
||||
}
|
||||
|
||||
for (byte i = 0; i < packet.CUFProfiles.Count; ++i)
|
||||
GetPlayer().SaveCUFProfile(i, packet.CUFProfiles[i]);
|
||||
|
||||
for (byte i = (byte)packet.CUFProfiles.Count; i < PlayerConst.MaxCUFProfiles; ++i)
|
||||
GetPlayer().SaveCUFProfile(i, null);
|
||||
}
|
||||
|
||||
public void SendLoadCUFProfiles()
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
LoadCUFProfiles loadCUFProfiles = new LoadCUFProfiles();
|
||||
|
||||
for (byte i = 0; i < PlayerConst.MaxCUFProfiles; ++i)
|
||||
{
|
||||
CUFProfile cufProfile = player.GetCUFProfile(i);
|
||||
if (cufProfile != null)
|
||||
loadCUFProfiles.CUFProfiles.Add(cufProfile);
|
||||
}
|
||||
|
||||
SendPacket(loadCUFProfiles);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetAdvancedCombatLogging, Processing = PacketProcessing.Inplace)]
|
||||
void HandleSetAdvancedCombatLogging(SetAdvancedCombatLogging setAdvancedCombatLogging)
|
||||
{
|
||||
GetPlayer().SetAdvancedCombatLogging(setAdvancedCombatLogging.Enable);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.MountSpecialAnim)]
|
||||
void HandleMountSpecialAnim(MountSpecial mountSpecial)
|
||||
{
|
||||
SpecialMountAnim specialMountAnim = new SpecialMountAnim();
|
||||
specialMountAnim.UnitGUID = _player.GetGUID();
|
||||
GetPlayer().SendMessageToSet(specialMountAnim, false);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.MountSetFavorite)]
|
||||
void HandleMountSetFavorite(MountSetFavorite mountSetFavorite)
|
||||
{
|
||||
_collectionMgr.MountSetFavorite(mountSetFavorite.MountSpellID, mountSetFavorite.IsFavorite);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.PvpPrestigeRankUp)]
|
||||
void HandlePvpPrestigeRankUp(PvpPrestigeRankUp pvpPrestigeRankUp)
|
||||
{
|
||||
if (_player.CanPrestige())
|
||||
_player.Prestige();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.CloseInteraction)]
|
||||
void HandleCloseInteraction(CloseInteraction closeInteraction)
|
||||
{
|
||||
if (_player.PlayerTalkClass.GetInteractionData().SourceGuid == closeInteraction.SourceGuid)
|
||||
_player.PlayerTalkClass.GetInteractionData().Reset();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ChatUnregisterAllAddonPrefixes)]
|
||||
void HandleUnregisterAllAddonPrefixes(ChatUnregisterAllAddonPrefixes packet)
|
||||
{
|
||||
_registeredAddonPrefixes.Clear();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ChatRegisterAddonPrefixes)]
|
||||
void HandleAddonRegisteredPrefixes(ChatRegisterAddonPrefixes packet)
|
||||
{
|
||||
_registeredAddonPrefixes.AddRange(packet.Prefixes);
|
||||
|
||||
if (_registeredAddonPrefixes.Count > 64) // shouldn't happen
|
||||
{
|
||||
_filterAddonMessages = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_filterAddonMessages = true;
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.TogglePvp)]
|
||||
void HandleTogglePvP(TogglePvP packet)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
bool inPvP = player.HasFlag(PlayerFields.Flags, PlayerFlags.InPVP);
|
||||
player.ApplyModFlag(PlayerFields.Flags, PlayerFlags.InPVP, !inPvP);
|
||||
player.ApplyModFlag(PlayerFields.Flags, PlayerFlags.PVPTimer, inPvP);
|
||||
|
||||
if (player.HasFlag(PlayerFields.Flags, PlayerFlags.InPVP))
|
||||
{
|
||||
if (!player.IsPvP() || player.pvpInfo.EndTimer != 0)
|
||||
player.UpdatePvP(true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!player.pvpInfo.IsHostile && player.IsPvP())
|
||||
player.pvpInfo.EndTimer = Time.UnixTime; // start toggle-off
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetPvp)]
|
||||
void HandleSetPvP(SetPvP packet)
|
||||
{
|
||||
Player player = GetPlayer();
|
||||
|
||||
player.ApplyModFlag(PlayerFields.Flags, PlayerFlags.InPVP, packet.EnablePVP);
|
||||
player.ApplyModFlag(PlayerFields.Flags, PlayerFlags.PVPTimer, !packet.EnablePVP);
|
||||
|
||||
if (player.HasFlag(PlayerFields.Flags, PlayerFlags.InPVP))
|
||||
{
|
||||
if (!player.IsPvP() || player.pvpInfo.EndTimer != 0)
|
||||
player.UpdatePvP(true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!player.pvpInfo.IsHostile && player.IsPvP())
|
||||
player.pvpInfo.EndTimer = Time.UnixTime; // start set-off
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.FarSight)]
|
||||
void HandleFarSight(FarSight farSight)
|
||||
{
|
||||
if (farSight.Enable)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "Added FarSight {0} to player {1}", GetPlayer().GetUInt64Value(PlayerFields.Farsight), GetPlayer().GetGUID().ToString());
|
||||
WorldObject target = GetPlayer().GetViewpoint();
|
||||
if (target)
|
||||
GetPlayer().SetSeer(target);
|
||||
else
|
||||
Log.outDebug(LogFilter.Network, "Player {0} (GUID: {1}) requests non-existing seer {2}", GetPlayer().GetName(), GetPlayer().GetGUID().ToString(), GetPlayer().GetUInt64Value(PlayerFields.Farsight));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "Player {0} set vision to self", GetPlayer().GetGUID().ToString());
|
||||
GetPlayer().SetSeer(GetPlayer());
|
||||
}
|
||||
|
||||
GetPlayer().UpdateVisibilityForPlayer();
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetTitle)]
|
||||
void HandleSetTitle(SetTitle packet)
|
||||
{
|
||||
// -1 at none
|
||||
if (packet.TitleID > 0 && packet.TitleID < PlayerConst.MaxTitleIndex)
|
||||
{
|
||||
if (!GetPlayer().HasTitle((uint)packet.TitleID))
|
||||
return;
|
||||
}
|
||||
else
|
||||
packet.TitleID = 0;
|
||||
|
||||
GetPlayer().SetUInt32Value(PlayerFields.ChosenTitle, (uint)packet.TitleID);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ResetInstances)]
|
||||
void HandleResetInstances(ResetInstances packet)
|
||||
{
|
||||
Group group = GetPlayer().GetGroup();
|
||||
if (group)
|
||||
{
|
||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
||||
group.ResetInstances(InstanceResetMethod.All, false, false, GetPlayer());
|
||||
}
|
||||
else
|
||||
GetPlayer().ResetInstances(InstanceResetMethod.All, false, false);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetDungeonDifficulty)]
|
||||
void HandleSetDungeonDifficulty(SetDungeonDifficulty setDungeonDifficulty)
|
||||
{
|
||||
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setDungeonDifficulty.DifficultyID);
|
||||
if (difficultyEntry == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), setDungeonDifficulty.DifficultyID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (difficultyEntry.InstanceType != MapTypes.Instance)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
Difficulty difficultyID = (Difficulty)difficultyEntry.Id;
|
||||
if (difficultyID == GetPlayer().GetDungeonDifficultyID())
|
||||
return;
|
||||
|
||||
// cannot reset while in an instance
|
||||
Map map = GetPlayer().GetMap();
|
||||
if (map && map.IsDungeon())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: player (Name: {0}, {1}) tried to reset the instance while player is inside!",
|
||||
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = GetPlayer().GetGroup();
|
||||
if (group)
|
||||
{
|
||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
||||
{
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||
{
|
||||
Player groupGuy = refe.GetSource();
|
||||
if (!groupGuy)
|
||||
continue;
|
||||
|
||||
if (!groupGuy.IsInMap(groupGuy))
|
||||
return;
|
||||
|
||||
if (groupGuy.GetMap().IsNonRaidDungeon())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetDungeonDifficulty: {0} tried to reset the instance while group member (Name: {1}, {2}) is inside!",
|
||||
GetPlayer().GetGUID().ToString(), groupGuy.GetName(), groupGuy.GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// the difficulty is set even if the instances can't be reset
|
||||
//_player->SendDungeonDifficulty(true);
|
||||
group.ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false, GetPlayer());
|
||||
group.SetDungeonDifficultyID(difficultyID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, false, false);
|
||||
GetPlayer().SetDungeonDifficultyID(difficultyID);
|
||||
GetPlayer().SendDungeonDifficulty();
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetRaidDifficulty)]
|
||||
void HandleSetRaidDifficulty(SetRaidDifficulty setRaidDifficulty)
|
||||
{
|
||||
DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(setRaidDifficulty.DifficultyID);
|
||||
if (difficultyEntry == null)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an invalid instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), setRaidDifficulty.DifficultyID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (difficultyEntry.InstanceType != MapTypes.Raid)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent an non-dungeon instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!difficultyEntry.Flags.HasAnyFlag(DifficultyFlags.CanSelect))
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent unselectable instance mode {1}!",
|
||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((int)(difficultyEntry.Flags & DifficultyFlags.Legacy) >> 5) != setRaidDifficulty.Legacy)
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession.HandleSetDungeonDifficulty: {0} sent not matching legacy difficulty {1}!",
|
||||
GetPlayer().GetGUID().ToString(), difficultyEntry.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
Difficulty difficultyID = (Difficulty)difficultyEntry.Id;
|
||||
if (difficultyID == (setRaidDifficulty.Legacy != 0 ? GetPlayer().GetLegacyRaidDifficultyID() : GetPlayer().GetRaidDifficultyID()))
|
||||
return;
|
||||
|
||||
// cannot reset while in an instance
|
||||
Map map = GetPlayer().GetMap();
|
||||
if (map && map.IsDungeon())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player (Name: {0}, {1} tried to reset the instance while inside!",
|
||||
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
Group group = GetPlayer().GetGroup();
|
||||
if (group)
|
||||
{
|
||||
if (group.IsLeader(GetPlayer().GetGUID()))
|
||||
{
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next())
|
||||
{
|
||||
Player groupGuy = refe.GetSource();
|
||||
if (!groupGuy)
|
||||
continue;
|
||||
|
||||
if (!groupGuy.IsInMap(groupGuy))
|
||||
return;
|
||||
|
||||
if (groupGuy.GetMap().IsRaid())
|
||||
{
|
||||
Log.outDebug(LogFilter.Network, "WorldSession:HandleSetRaidDifficulty: player {0} tried to reset the instance while inside!", GetPlayer().GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// the difficulty is set even if the instances can't be reset
|
||||
group.ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0, GetPlayer());
|
||||
if (setRaidDifficulty.Legacy != 0)
|
||||
group.SetLegacyRaidDifficultyID(difficultyID);
|
||||
else
|
||||
group.SetRaidDifficultyID(difficultyID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPlayer().ResetInstances(InstanceResetMethod.ChangeDifficulty, true, setRaidDifficulty.Legacy != 0);
|
||||
if (setRaidDifficulty.Legacy != 0)
|
||||
GetPlayer().SetLegacyRaidDifficultyID(difficultyID);
|
||||
else
|
||||
GetPlayer().SetRaidDifficultyID(difficultyID);
|
||||
|
||||
GetPlayer().SendRaidDifficulty(setRaidDifficulty.Legacy != 0);
|
||||
}
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.SetTaxiBenchmarkMode, Processing = PacketProcessing.Inplace)]
|
||||
void HandleSetTaxiBenchmark(SetTaxiBenchmarkMode packet)
|
||||
{
|
||||
_player.ApplyModFlag(PlayerFields.Flags, PlayerFlags.TaxiBenchmark, packet.Enable);
|
||||
}
|
||||
|
||||
public void SendSetPhaseShift(List<uint> phaseIds, List<uint> terrainswaps, List<uint> worldMapAreaSwaps)
|
||||
{
|
||||
PhaseShift phaseShift = new PhaseShift();
|
||||
phaseShift.ClientGUID = GetPlayer().GetGUID();
|
||||
phaseShift.PersonalGUID = GetPlayer().GetGUID();
|
||||
phaseShift.PhaseShifts = phaseIds;
|
||||
phaseShift.VisibleMapIDs = terrainswaps;
|
||||
phaseShift.UiWorldMapAreaIDSwaps = worldMapAreaSwaps;
|
||||
SendPacket(phaseShift);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.GuildSetFocusedAchievement)]
|
||||
void HandleGuildSetFocusedAchievement(GuildSetFocusedAchievement setFocusedAchievement)
|
||||
{
|
||||
Guild guild = Global.GuildMgr.GetGuildById(GetPlayer().GetGuildId());
|
||||
if (guild)
|
||||
guild.GetAchievementMgr().SendAchievementInfo(GetPlayer(), setFocusedAchievement.AchievementID);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.InstanceLockResponse)]
|
||||
void HandleInstanceLockResponse(InstanceLockResponse packet)
|
||||
{
|
||||
if (!GetPlayer().HasPendingBind())
|
||||
{
|
||||
Log.outInfo(LogFilter.Network, "InstanceLockResponse: Player {0} (guid {1}) tried to bind himself/teleport to graveyard without a pending bind!",
|
||||
GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.AcceptLock)
|
||||
GetPlayer().BindToInstance();
|
||||
else
|
||||
GetPlayer().RepopAtGraveyard();
|
||||
|
||||
GetPlayer().SetPendingBind(0, 0);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.WardenData)]
|
||||
void HandleWardenDataOpcode(WardenData packet)
|
||||
{
|
||||
if (_warden == null || packet.Data.GetSize() == 0)
|
||||
return;
|
||||
|
||||
var unpacked = new ByteBuffer(_warden.DecryptData(packet.Data.GetData()));
|
||||
WardenOpcodes opcode = (WardenOpcodes)packet.Data.ReadUInt8();
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case WardenOpcodes.CMSG_ModuleMissing:
|
||||
_warden.SendModuleToClient();
|
||||
break;
|
||||
case WardenOpcodes.Cmsg_ModuleOk:
|
||||
_warden.RequestHash();
|
||||
break;
|
||||
case WardenOpcodes.Smsg_CheatChecksRequest:
|
||||
_warden.HandleData(packet.Data);
|
||||
break;
|
||||
case WardenOpcodes.Cmsg_MemChecksResult:
|
||||
Log.outDebug(LogFilter.Warden, "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
|
||||
break;
|
||||
case WardenOpcodes.Cmsg_HashResult:
|
||||
_warden.HandleHashResult(packet.Data);
|
||||
_warden.InitializeModule();
|
||||
break;
|
||||
case WardenOpcodes.Cmsg_ModuleFailed:
|
||||
Log.outDebug(LogFilter.Warden, "NYI WARDEN_CMSG_MODULE_FAILED received!");
|
||||
break;
|
||||
default:
|
||||
Log.outDebug(LogFilter.Warden, "Got unknown warden opcode {0} of size {1}.", opcode, packet.Data.GetSize() - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user