Пример #1
0
        private void CalculatePing(IntPtr dataPtr, ushort opcode, NetworkMessageDirection direction)
        {
            if (direction == NetworkMessageDirection.ZoneDown && opcode == this.predictedDownOpcode)
            {
                // The response packet has the same timestamp as the request packet, so we can just
                // take it from here instead of keeping state.
                var prevMs = (uint)Marshal.ReadInt32(dataPtr);

                if (QueryPerformanceCounter(out var nextNs))
                {
                    var nextMs = nextNs / 10000;
                    this.pingMs  = nextMs - prevMs;
                    this.gotPing = true;

                    if (Verbose)
                    {
                        PluginLog.LogDebug("Packet ping: {LastPing}ms", this.pingMs);
                    }
                }
                else
                {
                    PluginLog.LogError("Failed to call QueryPerformanceCounter! (How can this happen?)");
                }
            }
        }
Пример #2
0
        static ActivityType ToNetworkActivityType(NetworkMessageDirection direction)
        {
            switch (direction)
            {
            case NetworkMessageDirection.Incoming:
                return(ActivityType.IncomingNetworking);

            case NetworkMessageDirection.Outgoing:
                return(ActivityType.OutgoingNetworking);

            default:
                return(ActivityType.Procedure);
            }
        }
Пример #3
0
        private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint targetId, NetworkMessageDirection direction)
        {
            if (!this.pluginInterface.Data.IsDataReady || this.pluginInterface.ClientState.LocalPlayer == null)
            {
                return;
            }

            if (direction == NetworkMessageDirection.ZoneUp)
            {
                if (opCode == 0x241)
                {
                    this.pingTracker.StartNextRTTWait();
                }
            }

            if (direction == NetworkMessageDirection.ZoneDown)
            {
                if (opCode == 0xC4 && targetId == this.pluginInterface.ClientState.LocalPlayer.ActorId)
                {
                    this.pingTracker.StartNextRTTCalculation();
                }
            }
        }
Пример #4
0
        private void OnNetworkMessage(IntPtr dataPtr,
                                      ushort opcode,
                                      uint sourceActorId,
                                      uint targetActorId,
                                      NetworkMessageDirection direction)
        {
            if (OnNetworkContext == null)
            {
                return;
            }

            var header = new byte[IpcHeader.IpcHeaderLength];

            if (direction == NetworkMessageDirection.ZoneDown)
            {
                Marshal.Copy(dataPtr - 0x20, header, 0, header.Length);
            }

            var data = new byte[maxByteLength];

            Marshal.Copy(dataPtr, data, 0, data.Length);

            var context = new NetworkContext
            {
                Time          = DateTime.Now,
                RawHeader     = header,
                Opcode        = opcode,
                Data          = data,
                DataPtr       = dataPtr,
                SourceActorId = sourceActorId,
                TargetActorId = targetActorId,
                Direction     = direction,
            };

            OnNetworkContext.Invoke(context);
        }
Пример #5
0
 public NetworkMessageEvent(object trigger, string displayName, string messageId, ActivityEventType type, NetworkMessageDirection direction,
                            int templateId = 0, ActivityStatus status = ActivityStatus.Unspecified) :
     base(trigger, displayName, messageId, type, templateId, status)
 {
     Direction = direction;
 }
Пример #6
0
        private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            const ushort eventPlay   = 0x02C3; // TODO: Get goat to hook the handlers for these
            const ushort eventFinish = 0x0239;

            if (opCode == eventPlay)
            {
                var packetData = Marshal.PtrToStructure <EventPlay>(dataPtr);

                if ((packetData.Flags & 0x00000400) != 0) // TODO: PR Sapphire, HIDE_UI seems to be wrong now
                {
                    this.ui.CutsceneActive = true;
                }
            }
            else if (opCode == eventFinish)
            {
                this.ui.CutsceneActive = false;
            }
        }
Пример #7
0
 private void OnNetworkEvent(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
 {
     if (!this.configuration.Enabled)
     {
         return;
     }
     if (direction != NetworkMessageDirection.ZoneDown)
     {
         return;
     }
     if (!this.pi.Data.IsDataReady)
     {
         return;
     }
     if (opCode == this.pi.Data.ServerOpCodes["HousingWardInfo"])
     {
         this.OnHousingWardInfo(dataPtr);
     }
 }
Пример #8
0
        private void OnNetworkMessage(IntPtr dataPtr, ushort opcode, uint sourceId, uint targetId, NetworkMessageDirection direction)
        {
            // Tracking ping using ping packets is unreliable, because we can't confirm that the server
            // responds to the ping immediately. With ICMP, we know that this is true, but using packets,
            // messages on both the client and server are restrained by TCP ordering requirements. That
            // said, considering TCP-related latency in calculations is arguably more useful than a real
            // ping calculation.

            // Predict the up/down Ping opcodes
            if (!this.predictedUpOpcodeSet && direction == NetworkMessageDirection.ZoneUp)
            {
                // Client send, executes first
                TrackPredictedPingUp(dataPtr, opcode);
            }
            else if (this.predictedUpOpcodeSet && !this.predictedDownOpcodeSet && direction == NetworkMessageDirection.ZoneDown)
            {
                // Server send, executes last
                CheckPredictedPingDown(dataPtr, opcode);
            }

            // Calculate ping
            if (this.predictedDownOpcodeSet && this.predictedUpOpcodeSet)
            {
                CalculatePing(dataPtr, opcode, direction);
            }
        }
Пример #9
0
        public void OnNetwork(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            var OpcodeLoadHousing = Int32.Parse(Offset.LoadHousing, NumberStyles.HexNumber);
            var OpcodeMoveItem    = Int32.Parse(Offset.MoveItem, NumberStyles.HexNumber);

            if (direction == NetworkMessageDirection.ZoneDown)
            {
                if (opCode != OpcodeLoadHousing || !Config.Recording)
                {
                    return;
                }
                byte[] posArr = new byte[2416];
                Marshal.Copy(dataPtr, posArr, 0, 2416);
                if (BitConverter.ToString(posArr).Replace("-", " ").StartsWith("FF FF FF FF FF FF FF FF"))
                {
                    Config.SelectedItemIndex = -1;
                    Config.HousingItemList.Clear();
                    Config.Save();
                    return;
                }
                if (DateTime.Now > Config.lastPosPackageTime.AddSeconds(5))
                {
                    Config.HousingItemList.Clear();
                    Config.lastPosPackageTime = DateTime.Now;
                    Config.Save();
                }
                for (int i = 12; i < posArr.Length && i + 24 < posArr.Length; i += 24)
                {
                    var modelKey = BitConverter.ToUInt16(posArr, i);
                    var item     = Interface.Data.GetExcelSheet <HousingFurniture>().GetRow((uint)(modelKey + 196608)).Item.Value;
                    if (item.RowId == 0)
                    {
                        continue;
                    }
                    var rotate = BitConverter.ToSingle(posArr, i + 8);
                    var x      = BitConverter.ToSingle(posArr, i + 12);
                    var y      = BitConverter.ToSingle(posArr, i + 16);
                    var z      = BitConverter.ToSingle(posArr, i + 20);
                    Config.HousingItemList.Add(new HousingItem(
                                                   modelKey,
                                                   item.RowId,
                                                   x,
                                                   y,
                                                   z,
                                                   rotate,
                                                   item.Name
                                                   ));
                }
                Log($"Load {Config.HousingItemList.Count} items.");
                Config.Save();
            }
            else
            {
                if (opCode != OpcodeMoveItem || !Config.ForceMove)
                {
                    return;
                }
                byte[] posArr = new byte[28];
                Marshal.Copy(dataPtr, posArr, 0, 28);
                //Log(BitConverter.ToString(posArr).Replace("-", " "));
                float x      = BitConverter.ToSingle(posArr, 12);
                float y      = BitConverter.ToSingle(posArr, 16);
                float z      = BitConverter.ToSingle(posArr, 20);
                float rotate = BitConverter.ToSingle(posArr, 24);
                Log($"Moving to ({x:N3}, {y:N3}, {z:N3}, {rotate:N3})");
                x      = Config.PlaceX;
                y      = Config.PlaceY;
                z      = Config.PlaceZ;
                rotate = Config.PlaceRotate;
                Log($"Forced to ({x:N3}, {y:N3}, {z:N3}, {rotate:N3})");
                byte[] bx = BitConverter.GetBytes(x);
                bx.CopyTo(posArr, 12);
                byte[] by = BitConverter.GetBytes(y);
                by.CopyTo(posArr, 16);
                byte[] bz = BitConverter.GetBytes(z);
                bz.CopyTo(posArr, 20);
                byte[] br = BitConverter.GetBytes(rotate);
                br.CopyTo(posArr, 24);
                Marshal.Copy(posArr, 0, dataPtr, 28);
                Config.ForceMove = false;
                Config.Save();
                WritePrePosition();
            }
        }
Пример #10
0
        private void Chat_OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            return;

            /*
             * if (!Config.Enable || !Config.Eureka) return;
             * if (direction != NetworkMessageDirection.ZoneDown)
             *  return;
             * var client = ClientState.ClientLanguage == ClientLanguage.ChineseSimplified ? "cn" : "intl";
             * // not used after hooking the function
             * // https://github.com/karashiiro/MachinaWrapperJSON/blob/master/MachinaWrapper/Models/Sapphire/Ipcs.cs
             * // https://github.com/karashiiro/MachinaWrapperJSON/blob/master/MachinaWrapper/Models/Sapphire/Ipcs_cn.cs
             * // if not found, it'll be triggered when chatting and the length should be 1104.
             * ushort chat_opcode = (ushort)(client == "cn" ? 0x021e : 0x02c2);
             * if (opCode != chat_opcode)
             *  return;
             * byte[] managedArray = new byte[32];
             * Marshal.Copy(dataPtr, managedArray, 0, 32);
             * Log("Network dataPtr");
             * Log(BitConverter.ToString(managedArray).Replace("-", " "));
             * return;
             * Int64 CID = Marshal.ReadInt64(dataPtr);
             * short world_id = Marshal.ReadInt16(dataPtr, 12);
             * string name = StringFromNativeUtf8(dataPtr + 16);
             * Log($"{name}@{world_id}:{CID}");
             * string playerNameKey = $"{name}@{world_id}";
             * if (!name2CID.ContainsKey(playerNameKey))
             * {
             *  name2CID.Add(playerNameKey, CID);
             * }
             */
        }
Пример #11
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.");
                    }
                }
            }
        }
Пример #12
0
 public NetworkMessageEvent(object trigger, string displayName, string messageId, ActivityEventType type, NetworkMessageDirection direction, int templateId = 0) :
     base(trigger, displayName, messageId, type, templateId)
 {
     Direction = direction;
 }
Пример #13
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;
                }

                if (string.IsNullOrEmpty(contentFinderCondition.Name))
                {
                    contentFinderCondition.Name  = "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(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[rouletteIndex];
                        var prevRoleKey    = this.lastPreferredRole[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);
                    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 (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
                {
                    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.");
                    }
                }
            }
        }
Пример #14
0
        private void OnNetworkEvent(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            if (direction != NetworkMessageDirection.ZoneDown)
            {
                return;
            }
            if (!this.pi.Data.IsDataReady)
            {
                return;
            }
            if (opCode == this.pi.Data.ServerOpCodes["MarketBoardItemRequestStart"])
            {
                this.newRequest = true;
            }
            if (opCode != this.pi.Data.ServerOpCodes["MarketBoardOfferings"] || !this.newRequest)
            {
                return;
            }
            if (!this.configuration.alwaysOn && (!this.configuration.smart || !Retainer()))
            {
                return;
            }
            var listing = MarketBoardCurrentOfferings.Read(dataPtr);
            var i       = 0;

            if (this.configuration.hq && this.items.Single(j => j.RowId == listing.ItemListings[0].CatalogId).CanBeHq)
            {
                while (i < listing.ItemListings.Count && !listing.ItemListings[i].IsHq)
                {
                    i++;
                }
                if (i == listing.ItemListings.Count)
                {
                    return;
                }
            }
            while (i != listing.ItemListings.Count && this.configuration.whitelist.Contains(listing.ItemListings[i].RetainerName))
            {
                i++;
            }
            var price = listing.ItemListings[i].PricePerUnit - this.configuration.delta;

            Clipboard.SetText(price.ToString());
            if (this.configuration.verbose)
            {
                this.pi.Framework.Gui.Chat.Print($"{price} copied to clipboard.");
            }
            this.newRequest = false;
        }
Пример #15
0
        private void OnNetworkEvent(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            if (direction != NetworkMessageDirection.ZoneDown)
            {
                return;
            }
            if (!Data.IsDataReady)
            {
                return;
            }
            if (opCode == Data.ServerOpCodes["MarketBoardItemRequestStart"])
            {
                newRequest = true;
            }
            if (opCode != Data.ServerOpCodes["MarketBoardOfferings"] || !newRequest)
            {
                return;
            }
            if (!configuration.alwaysOn && (!configuration.smart || !Retainer()))
            {
                return;
            }
            var listing = MarketBoardCurrentOfferings.Read(dataPtr);
            var i       = 0;

            if (configuration.hq && items.Single(j => j.RowId == listing.ItemListings[0].CatalogId).CanBeHq)
            {
                while (i < listing.ItemListings.Count && !listing.ItemListings[i].IsHq)
                {
                    i++;
                }
                if (i == listing.ItemListings.Count)
                {
                    return;
                }
            }

            var price = listing.ItemListings[i].PricePerUnit - (listing.ItemListings[i].PricePerUnit % configuration.mod) - configuration.delta;

            price = Math.Max(price, configuration.min);
            ImGui.SetClipboardText(price.ToString());
            if (configuration.verbose)
            {
                Chat.Print((configuration.hq ? "[HQ] " : string.Empty) + $"{price:n0} copied to clipboard.");
            }

            newRequest = false;
        }
Пример #16
0
        public void OnNetwork(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction)
        {
            return;

            if (direction == NetworkMessageDirection.ZoneDown)
            {
                ushort[] filteredOpcodes = new ushort[] { 439, 0x1CB, 0xA1, 0x269, 0x30C, 0x103, 0x263 };
                if (filteredOpcodes.ToList().IndexOf(opCode) == -1)
                {
                    Log($"Receive opcode:0x{opCode:X}");
                }
            }
        }