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.");
                    }
                }
            }
        }
        private void DataSubscriptionOnNetworkReceived(string connection, long epoch, byte[] message)
        {
            var opCode = BitConverter.ToInt16(message, 0x12);

            if (opCode == _definitions.PlayerSetup)
            {
                LocalContentId = BitConverter.ToUInt64(message, 0x20);
                Log($"New CID: {LocalContentId.ToString("X")}");
                return;
            }

            if (opCode == _definitions.MarketBoardItemRequestStart)
            {
                var catalogId = (uint)BitConverter.ToInt32(message, 0x20);
                var amount    = message[0x2B];

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

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

            if (opCode == _definitions.MarketBoardOfferings)
            {
                var listing = MarketBoardCurrentOfferings.Read(message.Skip(0x20).ToArray());

                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($"First Market Board packet in sequence: {listing.RequestId}");
                }

                request.Listings.AddRange(listing.ItemListings);

                Log($"Added {listing.ItemListings.Count} ItemListings to request#{request.ListingsRequestId}, now {request.Listings.Count}/{request.AmountToArrive}, item#{request.CatalogId}");

                if (request.IsDone)
                {
                    Log($"Market Board request finished, starting upload: request#{request.ListingsRequestId} item#{request.CatalogId} amount#{request.AmountToArrive}");
                    try
                    {
                        this._uploader.Upload(request);
                    }
                    catch (Exception ex)
                    {
                        Log("[ERROR] Market Board data upload failed:\n" + ex);
                    }
                }

                return;
            }

            if (opCode == _definitions.MarketBoardHistory)
            {
                var listing = MarketBoardHistory.Read(message.Skip(0x20).ToArray());

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

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

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

                request.History.AddRange(listing.HistoryListings);

                Log($"Added history for item#{listing.CatalogId}");
            }
        }
Beispiel #3
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.");
                    }
                }
            }
        }
        /// <summary>
        /// Process a zone proto message and scan for relevant data.
        /// </summary>
        /// <param name="message">The message bytes</param>
        /// <returns>True if an upload succeeded</returns>
        public bool ProcessZonePacket(byte[] message)
        {
            var opCode = BitConverter.ToInt16(message, 0x12);

            if (opCode == _definitions.PlayerSpawn)
            {
                CurrentWorldId = BitConverter.ToUInt16(message, 0x24);

                return(false);
            }

            if (opCode == _definitions.PlayerSetup)
            {
                LocalContentId = BitConverter.ToUInt64(message, 0x20);
                Log?.Invoke(this, $"New CID: {LocalContentId.ToString("X")}");
                LocalContentIdUpdated?.Invoke(this, LocalContentId);
                return(false);
            }

            if (opCode == _definitions.MarketBoardItemRequestStart)
            {
                var catalogId = (uint)BitConverter.ToInt32(message, 0x20);
                var amount    = message[0x2B];

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

                Log?.Invoke(this, $"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
                return(false);
            }

            if (opCode == _definitions.MarketBoardOfferings)
            {
                var listing = MarketBoardCurrentOfferings.Read(message.Skip(0x20).ToArray());

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

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

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

                if (request.ListingsRequestId != -1 && request.ListingsRequestId != listing.RequestId)
                {
                    Log?.Invoke(this,
                                $"[ERROR] Non-matching RequestIds for Market Board data request: {request.ListingsRequestId}, {listing.RequestId}");
                    return(false);
                }

                if (request.ListingsRequestId == -1 && request.Listings.Count > 0)
                {
                    Log?.Invoke(this,
                                $"[ERROR] Market Board data request sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                    return(false);
                }

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

                request.Listings.AddRange(listing.ItemListings);

                Log?.Invoke(this,
                            $"Added {listing.ItemListings.Count} ItemListings to request#{request.ListingsRequestId}, now {request.Listings.Count}/{request.AmountToArrive}, item#{request.CatalogId}");

                if (request.IsDone)
                {
                    if (CurrentWorldId == 0)
                    {
                        Log?.Invoke(this, "[ERROR] Not sure about your current world. Please move your character between zones once to start uploading.");
                        return(false);
                    }

                    RequestContentIdUpdate?.Invoke(this, null);

                    if (LocalContentId == 0)
                    {
                        Log?.Invoke(this, "[ERROR] Not sure about your character information. Please log in once with your character while having the program open to verify it.");
                        //return false;
                    }

                    LocalContentIdUpdated?.Invoke(this, LocalContentId);

                    Log?.Invoke(this,
                                $"Market Board request finished, starting upload: request#{request.ListingsRequestId} item#{request.CatalogId} amount#{request.AmountToArrive}");
                    try
                    {
                        _uploader.Upload(request);
                        return(true);
                    }
                    catch (Exception ex)
                    {
                        Log?.Invoke(this, "[ERROR] Market Board data upload failed:\n" + ex);
                    }
                }

                return(false);
            }

            if (opCode == _definitions.MarketBoardHistory)
            {
                var listing = MarketBoardHistory.Read(message.Skip(0x20).ToArray());

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

                if (request == null)
                {
                    Log?.Invoke(this,
                                $"[ERROR] Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
                    return(false);
                }

                if (request.ListingsRequestId != -1)
                {
                    Log?.Invoke(this,
                                $"[ERROR] Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
                    return(false);
                }

                request.History.AddRange(listing.HistoryListings);

                Log?.Invoke(this, $"Added history for item#{listing.CatalogId}");
                return(false);
            }

            if (opCode == _definitions.ContentIdNameMapResp)
            {
                var cid  = BitConverter.ToUInt64(message, 0x20);
                var name = Encoding.UTF8.GetString(message, 0x28, 32).TrimEnd(new [] { '\u0000' });

                try
                {
                    _uploader.UploadCrafterName(cid, name);
                    return(true);
                }
                catch (Exception ex)
                {
                    Log?.Invoke(this, "[ERROR] Content ID upload failed:\n" + ex);
                }
            }

            return(false);
        }