/// <inheritdoc/>
        public async Task UploadTax(MarketTaxRates taxRates)
        {
            var clientState = Service <ClientState.ClientState> .Get();

            // ====================================================================================

            var taxUploadObject = new UniversalisTaxUploadRequest
            {
                WorldId    = clientState.LocalPlayer?.CurrentWorld.Id ?? 0,
                UploaderId = clientState.LocalContentId.ToString(),
                TaxData    = new UniversalisTaxData
                {
                    LimsaLominsa = taxRates.LimsaLominsaTax,
                    Gridania     = taxRates.GridaniaTax,
                    Uldah        = taxRates.UldahTax,
                    Ishgard      = taxRates.IshgardTax,
                    Kugane       = taxRates.KuganeTax,
                    Crystarium   = taxRates.CrystariumTax,
                    Sharlayan    = taxRates.SharlayanTax,
                },
            };

            var taxPath   = "/upload";
            var taxUpload = JsonConvert.SerializeObject(taxUploadObject);

            Log.Verbose($"{taxPath}: {taxUpload}");

            await Util.HttpClient.PostAsync($"{ApiBase}{taxPath}/{ApiKey}", new StringContent(taxUpload, Encoding.UTF8, "application/json"));

            // ====================================================================================

            Log.Verbose("Universalis tax upload completed.");
        }
Esempio n. 2
0
        public void UploadTax(MarketTaxRates taxRates)
        {
            using (var client = new WebClient())
            {
                var taxRatesRequest = new UniversalisTaxUploadRequest();
                taxRatesRequest.WorldId    = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0;
                taxRatesRequest.UploaderId = this.dalamud.ClientState.LocalContentId;

                taxRatesRequest.TaxData = new UniversalisTaxData {
                    LimsaLominsa = taxRates.LimsaLominsaTax,
                    Gridania     = taxRates.GridaniaTax,
                    Uldah        = taxRates.UldahTax,
                    Ishgard      = taxRates.IshgardTax,
                    Kugane       = taxRates.KuganeTax,
                    Crystarium   = taxRates.CrystariumTax
                };

                client.Headers.Add(HttpRequestHeader.ContentType, "application/json");

                var historyUpload = JsonConvert.SerializeObject(taxRatesRequest);
                client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
                Log.Verbose(historyUpload);

                Log.Verbose("Universalis tax upload completed.");
            }
        }
Esempio n. 3
0
    /// <summary>
    /// Read a <see cref="MarketTaxRates"/> object from memory.
    /// </summary>
    /// <param name="dataPtr">Address to read.</param>
    /// <returns>A new <see cref="MarketTaxRates"/> object.</returns>
    public static unsafe MarketTaxRates Read(IntPtr dataPtr)
    {
        using var stream = new UnmanagedMemoryStream((byte *)dataPtr.ToPointer(), 1544);
        using var reader = new BinaryReader(stream);

        var output = new MarketTaxRates();

        stream.Position       += 8;
        output.LimsaLominsaTax = reader.ReadUInt32();
        output.GridaniaTax     = reader.ReadUInt32();
        output.UldahTax        = reader.ReadUInt32();
        output.IshgardTax      = reader.ReadUInt32();
        output.KuganeTax       = reader.ReadUInt32();
        output.CrystariumTax   = reader.ReadUInt32();

        return(output);
    }
Esempio n. 4
0
        private void OnZonePacket(IntPtr dataPtr)
        {
            if (!this.dalamud.Data.IsDataReady)
            {
                return;
            }

            var opCode = (ushort)Marshal.ReadInt16(dataPtr, 2);

            if (opCode == this.dalamud.Data.ServerOpCodes["CfNotifyPop"])
            {
                var data = new byte[64];
                Marshal.Copy(dataPtr, data, 0, 64);

                var notifyType = data[16];
                var contentFinderConditionId = BitConverter.ToUInt16(data, 36);

                if (notifyType != 3)
                {
                    return;
                }

                var contentFinderCondition = this.dalamud.Data.GetExcelSheet <ContentFinderCondition>().GetRow(contentFinderConditionId);

                if (contentFinderCondition == null)
                {
                    Log.Error("CFC key {0} not in lumina data.", contentFinderConditionId);
                    return;
                }

                if (string.IsNullOrEmpty(contentFinderCondition.Name))
                {
                    contentFinderCondition.Name  = "Duty Roulette";
                    contentFinderCondition.Image = 112324;
                }

                var flashInfo = new NativeFunctions.FLASHWINFO();
                flashInfo.cbSize    = (uint)Marshal.SizeOf <NativeFunctions.FLASHWINFO>();
                flashInfo.uCount    = uint.MaxValue;
                flashInfo.dwTimeout = 0;
                flashInfo.dwFlags   = NativeFunctions.FlashWindow.FLASHW_TRAY |
                                      NativeFunctions.FlashWindow.FLASHW_TIMERNOFG;
                flashInfo.hwnd = Process.GetCurrentProcess().MainWindowHandle;
                NativeFunctions.FlashWindowEx(ref flashInfo);

                Task.Run(async() => {
                    this.dalamud.Framework.Gui.Chat.Print("Duty pop: " + contentFinderCondition.Name);

                    await this.ProcessCfPop?.Invoke(contentFinderCondition);
                });

                return;
            }

            if (opCode == this.dalamud.Data.ServerOpCodes["CfPreferredRole"])
            {
                if (this.dalamud.Configuration.PreferredRoleReminders == null)
                {
                    return;
                }

                var data = new byte[64];
                Marshal.Copy(dataPtr, data, 0, 32);

                if (this.lastPreferredRole == null)
                {
                    this.lastPreferredRole = data;
                    return;
                }

                Task.Run(async() => {
                    for (var rouletteIndex = 1; rouletteIndex < 11; rouletteIndex++)
                    {
                        var currentRoleKey = data[16 + rouletteIndex];
                        var prevRoleKey    = this.lastPreferredRole[16 + rouletteIndex];

                        Log.Verbose("CfPreferredRole: {0} - {1} => {2}", rouletteIndex, prevRoleKey, currentRoleKey);

                        if (currentRoleKey != prevRoleKey)
                        {
                            var rouletteName = rouletteIndex switch {
                                1 => "Duty Roulette: Leveling",
                                2 => "Duty Roulette: Level 50/60/70 Dungeons",
                                3 => "Duty Roulette: Main Scenario",
                                4 => "Duty Roulette: Guildhests",
                                5 => "Duty Roulette: Expert",
                                6 => "Duty Roulette: Trials",
                                8 => "Duty Roulette: Mentor",
                                9 => "Duty Roulette: Alliance Raids",
                                10 => "Duty Roulette: Normal Raids",
                                _ => "Unknown ContentRoulette"
                            };

                            var prevRoleName    = RoleKeyToPreferredRole(prevRoleKey);
                            var currentRoleName = RoleKeyToPreferredRole(currentRoleKey);

                            if (!this.dalamud.Configuration.PreferredRoleReminders.TryGetValue(rouletteIndex, out var roleToCheck))
                            {
                                return;
                            }

                            if (roleToCheck == DalamudConfiguration.PreferredRole.All || currentRoleName != roleToCheck)
                            {
                                return;
                            }

                            this.dalamud.Framework.Gui.Chat.Print($"Roulette bonus for {rouletteName} changed: {prevRoleName} => {currentRoleName}");

                            if (this.dalamud.BotManager.IsConnected)
                            {
                                await this.dalamud.BotManager.ProcessCfPreferredRoleChange(rouletteName, prevRoleName.ToString(), currentRoleName.ToString());
                            }
                        }
                    }

                    this.lastPreferredRole = data;
                });
                return;
            }

            if (!this.optOutMbUploads)
            {
                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardItemRequestStart"])
                {
                    var catalogId = (uint)Marshal.ReadInt32(dataPtr + 0x10);
                    var amount    = Marshal.ReadByte(dataPtr + 0x1B);

                    this.marketBoardRequests.Add(new MarketBoardItemRequest {
                        CatalogId      = catalogId,
                        AmountToArrive = amount,
                        Listings       = new List <MarketBoardCurrentOfferings.MarketBoardItemListing>(),
                        History        = new List <MarketBoardHistory.MarketBoardHistoryListing>()
                    });

                    Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
                    return;
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardOfferings"])
                {
                    var listing = MarketBoardCurrentOfferings.Read(dataPtr + 0x10);

                    var request =
                        this.marketBoardRequests.LastOrDefault(
                            r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);

                    if (request == null)
                    {
                        Log.Error(
                            $"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
                        return;
                    }

                    if (request.Listings.Count + listing.ItemListings.Count > request.AmountToArrive)
                    {
                        Log.Error(
                            $"Too many Market Board listings received for request: {request.Listings.Count + listing.ItemListings.Count} > {request.AmountToArrive} item#{listing.ItemListings[0].CatalogId}");
                        return;
                    }

                    if (request.ListingsRequestId != -1 && request.ListingsRequestId != listing.RequestId)
                    {
                        Log.Error(
                            $"Non-matching RequestIds for Market Board data request: {request.ListingsRequestId}, {listing.RequestId}");
                        return;
                    }

                    if (request.ListingsRequestId == -1 && request.Listings.Count > 0)
                    {
                        Log.Error(
                            $"Market Board data request sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                        return;
                    }

                    if (request.ListingsRequestId == -1)
                    {
                        request.ListingsRequestId = listing.RequestId;
                        Log.Verbose($"First Market Board packet in sequence: {listing.RequestId}");
                    }

                    request.Listings.AddRange(listing.ItemListings);

                    Log.Verbose("Added {0} ItemListings to request#{1}, now {2}/{3}, item#{4}",
                                listing.ItemListings.Count, request.ListingsRequestId, request.Listings.Count,
                                request.AmountToArrive, request.CatalogId);

                    if (request.IsDone)
                    {
                        Log.Verbose("Market Board request finished, starting upload: request#{0} item#{1} amount#{2}",
                                    request.ListingsRequestId, request.CatalogId, request.AmountToArrive);
                        try {
                            Task.Run(() => this.uploader.Upload(request));
                        } catch (Exception ex) {
                            Log.Error(ex, "Market Board data upload failed.");
                        }
                    }

                    return;
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardHistory"])
                {
                    var listing = MarketBoardHistory.Read(dataPtr + 0x10);

                    var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);

                    if (request == null)
                    {
                        Log.Error(
                            $"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
                        return;
                    }

                    if (request.ListingsRequestId != -1)
                    {
                        Log.Error(
                            $"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                        return;
                    }

                    request.History.AddRange(listing.HistoryListings);

                    Log.Verbose("Added history for item#{0}", listing.CatalogId);
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
                {
                    var taxes = MarketTaxRates.Read(dataPtr + 0x10);

                    Log.Verbose("MarketTaxRates: limsa#{0} grid#{1} uldah#{2} ish#{3} kugane#{4} cr#{5}",
                                taxes.LimsaLominsaTax, taxes.GridaniaTax, taxes.UldahTax, taxes.IshgardTax, taxes.KuganeTax, taxes.CrystariumTax);
                    try
                    {
                        Task.Run(() => this.uploader.UploadTax(taxes));
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Market Board data upload failed.");
                    }
                }
            }
        }
Esempio n. 5
0
        private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            if (direction != NetworkMessageDirection.ZoneDown)
            {
                return;
            }

            if (!this.dalamud.Data.IsDataReady)
            {
                return;
            }

            if (opCode == this.dalamud.Data.ServerOpCodes["CfNotifyPop"])
            {
                var data = new byte[64];
                Marshal.Copy(dataPtr, data, 0, 64);

                var notifyType = data[0];
                var contentFinderConditionId = BitConverter.ToUInt16(data, 0x14);

                if (notifyType != 3)
                {
                    return;
                }

                var contentFinderCondition = this.dalamud.Data.GetExcelSheet <ContentFinderCondition>().GetRow(contentFinderConditionId);

                if (contentFinderCondition == null)
                {
                    Log.Error("CFC key {0} not in lumina data.", contentFinderConditionId);
                    return;
                }

                var cfcName = contentFinderCondition.Name.ToString();
                if (string.IsNullOrEmpty(contentFinderCondition.Name))
                {
                    cfcName = "Duty Roulette";
                    contentFinderCondition.Image = 112324;
                }

                if (this.dalamud.Configuration.DutyFinderTaskbarFlash && !NativeFunctions.ApplicationIsActivated())
                {
                    var flashInfo = new NativeFunctions.FLASHWINFO
                    {
                        cbSize    = (uint)Marshal.SizeOf <NativeFunctions.FLASHWINFO>(),
                        uCount    = uint.MaxValue,
                        dwTimeout = 0,
                        dwFlags   = NativeFunctions.FlashWindow.FLASHW_ALL |
                                    NativeFunctions.FlashWindow.FLASHW_TIMERNOFG,
                        hwnd = Process.GetCurrentProcess().MainWindowHandle
                    };
                    NativeFunctions.FlashWindowEx(ref flashInfo);
                }

                Task.Run(() => {
                    if (this.dalamud.Configuration.DutyFinderChatMessage)
                    {
                        this.dalamud.Framework.Gui.Chat.Print("Duty pop: " + cfcName);
                    }

                    CfPop?.Invoke(this, contentFinderCondition);
                });

                return;
            }

            if (!this.optOutMbUploads)
            {
                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardItemRequestStart"])
                {
                    var catalogId = (uint)Marshal.ReadInt32(dataPtr);
                    var amount    = Marshal.ReadByte(dataPtr + 0xB);

                    this.marketBoardRequests.Add(new MarketBoardItemRequest {
                        CatalogId      = catalogId,
                        AmountToArrive = amount,
                        Listings       = new List <MarketBoardCurrentOfferings.MarketBoardItemListing>(),
                        History        = new List <MarketBoardHistory.MarketBoardHistoryListing>()
                    });

                    Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
                    return;
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardOfferings"])
                {
                    var listing = MarketBoardCurrentOfferings.Read(dataPtr);

                    var request =
                        this.marketBoardRequests.LastOrDefault(
                            r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);

                    if (request == null)
                    {
                        Log.Error(
                            $"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
                        return;
                    }

                    if (request.Listings.Count + listing.ItemListings.Count > request.AmountToArrive)
                    {
                        Log.Error(
                            $"Too many Market Board listings received for request: {request.Listings.Count + listing.ItemListings.Count} > {request.AmountToArrive} item#{listing.ItemListings[0].CatalogId}");
                        return;
                    }

                    if (request.ListingsRequestId != -1 && request.ListingsRequestId != listing.RequestId)
                    {
                        Log.Error(
                            $"Non-matching RequestIds for Market Board data request: {request.ListingsRequestId}, {listing.RequestId}");
                        return;
                    }

                    if (request.ListingsRequestId == -1 && request.Listings.Count > 0)
                    {
                        Log.Error(
                            $"Market Board data request sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                        return;
                    }

                    if (request.ListingsRequestId == -1)
                    {
                        request.ListingsRequestId = listing.RequestId;
                        Log.Verbose($"First Market Board packet in sequence: {listing.RequestId}");
                    }

                    request.Listings.AddRange(listing.ItemListings);

                    Log.Verbose("Added {0} ItemListings to request#{1}, now {2}/{3}, item#{4}",
                                listing.ItemListings.Count, request.ListingsRequestId, request.Listings.Count,
                                request.AmountToArrive, request.CatalogId);

                    if (request.IsDone)
                    {
                        Log.Verbose("Market Board request finished, starting upload: request#{0} item#{1} amount#{2}",
                                    request.ListingsRequestId, request.CatalogId, request.AmountToArrive);
                        try {
                            Task.Run(() => this.uploader.Upload(request));
                        } catch (Exception ex) {
                            Log.Error(ex, "Market Board data upload failed.");
                        }
                    }

                    return;
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardHistory"])
                {
                    var listing = MarketBoardHistory.Read(dataPtr);

                    var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);

                    if (request == null)
                    {
                        Log.Error(
                            $"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
                        return;
                    }

                    if (request.ListingsRequestId != -1)
                    {
                        Log.Error(
                            $"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                        return;
                    }

                    request.History.AddRange(listing.HistoryListings);

                    Log.Verbose("Added history for item#{0}", listing.CatalogId);

                    if (request.AmountToArrive == 0)
                    {
                        Log.Verbose("Request had 0 amount, uploading now");

                        try
                        {
                            Task.Run(() => this.uploader.Upload(request));
                        }
                        catch (Exception ex)
                        {
                            Log.Error(ex, "Market Board data upload failed.");
                        }
                    }
                }

                if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
                {
                    var category = (uint)Marshal.ReadInt32(dataPtr);
                    // Result dialog packet does not contain market tax rates
                    if (category != 720905)
                    {
                        return;
                    }

                    var taxes = MarketTaxRates.Read(dataPtr);

                    Log.Verbose("MarketTaxRates: limsa#{0} grid#{1} uldah#{2} ish#{3} kugane#{4} cr#{5}",
                                taxes.LimsaLominsaTax, taxes.GridaniaTax, taxes.UldahTax, taxes.IshgardTax, taxes.KuganeTax, taxes.CrystariumTax);
                    try
                    {
                        Task.Run(() => this.uploader.UploadTax(taxes));
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Market Board data upload failed.");
                    }
                }
            }
        }