From 8df79c9e6f562901cd14ed880d26adf7791bc636 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Mon, 9 May 2016 20:48:18 -0400 Subject: [PATCH] Modified the SetWeatherPacket. Second value is a toggle for instant or smooth transitions. --- FFXIVClassic Map Server/CommandProcessor.cs | 1566 ++++++++--------- .../actors/chara/player/Player.cs | 2 +- FFXIVClassic Map Server/lua/LuaPlayer.cs | 2 +- .../packets/send/SetWeatherPacket.cs | 94 +- 4 files changed, 832 insertions(+), 832 deletions(-) diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/FFXIVClassic Map Server/CommandProcessor.cs index 4c4d63d4..b03d3d88 100644 --- a/FFXIVClassic Map Server/CommandProcessor.cs +++ b/FFXIVClassic Map Server/CommandProcessor.cs @@ -1,474 +1,474 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; -using System.Threading; -using FFXIVClassic_Lobby_Server.common; -using FFXIVClassic_Map_Server.dataobjects; -using FFXIVClassic_Lobby_Server.packets; -using System.IO; -using FFXIVClassic_Map_Server.packets.send.actor; -using FFXIVClassic_Map_Server; -using FFXIVClassic_Map_Server.packets.send; -using FFXIVClassic_Map_Server.dataobjects.chara; -using FFXIVClassic_Map_Server.Actors; -using FFXIVClassic_Map_Server.lua; -using FFXIVClassic_Map_Server.actors.chara.player; -using FFXIVClassic_Map_Server.Properties; - -namespace FFXIVClassic_Lobby_Server -{ - class CommandProcessor - { - private Dictionary mConnectedPlayerList; - private static WorldManager mWorldManager = Server.GetWorldManager(); - private static Dictionary gamedataItems = Server.GetGamedataItems(); - - // For the moment, this is the only predefined item - // TODO: make a list/enum in the future so that items can be given by name, instead of by id - const UInt32 ITEM_GIL = 1000001; - - public CommandProcessor(Dictionary playerList) - { - mConnectedPlayerList = playerList; - } - - public void sendPacket(ConnectedPlayer client, string path) - { - BasePacket packet = new BasePacket(path); - - if (client != null) - { - packet.replaceActorID(client.actorID); - client.queuePacket(packet); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - packet.replaceActorID(entry.Value.actorID); - entry.Value.queuePacket(packet); - } - } - } - - public void changeProperty(uint id, uint value, string target) - { - SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(target); - - changeProperty.setTarget(target); - changeProperty.addInt(id, value); - changeProperty.addTarget(); - - foreach (KeyValuePair entry in mConnectedPlayerList) - { - SubPacket changePropertyPacket = changeProperty.buildPacket((entry.Value.actorID), (entry.Value.actorID)); - - BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false); - packet.debugPrintPacket(); - - entry.Value.queuePacket(packet); - } - } - - public void doMusic(ConnectedPlayer client, string music) - { - ushort musicId; - - if (music.ToLower().StartsWith("0x")) - musicId = Convert.ToUInt16(music, 16); - else - musicId = Convert.ToUInt16(music); - - if (client != null) - client.queuePacket(BasePacket.createPacket(SetMusicPacket.buildPacket(client.actorID, musicId, 1), true, false)); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - BasePacket musicPacket = BasePacket.createPacket(SetMusicPacket.buildPacket(entry.Value.actorID, musicId, 1), true, false); - entry.Value.queuePacket(musicPacket); - } - } - } - - /// - /// Teleports player to a location on a predefined list - /// - /// The current player - /// Predefined list: <ffxiv_database>\server_zones_spawnlocations - public void doWarp(ConnectedPlayer client, uint id) - { - FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = mWorldManager.getZoneEntrance(id); - - if (ze == null) - return; - - if (client != null) - mWorldManager.DoZoneChange(client.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - mWorldManager.DoZoneChange(entry.Value.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - } - } - } - - public void doWarp(ConnectedPlayer client, uint zoneId, string privateArea, byte spawnType, float x, float y, float z, float r) - { - if (mWorldManager.GetZone(zoneId) == null) - { - if (client != null) - client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false)); - Log.error("Zone does not exist or setting isn't valid."); - } - - if (client != null) - mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, spawnType, x, y, z, r); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, spawnType, x, y, z, r); - } - } - } - - public void printPos(ConnectedPlayer client) - { - if (client != null) - { - Player p = client.getActor(); - client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false)); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - Log.info(String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)); - } - } - } - - private void setGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId) - { - if (client != null) - { - Player p = client.getActor(); - p.graphicChange(slot, wId, eId, vId, cId); - p.sendAppearance(); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.graphicChange(slot, wId, eId, vId, cId); - p.sendAppearance(); - } - } - } - - private void giveItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.NORMAL).addItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.NORMAL).addItem(itemId, quantity); - } - } - } - - private void giveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.getActor(); - - if (p.getInventory(type) != null) - p.getInventory(type).addItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - - if (p.getInventory(type) != null) - p.getInventory(type).addItem(itemId, quantity); - } - } - } - - private void removeItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity); - } - } - } - - private void removeItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.getActor(); - - if (p.getInventory(type) != null) - p.getInventory(type).removeItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - - if (p.getInventory(type) != null) - p.getInventory(type).removeItem(itemId, quantity); - } - } - } - - private void giveCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity); - } - } - } - - // TODO: make removeCurrency() remove all quantity of a currency if quantity_to_remove > quantity_in_inventory instead of silently failing - private void removeCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity); - } - } - } - - private void giveKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1); - } - } - } - - private void removeKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.getActor(); - p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.getActor(); - p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1); - } - } - } - - private void parseWarp(ConnectedPlayer client, string[] split) - { - float x = 0, y = 0, z = 0, r = 0.0f; - uint zoneId = 0; - string privatearea = null; - - if (split.Length == 2) // Predefined list - { - // TODO: Handle !warp Playername - #region !warp (predefined list) - try - { - if (split[1].ToLower().StartsWith("0x")) - zoneId = Convert.ToUInt32(split[1], 16); - else - zoneId = Convert.ToUInt32(split[1]); - } - catch{return;} - #endregion - - doWarp(client, zoneId); - } - else if (split.Length == 4) - { - #region !warp X Y Z - if (split[1].StartsWith("@")) - { - split[1] = split[1].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[1])) - split[1] = "0"; - - try { x = Single.Parse(split[1]) + client.getActor().positionX; } - catch{return;} - - split[1] = x.ToString(); - } - if (split[2].StartsWith("@")) - { - split[2] = split[2].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[2])) - split[2] = "0"; - - try { y = Single.Parse(split[2]) + client.getActor().positionY; } - catch{return;} - - split[2] = y.ToString(); - } - if (split[3].StartsWith("@")) - { - split[3] = split[3].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[3])) - split[3] = "0"; - - try { z = Single.Parse(split[3]) + client.getActor().positionZ; } - catch{return;} - - split[3] = z.ToString(); - } - - try - { - x = Single.Parse(split[1]); - y = Single.Parse(split[2]); - z = Single.Parse(split[3]); - } - catch{return;} - - zoneId = client.getActor().zoneId; - r = client.getActor().rotation; - #endregion - - sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - doWarp(client, zoneId, privatearea, 0x00, x, y, z, r); - } - else if (split.Length == 5) - { - #region !warp Zone X Y Z - try - { - x = Single.Parse(split[2]); - y = Single.Parse(split[3]); - z = Single.Parse(split[4]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - #endregion - - sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - doWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else if (split.Length == 6) - { - #region !warp Zone Instance X Y Z - try - { - x = Single.Parse(split[3]); - y = Single.Parse(split[4]); - z = Single.Parse(split[5]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - - privatearea = split[2]; - #endregion - - sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - doWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else - return; // catch any invalid warps here - } - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; +using System.Threading; +using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Map_Server.dataobjects; +using FFXIVClassic_Lobby_Server.packets; +using System.IO; +using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server; +using FFXIVClassic_Map_Server.packets.send; +using FFXIVClassic_Map_Server.dataobjects.chara; +using FFXIVClassic_Map_Server.Actors; +using FFXIVClassic_Map_Server.lua; +using FFXIVClassic_Map_Server.actors.chara.player; +using FFXIVClassic_Map_Server.Properties; + +namespace FFXIVClassic_Lobby_Server +{ + class CommandProcessor + { + private Dictionary mConnectedPlayerList; + private static WorldManager mWorldManager = Server.GetWorldManager(); + private static Dictionary gamedataItems = Server.GetGamedataItems(); + + // For the moment, this is the only predefined item + // TODO: make a list/enum in the future so that items can be given by name, instead of by id + const UInt32 ITEM_GIL = 1000001; + + public CommandProcessor(Dictionary playerList) + { + mConnectedPlayerList = playerList; + } + + public void sendPacket(ConnectedPlayer client, string path) + { + BasePacket packet = new BasePacket(path); + + if (client != null) + { + packet.replaceActorID(client.actorID); + client.queuePacket(packet); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + packet.replaceActorID(entry.Value.actorID); + entry.Value.queuePacket(packet); + } + } + } + + public void changeProperty(uint id, uint value, string target) + { + SetActorPropetyPacket changeProperty = new SetActorPropetyPacket(target); + + changeProperty.setTarget(target); + changeProperty.addInt(id, value); + changeProperty.addTarget(); + + foreach (KeyValuePair entry in mConnectedPlayerList) + { + SubPacket changePropertyPacket = changeProperty.buildPacket((entry.Value.actorID), (entry.Value.actorID)); + + BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false); + packet.debugPrintPacket(); + + entry.Value.queuePacket(packet); + } + } + + public void doMusic(ConnectedPlayer client, string music) + { + ushort musicId; + + if (music.ToLower().StartsWith("0x")) + musicId = Convert.ToUInt16(music, 16); + else + musicId = Convert.ToUInt16(music); + + if (client != null) + client.queuePacket(BasePacket.createPacket(SetMusicPacket.buildPacket(client.actorID, musicId, 1), true, false)); + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + BasePacket musicPacket = BasePacket.createPacket(SetMusicPacket.buildPacket(entry.Value.actorID, musicId, 1), true, false); + entry.Value.queuePacket(musicPacket); + } + } + } + + /// + /// Teleports player to a location on a predefined list + /// + /// The current player + /// Predefined list: <ffxiv_database>\server_zones_spawnlocations + public void doWarp(ConnectedPlayer client, uint id) + { + FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = mWorldManager.getZoneEntrance(id); + + if (ze == null) + return; + + if (client != null) + mWorldManager.DoZoneChange(client.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + mWorldManager.DoZoneChange(entry.Value.getActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); + } + } + } + + public void doWarp(ConnectedPlayer client, uint zoneId, string privateArea, byte spawnType, float x, float y, float z, float r) + { + if (mWorldManager.GetZone(zoneId) == null) + { + if (client != null) + client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false)); + Log.error("Zone does not exist or setting isn't valid."); + } + + if (client != null) + mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, spawnType, x, y, z, r); + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, spawnType, x, y, z, r); + } + } + } + + public void printPos(ConnectedPlayer client) + { + if (client != null) + { + Player p = client.getActor(); + client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false)); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + Log.info(String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)); + } + } + } + + private void setGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId) + { + if (client != null) + { + Player p = client.getActor(); + p.graphicChange(slot, wId, eId, vId, cId); + p.sendAppearance(); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.graphicChange(slot, wId, eId, vId, cId); + p.sendAppearance(); + } + } + } + + private void giveItem(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.NORMAL).addItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.NORMAL).addItem(itemId, quantity); + } + } + } + + private void giveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) + { + if (client != null) + { + Player p = client.getActor(); + + if (p.getInventory(type) != null) + p.getInventory(type).addItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + + if (p.getInventory(type) != null) + p.getInventory(type).addItem(itemId, quantity); + } + } + } + + private void removeItem(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.NORMAL).removeItem(itemId, quantity); + } + } + } + + private void removeItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) + { + if (client != null) + { + Player p = client.getActor(); + + if (p.getInventory(type) != null) + p.getInventory(type).removeItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + + if (p.getInventory(type) != null) + p.getInventory(type).removeItem(itemId, quantity); + } + } + } + + private void giveCurrency(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.CURRENCY).addItem(itemId, quantity); + } + } + } + + // TODO: make removeCurrency() remove all quantity of a currency if quantity_to_remove > quantity_in_inventory instead of silently failing + private void removeCurrency(ConnectedPlayer client, uint itemId, int quantity) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.CURRENCY).removeItem(itemId, quantity); + } + } + } + + private void giveKeyItem(ConnectedPlayer client, uint itemId) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.KEYITEMS).addItem(itemId, 1); + } + } + } + + private void removeKeyItem(ConnectedPlayer client, uint itemId) + { + if (client != null) + { + Player p = client.getActor(); + p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1); + } + else + { + foreach (KeyValuePair entry in mConnectedPlayerList) + { + Player p = entry.Value.getActor(); + p.getInventory(Inventory.KEYITEMS).removeItem(itemId, 1); + } + } + } + + private void parseWarp(ConnectedPlayer client, string[] split) + { + float x = 0, y = 0, z = 0, r = 0.0f; + uint zoneId = 0; + string privatearea = null; + + if (split.Length == 2) // Predefined list + { + // TODO: Handle !warp Playername + #region !warp (predefined list) + try + { + if (split[1].ToLower().StartsWith("0x")) + zoneId = Convert.ToUInt32(split[1], 16); + else + zoneId = Convert.ToUInt32(split[1]); + } + catch{return;} + #endregion + + doWarp(client, zoneId); + } + else if (split.Length == 4) + { + #region !warp X Y Z + if (split[1].StartsWith("@")) + { + split[1] = split[1].Replace("@", string.Empty); + + if (String.IsNullOrEmpty(split[1])) + split[1] = "0"; + + try { x = Single.Parse(split[1]) + client.getActor().positionX; } + catch{return;} + + split[1] = x.ToString(); + } + if (split[2].StartsWith("@")) + { + split[2] = split[2].Replace("@", string.Empty); + + if (String.IsNullOrEmpty(split[2])) + split[2] = "0"; + + try { y = Single.Parse(split[2]) + client.getActor().positionY; } + catch{return;} + + split[2] = y.ToString(); + } + if (split[3].StartsWith("@")) + { + split[3] = split[3].Replace("@", string.Empty); + + if (String.IsNullOrEmpty(split[3])) + split[3] = "0"; + + try { z = Single.Parse(split[3]) + client.getActor().positionZ; } + catch{return;} + + split[3] = z.ToString(); + } + + try + { + x = Single.Parse(split[1]); + y = Single.Parse(split[2]); + z = Single.Parse(split[3]); + } + catch{return;} + + zoneId = client.getActor().zoneId; + r = client.getActor().rotation; + #endregion + + sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); + doWarp(client, zoneId, privatearea, 0x00, x, y, z, r); + } + else if (split.Length == 5) + { + #region !warp Zone X Y Z + try + { + x = Single.Parse(split[2]); + y = Single.Parse(split[3]); + z = Single.Parse(split[4]); + } + catch{return;} + + if (split[1].ToLower().StartsWith("0x")) + { + try { zoneId = Convert.ToUInt32(split[1], 16); } + catch{return;} + } + else + { + try { zoneId = Convert.ToUInt32(split[1]); } + catch{return;} + } + #endregion + + sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); + doWarp(client, zoneId, privatearea, 0x2, x, y, z, r); + } + else if (split.Length == 6) + { + #region !warp Zone Instance X Y Z + try + { + x = Single.Parse(split[3]); + y = Single.Parse(split[4]); + z = Single.Parse(split[5]); + } + catch{return;} + + if (split[1].ToLower().StartsWith("0x")) + { + try { zoneId = Convert.ToUInt32(split[1], 16); } + catch{return;} + } + else + { + try { zoneId = Convert.ToUInt32(split[1]); } + catch{return;} + } + + privatearea = split[2]; + #endregion + + sendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); + doWarp(client, zoneId, privatearea, 0x2, x, y, z, r); + } + else + return; // catch any invalid warps here + } + private void doWeather(ConnectedPlayer client, string weatherID) { long weather = Convert.ToInt64(weatherID); if (client != null) { - client.queuePacket(BasePacket.createPacket(SetWeatherPacket.buildPacket(client.actorID, weather), true, false)); + client.queuePacket(BasePacket.createPacket(SetWeatherPacket.buildPacket(client.actorID, weather, true), true, false)); } /* * WIP: Change weather serverside, currently only clientside * uint currentZoneID; - if (client != null) - { + if (client != null) + { currentZoneID = client.getActor().zoneId; foreach (KeyValuePair entry in mConnectedPlayerList) @@ -479,80 +479,80 @@ namespace FFXIVClassic_Lobby_Server BasePacket weatherPacket = BasePacket.createPacket(SetWeatherPacket.buildPacket(entry.Value.actorID, weather), true, false); entry.Value.queuePacket(weatherPacket); } - } + } } */ - } - - /// - /// We only use the default options for SendMessagePacket. - /// May as well make it less unwieldly to view - /// - /// - /// - private void sendMessage(ConnectedPlayer client, String message) - { - if (client != null) - client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message)); - } - - internal bool doCommand(string input, ConnectedPlayer client) - { - input.Trim(); - if (input.StartsWith("!")) - input = input.Substring(1); - - String[] split = input.Split(' '); - split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands - split = split.Where(temp => temp != "").ToArray(); // strips extra whitespace from commands - - // Debug - //sendMessage(client, string.Join(",", split)); - - if (split.Length >= 1) - { - #region !help - if (split[0].Equals("help")) - { - if (split.Length == 1) - { - sendMessage(client, Resources.CPhelp); - } - if (split.Length == 2) - { - if (split[1].Equals("mypos")) - sendMessage(client, Resources.CPmypos); - else if (split[1].Equals("music")) - sendMessage(client, Resources.CPmusic); - else if (split[1].Equals("warp")) - sendMessage(client, Resources.CPwarp); - else if (split[1].Equals("givecurrency")) - sendMessage(client, Resources.CPgivecurrency); - else if (split[1].Equals("giveitem")) - sendMessage(client, Resources.CPgiveitem); - else if (split[1].Equals("givekeyitem")) - sendMessage(client, Resources.CPgivekeyitem); - else if (split[1].Equals("removecurrency")) - sendMessage(client, Resources.CPremovecurrency); - else if (split[1].Equals("removeitem")) - sendMessage(client, Resources.CPremoveitem); - else if (split[1].Equals("removekeyitem")) - sendMessage(client, Resources.CPremovekeyitem); - else if (split[1].Equals("reloaditems")) - sendMessage(client, Resources.CPreloaditems); - else if (split[1].Equals("reloadzones")) - sendMessage(client, Resources.CPreloadzones); - /* - else if (split[1].Equals("property")) - sendMessage(client, Resources.CPproperty); - else if (split[1].Equals("property2")) - sendMessage(client, Resources.CPproperty2); - else if (split[1].Equals("sendpacket")) - sendMessage(client, Resources.CPsendpacket); - else if (split[1].Equals("setgraphic")) - sendMessage(client, Resources.CPsetgraphic); + } + + /// + /// We only use the default options for SendMessagePacket. + /// May as well make it less unwieldly to view + /// + /// + /// + private void sendMessage(ConnectedPlayer client, String message) + { + if (client != null) + client.getActor().queuePacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", message)); + } + + internal bool doCommand(string input, ConnectedPlayer client) + { + input.Trim(); + if (input.StartsWith("!")) + input = input.Substring(1); + + String[] split = input.Split(' '); + split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands + split = split.Where(temp => temp != "").ToArray(); // strips extra whitespace from commands + + // Debug + //sendMessage(client, string.Join(",", split)); + + if (split.Length >= 1) + { + #region !help + if (split[0].Equals("help")) + { + if (split.Length == 1) + { + sendMessage(client, Resources.CPhelp); + } + if (split.Length == 2) + { + if (split[1].Equals("mypos")) + sendMessage(client, Resources.CPmypos); + else if (split[1].Equals("music")) + sendMessage(client, Resources.CPmusic); + else if (split[1].Equals("warp")) + sendMessage(client, Resources.CPwarp); + else if (split[1].Equals("givecurrency")) + sendMessage(client, Resources.CPgivecurrency); + else if (split[1].Equals("giveitem")) + sendMessage(client, Resources.CPgiveitem); + else if (split[1].Equals("givekeyitem")) + sendMessage(client, Resources.CPgivekeyitem); + else if (split[1].Equals("removecurrency")) + sendMessage(client, Resources.CPremovecurrency); + else if (split[1].Equals("removeitem")) + sendMessage(client, Resources.CPremoveitem); + else if (split[1].Equals("removekeyitem")) + sendMessage(client, Resources.CPremovekeyitem); + else if (split[1].Equals("reloaditems")) + sendMessage(client, Resources.CPreloaditems); + else if (split[1].Equals("reloadzones")) + sendMessage(client, Resources.CPreloadzones); + /* + else if (split[1].Equals("property")) + sendMessage(client, Resources.CPproperty); + else if (split[1].Equals("property2")) + sendMessage(client, Resources.CPproperty2); + else if (split[1].Equals("sendpacket")) + sendMessage(client, Resources.CPsendpacket); + else if (split[1].Equals("setgraphic")) + sendMessage(client, Resources.CPsetgraphic); */ - } + } if (split.Length == 3) { if(split[1].Equals("test")) @@ -560,13 +560,13 @@ namespace FFXIVClassic_Lobby_Server if (split[2].Equals("weather")) sendMessage(client, Resources.CPtestweather); } - } - - return true; - } - #endregion + } - #region !test + return true; + } + #endregion + + #region !test else if (split[0].Equals("test")) { if (split.Length == 1) @@ -593,251 +593,251 @@ namespace FFXIVClassic_Lobby_Server } } - #endregion + #endregion - #region !mypos - else if (split[0].Equals("mypos")) - { - try - { - printPos(client); - return true; - } - catch (Exception e) - { - Log.error("Could not load packet: " + e); - } - } - #endregion - - #region !reloadzones - else if (split[0].Equals("reloadzones")) - { - if (client != null) - { - Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId)); - client.getActor().zone.clear(); - client.getActor().zone.addActorToZone(client.getActor()); - client.getActor().sendInstanceUpdate(); - client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Reseting zone {0}...", client.getActor().zoneId)), true, false)); - } - mWorldManager.reloadZone(client.getActor().zoneId); - return true; - } - #endregion - - #region !reloaditems - else if (split[0].Equals("reloaditems")) - { - Log.info(String.Format("Got request to reload item gamedata")); - sendMessage(client, "Reloading Item Gamedata..."); - gamedataItems.Clear(); - gamedataItems = Database.getItemGamedata(); - Log.info(String.Format("Loaded {0} items.", gamedataItems.Count)); - sendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count)); - return true; - } - #endregion - - #region !sendpacket - else if (split[0].Equals("sendpacket")) - { - if (split.Length < 2) - return false; - - try - { - sendPacket(client, "./packets/" + split[1]); - return true; - } - catch (Exception e) - { - Log.error("Could not load packet: " + e); - } - } - #endregion - - #region !graphic - else if (split[0].Equals("graphic")) - { - try - { - if (split.Length == 6) - setGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5])); - return true; - } - catch (Exception e) - { - Log.error("Could not give item."); - } - } - #endregion - - #region !giveitem - else if (split[0].Equals("giveitem")) - { - try - { - if (split.Length == 2) - giveItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Log.error("Could not give item."); - } - } - #endregion - - #region !removeitem - else if (split[0].Equals("removeitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - removeItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Log.error("Could not remove item."); - } - } - #endregion - - #region !givekeyitem - else if (split[0].Equals("givekeyitem")) - { - try - { - if (split.Length == 2) - giveKeyItem(client, UInt32.Parse(split[1])); - } - catch (Exception e) - { - Log.error("Could not give keyitem."); - } - } - #endregion - - #region !removekeyitem - else if (split[0].Equals("removekeyitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - removeKeyItem(client, UInt32.Parse(split[1])); - return true; - } - catch (Exception e) - { - Log.error("Could not remove keyitem."); - } - } - #endregion - - #region !givecurrency - else if (split[0].Equals("givecurrency")) - { - try - { - if (split.Length == 2) - giveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - giveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - } - catch (Exception e) - { - Log.error("Could not give currency."); - } - } - #endregion - - #region !removecurrency - else if (split[0].Equals("removecurrency")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - removeCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - removeCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - return true; - } - catch (Exception e) - { - Log.error("Could not remove currency."); - } - } - #endregion - - #region !music - else if (split[0].Equals("music")) - { - if (split.Length < 2) - return false; - - try - { - doMusic(client, split[1]); - return true; - } - catch (Exception e) - { - Log.error("Could not change music: " + e); - } - } - #endregion - - #region !warp - else if (split[0].Equals("warp")) - { - parseWarp(client, split); - return true; - } - #endregion - - #region !property - else if (split[0].Equals("property")) - { - if (split.Length == 4) - { - changeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]); - } - return true; - } - #endregion - - #region !property2 - else if (split[0].Equals("property2")) - { - if (split.Length == 4) - { - changeProperty(Convert.ToUInt32(split[1], 16), Convert.ToUInt32(split[2], 16), split[3]); - } - return true; - } - #endregion - } - return false; - } - } - -} + #region !mypos + else if (split[0].Equals("mypos")) + { + try + { + printPos(client); + return true; + } + catch (Exception e) + { + Log.error("Could not load packet: " + e); + } + } + #endregion + + #region !reloadzones + else if (split[0].Equals("reloadzones")) + { + if (client != null) + { + Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId)); + client.getActor().zone.clear(); + client.getActor().zone.addActorToZone(client.getActor()); + client.getActor().sendInstanceUpdate(); + client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Reseting zone {0}...", client.getActor().zoneId)), true, false)); + } + mWorldManager.reloadZone(client.getActor().zoneId); + return true; + } + #endregion + + #region !reloaditems + else if (split[0].Equals("reloaditems")) + { + Log.info(String.Format("Got request to reload item gamedata")); + sendMessage(client, "Reloading Item Gamedata..."); + gamedataItems.Clear(); + gamedataItems = Database.getItemGamedata(); + Log.info(String.Format("Loaded {0} items.", gamedataItems.Count)); + sendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count)); + return true; + } + #endregion + + #region !sendpacket + else if (split[0].Equals("sendpacket")) + { + if (split.Length < 2) + return false; + + try + { + sendPacket(client, "./packets/" + split[1]); + return true; + } + catch (Exception e) + { + Log.error("Could not load packet: " + e); + } + } + #endregion + + #region !graphic + else if (split[0].Equals("graphic")) + { + try + { + if (split.Length == 6) + setGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5])); + return true; + } + catch (Exception e) + { + Log.error("Could not give item."); + } + } + #endregion + + #region !giveitem + else if (split[0].Equals("giveitem")) + { + try + { + if (split.Length == 2) + giveItem(client, UInt32.Parse(split[1]), 1); + else if (split.Length == 3) + giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + else if (split.Length == 4) + giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); + return true; + } + catch (Exception e) + { + Log.error("Could not give item."); + } + } + #endregion + + #region !removeitem + else if (split[0].Equals("removeitem")) + { + if (split.Length < 2) + return false; + + try + { + if (split.Length == 2) + removeItem(client, UInt32.Parse(split[1]), 1); + else if (split.Length == 3) + removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + else if (split.Length == 4) + removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); + return true; + } + catch (Exception e) + { + Log.error("Could not remove item."); + } + } + #endregion + + #region !givekeyitem + else if (split[0].Equals("givekeyitem")) + { + try + { + if (split.Length == 2) + giveKeyItem(client, UInt32.Parse(split[1])); + } + catch (Exception e) + { + Log.error("Could not give keyitem."); + } + } + #endregion + + #region !removekeyitem + else if (split[0].Equals("removekeyitem")) + { + if (split.Length < 2) + return false; + + try + { + if (split.Length == 2) + removeKeyItem(client, UInt32.Parse(split[1])); + return true; + } + catch (Exception e) + { + Log.error("Could not remove keyitem."); + } + } + #endregion + + #region !givecurrency + else if (split[0].Equals("givecurrency")) + { + try + { + if (split.Length == 2) + giveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); + else if (split.Length == 3) + giveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + } + catch (Exception e) + { + Log.error("Could not give currency."); + } + } + #endregion + + #region !removecurrency + else if (split[0].Equals("removecurrency")) + { + if (split.Length < 2) + return false; + + try + { + if (split.Length == 2) + removeCurrency(client, ITEM_GIL, Int32.Parse(split[1])); + else if (split.Length == 3) + removeCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); + return true; + } + catch (Exception e) + { + Log.error("Could not remove currency."); + } + } + #endregion + + #region !music + else if (split[0].Equals("music")) + { + if (split.Length < 2) + return false; + + try + { + doMusic(client, split[1]); + return true; + } + catch (Exception e) + { + Log.error("Could not change music: " + e); + } + } + #endregion + + #region !warp + else if (split[0].Equals("warp")) + { + parseWarp(client, split); + return true; + } + #endregion + + #region !property + else if (split[0].Equals("property")) + { + if (split.Length == 4) + { + changeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]); + } + return true; + } + #endregion + + #region !property2 + else if (split[0].Equals("property2")) + { + if (split.Length == 4) + { + changeProperty(Convert.ToUInt32(split[1], 16), Convert.ToUInt32(split[2], 16), split[3]); + } + return true; + } + #endregion + } + return false; + } + } + +} diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 80f02af9..b5c3cf3b 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -479,7 +479,7 @@ namespace FFXIVClassic_Map_Server.Actors queuePacket(SetActorIsZoningPacket.buildPacket(actorId, actorId, false)); queuePacket(_0x10Packet.buildPacket(actorId, 0xFF)); queuePacket(SetMusicPacket.buildPacket(actorId, zone.bgmDay, 0x01)); - queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR)); + queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, true)); queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId)); diff --git a/FFXIVClassic Map Server/lua/LuaPlayer.cs b/FFXIVClassic Map Server/lua/LuaPlayer.cs index e98656d2..af077d81 100644 --- a/FFXIVClassic Map Server/lua/LuaPlayer.cs +++ b/FFXIVClassic Map Server/lua/LuaPlayer.cs @@ -28,7 +28,7 @@ namespace FFXIVClassic_Map_Server.lua public void setWeather(uint weatherID) { - player.playerSession.queuePacket(SetWeatherPacket.buildPacket(player.actorId, weatherID), true, false); + player.playerSession.queuePacket(SetWeatherPacket.buildPacket(player.actorId, weatherID, true), true, false); } public void getParameter(string paramName) diff --git a/FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs b/FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs index 44d7ae3a..070b8d42 100644 --- a/FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs +++ b/FFXIVClassic Map Server/packets/send/SetWeatherPacket.cs @@ -1,49 +1,49 @@ -using FFXIVClassic_Lobby_Server.packets; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FFXIVClassic_Map_Server.packets.send -{ - class SetWeatherPacket - { - // Use the first value to change without a transition, the second value to do a standard transition - public const uint WEATHER_CLEAR = 0x011F41; // 8001 / 73537 - public const uint WEATHER_FAIR = 0x011F42; // 8002 / 73538 - public const uint WEATHER_CLOUDY = 0x011F43; // 8003 / 73539 - public const uint WEATHER_FOGGY = 0x011F44; // 8004 / 73540 - public const uint WEATHER_WINDY = 0x011F45; // 8005 / 73541 - NOT SUPPORTED in v1.23b - public const uint WEATHER_BLUSTERY = 0x011F46; // 8006 / 73542 - public const uint WEATHER_RAINY = 0x011F47; // 8007 / 73543 - public const uint WEATHER_SHOWERY = 0x011F48; // 8008 / 73544 - NOT SUPPORTED in v1.23b - public const uint WEATHER_THUNDERY = 0x011F49; // 8009 / 73545 - NOT SUPPORTED in v1.23b - public const uint WEATHER_STORMY = 0x011F4A; // 8010 / 73546 - public const uint WEATHER_DUSTY = 0x011F4B; // 8011 / 73547 - NOT SUPPORTED in v1.23b - public const uint WEATHER_SANDY = 0x011F4C; // 8012 / 73548 - public const uint WEATHER_HOT = 0x011F4D; // 8013 / 73549 - NOT SUPPORTED in v1.23b - public const uint WEATHER_BLISTERING = 0x011F4E; // 8014 / 73550 - Bowl Of Embers Weather - public const uint WEATHER_SNOWY = 0x011F4F; // 8015 / 73551 - NOT SUPPORTED in v1.23b - public const uint WEATHER_WINTRY = 0x011F50; // 8016 / 73552 - NOT SUPPORTED in v1.23b - public const uint WEATHER_GLOOMY = 0x011F51; // 8017 / 73553 - // 8018 - 8026 / 73554 - 73562 - NOT SUPPORTED in v1.23b - public const uint WEATHER_SEASONAL = 0x011F5B; // 8027 / 73563 - Snow in Black Shroud, nothing elsewhere - public const uint WEATHER_PRIMAL = 0x011F5C; // 8028 / 73564 - Howling Eye and Thornmarch Weather - public const uint WEATHER_SEASONAL_FIREWORKS = 0x011F5D; // 8029 / 73565 - Plays fireworks between 20:00 - 21:00 ET - public const uint WEATHER_DALAMUD = 0x011F5E; // 8030 / 73566 - public const uint WEATHER_AURORA = 0x011F5F; // 8031 / 73567 - public const uint WEATHER_DALAMUD_THUNDER = 0x011F60; // 8032 / 73568 - // 8033 - 8064 / 73569 - 73600 - NOT SUPPORTED in v1.23b - public const uint WEATHER_DAY = 0x011F81; // 8065 / 73601 - Force skybox to show Day + Fair regardless of current ET - public const uint WEATHER_TWILIGHT = 0x011F82; // 8066 / 73602 - Force skybox to show Twilight + Clear regardless of current ET +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send +{ + class SetWeatherPacket + { + public const uint WEATHER_CLEAR = 8001; + public const uint WEATHER_FAIR = 8002; + public const uint WEATHER_CLOUDY = 8003; + public const uint WEATHER_FOGGY = 8004; + public const uint WEATHER_WINDY = 8005; + public const uint WEATHER_BLUSTERY = 8006; + public const uint WEATHER_RAINY = 8007; + public const uint WEATHER_SHOWERY = 8008; + public const uint WEATHER_THUNDERY = 8009; + public const uint WEATHER_STORMY = 8010; + public const uint WEATHER_DUSTY = 8011; + public const uint WEATHER_SANDY = 8012; + public const uint WEATHER_HOT = 8013; + public const uint WEATHER_BLISTERING = 8014; //Bowl Of Embers Weather + public const uint WEATHER_SNOWY = 8015; + public const uint WEATHER_WINTRY = 8016; + public const uint WEATHER_GLOOMY = 8017; + + public const uint WEATHER_SEASONAL = 8027; //Snow in Black Shroud, nothing elsewhere + public const uint WEATHER_PRIMAL = 8028; //Howling Eye and Thornmarch Weather + public const uint WEATHER_SEASONAL_FIREWORKS = 8029; //Plays fireworks between 20:00 - 21:00 ET + public const uint WEATHER_DALAMUD = 8030; + public const uint WEATHER_AURORA = 8031; + public const uint WEATHER_DALAMUD_THUNDER = 8032; + + public const uint WEATHER_DAY = 8065; //Force skybox to show Day + Fair regardless of current ET + public const uint WEATHER_TWILIGHT = 8066; //Force skybox to show Twilight + Clear regardless of current ET public const ushort OPCODE = 0x000D; - public const uint PACKET_SIZE = 0x28; - - public static SubPacket buildPacket(uint playerActorID, long weatherId) - { - return new SubPacket(OPCODE, 0, playerActorID, BitConverter.GetBytes(weatherId)); - } - } -} + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorID, long weatherId, bool smoothTransition) + { + ulong combined = (uint)(weatherId | ((smoothTransition ? 1 : 0) << 16)); + return new SubPacket(OPCODE, 0, playerActorID, BitConverter.GetBytes(combined)); + } + } +}