From d1b8d53619e62f67c25ff820ae8e13bb7b51464e Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Sat, 20 Aug 2022 13:39:51 +0200 Subject: [PATCH 1/3] Auto refresh skins when changing related settings --- src/game/client/components/menus.h | 2 ++ src/game/client/components/menus_settings.cpp | 26 +++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index a3476aae4..38d0eac7a 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -103,6 +103,8 @@ class CMenus : public CComponent void RenderColorPicker(); + void RefreshSkins(); + // new gui with gui elements template int DoButtonMenu(CUIElement &UIElement, const void *pID, T &&GetTextLambda, int Checked, const CUIRect *pRect, bool HintRequiresStringCheck, bool HintCanChangePositionOrSize = false, int Corners = IGraphics::CORNER_ALL, float r = 5.0f, float FontFactor = 0.0f, vec4 ColorHot = vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4 Color = vec4(1, 1, 1, 0.5f), int AlignVertically = 1) diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 70c178052..e851fe179 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -409,6 +409,18 @@ struct CUISkin bool operator==(const char *pOther) const { return !str_comp_nocase(m_pSkin->m_aName, pOther); } }; +void CMenus::RefreshSkins() +{ + auto SkinStartLoadTime = time_get_nanoseconds(); + m_pClient->m_Skins.Refresh([&](int) { + // if skin refreshing takes to long, swap to a loading screen + if(time_get_nanoseconds() - SkinStartLoadTime > 500ms) + { + RenderLoading(Localize("Loading skin files"), "", 0, false); + } + }); +} + void CMenus::RenderSettingsTee(CUIRect MainView) { CUIRect Button, Label, Dummy, DummyLabel, SkinList, QuickSearch, QuickSearchClearButton, SkinDB, SkinPrefix, SkinPrefixLabel, DirectoryButton, RefreshButton, Eyes, EyesLabel, EyesTee, EyesRight; @@ -470,6 +482,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView) if(DoButton_CheckBox(&g_Config.m_ClDownloadSkins, Localize("Download skins"), g_Config.m_ClDownloadSkins, &DummyLabel)) { g_Config.m_ClDownloadSkins ^= 1; + RefreshSkins(); + s_InitSkinlist = true; } Dummy.HSplitTop(20.0f, &DummyLabel, &Dummy); @@ -477,6 +491,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView) if(DoButton_CheckBox(&g_Config.m_ClDownloadCommunitySkins, Localize("Download community skins"), g_Config.m_ClDownloadCommunitySkins, &DummyLabel)) { g_Config.m_ClDownloadCommunitySkins ^= 1; + RefreshSkins(); + s_InitSkinlist = true; } Dummy.HSplitTop(20.0f, &DummyLabel, &Dummy); @@ -484,6 +500,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) if(DoButton_CheckBox(&g_Config.m_ClVanillaSkinsOnly, Localize("Vanilla skins only"), g_Config.m_ClVanillaSkinsOnly, &DummyLabel)) { g_Config.m_ClVanillaSkinsOnly ^= 1; + RefreshSkins(); s_InitSkinlist = true; } @@ -779,14 +796,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) // reset render flags for possible loading screen TextRender()->SetRenderFlags(0); TextRender()->SetCurFont(NULL); - auto SkinStartLoadTime = time_get_nanoseconds(); - m_pClient->m_Skins.Refresh([&](int) { - // if skin refreshing takes to long, swap to a loading screen - if(time_get_nanoseconds() - SkinStartLoadTime > 500ms) - { - RenderLoading(Localize("Loading skin files"), "", 0, false); - } - }); + RefreshSkins(); s_InitSkinlist = true; if(Client()->State() >= IClient::STATE_ONLINE) { From 6e5c5cba8f0a37ead58e9971aacba0d2a2afd150 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Sat, 20 Aug 2022 14:39:25 +0200 Subject: [PATCH 2/3] Filter vanilla only skins at loading already --- src/game/client/components/menus_settings.cpp | 4 ---- src/game/client/components/skins.cpp | 5 +++-- src/game/client/skin.h | 2 -- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index e851fe179..aec4f9333 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -668,10 +668,6 @@ void CMenus::RenderSettingsTee(CUIRect MainView) if((pSkinToBeSelected->m_aName[0] == 'x' && pSkinToBeSelected->m_aName[1] == '_')) continue; - // vanilla skins only - if(g_Config.m_ClVanillaSkinsOnly && !pSkinToBeSelected->m_IsVanilla) - continue; - if(pSkinToBeSelected == 0) continue; diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp index 023019939..c9af05e10 100644 --- a/src/game/client/components/skins.cpp +++ b/src/game/client/components/skins.cpp @@ -65,6 +65,9 @@ int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser) str_copy(aNameWithoutPng, pName); aNameWithoutPng[str_length(aNameWithoutPng) - 4] = 0; + if(g_Config.m_ClVanillaSkinsOnly && !IsVanillaSkin(aNameWithoutPng)) + return 0; + // Don't add duplicate skins (one from user's config directory, other from // client itself) for(int i = 0; i < pSelf->Num(); i++) @@ -154,7 +157,6 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info) } CSkin Skin; - Skin.m_IsVanilla = IsVanillaSkin(pName); Skin.m_OriginalSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]); Skin.m_OriginalSkin.m_BodyOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY_OUTLINE]); Skin.m_OriginalSkin.m_Feet = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT]); @@ -355,7 +357,6 @@ void CSkins::Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc) { Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load skins. folder='skins/'"); CSkin DummySkin; - DummySkin.m_IsVanilla = true; str_copy(DummySkin.m_aName, "dummy"); DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f); m_vSkins.push_back(DummySkin); diff --git a/src/game/client/skin.h b/src/game/client/skin.h index a8dd188a6..e40341829 100644 --- a/src/game/client/skin.h +++ b/src/game/client/skin.h @@ -8,8 +8,6 @@ // do this better and nicer struct CSkin { - bool m_IsVanilla; - struct SSkinTextures { IGraphics::CTextureHandle m_Body; From 21fe945ca7ccc144e11c1a3869ae286ae81b701a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 20 Aug 2022 20:54:25 +0200 Subject: [PATCH 3/3] Make file link absolute, add `fs_is_relative_path` This fixes links not opening for relative paths, as links like `file://temp/skins` cannot be resolved by the shell. --- CMakeLists.txt | 2 +- src/base/system.cpp | 24 +++++++++++++++++++++++- src/base/system.h | 9 +++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8b11ba58..9ecc33c3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,7 +721,7 @@ endif() if(TARGET_OS STREQUAL "windows") set(PLATFORM_CLIENT) set(PLATFORM_CLIENT_LIBS opengl32 winmm) - set(PLATFORM_LIBS version ws2_32) # Windows sockets + set(PLATFORM_LIBS shlwapi version ws2_32) # Windows sockets elseif(TARGET_OS STREQUAL "mac") find_library(CARBON Carbon) find_library(COCOA Cocoa) diff --git a/src/base/system.cpp b/src/base/system.cpp index a7e94447b..331855ced 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include #else #error NOT IMPLEMENTED @@ -2309,6 +2310,17 @@ int fs_is_dir(const char *path) #endif } +int fs_is_relative_path(const char *path) +{ +#if defined(CONF_FAMILY_WINDOWS) + WCHAR wPath[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wPath, std::size(wPath)); + return PathIsRelativeW(wPath) ? 1 : 0; +#else + return path[0] == '/' ? 0 : 1; // yes, it's that simple +#endif +} + int fs_chdir(const char *path) { if(fs_is_dir(path)) @@ -3866,8 +3878,18 @@ int open_file(const char *path) #if defined(CONF_PLATFORM_MACOS) return open_link(path); #else + // Create a file link so the path can contain forward and + // backward slashes. But the file link must be absolute. char buf[512]; - str_format(buf, sizeof(buf), "file://%s", path); + char workingDir[IO_MAX_PATH_LENGTH]; + if(fs_is_relative_path(path)) + { + fs_getcwd(workingDir, sizeof(workingDir)); + str_append(workingDir, "/", sizeof(workingDir)); + } + else + workingDir[0] = '\0'; + str_format(buf, sizeof(buf), "file://%s%s", workingDir, path); return open_link(buf); #endif } diff --git a/src/base/system.h b/src/base/system.h index a20aac955..379a7b044 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1821,6 +1821,15 @@ int fs_storage_path(const char *appname, char *path, int max); */ int fs_is_dir(const char *path); +/* + Function: fs_is_relative_path + Checks whether a given path is relative or absolute. + + Returns: + Returns 1 if relative, 0 if absolute. +*/ +int fs_is_relative_path(const char *path); + /* Function: fs_chdir Changes current working directory