mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
5754: Auto refresh skins when changing related settings r=def- a=Jupeyy motivation: downloaded skins aren't resettet, e.g. if they failed before. config change -> resets everything ## Checklist - [x] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) 5757: Make file link absolute, add `fs_is_relative_path` r=def- a=Robyt3 This fixes links not opening for relative paths, as links like `file://temp/skins` cannot be resolved by the shell. Closes #5746. ## Checklist - [X] Tested the change ingame (only on Windows) - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test (especially base/) or added coverage to integration test - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: Jupeyy <jupjopjap@gmail.com> Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
commit
4fc6a5b924
|
@ -721,7 +721,7 @@ endif()
|
||||||
if(TARGET_OS STREQUAL "windows")
|
if(TARGET_OS STREQUAL "windows")
|
||||||
set(PLATFORM_CLIENT)
|
set(PLATFORM_CLIENT)
|
||||||
set(PLATFORM_CLIENT_LIBS opengl32 winmm)
|
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")
|
elseif(TARGET_OS STREQUAL "mac")
|
||||||
find_library(CARBON Carbon)
|
find_library(CARBON Carbon)
|
||||||
find_library(COCOA Cocoa)
|
find_library(COCOA Cocoa)
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <share.h>
|
#include <share.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#else
|
#else
|
||||||
#error NOT IMPLEMENTED
|
#error NOT IMPLEMENTED
|
||||||
|
@ -2309,6 +2310,17 @@ int fs_is_dir(const char *path)
|
||||||
#endif
|
#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)
|
int fs_chdir(const char *path)
|
||||||
{
|
{
|
||||||
if(fs_is_dir(path))
|
if(fs_is_dir(path))
|
||||||
|
@ -3866,8 +3878,18 @@ int open_file(const char *path)
|
||||||
#if defined(CONF_PLATFORM_MACOS)
|
#if defined(CONF_PLATFORM_MACOS)
|
||||||
return open_link(path);
|
return open_link(path);
|
||||||
#else
|
#else
|
||||||
|
// Create a file link so the path can contain forward and
|
||||||
|
// backward slashes. But the file link must be absolute.
|
||||||
char buf[512];
|
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);
|
return open_link(buf);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1821,6 +1821,15 @@ int fs_storage_path(const char *appname, char *path, int max);
|
||||||
*/
|
*/
|
||||||
int fs_is_dir(const char *path);
|
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
|
Function: fs_chdir
|
||||||
Changes current working directory
|
Changes current working directory
|
||||||
|
|
|
@ -103,6 +103,8 @@ class CMenus : public CComponent
|
||||||
|
|
||||||
void RenderColorPicker();
|
void RenderColorPicker();
|
||||||
|
|
||||||
|
void RefreshSkins();
|
||||||
|
|
||||||
// new gui with gui elements
|
// new gui with gui elements
|
||||||
template<typename T>
|
template<typename T>
|
||||||
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)
|
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)
|
||||||
|
|
|
@ -409,6 +409,18 @@ struct CUISkin
|
||||||
bool operator==(const char *pOther) const { return !str_comp_nocase(m_pSkin->m_aName, pOther); }
|
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)
|
void CMenus::RenderSettingsTee(CUIRect MainView)
|
||||||
{
|
{
|
||||||
CUIRect Button, Label, Dummy, DummyLabel, SkinList, QuickSearch, QuickSearchClearButton, SkinDB, SkinPrefix, SkinPrefixLabel, DirectoryButton, RefreshButton, Eyes, EyesLabel, EyesTee, EyesRight;
|
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))
|
if(DoButton_CheckBox(&g_Config.m_ClDownloadSkins, Localize("Download skins"), g_Config.m_ClDownloadSkins, &DummyLabel))
|
||||||
{
|
{
|
||||||
g_Config.m_ClDownloadSkins ^= 1;
|
g_Config.m_ClDownloadSkins ^= 1;
|
||||||
|
RefreshSkins();
|
||||||
|
s_InitSkinlist = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dummy.HSplitTop(20.0f, &DummyLabel, &Dummy);
|
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))
|
if(DoButton_CheckBox(&g_Config.m_ClDownloadCommunitySkins, Localize("Download community skins"), g_Config.m_ClDownloadCommunitySkins, &DummyLabel))
|
||||||
{
|
{
|
||||||
g_Config.m_ClDownloadCommunitySkins ^= 1;
|
g_Config.m_ClDownloadCommunitySkins ^= 1;
|
||||||
|
RefreshSkins();
|
||||||
|
s_InitSkinlist = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dummy.HSplitTop(20.0f, &DummyLabel, &Dummy);
|
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))
|
if(DoButton_CheckBox(&g_Config.m_ClVanillaSkinsOnly, Localize("Vanilla skins only"), g_Config.m_ClVanillaSkinsOnly, &DummyLabel))
|
||||||
{
|
{
|
||||||
g_Config.m_ClVanillaSkinsOnly ^= 1;
|
g_Config.m_ClVanillaSkinsOnly ^= 1;
|
||||||
|
RefreshSkins();
|
||||||
s_InitSkinlist = true;
|
s_InitSkinlist = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,10 +668,6 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
||||||
if((pSkinToBeSelected->m_aName[0] == 'x' && pSkinToBeSelected->m_aName[1] == '_'))
|
if((pSkinToBeSelected->m_aName[0] == 'x' && pSkinToBeSelected->m_aName[1] == '_'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// vanilla skins only
|
|
||||||
if(g_Config.m_ClVanillaSkinsOnly && !pSkinToBeSelected->m_IsVanilla)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(pSkinToBeSelected == 0)
|
if(pSkinToBeSelected == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -779,14 +792,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
||||||
// reset render flags for possible loading screen
|
// reset render flags for possible loading screen
|
||||||
TextRender()->SetRenderFlags(0);
|
TextRender()->SetRenderFlags(0);
|
||||||
TextRender()->SetCurFont(NULL);
|
TextRender()->SetCurFont(NULL);
|
||||||
auto SkinStartLoadTime = time_get_nanoseconds();
|
RefreshSkins();
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
s_InitSkinlist = true;
|
s_InitSkinlist = true;
|
||||||
if(Client()->State() >= IClient::STATE_ONLINE)
|
if(Client()->State() >= IClient::STATE_ONLINE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,6 +65,9 @@ int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
|
||||||
str_copy(aNameWithoutPng, pName);
|
str_copy(aNameWithoutPng, pName);
|
||||||
aNameWithoutPng[str_length(aNameWithoutPng) - 4] = 0;
|
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
|
// Don't add duplicate skins (one from user's config directory, other from
|
||||||
// client itself)
|
// client itself)
|
||||||
for(int i = 0; i < pSelf->Num(); i++)
|
for(int i = 0; i < pSelf->Num(); i++)
|
||||||
|
@ -154,7 +157,6 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSkin Skin;
|
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_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_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]);
|
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/'");
|
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load skins. folder='skins/'");
|
||||||
CSkin DummySkin;
|
CSkin DummySkin;
|
||||||
DummySkin.m_IsVanilla = true;
|
|
||||||
str_copy(DummySkin.m_aName, "dummy");
|
str_copy(DummySkin.m_aName, "dummy");
|
||||||
DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f);
|
DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f);
|
||||||
m_vSkins.push_back(DummySkin);
|
m_vSkins.push_back(DummySkin);
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// do this better and nicer
|
// do this better and nicer
|
||||||
struct CSkin
|
struct CSkin
|
||||||
{
|
{
|
||||||
bool m_IsVanilla;
|
|
||||||
|
|
||||||
struct SSkinTextures
|
struct SSkinTextures
|
||||||
{
|
{
|
||||||
IGraphics::CTextureHandle m_Body;
|
IGraphics::CTextureHandle m_Body;
|
||||||
|
|
Loading…
Reference in a new issue