diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index bf4fb7c7..a9de1656 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -33,6 +33,7 @@ using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.dataobjects.actors; using FFXIVClassic_Map_Server.dataobjects.chara.npc; using FFXIVClassic_Map_Server.actors; +using System.Net; namespace FFXIVClassic_Lobby_Server { @@ -123,11 +124,7 @@ namespace FFXIVClassic_Lobby_Server if (actorID == 0) break; - - //Second connection - if (mPlayers.ContainsKey(actorID)) - player = mPlayers[actorID]; - + using (MemoryStream mem = new MemoryStream(reply2.data)) { using (BinaryWriter binReader = new BinaryWriter(mem)) @@ -137,7 +134,7 @@ namespace FFXIVClassic_Lobby_Server } } - if (player == null) + if (((IPEndPoint)client.socket.LocalEndPoint).Port == 54992) { player = new ConnectedPlayer(actorID); mPlayers[actorID] = player; diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index f34d2a28..789ffcd9 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -5,7 +5,6 @@ using FFXIVClassic_Lobby_Server.packets; 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; using System; using System.Collections; using System.Collections.Generic; @@ -94,7 +93,7 @@ namespace FFXIVClassic_Map_Server.dataobjects return null; } - public virtual BasePacket getInitPackets(uint playerActorId) + public virtual BasePacket getSpawnPackets(uint playerActorId) { List subpackets = new List(); subpackets.Add(createAddActorPacket(playerActorId)); @@ -105,7 +104,14 @@ namespace FFXIVClassic_Map_Server.dataobjects subpackets.Add(createIsZoneingPacket(playerActorId)); return BasePacket.createPacket(subpackets, true, false); } - + + public virtual BasePacket getInitPackets(uint playerActorId) + { + SetActorPropetyPacket initProperties = new SetActorPropetyPacket("/_init"); + initProperties.addTarget(); + return BasePacket.createPacket(initProperties.buildPacket(playerActorId, actorId), true, false); + } + public override bool Equals(Object obj) { Actor actorObj = obj as Actor; diff --git a/FFXIVClassic Map Server/actors/chara/BattleTemp.cs b/FFXIVClassic Map Server/actors/chara/BattleTemp.cs index 78ecab38..7928b1c4 100644 --- a/FFXIVClassic Map Server/actors/chara/BattleTemp.cs +++ b/FFXIVClassic Map Server/actors/chara/BattleTemp.cs @@ -45,7 +45,7 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara public const uint STAT_HARVEST_LIMIT = 34; public const uint STAT_HARVEST_RATE = 35; - public int[] castGauge_speed = new int[2]; + public float[] castGauge_speed = { 1.0f, 0.25f}; public bool[] timingCommandFlag = new bool[4]; public ushort[] generalParameter = new ushort[32]; } diff --git a/FFXIVClassic Map Server/actors/chara/ParameterTemp.cs b/FFXIVClassic Map Server/actors/chara/ParameterTemp.cs index 9d77e566..a42e7bb9 100644 --- a/FFXIVClassic Map Server/actors/chara/ParameterTemp.cs +++ b/FFXIVClassic Map Server/actors/chara/ParameterTemp.cs @@ -14,8 +14,8 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara public int[] maxCommandRecastTime = new int[40]; - public float[] forceControl_float_forClientSelf = new float[4]; - public short[] forceControl_int16_forClientSelf = new short[2]; + public float[] forceControl_float_forClientSelf = { 1.0f, 1.0f}; + public short[] forceControl_int16_forClientSelf = { -1, -1 }; public int[] otherClassAbilityCount = new int[2]; public int[] giftCount = new int[2]; diff --git a/FFXIVClassic Map Server/actors/chara/Work.cs b/FFXIVClassic Map Server/actors/chara/Work.cs index be564bc2..4cbfa626 100644 --- a/FFXIVClassic Map Server/actors/chara/Work.cs +++ b/FFXIVClassic Map Server/actors/chara/Work.cs @@ -8,6 +8,7 @@ namespace FFXIVClassic_Map_Server.actors.chara { class Work { + public ushort[] guildleveId = new ushort[16]; public bool[] guildleveDone = new bool[16]; public bool[] guildleveChecked = new bool[16]; public bool betacheck = false; diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 7f0b23c6..24084bda 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -5,6 +5,7 @@ using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Map_Server.dataobjects.database; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.utils; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -101,7 +102,7 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams); } - public override BasePacket getInitPackets(uint playerActorId) + public override BasePacket getSpawnPackets(uint playerActorId) { List subpackets = new List(); subpackets.Add(createAddActorPacket(playerActorId)); @@ -117,11 +118,127 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara subpackets.Add(createInitStatusPacket(playerActorId)); subpackets.Add(createSetActorIconPacket(playerActorId)); subpackets.Add(createIsZoneingPacket(playerActorId)); - subpackets.Add(createScriptBindPacket(playerActorId)); - + subpackets.Add(createScriptBindPacket(playerActorId)); return BasePacket.createPacket(subpackets, true, false); } + public override BasePacket getInitPackets(uint playerActorId) + { + ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("/_init", this, playerActorId); + + //Properties + for (int i = 0; i < charaWork.property.Length; i++) + { + 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]"); + propPacketUtil.addProperty("charaWork.parameterSave.mp"); + propPacketUtil.addProperty("charaWork.parameterSave.mpMax"); + propPacketUtil.addProperty("charaWork.parameterSave.mpMax"); + 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 = 0; i < 36; i++) + { + propPacketUtil.addProperty(String.Format("charaWork.battleTemp.generalParameter[{0}]", i)); + } + + propPacketUtil.addProperty("charaWork.battleTemp.castGauge_speed[0]"); + propPacketUtil.addProperty("charaWork.battleTemp.castGauge_speed[1]"); + + //Battle Save Skillpoint + + //Commands + for (int i = 0; i < charaWork.command.Length; i++) + { + if (charaWork.command[i] != 0) + propPacketUtil.addProperty(String.Format("charaWork.command[{0}]", i)); + } + for (int i = 0; i < charaWork.commandCategory.Length; i++) + { + if (charaWork.commandCategory[i] != 0) + propPacketUtil.addProperty(String.Format("charaWork.commandCategory[{0}]", i)); + } + + propPacketUtil.addProperty("charaWork.commandBorder"); + + for (int i = 0; i < charaWork.parameterSave.commandSlot_compatibility.Length; i++) + { + if (charaWork.parameterSave.commandSlot_compatibility[i] != 0) + propPacketUtil.addProperty(String.Format("charaWork.parameterSave.commandSlot_compatibility[{0}]", i)); + } + for (int i = 0; i < charaWork.parameterSave.commandSlot_recastTime.Length; i++) + { + if (charaWork.parameterSave.commandSlot_recastTime[i] != 0) + propPacketUtil.addProperty(String.Format("charaWork.parameterSave.commandSlot_recastTime[{0}]", i)); + } + + //System + propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[0]"); + propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_float_forClientSelf[1]"); + propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[0]"); + propPacketUtil.addProperty("charaWork.parameterTemp.forceControl_int16_forClientSelf[1]"); + + propPacketUtil.addProperty("charaWork.depictionJudge"); + propPacketUtil.addProperty("playerWork.restBonusExpRate"); + + //Scenario + for (int i = 0; i < playerWork.questScenario.Length; i++) + { + if (playerWork.questScenario[i] != 0) + propPacketUtil.addProperty(String.Format("playerWork.questScenario[{0}]", i)); + } + + //Guildleve - Local + for (int i = 0; i < playerWork.questGuildLeve.Length; i++) + { + if (playerWork.questGuildLeve[i] != 0) + propPacketUtil.addProperty(String.Format("playerWork.questGuildLeve[{0}]", i)); + } + + //NPC Linkshell + for (int i = 0; i < playerWork.npcLinkshellChatCalling.Length; i++) + { + if (playerWork.npcLinkshellChatCalling[i] != false) + propPacketUtil.addProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", i)); + if (playerWork.npcLinkshellChatExtra[i] != false) + propPacketUtil.addProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", i)); + } + + //Guildleve - Regional + for (int i = 0; i < work.guildleveId.Length; i++) + { + if (work.guildleveId[i] != 0) + propPacketUtil.addProperty(String.Format("work.guildleveId[{0}]", i)); + if (work.guildleveDone[i] != false) + propPacketUtil.addProperty(String.Format("work.guildleveDone[{0}]", i)); + if (work.guildleveChecked[i] != false) + propPacketUtil.addProperty(String.Format("work.guildleveChecked[{0}]", i)); + } + + //Profile + propPacketUtil.addProperty("playerWork.tribe"); + propPacketUtil.addProperty("playerWork.guardian"); + propPacketUtil.addProperty("playerWork.birthdayMonth"); + propPacketUtil.addProperty("playerWork.birthdayDay"); + propPacketUtil.addProperty("playerWork.initialTown"); + + return propPacketUtil.done(); + } + public bool isMyPlayer(uint otherActorId) { return actorId == otherActorId; diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs index e6dd9637..b455d3a1 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorNamePacket.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FFXIVClassic_Map_Server.packets.send.Actor +namespace FFXIVClassic_Map_Server.packets.send.actor { class SetActorNamePacket { diff --git a/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs b/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs index cd61c7f4..f4d74dda 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/SetActorPropetyPacket.cs @@ -22,14 +22,17 @@ namespace FFXIVClassic_Map_Server.packets.send.actor private byte[] data = new byte[PACKET_SIZE - 0x20]; private bool isMore = false; + string currentTarget; + private MemoryStream mem; private BinaryWriter binWriter; - public SetActorPropetyPacket() + public SetActorPropetyPacket(string startingTarget) { mem = new MemoryStream(data); binWriter = new BinaryWriter(mem); binWriter.Seek(1, SeekOrigin.Begin); + currentTarget = startingTarget; } public void closeStreams() @@ -40,7 +43,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public bool addByte(uint id, byte value) { - if (runningByteTotal + 6 > MAXBYTES) + if (runningByteTotal + 6 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES) return false; binWriter.Write((byte)1); @@ -53,7 +56,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public bool addShort(uint id, ushort value) { - if (runningByteTotal + 7 > MAXBYTES) + if (runningByteTotal + 7 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES) return false; binWriter.Write((byte)2); @@ -66,7 +69,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public bool addInt(uint id, uint value) { - if (runningByteTotal + 9 > MAXBYTES) + if (runningByteTotal + 9 + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES) return false; binWriter.Write((byte)4); @@ -79,7 +82,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public bool addBuffer(uint id, byte[] buffer) { - if (runningByteTotal + 5 + buffer.Length > MAXBYTES) + if (runningByteTotal + 5 + buffer.Length + (1 + Encoding.ASCII.GetByteCount(currentTarget)) > MAXBYTES) return false; binWriter.Write((byte)buffer.Length); @@ -90,13 +93,13 @@ namespace FFXIVClassic_Map_Server.packets.send.actor return true; } - public void addProperty(FFXIVClassic_Map_Server.dataobjects.Actor actor, string name) + public bool addProperty(FFXIVClassic_Map_Server.dataobjects.Actor actor, string name) { string[] split = name.Split('.'); int arrayIndex = 0; if (!(split[0].Equals("work") || split[0].Equals("charaWork") || split[0].Equals("playerWork") || split[0].Equals("npcWork"))) - return; + return false; Object curObj = actor; for (int i = 0; i < split.Length; i++) @@ -105,7 +108,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor if (split[i].Contains('[')) { if (split[i].LastIndexOf(']') - split[i].IndexOf('[') <= 0) - return; + return false; arrayIndex = Convert.ToInt32(split[i].Substring(split[i].IndexOf('[') + 1, split[i].Length - split[i].LastIndexOf(']'))); split[i] = split[i].Substring(0, split[i].IndexOf('[')); @@ -113,46 +116,46 @@ namespace FFXIVClassic_Map_Server.packets.send.actor FieldInfo field = curObj.GetType().GetField(split[i]); if (field == null) - return; + return false; curObj = field.GetValue(curObj); if (curObj == null) - return; + return false; } if (curObj == null) - return; + return false; else { //Array, we actually care whats inside if (curObj.GetType().IsArray) { if (((Array)curObj).Length <= arrayIndex) - return; + return false; curObj = ((Array)curObj).GetValue(arrayIndex); } if (curObj == null) - return; + return false; //Cast to the proper object and add to packet uint id = Utils.MurmurHash2(name, 0); if (curObj is bool) - addByte(id, (byte)(((bool)curObj) ? 1 : 0)); + return addByte(id, (byte)(((bool)curObj) ? 1 : 0)); else if (curObj is byte) - addByte(id, (byte)curObj); + return addByte(id, (byte)curObj); else if (curObj is ushort) - addShort(id, (ushort)curObj); - else if (curObj is short) - addShort(id, (ushort)(short)curObj); + return addShort(id, (ushort)curObj); + else if (curObj is short) + return addShort(id, (ushort)(short)curObj); else if (curObj is uint) - addInt(id, (uint)curObj); - else if (curObj is int) - addInt(id, (uint)(int)curObj); + return addInt(id, (uint)curObj); + else if (curObj is int) + return addInt(id, (uint)(int)curObj); else if (curObj is float) - addBuffer(id, BitConverter.GetBytes((float)curObj)); + return addBuffer(id, BitConverter.GetBytes((float)curObj)); else - return; + return false; } } @@ -163,10 +166,22 @@ namespace FFXIVClassic_Map_Server.packets.send.actor public void setTarget(string target) { - binWriter.Write((byte)(isMore ? 0x62 + target.Length : 0x82 + target.Length)); - binWriter.Write(Encoding.ASCII.GetBytes(target)); - runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(target)); + currentTarget = target; + } + public void addTarget() + { + binWriter.Write((byte)(isMore ? 0x62 + currentTarget.Length : 0x82 + currentTarget.Length)); + binWriter.Write(Encoding.ASCII.GetBytes(currentTarget)); + runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(currentTarget)); + } + + public void addTarget(string newTarget) + { + binWriter.Write((byte)(isMore ? 0x62 + currentTarget.Length : 0x82 + currentTarget.Length)); + binWriter.Write(Encoding.ASCII.GetBytes(currentTarget)); + runningByteTotal += (ushort)(1 + Encoding.ASCII.GetByteCount(currentTarget)); + currentTarget = newTarget; } public SubPacket buildPacket(uint playerActorID, uint actorID) @@ -176,7 +191,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor closeStreams(); - SubPacket packet = new SubPacket(OPCODE, playerActorID, actorID, data); + SubPacket packet = new SubPacket(OPCODE, actorID, playerActorID, data); return packet; } diff --git a/FFXIVClassic Map Server/utils/ActorPropertyPacketUtil.cs b/FFXIVClassic Map Server/utils/ActorPropertyPacketUtil.cs new file mode 100644 index 00000000..ab50dab9 --- /dev/null +++ b/FFXIVClassic Map Server/utils/ActorPropertyPacketUtil.cs @@ -0,0 +1,48 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.dataobjects; + +namespace FFXIVClassic_Map_Server.utils +{ + class ActorPropertyPacketUtil + { + Actor forActor; + uint playerActorId; + List subPackets = new List(); + SetActorPropetyPacket currentActorPropertyPacket; + string currentTarget; + + public ActorPropertyPacketUtil(string firstTarget, Actor forActor, uint playerActorId) + { + currentActorPropertyPacket = new SetActorPropetyPacket(firstTarget); + this.forActor = forActor; + this.playerActorId = playerActorId; + this.currentTarget = firstTarget; + } + + public void addProperty(string property) + { + if (!currentActorPropertyPacket.addProperty(forActor, property)) + { + currentActorPropertyPacket.setIsMore(true); + currentActorPropertyPacket.addTarget(); + subPackets.Add(currentActorPropertyPacket.buildPacket(playerActorId, forActor.actorId)); + currentActorPropertyPacket = new SetActorPropetyPacket(currentTarget); + } + } + + public BasePacket done() + { + currentActorPropertyPacket.addTarget(); + currentActorPropertyPacket.setIsMore(false); + subPackets.Add(currentActorPropertyPacket.buildPacket(playerActorId, forActor.actorId)); + return BasePacket.createPacket(subPackets, true, false); + } + + } +}