From aa54fb11cc195090bcf9183bdc257160baa2bcb2 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sat, 27 Jul 2019 21:54:05 -0400 Subject: [PATCH] Reimplemented dream packets. Fixed instance update bug that was locking up client when waking up. When going to sleep the proper position is saved. Still need to handle if the player logs out in the inn vs sleeping. --- Map Server/Actors/Chara/Player/Player.cs | 119 ++++++++++++------ Map Server/DataObjects/Session.cs | 4 +- .../Send/Player/SetPlayerDreamPacket.cs | 6 +- Map Server/WorldManager.cs | 6 +- 4 files changed, 93 insertions(+), 42 deletions(-) diff --git a/Map Server/Actors/Chara/Player/Player.cs b/Map Server/Actors/Chara/Player/Player.cs index 84233d31..d57f485b 100644 --- a/Map Server/Actors/Chara/Player/Player.cs +++ b/Map Server/Actors/Chara/Player/Player.cs @@ -1,4 +1,4 @@ -/* +/* =========================================================================== Copyright (C) 2015-2019 Project Meteor Dev Team @@ -51,7 +51,7 @@ namespace Meteor.Map.Actors class Player : Character { public const int TIMER_TOTORAK = 0; - public const int TIMER_DZEMAEL = 1; + public const int TIMER_DZEMAEL = 1; public const int TIMER_BOWL_OF_EMBERS_HARD = 2; public const int TIMER_BOWL_OF_EMBERS = 3; public const int TIMER_THORNMARCH = 4; @@ -71,10 +71,10 @@ namespace Meteor.Map.Actors public const int TIMER_RETURN = 18; public const int TIMER_SKIRMISH = 19; - public const int NPCLS_GONE = 0; + public const int NPCLS_GONE = 0; public const int NPCLS_INACTIVE = 1; - public const int NPCLS_ACTIVE = 2; - public const int NPCLS_ALERT = 3; + public const int NPCLS_ACTIVE = 2; + public const int NPCLS_ALERT = 3; public const int SLOT_MAINHAND = 0; public const int SLOT_OFFHAND = 1; @@ -269,12 +269,12 @@ namespace Meteor.Map.Actors Database.LoadPlayerCharacter(this); lastPlayTimeUpdate = Utils.UnixTimeStampUTC(); - + this.aiContainer = new AIContainer(this, new PlayerController(this), null, new TargetFind(this)); allegiance = CharacterTargetingAllegiance.Player; CalculateBaseStats(); } - + public List Create0x132Packets() { List packets = new List(); @@ -336,7 +336,7 @@ namespace Meteor.Map.Actors subpackets.Add(CreateSetActorIconPacket()); subpackets.Add(CreateIsZoneingPacket()); subpackets.AddRange(CreatePlayerRelatedPackets(requestPlayer.actorId)); - subpackets.Add(CreateScriptBindPacket(requestPlayer)); + subpackets.Add(CreateScriptBindPacket(requestPlayer)); return subpackets; } @@ -369,31 +369,41 @@ namespace Meteor.Map.Actors subpackets.Add(SetAchievementPointsPacket.BuildPacket(actorId, achievementPoints)); subpackets.Add(Database.GetLatestAchievements(this)); - subpackets.Add(Database.GetAchievementsPacket(this)); + subpackets.Add(Database.GetAchievementsPacket(this)); } if (mountState == 1) subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft)); else if (mountState == 2) subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1)); - + + //Inn Packets (Dream, Cutscenes, Armoire) + if (zone.isInn) + { + SetCutsceneBookPacket cutsceneBookPacket = new SetCutsceneBookPacket(); + for (int i = 0; i < 2048; i++) + cutsceneBookPacket.cutsceneFlags[i] = true; + QueuePacket(cutsceneBookPacket.BuildPacket(actorId, "", 11, 1, 1)); + QueuePacket(SetPlayerDreamPacket.BuildPacket(actorId, 0x16, GetInnCode())); + } + return subpackets; } public override List GetInitPackets() { ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this); - + propPacketUtil.AddProperty("charaWork.eventSave.bazaarTax"); propPacketUtil.AddProperty("charaWork.battleSave.potencial"); //Properties for (int i = 0; i < charaWork.property.Length; i++) { - if (charaWork.property[i] != 0) + if (charaWork.property[i] != 0) propPacketUtil.AddProperty(String.Format("charaWork.property[{0}]", i)); } - + //Parameters propPacketUtil.AddProperty("charaWork.parameterSave.hp[0]"); propPacketUtil.AddProperty("charaWork.parameterSave.hpMax[0]"); @@ -402,21 +412,21 @@ namespace Meteor.Map.Actors propPacketUtil.AddProperty("charaWork.parameterTemp.tp"); propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkill[0]"); propPacketUtil.AddProperty("charaWork.parameterSave.state_mainSkillLevel"); - + //Status Times for (int i = 0; i < charaWork.statusShownTime.Length; i++) { if (charaWork.statusShownTime[i] != 0) propPacketUtil.AddProperty(String.Format("charaWork.statusShownTime[{0}]", i)); } - + //General Parameters for (int i = 3; i < charaWork.battleTemp.generalParameter.Length; i++) { if (charaWork.battleTemp.generalParameter[i] != 0) propPacketUtil.AddProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i)); } - + propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[0]"); propPacketUtil.AddProperty("charaWork.battleTemp.castGauge_speed[1]"); @@ -425,23 +435,23 @@ namespace Meteor.Map.Actors //Commands propPacketUtil.AddProperty("charaWork.commandBorder"); - + propPacketUtil.AddProperty("charaWork.battleSave.negotiationFlag[0]"); - + for (int i = 0; i < charaWork.command.Length; i++) { if (charaWork.command[i] != 0) { propPacketUtil.AddProperty(String.Format("charaWork.command[{0}]", i)); //Recast Timers - if(i >= charaWork.commandBorder) + if (i >= charaWork.commandBorder) { propPacketUtil.AddProperty(String.Format("charaWork.parameterTemp.maxCommandRecastTime[{0}]", i - charaWork.commandBorder)); propPacketUtil.AddProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i - charaWork.commandBorder)); } } } - + for (int i = 0; i < charaWork.commandCategory.Length; i++) { charaWork.commandCategory[i] = 1; @@ -460,7 +470,7 @@ namespace Meteor.Map.Actors if (charaWork.additionalCommandAcquired[i] != false) propPacketUtil.AddProperty(String.Format("charaWork.additionalCommandAcquired[{0}]", i)); } - + for (int i = 0; i < charaWork.parameterSave.commandSlot_compatibility.Length; i++) { charaWork.parameterSave.commandSlot_compatibility[i] = true; @@ -489,7 +499,7 @@ namespace Meteor.Map.Actors propPacketUtil.AddProperty("charaWork.parameterTemp.giftCount[1]"); propPacketUtil.AddProperty("charaWork.depictionJudge"); - + //Scenario for (int i = 0; i < playerWork.questScenario.Length; i++) { @@ -543,7 +553,7 @@ namespace Meteor.Map.Actors propPacketUtil.AddProperty("playerWork.birthdayMonth"); propPacketUtil.AddProperty("playerWork.birthdayDay"); propPacketUtil.AddProperty("playerWork.initialTown"); - + return propPacketUtil.Done(); } @@ -577,10 +587,8 @@ namespace Meteor.Map.Actors QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1)); QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId)); - QueuePacket(SetPlayerDreamPacket.BuildPacket(actorId, 0)); - QueuePackets(GetSpawnPackets(this, spawnType)); - //GetSpawnPackets(actorId, spawnType).DebugPrintPacket(); + QueuePackets(GetSpawnPackets(this, spawnType)); #region Inventory & Equipment QueuePacket(InventoryBeginChangePacket.BuildPacket(actorId, true)); @@ -590,7 +598,7 @@ namespace Meteor.Map.Actors itemPackages[ItemPackage.BAZAAR].SendFullPackage(this); itemPackages[ItemPackage.MELDREQUEST].SendFullPackage(this); itemPackages[ItemPackage.LOOT].SendFullPackage(this); - equipment.SendUpdate(this); + equipment.SendUpdate(this); playerSession.QueuePacket(InventoryEndChangePacket.BuildPacket(actorId)); #endregion @@ -599,19 +607,16 @@ namespace Meteor.Map.Actors List areaMasterSpawn = zone.GetSpawnPackets(); List debugSpawn = world.GetDebugActor().GetSpawnPackets(); List worldMasterSpawn = world.GetActor().GetSpawnPackets(); - + playerSession.QueuePacket(areaMasterSpawn); playerSession.QueuePacket(debugSpawn); playerSession.QueuePacket(worldMasterSpawn); - //Inn Packets (Dream, Cutscenes, Armoire) - if (zone.GetWeatherDirector() != null) { playerSession.QueuePacket(zone.GetWeatherDirector().GetSpawnPackets()); } - foreach (Director director in ownedDirectors) { QueuePackets(director.GetSpawnPackets()); @@ -623,6 +628,8 @@ namespace Meteor.Map.Actors if (currentParty != null) currentParty.SendGroupPackets(playerSession); + + SendInstanceUpdate(); } private void SendRemoveInventoryPackets(List slots) @@ -650,7 +657,7 @@ namespace Meteor.Map.Actors public bool IsMyPlayer(uint otherActorId) { return actorId == otherActorId; - } + } public void QueuePacket(SubPacket packet) @@ -808,6 +815,48 @@ namespace Meteor.Map.Actors QueuePacket(SendMessagePacket.BuildPacket(actorId, logType, sender, message)); } + //Only use at logout since it's intensive + private byte GetInnCode() + { + if (zone.isInn) + { + Vector3 position = new Vector3(positionX, 0, positionZ); + if (Utils.Distance(position, new Vector3(0, 0, 0)) <= 20f) + return 3; + else if (Utils.Distance(position, new Vector3(160, 0, 160)) <= 20f) + return 2; + else if (Utils.Distance(position, new Vector3(-160, 0, -160)) <= 20f) + return 1; + } + return 0; + } + + public void SetSleeping() + { + playerSession.LockUpdates(true); + switch(GetInnCode()) + { + case 1: + positionX = -162.42f; + positionY = 0f; + positionZ = -154.21f; + rotation = 1.56f; + break; + case 2: + positionX = 157.55f; + positionY = 0f; + positionZ = 165.05f; + rotation = 1.53f; + break; + case 3: + positionX = -2.65f; + positionY = 0f; + positionZ = 3.94f; + rotation = 1.52f; + break; + } + } + public void Logout() { // todo: really this should be in CleanupAndSave but we might want logout/disconnect handled separately for some effects @@ -1809,8 +1858,8 @@ namespace Meteor.Map.Actors { BroadcastPacket(StartCountdownPacket.BuildPacket(actorId, countdownLength, syncTime, "Go!"), true); } - - public void SendInstanceUpdate() + + public void SendInstanceUpdate(bool force = false) { //Server.GetWorldManager().SeamlessCheck(this); @@ -1821,7 +1870,7 @@ namespace Meteor.Map.Actors aroundMe.AddRange(zone.GetActorsAroundActor(this, 50)); if (zone2 != null) aroundMe.AddRange(zone2.GetActorsAroundActor(this, 50)); - playerSession.UpdateInstance(aroundMe); + playerSession.UpdateInstance(aroundMe, force); } public bool IsInParty() diff --git a/Map Server/DataObjects/Session.cs b/Map Server/DataObjects/Session.cs index 8b0259a2..4d20dc30 100644 --- a/Map Server/DataObjects/Session.cs +++ b/Map Server/DataObjects/Session.cs @@ -105,9 +105,9 @@ namespace Meteor.Map.dataobjects playerActor.QueuePositionUpdate(new Vector3(x,y,z)); } - public void UpdateInstance(List list) + public void UpdateInstance(List list, bool force = false) { - if (isUpdatesLocked) + if (isUpdatesLocked && !force) return; List basePackets = new List(); diff --git a/Map Server/Packets/Send/Player/SetPlayerDreamPacket.cs b/Map Server/Packets/Send/Player/SetPlayerDreamPacket.cs index d35bf24d..40e599b4 100644 --- a/Map Server/Packets/Send/Player/SetPlayerDreamPacket.cs +++ b/Map Server/Packets/Send/Player/SetPlayerDreamPacket.cs @@ -30,16 +30,16 @@ namespace Meteor.Map.packets.send.player public const ushort OPCODE = 0x01A7; public const uint PACKET_SIZE = 0x28; - public static SubPacket BuildPacket(uint sourceActorId, uint dreamID) + public static SubPacket BuildPacket(uint sourceActorId, byte dreamID, byte innID) { - dreamID = 0x0216; byte[] data = new byte[PACKET_SIZE - 0x20]; using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - binWriter.Write((Int32)0x216); + binWriter.Write((Byte)dreamID); + binWriter.Write((Byte)innID); } } diff --git a/Map Server/WorldManager.cs b/Map Server/WorldManager.cs index adca83c4..afb66c3c 100644 --- a/Map Server/WorldManager.cs +++ b/Map Server/WorldManager.cs @@ -1047,7 +1047,7 @@ namespace Meteor.Map player.playerSession.QueuePacket(_0xE2Packet.BuildPacket(player.actorId, 0x10)); player.SendZoneInPackets(this, spawnType); player.playerSession.ClearInstance(); - player.SendInstanceUpdate(); + player.SendInstanceUpdate(true); player.playerSession.LockUpdates(false); @@ -1078,7 +1078,6 @@ namespace Meteor.Map { player.playerSession.QueuePacket(DeleteAllActorsPacket.BuildPacket(player.actorId)); player.playerSession.QueuePacket(_0xE2Packet.BuildPacket(player.actorId, 0x2)); - //player.SendZoneInPackets(this, spawnType); } player.SendZoneInPackets(this, spawnType); @@ -1087,6 +1086,9 @@ namespace Meteor.Map player.destinationSpawnType = 0; Database.SavePlayerPosition(player); + player.playerSession.ClearInstance(); + player.SendInstanceUpdate(true); + player.playerSession.LockUpdates(false); LuaEngine.GetInstance().CallLuaFunction(player, playerArea, "onZoneIn", true);