mirror of
https://github.com/ddnet/ddnet.git
synced 2024-10-20 15:58:18 +00:00
6fc3470a8d
Favorite skin names were previously not escaped as intended when saving, as the variable `aNameEscaped` was unused so the original skin name was saved instead of the escaped one. Escaping is not really necessary, as skins should not contain `\` and `"` anyway and it was only possible to add such favorites through the console or config files. Instead of escaping the favorite skin names when saving, now favorite skin names are validated when they are added so no escaping is necessary. Skins names are considered valid when they have a length of 1-23 bytes and don't contain the characters `/`, `\` and `"`.
165 lines
3.2 KiB
C++
165 lines
3.2 KiB
C++
#ifndef GAME_CLIENT_SKIN_H
|
|
#define GAME_CLIENT_SKIN_H
|
|
#include <base/color.h>
|
|
#include <base/system.h>
|
|
#include <base/vmath.h>
|
|
#include <engine/graphics.h>
|
|
#include <limits>
|
|
|
|
// do this better and nicer
|
|
struct CSkin
|
|
{
|
|
private:
|
|
char m_aName[24];
|
|
|
|
public:
|
|
struct SSkinTextures
|
|
{
|
|
IGraphics::CTextureHandle m_Body;
|
|
IGraphics::CTextureHandle m_BodyOutline;
|
|
|
|
IGraphics::CTextureHandle m_Feet;
|
|
IGraphics::CTextureHandle m_FeetOutline;
|
|
|
|
IGraphics::CTextureHandle m_Hands;
|
|
IGraphics::CTextureHandle m_HandsOutline;
|
|
|
|
IGraphics::CTextureHandle m_aEyes[6];
|
|
|
|
void Reset()
|
|
{
|
|
m_Body = IGraphics::CTextureHandle();
|
|
m_BodyOutline = IGraphics::CTextureHandle();
|
|
m_Feet = IGraphics::CTextureHandle();
|
|
m_FeetOutline = IGraphics::CTextureHandle();
|
|
m_Hands = IGraphics::CTextureHandle();
|
|
m_HandsOutline = IGraphics::CTextureHandle();
|
|
for(auto &Eye : m_aEyes)
|
|
Eye = IGraphics::CTextureHandle();
|
|
}
|
|
};
|
|
|
|
SSkinTextures m_OriginalSkin;
|
|
SSkinTextures m_ColorableSkin;
|
|
ColorRGBA m_BloodColor;
|
|
|
|
template<bool IsSizeType>
|
|
struct SSkinMetricVariableInt
|
|
{
|
|
int m_Value;
|
|
operator int() const { return m_Value; }
|
|
SSkinMetricVariableInt &operator=(int NewVal)
|
|
{
|
|
if(IsSizeType)
|
|
m_Value = maximum(m_Value, NewVal);
|
|
else
|
|
m_Value = minimum(m_Value, NewVal);
|
|
return *this;
|
|
}
|
|
|
|
SSkinMetricVariableInt()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
if(IsSizeType)
|
|
m_Value = std::numeric_limits<int>::lowest();
|
|
else
|
|
m_Value = std::numeric_limits<int>::max();
|
|
}
|
|
};
|
|
|
|
struct SSkinMetricVariable
|
|
{
|
|
SSkinMetricVariableInt<true> m_Width;
|
|
SSkinMetricVariableInt<true> m_Height;
|
|
SSkinMetricVariableInt<false> m_OffsetX;
|
|
SSkinMetricVariableInt<false> m_OffsetY;
|
|
|
|
// these can be used to normalize the metrics
|
|
SSkinMetricVariableInt<true> m_MaxWidth;
|
|
SSkinMetricVariableInt<true> m_MaxHeight;
|
|
|
|
float WidthNormalized() const
|
|
{
|
|
return (float)m_Width / (float)m_MaxWidth;
|
|
}
|
|
|
|
float HeightNormalized() const
|
|
{
|
|
return (float)m_Height / (float)m_MaxHeight;
|
|
}
|
|
|
|
float OffsetXNormalized() const
|
|
{
|
|
return (float)m_OffsetX / (float)m_MaxWidth;
|
|
}
|
|
|
|
float OffsetYNormalized() const
|
|
{
|
|
return (float)m_OffsetY / (float)m_MaxHeight;
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
m_Width.Reset();
|
|
m_Height.Reset();
|
|
m_OffsetX.Reset();
|
|
m_OffsetY.Reset();
|
|
m_MaxWidth.Reset();
|
|
m_MaxHeight.Reset();
|
|
}
|
|
};
|
|
|
|
struct SSkinMetrics
|
|
{
|
|
SSkinMetricVariable m_Body;
|
|
SSkinMetricVariable m_Feet;
|
|
|
|
void Reset()
|
|
{
|
|
m_Body.Reset();
|
|
m_Feet.Reset();
|
|
}
|
|
|
|
SSkinMetrics()
|
|
{
|
|
Reset();
|
|
}
|
|
};
|
|
SSkinMetrics m_Metrics;
|
|
|
|
bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
|
|
bool operator==(const CSkin &Other) const { return !str_comp(m_aName, Other.m_aName); }
|
|
|
|
CSkin(const char *pName)
|
|
{
|
|
str_copy(m_aName, pName);
|
|
}
|
|
CSkin(CSkin &&) = default;
|
|
CSkin &operator=(CSkin &&) = default;
|
|
|
|
const char *GetName() const { return m_aName; }
|
|
|
|
static bool IsValidName(const char *pName)
|
|
{
|
|
if(pName[0] == '\0' || str_length(pName) >= (int)sizeof(CSkin("").m_aName))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for(int i = 0; pName[i] != '\0'; ++i)
|
|
{
|
|
if(pName[i] == '"' || pName[i] == '/' || pName[i] == '\\')
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
#endif
|