diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 95cf9e30..e9ef2101 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -1385,6 +1385,45 @@ namespace FFXIVClassic_Map_Server return success; } + + public static void SaveNpcLS(Player player, uint npcLSId, bool isCalling, bool isExtra) + { + string query; + MySqlCommand cmd; + + using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) + { + try + { + conn.Open(); + + query = @" + INSERT INTO characters_npclinkshell + (characterId, npcLinkshellId, isCalling, isExtra) + VALUES + (@charaId, @lsId, @calling, @extra) + ON DUPLICATE KEY UPDATE + characterId = @charaId, npcLinkshellId = @lsId, isCalling = @calling, isExtra = @extra + "; + + cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@charaId", player.actorId); + cmd.Parameters.AddWithValue("@lsId", npcLSId); + cmd.Parameters.AddWithValue("@calling", isCalling ? 1 : 0); + cmd.Parameters.AddWithValue("@extra", isExtra ? 1 : 0); + + cmd.ExecuteNonQuery(); + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + } + finally + { + conn.Dispose(); + } + } + } } } diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 068b4dde..fb763db9 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -1254,6 +1254,19 @@ namespace FFXIVClassic_Map_Server.Actors return -1; } + public void SetNpcLS(uint npcLSId, bool isCalling, bool isExtra) + { + playerWork.npcLinkshellChatExtra[npcLSId] = isExtra; + playerWork.npcLinkshellChatCalling[npcLSId] = isCalling; + + Database.SaveNpcLS(this, npcLSId, isCalling, isExtra); + + ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/npcLinkshellChat", this, actorId); + propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatExtra[{0}]", npcLSId)); + propPacketUtil.AddProperty(String.Format("playerWork.npcLinkshellChatCalling[{0}]", npcLSId)); + QueuePackets(propPacketUtil.Done()); + } + private void SendQuestClientUpdate(int slot) { ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("playerWork/journal", this, actorId); diff --git a/data/scripts/commands/gm/setnpcls.lua b/data/scripts/commands/gm/setnpcls.lua new file mode 100644 index 00000000..5a195c99 --- /dev/null +++ b/data/scripts/commands/gm/setnpcls.lua @@ -0,0 +1,27 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "is", + description = "Sets a NPC LS' state. Args: npcLSId, ", +} + +function onTrigger(player, argc, lsId, state) + local id = tonumber(lsId) or 0; + + if (state == "alert") then + player:SetNpcLS(id, true, true); + elseif (state == "active") then + player:SetNpcLS(id, true, false); + elseif (state == "inactive") then + player:SetNpcLS(id, false, true); + elseif (state == "gone") then + player:SetNpcLS(id, false, false); + else + player:SendMessage(0x20, "", "Invalid state argument"); + return; + end + + player:SendMessage(0x20, "", string.format("NPC LS %d set to %s", id, state)); + +end \ No newline at end of file