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")
|
||||
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)
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include <process.h>
|
||||
#include <share.h>
|
||||
#include <shellapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <wincrypt.h>
|
||||
#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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -103,6 +103,8 @@ class CMenus : public CComponent
|
|||
|
||||
void RenderColorPicker();
|
||||
|
||||
void RefreshSkins();
|
||||
|
||||
// new gui with gui elements
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -651,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;
|
||||
|
||||
|
@ -779,14 +792,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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
// do this better and nicer
|
||||
struct CSkin
|
||||
{
|
||||
bool m_IsVanilla;
|
||||
|
||||
struct SSkinTextures
|
||||
{
|
||||
IGraphics::CTextureHandle m_Body;
|
||||
|
|
Loading…
Reference in a new issue