protected override void OnReload(GameMode currentGameMode, bool maintainState)
        {
            if (maintainState)
            {
                return;
            }

            var anyPrevious = _allOverlayTextures != null && _allOverlayTextures.Any();

            if (anyPrevious)
            {
                RemoveAllOverlays();
            }

            var pd = GetExtendedData();

            if (pd != null && pd.data.TryGetValue(OverlayDataKey, out var overlayData))
            {
                if (overlayData is byte[] overlayBytes)
                {
                    try
                    {
                        _allOverlayTextures = MessagePackSerializer.Deserialize <
                            Dictionary <CoordinateType, Dictionary <string, ClothesTexData> > >(
                            overlayBytes);
                    }
                    catch (Exception ex)
                    {
                        var logLevel = currentGameMode == GameMode.Maker ? LogLevel.Message | LogLevel.Warning : LogLevel.Warning;
                        Logger.Log(logLevel, "[KCOX] WARNING: Failed to load embedded overlay data for " + (ChaFileControl?.charaFileName ?? "?"));
                        Logger.Log(LogLevel.Debug, ex);
                    }
                }
            }

            if (_allOverlayTextures == null)
            {
                _allOverlayTextures = new Dictionary <CoordinateType, Dictionary <string, ClothesTexData> >();
            }

            if (anyPrevious || _allOverlayTextures.Any())
            {
                StartCoroutine(RefreshAllTexturesCo());
            }
        }
Esempio n. 2
0
            public static void ChangeCustomClothesPostHook(ChaControl __instance, bool main, int kind)
            {
                var controller = __instance.GetComponent <KoiClothesOverlayController>();

                if (controller == null)
                {
                    return;
                }

                var clothesCtrl = GetCustomClothesComponent(__instance, main, kind);

                if (clothesCtrl == null)
                {
                    return;
                }

                // Clean up no longer used textures when switching between top clothes with 3 parts and 1 part
                if (MakerAPI.InsideMaker && controller.CurrentOverlayTextures != null)
                {
                    List <KeyValuePair <string, ClothesTexData> > toRemoveList = null;
                    if (main && kind == 0)
                    {
                        toRemoveList = controller.CurrentOverlayTextures.Where(x => KoiClothesOverlayMgr.SubClothesNames.Contains(x.Key)).ToList();
                    }
                    else if (!main)
                    {
                        toRemoveList = controller.CurrentOverlayTextures.Where(x => KoiClothesOverlayMgr.MainClothesNames[0] == x.Key).ToList();
                    }

                    if (toRemoveList != null && toRemoveList.Count > 0)
                    {
                        Logger.Log(LogLevel.Warning | LogLevel.Message, $"[KCOX] Removing {toRemoveList.Count} no longer used Top overlay(s)");
                        foreach (var toRemove in toRemoveList)
                        {
                            controller.SetOverlayTex(null, toRemove.Key);
                        }
                    }
                }

                controller.ApplyOverlays(clothesCtrl);
            }
        private void DumpBaseTextureImpl(Renderer[][] rendererArrs)
        {
            var act = RenderTexture.active;

            try
            {
                var renderer      = GetApplicableRenderers(rendererArrs).FirstOrDefault();
                var renderTexture = (RenderTexture)renderer?.material?.mainTexture;

                if (renderTexture == null)
                {
                    throw new Exception("There are no renderers or textures to dump");
                }

                RenderTexture.active = renderTexture;

                var tex = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
                tex.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);

                var png = tex.EncodeToPNG();

                Destroy(tex);

                _dumpCallback(png);
            }
            catch (Exception e)
            {
                Logger.Log(LogLevel.Error | LogLevel.Message, "[KCOX] Dumping texture failed - " + e.Message);
                Logger.Log(LogLevel.Debug, e);
                RenderTexture.active = null;
            }
            finally
            {
                RenderTexture.active = act;
                _dumpCallback        = null;
            }
        }
        private void ApplyOverlays(ChaClothesComponent clothesCtrl)
        {
            if (CurrentOverlayTextures == null)
            {
                return;
            }

            var clothesName  = clothesCtrl.name;
            var rendererArrs = GetRendererArrays(clothesCtrl);

            if (_dumpCallback != null && _dumpClothesId == clothesName)
            {
                DumpBaseTextureImpl(rendererArrs);
            }

            if (CurrentOverlayTextures.Count == 0)
            {
                return;
            }

            if (!CurrentOverlayTextures.TryGetValue(clothesName, out var overlay))
            {
                return;
            }
            if (overlay == null || overlay.IsEmpty())
            {
                return;
            }

            var applicableRenderers = GetApplicableRenderers(rendererArrs).ToList();

            if (applicableRenderers.Count == 0)
            {
                Logger.Log(MakerAPI.InsideMaker ? LogLevel.Warning | LogLevel.Message : LogLevel.Debug, $"[KCOX] Removing unused overlay for {clothesName}");

                overlay.Dispose();
                CurrentOverlayTextures.Remove(clothesName);
                return;
            }

            foreach (var renderer in applicableRenderers)
            {
                var mat = renderer.material;

                var mainTexture = (RenderTexture)mat.mainTexture;
                if (mainTexture == null)
                {
                    return;
                }

                if (overlay.Override)
                {
                    var rta = RenderTexture.active;
                    RenderTexture.active = mainTexture;
                    GL.Clear(false, true, Color.clear);
                    RenderTexture.active = rta;
                }

                if (overlay.Texture != null)
                {
                    KoiSkinOverlayController.ApplyOverlay(mainTexture, overlay.Texture);
                }
            }
        }