Esempio n. 1
0
        /// <summary>
        /// Opens the in-game map with a flag on the location of the parameter.
        /// </summary>
        /// <param name="mapLink">Link to the map to be opened.</param>
        /// <returns>True if there were no errors and it could open the map.</returns>
        public bool OpenMapWithMapLink(MapLinkPayload mapLink)
        {
            var uiObjectPtr = this.getUIObject();

            if (uiObjectPtr.Equals(IntPtr.Zero))
            {
                Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
                return(false);
            }

            this.getUIMapObject = this.address.GetVirtualFunction <GetUIMapObjectDelegate>(uiObjectPtr, 0, 8);

            var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr);

            if (uiMapObjectPtr.Equals(IntPtr.Zero))
            {
                Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
                return(false);
            }

            this.openMapWithFlag = this.address.GetVirtualFunction <OpenMapWithFlagDelegate>(uiMapObjectPtr, 0, 63);

            var mapLinkString = mapLink.DataString;

            Log.Debug($"OpenMapWithMapLink: Opening Map Link: {mapLinkString}");

            return(this.openMapWithFlag(uiMapObjectPtr, mapLinkString));
        }
Esempio n. 2
0
        public bool OpenMapWithMapLink(MapLinkPayload mapLink)
        {
            var uiObjectPtr = getUIObject();

            if (uiObjectPtr.Equals(IntPtr.Zero))
            {
                Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
                return(false);
            }

            getUIMapObject =
                Address.GetVirtualFunction <GetUIMapObjectDelegate>(uiObjectPtr, 0, 8);


            var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr);

            if (uiMapObjectPtr.Equals(IntPtr.Zero))
            {
                Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
                return(false);
            }

            openMapWithFlag =
                Address.GetVirtualFunction <OpenMapWithFlagDelegate>(uiMapObjectPtr, 0, 63);

            var mapLinkString =
                $"m:{mapLink.TerritoryTypeId},{mapLink.MapId},{unchecked((int)mapLink.RawX)},{unchecked((int)mapLink.RawY)}";

            Log.Debug($"OpenMapWithMapLink: Opening Map Link: {mapLinkString}");

            return(this.openMapWithFlag(uiMapObjectPtr, mapLinkString));
        }
Esempio n. 3
0
        public void PlaceMapMarker(MapLinkMessage maplinkMessage)
        {
            Log($"Viewing {maplinkMessage.Text}");
            var map     = DataManager.GetExcelSheet <TerritoryType>().GetRow(maplinkMessage.TerritoryId).Map;
            var maplink = new MapLinkPayload(maplinkMessage.TerritoryId, map.Row, maplinkMessage.X, maplinkMessage.Y);

            GameGui.OpenMapWithMapLink(maplink);
        }
Esempio n. 4
0
 public MapLink(TeleporterPlugin plugin, XivChatType type, MapLinkPayload payload, string senderName, SeString message)
 {
     _plugin     = plugin;
     ChatType    = type;
     Location    = new Vector2(payload.XCoord, payload.YCoord);
     PlaceName   = payload.PlaceName;
     TerritoryId = payload.TerritoryType.RowId;
     SenderName  = senderName;
     Message     = message.TextValue;
     Data        = message.Encode();
     Aetheryte   = GetClosestAetheryte();
     Payload     = new MapLinkPayload(_plugin.Interface.Data, payload.TerritoryType.RowId, payload.Map.RowId, payload.RawX, payload.RawY);
 }
Esempio n. 5
0
        /// <summary>
        /// Creates an SeString representing an entire Payload chain that can be used to link a map position in the chat log.
        /// </summary>
        /// <param name="territoryId">The id of the TerritoryType for this map link.</param>
        /// <param name="mapId">The id of the Map for this map link.</param>
        /// <param name="xCoord">The human-readable x-coordinate for this link.</param>
        /// <param name="yCoord">The human-readable y-coordinate for this link.</param>
        /// <param name="fudgeFactor">An optional offset to account for rounding and truncation errors; it is best to leave this untouched in most cases.</param>
        /// <returns>An SeString containing all of the payloads necessary to display a map link in the chat log.</returns>
        public static SeString CreateMapLink(uint territoryId, uint mapId, float xCoord, float yCoord, float fudgeFactor = 0.05f)
        {
            var mapPayload = new MapLinkPayload(territoryId, mapId, xCoord, yCoord, fudgeFactor);
            var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";

            var payloads = new List <Payload>(new Payload[]
            {
                mapPayload,
                // arrow goes here
                new TextPayload(nameString),
                RawPayload.LinkTerminator
            });

            payloads.InsertRange(1, TextArrowPayloads());

            return(new SeString(payloads));
        }
Esempio n. 6
0
        public SeString CreateMapLink(uint territoryId, uint mapId, int rawX, int rawY)
        {
            var mapPayload = new MapLinkPayload(this.data, territoryId, mapId, rawX, rawY);
            var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";

            var payloads = new List <Payload>(new Payload[]
            {
                mapPayload,
                // arrow goes here
                new TextPayload(nameString),
                RawPayload.LinkTerminator
            });

            payloads.InsertRange(1, TextArrowPayloads());

            return(new SeString(payloads));
        }
Esempio n. 7
0
        private static Payload DecodeChunk(BinaryReader reader)
        {
            Payload payload = null;

            reader.ReadByte();  // START_BYTE
            var chunkType = (SeStringChunkType)reader.ReadByte();
            var chunkLen  = GetInteger(reader);

            var packetStart = reader.BaseStream.Position;

            // any unhandled payload types will be turned into a RawPayload with the exact same binary data
            switch (chunkType)
            {
            case SeStringChunkType.EmphasisItalic:
                payload = new EmphasisItalicPayload();
                break;

            case SeStringChunkType.SeHyphen:
                payload = SeHyphenPayload.Payload;
                break;

            case SeStringChunkType.Interactable:
            {
                var subType = (EmbeddedInfoType)reader.ReadByte();
                switch (subType)
                {
                case EmbeddedInfoType.PlayerName:
                    payload = new PlayerPayload();
                    break;

                case EmbeddedInfoType.ItemLink:
                    payload = new ItemPayload();
                    break;

                case EmbeddedInfoType.MapPositionLink:
                    payload = new MapLinkPayload();
                    break;

                case EmbeddedInfoType.Status:
                    payload = new StatusPayload();
                    break;

                case EmbeddedInfoType.QuestLink:
                    payload = new QuestPayload();
                    break;

                case EmbeddedInfoType.DalamudLink:
                    payload = new DalamudLinkPayload();
                    break;

                case EmbeddedInfoType.LinkTerminator:
                // this has no custom handling and so needs to fallthrough to ensure it is captured
                default:
                    // but I'm also tired of this log
                    if (subType != EmbeddedInfoType.LinkTerminator)
                    {
                        Log.Verbose("Unhandled EmbeddedInfoType: {0}", subType);
                    }

                    // rewind so we capture the Interactable byte in the raw data
                    reader.BaseStream.Seek(-1, SeekOrigin.Current);
                    break;
                }
            }

            break;

            case SeStringChunkType.AutoTranslateKey:
                payload = new AutoTranslatePayload();
                break;

            case SeStringChunkType.UIForeground:
                payload = new UIForegroundPayload();
                break;

            case SeStringChunkType.UIGlow:
                payload = new UIGlowPayload();
                break;

            case SeStringChunkType.Icon:
                payload = new IconPayload();
                break;

            default:
                Log.Verbose("Unhandled SeStringChunkType: {0}", chunkType);
                break;
            }

            payload ??= new RawPayload((byte)chunkType);
            payload.DecodeImpl(reader, reader.BaseStream.Position + chunkLen - 1);

            // read through the rest of the packet
            var readBytes = (uint)(reader.BaseStream.Position - packetStart);

            reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker

            return(payload);
        }
Esempio n. 8
0
        private static Payload ProcessChunk(BinaryReader reader)
        {
            Payload payload = null;

            reader.ReadByte();  // START_BYTE
            var chunkType = (SeStringChunkType)reader.ReadByte();
            var chunkLen  = GetInteger(reader);

            var packetStart = reader.BaseStream.Position;

            switch (chunkType)
            {
            case SeStringChunkType.Interactable:
            {
                var subType = (EmbeddedInfoType)reader.ReadByte();
                switch (subType)
                {
                case EmbeddedInfoType.PlayerName:
                    payload = new PlayerPayload();
                    break;

                case EmbeddedInfoType.ItemLink:
                    payload = new ItemPayload();
                    break;

                case EmbeddedInfoType.MapPositionLink:
                    payload = new MapLinkPayload();
                    break;

                case EmbeddedInfoType.Status:
                    payload = new StatusPayload();
                    break;

                case EmbeddedInfoType.LinkTerminator:
                // this has no custom handling and so needs to fallthrough to ensure it is captured
                default:
                    Log.Verbose("Unhandled EmbeddedInfoType: {0}", subType);
                    // rewind so we capture the Interactable byte in the raw data
                    reader.BaseStream.Seek(-1, SeekOrigin.Current);
                    payload = new RawPayload((byte)chunkType);
                    break;
                }
            }
            break;

            case SeStringChunkType.AutoTranslateKey:
                payload = new AutoTranslatePayload();
                break;

            case SeStringChunkType.UIForeground:
                payload = new UIForegroundPayload();
                break;

            case SeStringChunkType.UIGlow:
                payload = new UIGlowPayload();
                break;

            default:
                Log.Verbose("Unhandled SeStringChunkType: {0}", chunkType);
                payload = new RawPayload((byte)chunkType);
                break;
            }

            payload?.ProcessChunkImpl(reader, reader.BaseStream.Position + chunkLen - 1);

            // read through the rest of the packet
            var readBytes = (uint)(reader.BaseStream.Position - packetStart);

            reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker

            return(payload);
        }
Esempio n. 9
0
        private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
        {
            if (!Config.Recording)
            {
                return;
            }
            bool           hasMapLink     = false;
            float          coordX         = 0;
            float          coordY         = 0;
            float          scale          = 100;
            MapLinkPayload maplinkPayload = null;

            foreach (var payload in message.Payloads)
            {
                if (payload is MapLinkPayload mapLinkload)
                {
                    maplinkPayload = mapLinkload;
                    hasMapLink     = true;
                    // float fudge = 0.05f;
                    scale = mapLinkload.TerritoryType.Map.Value.SizeFactor;
                    // coordX = ConvertRawPositionToMapCoordinate(mapLinkload.RawX, scale) - fudge;
                    // coordY = ConvertRawPositionToMapCoordinate(mapLinkload.RawY, scale) - fudge;
                    coordX = mapLinkload.XCoord;
                    coordY = mapLinkload.YCoord;
                    Log($"TerritoryId: {mapLinkload.TerritoryType.RowId} {mapLinkload.PlaceName} ({coordX} ,{coordY})");
                }
            }
            string messageText = message.TextValue;

            if (hasMapLink)
            {
                var newMapLinkMessage = new MapLinkMessage(
                    (ushort)type,
                    sender.TextValue,
                    messageText,
                    coordX,
                    coordY,
                    scale,
                    maplinkPayload.TerritoryType.RowId,
                    maplinkPayload.PlaceName,
                    DateTime.Now
                    );
                bool filteredOut = false;
                if (sender.TextValue.ToLower() == "sonar")
                {
                    filteredOut = true;
                }
                bool alreadyInList = Config.MapLinkMessageList.Any(w => {
                    bool sameText  = w.Text == newMapLinkMessage.Text;
                    var timeoutMin = new TimeSpan(0, Config.FilterDupTimeout, 0);
                    if (newMapLinkMessage.RecordTime < w.RecordTime + timeoutMin)
                    {
                        bool sameX         = (int)(w.X * 10) == (int)(newMapLinkMessage.X * 10);
                        bool sameY         = (int)(w.Y * 10) == (int)(newMapLinkMessage.Y * 10);
                        bool sameTerritory = w.TerritoryId == newMapLinkMessage.TerritoryId;
                        return(sameTerritory && sameX && sameY);
                    }
                    return(sameText);
                });
                if (Config.FilterDuplicates && alreadyInList)
                {
                    filteredOut = true;
                }
                if (!filteredOut && Config.FilteredChannels.IndexOf((ushort)type) != -1)
                {
                    filteredOut = true;
                }
                if (!filteredOut)
                {
                    Config.MapLinkMessageList.Add(newMapLinkMessage);
                    if (Config.MapLinkMessageList.Count > Config.MaxRecordings)
                    {
                        var tempList = Config.MapLinkMessageList.OrderBy(e => e.RecordTime);
                        Config.MapLinkMessageList.RemoveRange(0, Config.MapLinkMessageList.Count - Config.MaxRecordings);
                        var infoMsg = $"There are too many records, truncated to the latest {Config.MaxRecordings} records";
                        PluginLog.Information(infoMsg);
                    }
                    Config.Save();
                }
            }
        }
Esempio n. 10
0
            public static IEnumerable <ColorString> FromMapLink(string str, ColorRef color, ColorRef shadowColor, MapLinkPayload map, TextTypes source)
            {
                yield return(MakeLinkChar(source));

                foreach (var s in FromStringSplitDelimiters(str, color, shadowColor, source))
                {
                    yield return(s);
                }
            }