diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index e7f74093..a8b0ad86 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -69,6 +69,7 @@ + @@ -122,7 +123,13 @@ - + + + + + + + diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 0700c9e5..4ae77867 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -143,7 +143,8 @@ namespace FFXIVClassic_Map_Server rotation, actorState, animationId, - actorClassName + actorClassName, + eventConditions FROM server_npclist "; @@ -155,6 +156,14 @@ namespace FFXIVClassic_Map_Server { Npc npc = new Npc(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt32(2), reader.GetUInt32(3), reader.GetFloat(4), reader.GetFloat(5), reader.GetFloat(6), reader.GetFloat(7), reader.GetUInt16(8), reader.GetUInt32(9), reader.GetString(10)); + if (!reader.IsDBNull(11)) + { + string eventConditions = reader.GetString(11); + npc.loadEventConditions(eventConditions); + } + + if (!zoneList.ContainsKey(npc.zoneId)) + continue; Zone zone = zoneList[npc.zoneId]; if (zone == null) continue; diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 89750949..976cae5d 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -1,9 +1,11 @@ using FFXIVClassic_Lobby_Server; using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.actors; using FFXIVClassic_Map_Server.dataobjects.chara; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.packets.send.actor.events; using System; using System.Collections; using System.Collections.Generic; @@ -37,6 +39,8 @@ namespace FFXIVClassic_Map_Server.Actors public string className; public List classParams; + public EventList eventConditions; + public Actor(uint actorId) { this.actorId = actorId; @@ -90,6 +94,64 @@ namespace FFXIVClassic_Map_Server.Actors return SetActorStatePacket.buildPacket(actorId, playerActorID, currentMainState, currentSubState); } + public List getEventConditionPackets(uint playerActorId) + { + List subpackets = new List(); + + //Return empty list + if (eventConditions == null) + return subpackets; + + if (eventConditions.talkEventConditions != null) + { + foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) + subpackets.Add(SetTalkEventCondition.buildPacket(playerActorId, actorId, condition.unknown1, condition.unknown2, condition.conditionName)); + } + + if (eventConditions.noticeEventConditions != null) + { + foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions) + subpackets.Add(SetNoticeEventCondition.buildPacket(playerActorId, actorId, condition.unknown1, condition.unknown2, condition.conditionName)); + } + + if (eventConditions.emoteEventConditions != null) + { + foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions) + subpackets.Add(SetEmoteEventCondition.buildPacket(playerActorId, actorId, condition.unknown1, condition.unknown2, condition.emoteId, condition.conditionName)); + } + + return subpackets; + } + + public BasePacket getSetEventStatusPackets(uint playerActorId) + { + List subpackets = new List(); + + //Return empty list + if (eventConditions == null) + return BasePacket.createPacket(subpackets, true, false); + + if (eventConditions.talkEventConditions != null) + { + foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) + subpackets.Add(SetEventStatus.buildPacket(playerActorId, actorId, 1, 1, condition.conditionName)); + } + + if (eventConditions.noticeEventConditions != null) + { + foreach (EventList.NoticeEventCondition condition in eventConditions.noticeEventConditions) + subpackets.Add(SetEventStatus.buildPacket(playerActorId, actorId, 1, 1, condition.conditionName)); + } + + if (eventConditions.emoteEventConditions != null) + { + foreach (EventList.EmoteEventCondition condition in eventConditions.emoteEventConditions) + subpackets.Add(SetEventStatus.buildPacket(playerActorId, actorId, 1, 1, condition.conditionName)); + } + + return BasePacket.createPacket(subpackets, true, false); + } + public SubPacket createIsZoneingPacket(uint playerActorId) { return SetActorIsZoningPacket.buildPacket(actorId, playerActorId, false); @@ -109,6 +171,7 @@ namespace FFXIVClassic_Map_Server.Actors { List subpackets = new List(); subpackets.Add(createAddActorPacket(playerActorId)); + subpackets.AddRange(getEventConditionPackets(playerActorId)); subpackets.Add(createSpeedPacket(playerActorId)); subpackets.Add(createSpawnPositonPacket(playerActorId, spawnType)); subpackets.Add(createNamePacket(playerActorId)); @@ -116,7 +179,7 @@ namespace FFXIVClassic_Map_Server.Actors subpackets.Add(createIsZoneingPacket(playerActorId)); subpackets.Add(createScriptBindPacket(playerActorId)); return BasePacket.createPacket(subpackets, true, false); - } + } public virtual BasePacket getInitPackets(uint playerActorId) { diff --git a/FFXIVClassic Map Server/actors/EventList.cs b/FFXIVClassic Map Server/actors/EventList.cs new file mode 100644 index 00000000..ae633288 --- /dev/null +++ b/FFXIVClassic Map Server/actors/EventList.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors +{ + class EventList + { + public List talkEventConditions; + public List noticeEventConditions; + public List emoteEventConditions; + public List pushWithCircleEventConditions; + public List pushWithFanEventConditions; + public List pushWithBoxEventConditions; + + public class TalkEventCondition + { + public byte unknown1; + public byte unknown2; + public string conditionName; + } + + public class NoticeEventCondition + { + public byte unknown1; + public byte unknown2; + public string conditionName; + } + + public class EmoteEventCondition + { + public byte unknown1; + public byte unknown2; + public byte emoteId; + public string conditionName; + } + + public class PushCircleEventCondition + { + public byte unknown1; + public byte unknown2; + public byte unknown4; + public byte emoteId; + public float radius; + public int unknown5; + public float unknown6; + public string conditionName; + } + + public class PushFanEventCondition + { + byte unknown1; + byte unknown2; + byte emoteId; + string conditionName; + } + + public class PushBoxEventCondition + { + byte unknown1; + byte unknown2; + byte emoteId; + string conditionName; + } + } +} diff --git a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs index 6f78d945..f664ef11 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs @@ -1,10 +1,12 @@ using FFXIVClassic_Lobby_Server; using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.actors; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.utils; using MySql.Data.MySqlClient; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -49,6 +51,7 @@ namespace FFXIVClassic_Map_Server.Actors { List subpackets = new List(); subpackets.Add(createAddActorPacket(playerActorId)); + subpackets.AddRange(getEventConditionPackets(playerActorId)); subpackets.Add(createSpeedPacket(playerActorId)); subpackets.Add(createSpawnPositonPacket(playerActorId, 0x0)); subpackets.Add(createAppearancePacket(playerActorId)); @@ -168,7 +171,12 @@ namespace FFXIVClassic_Map_Server.Actors conn.Dispose(); } } - } + } + public void loadEventConditions(string eventConditions) + { + EventList conditions = JsonConvert.DeserializeObject(eventConditions); + this.eventConditions = conditions; + } } } diff --git a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs index 55c6f2a5..55939a7f 100644 --- a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs +++ b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs @@ -112,6 +112,7 @@ namespace FFXIVClassic_Map_Server.dataobjects { basePackets.Add(actor.getSpawnPackets(playerActor.actorId, 1)); basePackets.Add(actor.getInitPackets(playerActor.actorId)); + basePackets.Add(actor.getSetEventStatusPackets(playerActor.actorId)); actorInstanceList.Add(actor); } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetEmoteEventCondition.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetEmoteEventCondition.cs index db73a2a7..7e47022b 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetEmoteEventCondition.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetEmoteEventCondition.cs @@ -13,24 +13,23 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x016C; public const uint PACKET_SIZE = 0x48; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID, byte unknown1, byte unknown2, ushort emoteId, string conditionName) { byte[] data = new byte[PACKET_SIZE - 0x20]; - string eventName = ""; - using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) - { - binWriter.Write((Byte)0); - binWriter.Write((Byte)0); - binWriter.Write((UInt16)0); - binWriter.Write(Encoding.ASCII.GetBytes(eventName), 0, Encoding.ASCII.GetByteCount(eventName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(eventName)); + { + binWriter.Write((Byte)unknown1); + binWriter.Write((Byte)unknown2); + binWriter.Write((UInt16)emoteId); + binWriter.Write(Encoding.ASCII.GetBytes(conditionName), 0, Encoding.ASCII.GetByteCount(conditionName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(conditionName)); } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } + } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetEventStatus.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetEventStatus.cs index be678eb9..1c566fca 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetEventStatus.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetEventStatus.cs @@ -13,22 +13,21 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x0136; public const uint PACKET_SIZE = 0x48; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID, uint unknown1, byte unknown2, string conditionName) { byte[] data = new byte[PACKET_SIZE - 0x20]; - string eventName = ""; - using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - binWriter.Write((UInt32)0); - binWriter.Write(Encoding.ASCII.GetBytes(eventName), 0, Encoding.ASCII.GetByteCount(eventName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(eventName)); + binWriter.Write((UInt32)unknown1); + binWriter.Write((Byte)unknown2); + binWriter.Write(Encoding.ASCII.GetBytes(conditionName), 0, Encoding.ASCII.GetByteCount(conditionName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(conditionName)); } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetNoticeEventCondition.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetNoticeEventCondition.cs index da1ccebe..d30dabe5 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetNoticeEventCondition.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetNoticeEventCondition.cs @@ -13,23 +13,22 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x016B; public const uint PACKET_SIZE = 0x48; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID, byte unknown1, byte unknown2, string conditionName) { byte[] data = new byte[PACKET_SIZE - 0x20]; - string eventName = ""; - using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) - { - binWriter.Write((Byte)0); - binWriter.Write((Byte)0); - binWriter.Write(Encoding.ASCII.GetBytes(eventName), 0, Encoding.ASCII.GetByteCount(eventName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(eventName)); + { + binWriter.Write((Byte)unknown1); + binWriter.Write((Byte)unknown2); + binWriter.Write(Encoding.ASCII.GetBytes(conditionName), 0, Encoding.ASCII.GetByteCount(conditionName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(conditionName)); } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } + } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithCircle.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithCircle.cs index d29bd240..c7545c24 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithCircle.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithCircle.cs @@ -13,7 +13,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x016F; public const uint PACKET_SIZE = 0x58; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID) { byte[] data = new byte[PACKET_SIZE - 0x20]; @@ -34,7 +34,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithFan.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithFan.cs index 5af69878..c37ac803 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithFan.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithFan.cs @@ -13,7 +13,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x0170; public const uint PACKET_SIZE = 0x60; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID) { byte[] data = new byte[PACKET_SIZE - 0x20]; @@ -34,7 +34,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithTriggerBox.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithTriggerBox.cs index 608a93f9..ae84ba4f 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithTriggerBox.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetPushEventConditionWithTriggerBox.cs @@ -13,7 +13,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x0175; public const uint PACKET_SIZE = 0x58; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID) { byte[] data = new byte[PACKET_SIZE - 0x20]; @@ -34,7 +34,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } } } diff --git a/FFXIVClassic Map Server/packets/send/Actor/events/SetTalkEventCondition.cs b/FFXIVClassic Map Server/packets/send/Actor/events/SetTalkEventCondition.cs index de9c4d6c..a84cf87b 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/events/SetTalkEventCondition.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/events/SetTalkEventCondition.cs @@ -13,23 +13,21 @@ namespace FFXIVClassic_Map_Server.packets.send.actor.events public const ushort OPCODE = 0x012E; public const uint PACKET_SIZE = 0x48; - public static SubPacket buildPacket(uint playerActorID, uint targetActorID) + public static SubPacket buildPacket(uint playerActorID, uint sourceActorID, byte unknown1, byte unknown2, string conditionName) { byte[] data = new byte[PACKET_SIZE - 0x20]; - string eventName = ""; - using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) - { - binWriter.Write((Byte)0); - binWriter.Write((Byte)0); - binWriter.Write(Encoding.ASCII.GetBytes(eventName), 0, Encoding.ASCII.GetByteCount(eventName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(eventName)); + { + binWriter.Write((Byte)unknown1); + binWriter.Write((Byte)unknown2); + binWriter.Write(Encoding.ASCII.GetBytes(conditionName), 0, Encoding.ASCII.GetByteCount(conditionName) >= 0x24 ? 0x24 : Encoding.ASCII.GetByteCount(conditionName)); } } - return new SubPacket(OPCODE, playerActorID, playerActorID, data); + return new SubPacket(OPCODE, sourceActorID, playerActorID, data); } } }