1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef GAME_CLIENT_COMPONENTS_SKINS_H |
4 | #define GAME_CLIENT_COMPONENTS_SKINS_H |
5 | |
6 | #include <base/system.h> |
7 | #include <engine/shared/http.h> |
8 | #include <game/client/component.h> |
9 | #include <game/client/skin.h> |
10 | #include <string_view> |
11 | #include <unordered_map> |
12 | |
13 | class CSkins : public CComponent |
14 | { |
15 | public: |
16 | CSkins(); |
17 | |
18 | class CGetPngFile : public CHttpRequest |
19 | { |
20 | CSkins *m_pSkins; |
21 | |
22 | protected: |
23 | virtual void OnCompletion(EHttpState State) override; |
24 | |
25 | public: |
26 | CGetPngFile(CSkins *pSkins, const char *pUrl, IStorage *pStorage, const char *pDest); |
27 | CImageInfo m_Info; |
28 | }; |
29 | |
30 | struct CDownloadSkin |
31 | { |
32 | private: |
33 | char m_aName[24]; |
34 | |
35 | public: |
36 | std::shared_ptr<CSkins::CGetPngFile> m_pTask; |
37 | char m_aPath[IO_MAX_PATH_LENGTH]; |
38 | |
39 | CDownloadSkin(CDownloadSkin &&Other) = default; |
40 | CDownloadSkin(const char *pName) |
41 | { |
42 | str_copy(dst&: m_aName, src: pName); |
43 | } |
44 | |
45 | ~CDownloadSkin() |
46 | { |
47 | if(m_pTask) |
48 | m_pTask->Abort(); |
49 | } |
50 | bool operator<(const CDownloadSkin &Other) const { return str_comp(a: m_aName, b: Other.m_aName) < 0; } |
51 | bool operator<(const char *pOther) const { return str_comp(a: m_aName, b: pOther) < 0; } |
52 | bool operator==(const char *pOther) const { return !str_comp(a: m_aName, b: pOther); } |
53 | |
54 | CDownloadSkin &operator=(CDownloadSkin &&Other) = default; |
55 | |
56 | const char *GetName() const { return m_aName; } |
57 | }; |
58 | |
59 | typedef std::function<void(int)> TSkinLoadedCBFunc; |
60 | |
61 | virtual int Sizeof() const override { return sizeof(*this); } |
62 | void OnInit() override; |
63 | |
64 | void Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc); |
65 | int Num(); |
66 | std::unordered_map<std::string_view, std::unique_ptr<CSkin>> &GetSkinsUnsafe() { return m_Skins; } |
67 | const CSkin *FindOrNullptr(const char *pName, bool IgnorePrefix = false); |
68 | const CSkin *Find(const char *pName); |
69 | |
70 | bool IsDownloadingSkins() { return m_DownloadingSkins; } |
71 | |
72 | static bool IsVanillaSkin(const char *pName); |
73 | |
74 | constexpr static const char *VANILLA_SKINS[] = {"bluekitty" , "bluestripe" , "brownbear" , |
75 | "cammo" , "cammostripes" , "coala" , "default" , "limekitty" , |
76 | "pinky" , "redbopp" , "redstripe" , "saddo" , "toptri" , |
77 | "twinbop" , "twintri" , "warpaint" , "x_ninja" , "x_spec" }; |
78 | |
79 | private: |
80 | std::unordered_map<std::string_view, std::unique_ptr<CSkin>> m_Skins; |
81 | std::unordered_map<std::string_view, std::unique_ptr<CDownloadSkin>> m_DownloadSkins; |
82 | CSkin m_PlaceholderSkin; |
83 | size_t m_DownloadingSkins = 0; |
84 | char m_aEventSkinPrefix[24]; |
85 | |
86 | bool LoadSkinPng(CImageInfo &Info, const char *pName, const char *pPath, int DirType); |
87 | const CSkin *LoadSkin(const char *pName, const char *pPath, int DirType); |
88 | const CSkin *LoadSkin(const char *pName, CImageInfo &Info); |
89 | const CSkin *FindImpl(const char *pName); |
90 | static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser); |
91 | }; |
92 | #endif |
93 | |