public void Queue(TextureDownloadInfo emote)
 {
     if (emote.type == ImageType.BTTV_Animated || emote.type == ImageType.Cheermote)
     {
         _animationDownloadQueue.Enqueue(emote);
     }
     else
     {
         _imageDownloadQueue.Enqueue(emote);
     }
 }
        public static IEnumerator PreloadAnimatedEmotes()
        {
            int count = 0;

            foreach (string emoteIndex in BTTVAnimatedEmoteIDs.Values)
            {
                if (!Plugin.Instance.IsAtMainMenu)
                {
                    yield return(new WaitUntil(() => Plugin.Instance.IsAtMainMenu));
                }

                if (!CachedTextures.ContainsKey(emoteIndex))
                {
                    TextureDownloadInfo downloadInfo = new TextureDownloadInfo("AB" + emoteIndex, ImageType.BTTV_Animated, "!NOTSET!");
                    //Plugin.Log($"Precaching {emoteIndex}");
                    Instance.Queue(downloadInfo);
                    count++;
                    yield return(new WaitUntil(() => !Instance._animationDownloadQueue.Contains(downloadInfo)));
                }
            }
            Plugin.Log($"Precached {count.ToString()} animated emotes successfully!");
        }
        public static IEnumerator Download(string imagePath, TextureDownloadInfo imageDownloadInfo, bool isRetry = false)
        {
            bool isAnimated = imageDownloadInfo.type == ImageType.BTTV_Animated || imageDownloadInfo.type == ImageType.Cheermote;

            if (!CachedTextures.ContainsKey(imageDownloadInfo.spriteIndex))
            {
                int _waitForFrames = 5;
                //Plugin.Log($"Downloading {imageDownloadInfo.spriteIndex}");
                if (isAnimated)
                {
                    Instance._animatedImageDownloading = true;
                }
                else
                {
                    Instance._imageDownloading = true;
                }

                Sprite sprite = null;
                if (imageDownloadInfo.type != ImageType.Emoji)
                {
                    string origImagePath = imagePath;

                    string imageCachePath     = "Cache\\Images";
                    string oldSpriteCachePath = "Cache\\Sprites";

                    // Migrate our cached sprites/images into our renamed "Images" folder
                    if (Directory.Exists(oldSpriteCachePath))
                    {
                        if (!Directory.Exists(imageCachePath))
                        {
                            Directory.Move(oldSpriteCachePath, imageCachePath);
                        }
                        else
                        {
                            Directory.Delete(oldSpriteCachePath, true);
                        }
                    }
                    if (!Directory.Exists(imageCachePath))
                    {
                        Directory.CreateDirectory(imageCachePath);
                    }

                    string typePath = $"{imageCachePath}\\{ImageTypeNames.Get(imageDownloadInfo.type)}";
                    if (!Directory.Exists(typePath))
                    {
                        Directory.CreateDirectory(typePath);
                    }

                    bool   localPathExists = false;
                    string localFilePath   = $"{typePath}\\{imageDownloadInfo.spriteIndex}";

                    if (File.Exists(localFilePath))
                    {
                        localPathExists = true;
                        imagePath       = $"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Replace("\\Plugins", "")}\\{localFilePath}";
                    }

                    using (var web = UnityWebRequestTexture.GetTexture(imagePath, true))
                    {
                        yield return(web.SendWebRequest());

                        if (web.isNetworkError || web.isHttpError)
                        {
                            Plugin.Log($"An error occured when requesting emote {imageDownloadInfo.spriteIndex}, Message: \"{web.error}\"");
                            CachedTextures.TryAdd(imageDownloadInfo.spriteIndex, null);
                            if (isAnimated)
                            {
                                Instance._animatedImageDownloading = false;
                            }
                            else
                            {
                                Instance._imageDownloading = false;
                            }
                            yield break;
                        }
                        else if (isAnimated)
                        {
                            CachedTextures.TryAdd(imageDownloadInfo.spriteIndex, null);
                            yield return(AnimationDecoder.Process(web.downloadHandler.data, ChatHandler.Instance.OverlayAnimatedImage, imageDownloadInfo));

                            if (!localPathExists)
                            {
                                ImageSaveQueue.Enqueue(new TextureSaveInfo(localFilePath, web.downloadHandler.data));
                            }

                            _waitForFrames = 10;
                            while (_waitForFrames > 0)
                            {
                                _waitForFrames--;
                                yield return(null);
                            }

                            Instance._animatedImageDownloading = false;
                            yield break;
                        }
                        else
                        {
                            sprite = UIUtilities.LoadSpriteFromTexture(DownloadHandlerTexture.GetContent(web));
                            if (sprite)
                            {
                                if (!localPathExists)
                                {
                                    ImageSaveQueue.Enqueue(new TextureSaveInfo(localFilePath, web.downloadHandler.data));
                                }
                            }
                        }
                    }
                }
                else
                {
                    sprite = UIUtilities.LoadSpriteFromResources($"EnhancedTwitchChat.Resources.Emojis.{imageDownloadInfo.spriteIndex.ToLower()}");
                }

                if (sprite)
                {
                    CachedTextures.TryAdd(imageDownloadInfo.spriteIndex, new CachedSpriteData(sprite, sprite.texture.width, sprite.texture.height));
                    yield return(null);

                    ChatHandler.Instance.OverlayImage(sprite, imageDownloadInfo);
                }

                _waitForFrames = 5;
                while (_waitForFrames > 0)
                {
                    _waitForFrames--;
                    yield return(null);
                }
                Instance._imageDownloading = false;
            }
        }
Example #4
0
        public static IEnumerator Process(byte[] gifData, Action <Texture2D, Rect[], float, TextureDownloadInfo> callback, TextureDownloadInfo imageDownloadInfo)
        {
            Plugin.Log($"Started decoding gif {imageDownloadInfo.spriteIndex}");

            List <Texture2D> texList   = new List <Texture2D>();
            GifInfo          frameInfo = new GifInfo();
            DateTime         startTime = DateTime.Now;

            Task.Run(() => ProcessingThread(gifData, ref frameInfo));
            yield return(new WaitUntil(() => { return frameInfo.initialized; }));


            int       textureSize = 2048;
            Texture2D texture     = null;
            float     delay       = -1f;

            for (int i = 0; i < frameInfo.frameCount; i++)
            {
                yield return(new WaitUntil(() => { return frameInfo.frames.Count > i; }));

                //Plugin.Log($"Frame {i} is ready for processing! Frame is {frameInfo.frames[i].frame.Width}x{frameInfo.frames[i].frame.Height}");

                if (texture == null)
                {
                    textureSize = GetTextureSize(frameInfo, i);
                    texture     = new Texture2D(textureSize, textureSize);
                }

                FrameInfo currentFrameInfo = frameInfo.frames[i];
                if (delay == -1f)
                {
                    delay = currentFrameInfo.delay;
                }

                var frameTexture = new Texture2D(currentFrameInfo.frame.Width, currentFrameInfo.frame.Height);
                try
                {
                    int       colorIndex = 0;
                    Color32[] colors     = new Color32[currentFrameInfo.frame.Width * currentFrameInfo.frame.Height];
                    for (int x = 0; x < currentFrameInfo.frame.Width; x++)
                    {
                        for (int y = 0; y < currentFrameInfo.frame.Height; y++)
                        {
                            System.Drawing.Color sourceColor = currentFrameInfo.colors[colorIndex];
                            colors[(currentFrameInfo.frame.Height - y - 1) * currentFrameInfo.frame.Width + x] = new Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A);
                            colorIndex++;
                        }
                    }
                    frameTexture.wrapMode = TextureWrapMode.Clamp;
                    frameTexture.SetPixels32(colors);
                    frameTexture.Apply(i == 0);
                }
                catch (Exception e)
                {
                    Plugin.Log($"Exception while decoding gif! Frame: {i}, Exception: {e}");
                    yield break;
                }
                yield return(null);

                texList.Add(frameTexture);

                // Instant callback after we decode the first frame in order to display a still image until the animated one is finished loading
                if (i == 0)
                {
                    callback?.Invoke(frameTexture, texture.PackTextures(new Texture2D[] { frameTexture }, 2, textureSize, true), delay, imageDownloadInfo);
                }
            }
            Rect[] atlas = texture.PackTextures(texList.ToArray(), 2, textureSize, true);

            yield return(null);

            callback?.Invoke(texture, atlas, delay, imageDownloadInfo);
            Plugin.Log($"Finished decoding gif {imageDownloadInfo.spriteIndex}! Elapsed time: {(DateTime.Now - startTime).TotalSeconds} seconds.");
        }