diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 6bc28b2b8..e1ec2f06e 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -1345,8 +1345,6 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket) int Type = -1; if(mem_comp(pPacket->m_pData, SERVERBROWSE_INFO, sizeof(SERVERBROWSE_INFO)) == 0) Type = SERVERINFO_VANILLA; - else if(mem_comp(pPacket->m_pData, SERVERBROWSE_INFO_64_LEGACY, sizeof(SERVERBROWSE_INFO_64_LEGACY)) == 0) - Type = SERVERINFO_64_LEGACY; else if(mem_comp(pPacket->m_pData, SERVERBROWSE_INFO_EXTENDED, sizeof(SERVERBROWSE_INFO_EXTENDED)) == 0) Type = SERVERINFO_EXTENDED; else if(mem_comp(pPacket->m_pData, SERVERBROWSE_INFO_EXTENDED_MORE, sizeof(SERVERBROWSE_INFO_EXTENDED_MORE)) == 0) @@ -1375,8 +1373,7 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData, CServerInfo Info = {0}; int SavedType = SavedServerInfoType(RawType); - if((SavedType == SERVERINFO_64_LEGACY || SavedType == SERVERINFO_EXTENDED) && - pEntry && pEntry->m_GotInfo && SavedType == pEntry->m_Info.m_Type) + if(SavedType == SERVERINFO_EXTENDED && pEntry && pEntry->m_GotInfo && SavedType == pEntry->m_Info.m_Type) { Info = pEntry->m_Info; } @@ -1391,7 +1388,6 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData, #define GET_STRING(array) str_copy(array, Up.GetString(CUnpacker::SANITIZE_CC | CUnpacker::SKIP_START_WHITESPACES), sizeof(array)) #define GET_INT(integer) (integer) = str_toint(Up.GetString()) - int Offset = 0; // Only used for SavedType == SERVERINFO_64_LEGACY int Token; int PacketNo = 0; // Only used if SavedType == SERVERINFO_EXTENDED @@ -1449,13 +1445,6 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData, dbg_assert(false, "unknown serverinfo type"); } - if(SavedType == SERVERINFO_64_LEGACY) - Offset = Up.GetInt(); - - // Check for valid offset. - if(Offset < 0) - return; - if(SavedType == SERVERINFO_EXTENDED) PacketNo = 0; } @@ -1478,7 +1467,7 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData, } bool IgnoreError = false; - for(int i = Offset; i < MAX_CLIENTS && Info.m_NumReceivedClients < MAX_CLIENTS && !Up.Error(); i++) + for(int i = 0; i < MAX_CLIENTS && Info.m_NumReceivedClients < MAX_CLIENTS && !Up.Error(); i++) { CServerInfo::CClient *pClient = &Info.m_aClients[Info.m_NumReceivedClients]; GET_STRING(pClient->m_aName); @@ -1572,15 +1561,6 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData, #undef GET_INT } -bool CClient::ShouldSendChatTimeoutCodeHeuristic() -{ - if(m_ServerSentCapabilities) - { - return false; - } - return IsDDNet(&m_CurrentServerInfo); -} - static CServerCapabilities GetServerCapabilities(int Version, int Flags) { CServerCapabilities Result; @@ -2167,7 +2147,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy) if(m_aReceivedSnapshots[Conn] > 50 && !m_aCodeRunAfterJoin[Conn]) { - if(m_ServerCapabilities.m_ChatTimeoutCode || ShouldSendChatTimeoutCodeHeuristic()) + if(m_ServerCapabilities.m_ChatTimeoutCode) { CNetMsg_Cl_Say MsgP; MsgP.m_Team = 0; diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 2f79ca3d6..d327f7c5d 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -251,8 +251,6 @@ class CClient : public IClient, public CDemoPlayer::IListener bool m_ServerSentCapabilities; CServerCapabilities m_ServerCapabilities; - bool ShouldSendChatTimeoutCodeHeuristic(); - CServerInfo m_CurrentServerInfo; int64_t m_CurrentServerInfoRequestTime; // >= 0 should request, == -1 got info diff --git a/src/engine/client/serverbrowser.cpp b/src/engine/client/serverbrowser.cpp index f5046c293..aadff40dd 100644 --- a/src/engine/client/serverbrowser.cpp +++ b/src/engine/client/serverbrowser.cpp @@ -720,12 +720,6 @@ void CServerBrowser::OnServerInfoUpdate(const NETADDR &Addr, int Token, const CS { SetInfo(pEntry, *pInfo); pEntry->m_Info.m_Latency = minimum(static_cast((time_get() - m_BroadcastTime) * 1000 / time_freq()), 999); - if(pInfo->m_Type == SERVERINFO_VANILLA && Is64Player(pInfo)) - { - pEntry->m_Request64Legacy = true; - // Force a quick update. - RequestImpl64(Addr, pEntry); - } } else if(pEntry->m_RequestTime > 0) { @@ -747,16 +741,6 @@ void CServerBrowser::OnServerInfoUpdate(const NETADDR &Addr, int Token, const CS SetLatency(Addr, Latency); } pEntry->m_RequestTime = -1; // Request has been answered - - if(!pEntry->m_RequestIgnoreInfo) - { - if(pInfo->m_Type == SERVERINFO_VANILLA && Is64Player(pInfo)) - { - pEntry->m_Request64Legacy = true; - // Force a quick update. - RequestImpl64(Addr, pEntry); - } - } } RemoveRequest(pEntry); @@ -872,35 +856,6 @@ void CServerBrowser::RequestImpl(const NETADDR &Addr, CServerEntry *pEntry, int pEntry->m_RequestTime = time_get(); } -void CServerBrowser::RequestImpl64(const NETADDR &Addr, CServerEntry *pEntry) const -{ - unsigned char aBuffer[sizeof(SERVERBROWSE_GETINFO_64_LEGACY) + 1]; - CNetChunk Packet; - - if(g_Config.m_Debug) - { - char aAddrStr[NETADDR_MAXSTRSIZE]; - net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr), true); - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "requesting server info 64 from %s", aAddrStr); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client_srvbrowse", aBuf); - } - - mem_copy(aBuffer, SERVERBROWSE_GETINFO_64_LEGACY, sizeof(SERVERBROWSE_GETINFO_64_LEGACY)); - aBuffer[sizeof(SERVERBROWSE_GETINFO_64_LEGACY)] = GetBasicToken(GenerateToken(Addr)); - - Packet.m_ClientID = -1; - Packet.m_Address = Addr; - Packet.m_Flags = NETSENDFLAG_CONNLESS; - Packet.m_DataSize = sizeof(aBuffer); - Packet.m_pData = aBuffer; - - m_pNetClient->Send(&Packet); - - if(pEntry) - pEntry->m_RequestTime = time_get(); -} - void CServerBrowser::RequestCurrentServer(const NETADDR &Addr) const { RequestImpl(Addr, nullptr, nullptr, nullptr, false); @@ -1123,10 +1078,7 @@ void CServerBrowser::Update(bool ForceResort) if(pEntry->m_RequestTime == 0) { - if(pEntry->m_Request64Legacy) - RequestImpl64(pEntry->m_Info.m_aAddresses[0], pEntry); - else - RequestImpl(pEntry->m_Info.m_aAddresses[0], pEntry, nullptr, nullptr, false); + RequestImpl(pEntry->m_Info.m_aAddresses[0], pEntry, nullptr, nullptr, false); } Count++; @@ -1563,71 +1515,3 @@ bool CServerInfo::ParseLocation(int *pResult, const char *pString) } return true; } - -bool IsVanilla(const CServerInfo *pInfo) -{ - return !str_comp(pInfo->m_aGameType, "DM") || !str_comp(pInfo->m_aGameType, "TDM") || !str_comp(pInfo->m_aGameType, "CTF"); -} - -bool IsCatch(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "catch"); -} - -bool IsInsta(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "idm") || str_find_nocase(pInfo->m_aGameType, "itdm") || str_find_nocase(pInfo->m_aGameType, "ictf"); -} - -bool IsFNG(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "fng"); -} - -bool IsRace(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "race") || str_find_nocase(pInfo->m_aGameType, "fastcap"); -} - -bool IsFastCap(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "fastcap"); -} - -bool IsBlockInfectionZ(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "blockz") || - str_find_nocase(pInfo->m_aGameType, "infectionz"); -} - -bool IsBlockWorlds(const CServerInfo *pInfo) -{ - return (str_startswith(pInfo->m_aGameType, "bw ")) || (str_comp_nocase(pInfo->m_aGameType, "bw") == 0); -} - -bool IsCity(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "city"); -} - -bool IsDDRace(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "ddrace") || str_find_nocase(pInfo->m_aGameType, "mkrace"); -} - -bool IsDDNet(const CServerInfo *pInfo) -{ - return str_find_nocase(pInfo->m_aGameType, "ddracenet") || str_find_nocase(pInfo->m_aGameType, "ddnet"); -} - -// other - -bool Is64Player(const CServerInfo *pInfo) -{ - return str_find(pInfo->m_aGameType, "64") || str_find(pInfo->m_aName, "64") || IsDDNet(pInfo); -} - -bool IsPlus(const CServerInfo *pInfo) -{ - return str_find(pInfo->m_aGameType, "+"); -} diff --git a/src/engine/client/serverbrowser.h b/src/engine/client/serverbrowser.h index ac617c5f6..a21d34474 100644 --- a/src/engine/client/serverbrowser.h +++ b/src/engine/client/serverbrowser.h @@ -32,7 +32,6 @@ public: int64_t m_RequestTime; bool m_RequestIgnoreInfo; int m_GotInfo; - bool m_Request64Legacy; CServerInfo m_Info; CServerEntry *m_pPrevReq; // request list @@ -131,7 +130,6 @@ public: void SetBaseInfo(class CNetClient *pClient, const char *pNetVersion); void OnInit(); - void RequestImpl64(const NETADDR &Addr, CServerEntry *pEntry) const; void QueueRequest(CServerEntry *pEntry); CServerEntry *Find(const NETADDR &Addr); int GetCurrentType() override { return m_ServerlistType; } diff --git a/src/engine/serverbrowser.h b/src/engine/serverbrowser.h index c11a4b110..1e9032036 100644 --- a/src/engine/serverbrowser.h +++ b/src/engine/serverbrowser.h @@ -85,20 +85,6 @@ public: static bool ParseLocation(int *pResult, const char *pString); }; -bool IsVanilla(const CServerInfo *pInfo); -bool IsCatch(const CServerInfo *pInfo); -bool IsInsta(const CServerInfo *pInfo); -bool IsFNG(const CServerInfo *pInfo); -bool IsRace(const CServerInfo *pInfo); -bool IsFastCap(const CServerInfo *pInfo); -bool IsDDRace(const CServerInfo *pInfo); -bool IsDDNet(const CServerInfo *pInfo); -bool IsBlockWorlds(const CServerInfo *pInfo); -bool IsCity(const CServerInfo *pInfo); - -bool Is64Player(const CServerInfo *pInfo); -bool IsPlus(const CServerInfo *pInfo); - class IServerBrowser : public IInterface { MACRO_INTERFACE("serverbrowser", 0) diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 36607f960..6fe27b422 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -928,7 +928,7 @@ void CChat::RefindSkins() { if(Line.m_HasRenderTee) { - const CSkin *pSkin = m_pClient->m_Skins.Get(m_pClient->m_Skins.Find(Line.m_aSkinName)); + const CSkin *pSkin = m_pClient->m_Skins.Find(Line.m_aSkinName); if(Line.m_CustomColoredSkin) Line.m_RenderSkin = pSkin->m_ColorableSkin; else diff --git a/src/game/client/components/ghost.cpp b/src/game/client/components/ghost.cpp index 5be45edca..aefb66e1f 100644 --- a/src/game/client/components/ghost.cpp +++ b/src/game/client/components/ghost.cpp @@ -352,15 +352,14 @@ void CGhost::OnRender() if(Player.m_Weapon == WEAPON_NINJA && g_Config.m_ClShowNinja) { // change the skin for the ghost to the ninja - int Skin = m_pClient->m_Skins.Find("x_ninja"); - if(Skin != -1) + const auto *pSkin = m_pClient->m_Skins.FindOrNullptr("x_ninja"); + if(pSkin != nullptr) { bool IsTeamplay = false; if(m_pClient->m_Snap.m_pGameInfoObj) IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) != 0; GhostNinjaRenderInfo = Ghost.m_RenderInfo; - const CSkin *pSkin = m_pClient->m_Skins.Get(Skin); GhostNinjaRenderInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin; GhostNinjaRenderInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin; GhostNinjaRenderInfo.m_BloodColor = pSkin->m_BloodColor; @@ -387,8 +386,7 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost) IntsToStr(&pGhost->m_Skin.m_Skin0, 6, aSkinName); CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo; - int SkinId = m_pClient->m_Skins.Find(aSkinName); - const CSkin *pSkin = m_pClient->m_Skins.Get(SkinId); + const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName); pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin; pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin; pRenderInfo->m_BloodColor = pSkin->m_BloodColor; @@ -679,8 +677,7 @@ void CGhost::RefindSkin() { CTeeRenderInfo *pRenderInfo = &Ghost.m_RenderInfo; - int SkinId = m_pClient->m_Skins.Find(aSkinName); - const CSkin *pSkin = m_pClient->m_Skins.Get(SkinId); + const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName); pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin; pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin; pRenderInfo->m_SkinMetrics = pSkin->m_Metrics; @@ -691,8 +688,7 @@ void CGhost::RefindSkin() { CTeeRenderInfo *pRenderInfo = &m_CurGhost.m_RenderInfo; - int SkinId = m_pClient->m_Skins.Find(aSkinName); - const CSkin *pSkin = m_pClient->m_Skins.Get(SkinId); + const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName); pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin; pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin; pRenderInfo->m_SkinMetrics = pSkin->m_Metrics; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index d27868253..6fec08c97 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -464,19 +464,19 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) { ColorHSLA hsl = ColorHSLA(1.0f, 1.0f, 1.0f); - if(IsVanilla(pItem)) + if(str_comp(pItem->m_aGameType, "DM") == 0 || str_comp(pItem->m_aGameType, "TDM") == 0 || str_comp(pItem->m_aGameType, "CTF") == 0) hsl = ColorHSLA(0.33f, 1.0f, 0.75f); - else if(IsCatch(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "catch")) hsl = ColorHSLA(0.17f, 1.0f, 0.75f); - else if(IsInsta(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "idm") || str_find_nocase(pItem->m_aGameType, "itdm") || str_find_nocase(pItem->m_aGameType, "ictf")) hsl = ColorHSLA(0.00f, 1.0f, 0.75f); - else if(IsFNG(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "fng")) hsl = ColorHSLA(0.83f, 1.0f, 0.75f); - else if(IsDDNet(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "ddracenet") || str_find_nocase(pItem->m_aGameType, "ddnet")) hsl = ColorHSLA(0.58f, 1.0f, 0.75f); - else if(IsDDRace(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "ddrace") || str_find_nocase(pItem->m_aGameType, "mkrace")) hsl = ColorHSLA(0.75f, 1.0f, 0.75f); - else if(IsRace(pItem)) + else if(str_find_nocase(pItem->m_aGameType, "race") || str_find_nocase(pItem->m_aGameType, "fastcap")) hsl = ColorHSLA(0.46f, 1.0f, 0.75f); ColorRGBA rgb = color_cast(hsl); @@ -1167,7 +1167,7 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) if(!pSelectedServer->m_aClients[i].m_Player) str_copy(aTemp, "SPEC"); - else if(IsRace(pSelectedServer) && g_Config.m_ClDDRaceScoreBoard) + else if((str_find_nocase(pSelectedServer->m_aGameType, "race") || str_find_nocase(pSelectedServer->m_aGameType, "fastcap")) && g_Config.m_ClDDRaceScoreBoard) { if(pSelectedServer->m_aClients[i].m_Score == -9999 || pSelectedServer->m_aClients[i].m_Score == 0) aTemp[0] = 0; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 044b817ac..e5275ca62 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -404,10 +405,10 @@ struct CUISkin CUISkin(const CSkin *pSkin) : m_pSkin(pSkin) {} - bool operator<(const CUISkin &Other) const { return str_comp_nocase(m_pSkin->m_aName, Other.m_pSkin->m_aName) < 0; } + bool operator<(const CUISkin &Other) const { return str_comp_nocase(m_pSkin->GetName(), Other.m_pSkin->GetName()) < 0; } - bool operator<(const char *pOther) const { return str_comp_nocase(m_pSkin->m_aName, pOther) < 0; } - 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->GetName(), pOther) < 0; } + bool operator==(const char *pOther) const { return !str_comp_nocase(m_pSkin->GetName(), pOther); } }; void CMenus::RefreshSkins() @@ -571,7 +572,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) // which invalidates the skin // skin info CTeeRenderInfo OwnSkinInfo; - const CSkin *pSkin = m_pClient->m_Skins.Get(m_pClient->m_Skins.Find(pSkinName)); + const CSkin *pSkin = m_pClient->m_Skins.Find(pSkinName); OwnSkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin; OwnSkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin; OwnSkinInfo.m_SkinMetrics = pSkin->m_Metrics; @@ -718,15 +719,14 @@ void CMenus::RenderSettingsTee(CUIRect MainView) // a downloading skin s_SkinCount = m_pClient->m_Skins.Num(); m_SkinFavoritesChanged = false; - bool RequiresRebuild = false; auto &&SkinNotFiltered = [&](const CSkin *pSkinToBeSelected) { // filter quick search - if(g_Config.m_ClSkinFilterString[0] != '\0' && !str_utf8_find_nocase(pSkinToBeSelected->m_aName, g_Config.m_ClSkinFilterString)) + if(g_Config.m_ClSkinFilterString[0] != '\0' && !str_utf8_find_nocase(pSkinToBeSelected->GetName(), g_Config.m_ClSkinFilterString)) return false; // no special skins - if((pSkinToBeSelected->m_aName[0] == 'x' && pSkinToBeSelected->m_aName[1] == '_')) + if((pSkinToBeSelected->GetName()[0] == 'x' && pSkinToBeSelected->GetName()[1] == '_')) return false; if(pSkinToBeSelected == 0) @@ -737,38 +737,27 @@ void CMenus::RenderSettingsTee(CUIRect MainView) for(const auto &it : m_SkinFavorites) { - const auto FirstSkinIndex = m_pClient->m_Skins.Find(it.c_str()); - // second call is intended, our implemention doesnt return the index in the call where the download finished - const auto SkinIndex = m_pClient->m_Skins.Find(it.c_str()); - if(SkinIndex == -1) - continue; - if(FirstSkinIndex == -1 && SkinIndex != -1) - { - // skin list changed, rebuild next frame - RequiresRebuild = true; - } - const CSkin *pSkinToBeSelected = m_pClient->m_Skins.Get(SkinIndex); + const CSkin *pSkinToBeSelected = m_pClient->m_Skins.FindOrNullptr(it.c_str()); - if(!SkinNotFiltered(pSkinToBeSelected)) + if(pSkinToBeSelected == nullptr || !SkinNotFiltered(pSkinToBeSelected)) continue; s_vFavoriteSkinListHelper.emplace_back(pSkinToBeSelected); } - for(int i = 0; i < m_pClient->m_Skins.Num(); ++i) + for(const auto &SkinIt : m_pClient->m_Skins.GetSkinsUnsafe()) { - const CSkin *pSkinToBeSelected = m_pClient->m_Skins.Get(i); - - if(!SkinNotFiltered(pSkinToBeSelected)) + const auto &pSkinToBeSelected = SkinIt.second; + if(!SkinNotFiltered(pSkinToBeSelected.get())) continue; - if(std::find(m_SkinFavorites.begin(), m_SkinFavorites.end(), pSkinToBeSelected->m_aName) == m_SkinFavorites.end()) - s_vSkinListHelper.emplace_back(pSkinToBeSelected); + if(std::find(m_SkinFavorites.begin(), m_SkinFavorites.end(), pSkinToBeSelected->GetName()) == m_SkinFavorites.end()) + s_vSkinListHelper.emplace_back(pSkinToBeSelected.get()); } std::sort(s_vSkinListHelper.begin(), s_vSkinListHelper.end()); std::sort(s_vFavoriteSkinListHelper.begin(), s_vFavoriteSkinListHelper.end()); s_vSkinList = s_vFavoriteSkinListHelper; s_vSkinList.insert(s_vSkinList.end(), s_vSkinListHelper.begin(), s_vSkinListHelper.end()); - s_InitSkinlist = RequiresRebuild; + s_InitSkinlist = false; } auto &&RenderFavIcon = [&](const CUIRect &FavIcon, bool AsFav) { @@ -793,7 +782,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) { const CSkin *pSkinToBeDraw = s_vSkinList[i].m_pSkin; - if(str_comp(pSkinToBeDraw->m_aName, pSkinName) == 0) + if(str_comp(pSkinToBeDraw->GetName(), pSkinName) == 0) OldSelected = i; CListboxItem Item = UiDoListboxNextItem(pSkinToBeDraw, OldSelected >= 0 && (size_t)OldSelected == i); @@ -816,7 +805,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) { SLabelProperties Props; Props.m_MaxWidth = Item.m_Rect.w; - UI()->DoLabel(&Item.m_Rect, pSkinToBeDraw->m_aName, 12.0f, TEXTALIGN_LEFT, Props); + UI()->DoLabel(&Item.m_Rect, pSkinToBeDraw->GetName(), 12.0f, TEXTALIGN_LEFT, Props); } if(g_Config.m_Debug) { @@ -831,7 +820,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) // render skin favorite icon { - const auto SkinItFav = m_SkinFavorites.find(pSkinToBeDraw->m_aName); + const auto SkinItFav = m_SkinFavorites.find(pSkinToBeDraw->GetName()); const auto IsFav = SkinItFav != m_SkinFavorites.end(); CUIRect FavIcon; OriginalRect.HSplitTop(20.0f, &FavIcon, nullptr); @@ -847,7 +836,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) RenderFavIcon(FavIcon, IsFav); } } - if(UI()->DoButtonLogic(pSkinToBeDraw->m_aName, 0, &FavIcon)) + if(UI()->DoButtonLogic(pSkinToBeDraw->GetName(), 0, &FavIcon)) { if(IsFav) { @@ -855,7 +844,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) } else { - m_SkinFavorites.emplace(pSkinToBeDraw->m_aName); + m_SkinFavorites.emplace(pSkinToBeDraw->GetName()); } s_InitSkinlist = true; } @@ -866,7 +855,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { - mem_copy(pSkinName, s_vSkinList[NewSelected].m_pSkin->m_aName, sizeof(g_Config.m_ClPlayerSkin)); + mem_copy(pSkinName, s_vSkinList[NewSelected].m_pSkin->GetName(), sizeof(g_Config.m_ClPlayerSkin)); SetNeedSendInfo(); } @@ -2900,7 +2889,7 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView) // Load skins - int DefaultInd = GameClient()->m_Skins.Find("default"); + const auto *pDefaultSkin = GameClient()->m_Skins.Find("default"); for(auto &Info : aRenderInfo) { @@ -2908,13 +2897,13 @@ void CMenus::RenderSettingsAppearance(CUIRect MainView) Info.m_CustomColoredSkin = false; } - int ind = -1; + const CSkin *pSkin = nullptr; int pos = 0; - aRenderInfo[pos++].m_OriginalRenderSkin = GameClient()->m_Skins.Get(DefaultInd)->m_OriginalSkin; - aRenderInfo[pos++].m_OriginalRenderSkin = (ind = GameClient()->m_Skins.Find("pinky")) != -1 ? GameClient()->m_Skins.Get(ind)->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; - aRenderInfo[pos++].m_OriginalRenderSkin = (ind = GameClient()->m_Skins.Find("cammostripes")) != -1 ? GameClient()->m_Skins.Get(ind)->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; - aRenderInfo[pos++].m_OriginalRenderSkin = (ind = GameClient()->m_Skins.Find("beast")) != -1 ? GameClient()->m_Skins.Get(ind)->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; + aRenderInfo[pos++].m_OriginalRenderSkin = pDefaultSkin->m_OriginalSkin; + aRenderInfo[pos++].m_OriginalRenderSkin = (pSkin = GameClient()->m_Skins.FindOrNullptr("pinky")) != nullptr ? pSkin->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; + aRenderInfo[pos++].m_OriginalRenderSkin = (pSkin = GameClient()->m_Skins.FindOrNullptr("cammostripes")) != nullptr ? pSkin->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; + aRenderInfo[pos++].m_OriginalRenderSkin = (pSkin = GameClient()->m_Skins.FindOrNullptr("beast")) != nullptr ? pSkin->m_OriginalSkin : aRenderInfo[0].m_OriginalRenderSkin; } // System diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 5c7664695..ed875dc73 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -769,10 +769,9 @@ void CPlayers::OnRender() if((CharacterInfo.m_Cur.m_Weapon == WEAPON_NINJA || (CharacterInfo.m_HasExtendedData && CharacterInfo.m_ExtendedData.m_FreezeEnd != 0)) && g_Config.m_ClShowNinja) { // change the skin for the player to the ninja - int Skin = m_pClient->m_Skins.Find("x_ninja"); - if(Skin != -1) + const auto *pSkin = m_pClient->m_Skins.FindOrNullptr("x_ninja"); + if(pSkin != nullptr) { - const CSkin *pSkin = m_pClient->m_Skins.Get(Skin); m_aRenderInfo[i].m_OriginalRenderSkin = pSkin->m_OriginalSkin; m_aRenderInfo[i].m_ColorableRenderSkin = pSkin->m_ColorableSkin; m_aRenderInfo[i].m_BloodColor = pSkin->m_BloodColor; @@ -786,8 +785,7 @@ void CPlayers::OnRender() } } } - int Skin = m_pClient->m_Skins.Find("x_spec"); - const CSkin *pSkin = m_pClient->m_Skins.Get(Skin); + const CSkin *pSkin = m_pClient->m_Skins.Find("x_spec"); m_RenderInfoSpec.m_OriginalRenderSkin = pSkin->m_OriginalSkin; m_RenderInfoSpec.m_ColorableRenderSkin = pSkin->m_ColorableSkin; m_RenderInfoSpec.m_BloodColor = pSkin->m_BloodColor; diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp index d759410a8..2938e8402 100644 --- a/src/game/client/components/skins.cpp +++ b/src/game/client/components/skins.cpp @@ -70,18 +70,14 @@ int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser) // Don't add duplicate skins (one from user's config directory, other from // client itself) - for(int i = 0; i < pSelf->Num(); i++) - { - const char *pExName = pSelf->Get(i)->m_aName; - if(str_comp(pExName, aNameWithoutPng) == 0) - return 0; - } + if(pSelf->m_Skins.find(aNameWithoutPng) != pSelf->m_Skins.end()) + return 0; char aBuf[IO_MAX_PATH_LENGTH]; str_format(aBuf, sizeof(aBuf), "skins/%s", pName); - auto SkinID = pSelf->LoadSkin(aNameWithoutPng, aBuf, DirType); - pUserReal->m_SkinLoadedFunc(SkinID); - return SkinID; + pSelf->LoadSkin(aNameWithoutPng, aBuf, DirType); + pUserReal->m_SkinLoadedFunc((int)pSelf->m_Skins.size()); + return 0; } static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int ImgWidth, int ImgX, int ImgY, int CheckWidth, int CheckHeight) @@ -119,7 +115,7 @@ static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int Metrics.m_MaxHeight = CheckHeight; } -int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType) +const CSkin *CSkins::LoadSkin(const char *pName, const char *pPath, int DirType) { CImageInfo Info; if(!LoadSkinPNG(Info, pName, pPath, DirType)) @@ -139,7 +135,7 @@ bool CSkins::LoadSkinPNG(CImageInfo &Info, const char *pName, const char *pPath, return true; } -int CSkins::LoadSkin(const char *pName, CImageInfo &Info) +const CSkin *CSkins::LoadSkin(const char *pName, CImageInfo &Info) { char aBuf[512]; @@ -147,16 +143,16 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info) { str_format(aBuf, sizeof(aBuf), "skin failed image divisibility: %s", pName); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); - return 0; + return nullptr; } if(!Graphics()->IsImageFormatRGBA(pName, Info)) { str_format(aBuf, sizeof(aBuf), "skin format is not RGBA: %s", pName); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); - return 0; + return nullptr; } - CSkin Skin; + CSkin Skin{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]); @@ -194,7 +190,7 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info) int BodyWidth = g_pData->m_aSprites[SPRITE_TEE_BODY].m_W * (Info.m_Width / g_pData->m_aSprites[SPRITE_TEE_BODY].m_pSet->m_Gridx); // body width int BodyHeight = g_pData->m_aSprites[SPRITE_TEE_BODY].m_H * (Info.m_Height / g_pData->m_aSprites[SPRITE_TEE_BODY].m_pSet->m_Gridy); // body height if(BodyWidth > Info.m_Width || BodyHeight > Info.m_Height) - return 0; + return nullptr; unsigned char *pData = (unsigned char *)Info.m_pData; const int PixelStep = 4; int Pitch = Info.m_Width * PixelStep; @@ -290,16 +286,16 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info) Graphics()->FreePNG(&Info); // set skin data - str_copy(Skin.m_aName, pName); if(g_Config.m_Debug) { - str_format(aBuf, sizeof(aBuf), "load skin %s", Skin.m_aName); + str_format(aBuf, sizeof(aBuf), "load skin %s", Skin.GetName()); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); } - m_vSkins.insert(std::lower_bound(m_vSkins.begin(), m_vSkins.end(), Skin), Skin); + auto &&pSkin = std::make_unique(std::move(Skin)); + const auto SkinInsertIt = m_Skins.insert({pSkin->GetName(), std::move(pSkin)}); - return 0; + return SkinInsertIt.first->second.get(); } void CSkins::OnInit() @@ -319,132 +315,132 @@ void CSkins::OnInit() } // load skins; - Refresh([this](int SkinID) { + Refresh([this](int SkinCounter) { GameClient()->m_Menus.RenderLoading(Localize("Loading DDNet Client"), Localize("Loading skin files"), 0); }); } void CSkins::Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc) { - for(auto &Skin : m_vSkins) + for(const auto &SkinIt : m_Skins) { - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Body); - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_BodyOutline); - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Feet); - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_FeetOutline); - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Hands); - Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_HandsOutline); - for(auto &Eye : Skin.m_OriginalSkin.m_aEyes) + const auto &pSkin = SkinIt.second; + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Body); + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_BodyOutline); + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Feet); + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_FeetOutline); + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_Hands); + Graphics()->UnloadTexture(&pSkin->m_OriginalSkin.m_HandsOutline); + for(auto &Eye : pSkin->m_OriginalSkin.m_aEyes) Graphics()->UnloadTexture(&Eye); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Body); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_BodyOutline); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Feet); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_FeetOutline); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Hands); - Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_HandsOutline); - for(auto &Eye : Skin.m_ColorableSkin.m_aEyes) + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Body); + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_BodyOutline); + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Feet); + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_FeetOutline); + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_Hands); + Graphics()->UnloadTexture(&pSkin->m_ColorableSkin.m_HandsOutline); + for(auto &Eye : pSkin->m_ColorableSkin.m_aEyes) Graphics()->UnloadTexture(&Eye); } - m_vSkins.clear(); - m_vDownloadSkins.clear(); + m_Skins.clear(); + m_DownloadSkins.clear(); m_DownloadingSkins = 0; SSkinScanUser SkinScanUser; SkinScanUser.m_pThis = this; SkinScanUser.m_SkinLoadedFunc = SkinLoadedFunc; Storage()->ListDirectory(IStorage::TYPE_ALL, "skins", SkinScan, &SkinScanUser); - if(m_vSkins.empty()) + if(m_Skins.empty()) { Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load skins. folder='skins/'"); - CSkin DummySkin; - str_copy(DummySkin.m_aName, "dummy"); + CSkin DummySkin{"dummy"}; DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f); - m_vSkins.push_back(DummySkin); + auto &&pDummySkin = std::make_unique(std::move(DummySkin)); + m_Skins.insert({pDummySkin->GetName(), std::move(pDummySkin)}); } } int CSkins::Num() { - return m_vSkins.size(); + return m_Skins.size(); } -const CSkin *CSkins::Get(int Index) +const CSkin *CSkins::Find(const char *pName) { - if(Index < 0) + const auto *pSkin = FindOrNullptr(pName); + if(pSkin == nullptr) { - Index = Find("default"); - - if(Index < 0) - Index = 0; + pSkin = FindOrNullptr("default"); + if(pSkin == nullptr) + return m_Skins.begin()->second.get(); + else + return pSkin; + } + else + { + return pSkin; } - return &m_vSkins[Index % m_vSkins.size()]; } -int CSkins::Find(const char *pName) +const CSkin *CSkins::FindOrNullptr(const char *pName) { const char *pSkinPrefix = m_aEventSkinPrefix[0] ? m_aEventSkinPrefix : g_Config.m_ClSkinPrefix; if(g_Config.m_ClVanillaSkinsOnly && !IsVanillaSkin(pName)) { - return -1; + return nullptr; } else if(pSkinPrefix && pSkinPrefix[0]) { char aBuf[24]; str_format(aBuf, sizeof(aBuf), "%s_%s", pSkinPrefix, pName); // If we find something, use it, otherwise fall back to normal skins. - int Result = FindImpl(aBuf); - if(Result != -1) + const auto *pResult = FindImpl(aBuf); + if(pResult != nullptr) { - return Result; + return pResult; } } return FindImpl(pName); } -int CSkins::FindImpl(const char *pName) +const CSkin *CSkins::FindImpl(const char *pName) { - CSkin Needle; - mem_zero(&Needle, sizeof(Needle)); - str_copy(Needle.m_aName, pName); - auto Range = std::equal_range(m_vSkins.begin(), m_vSkins.end(), Needle); - if(std::distance(Range.first, Range.second) == 1) - return Range.first - m_vSkins.begin(); + auto SkinIt = m_Skins.find(pName); + if(SkinIt != m_Skins.end()) + return SkinIt->second.get(); if(str_comp(pName, "default") == 0) - return -1; + return nullptr; if(!g_Config.m_ClDownloadSkins) - return -1; + return nullptr; if(str_find(pName, "/") != 0) - return -1; + return nullptr; - CDownloadSkin DownloadNeedle; - mem_zero(&DownloadNeedle, sizeof(DownloadNeedle)); - str_copy(DownloadNeedle.m_aName, pName); - const auto &[RangeBegin, RangeEnd] = std::equal_range(m_vDownloadSkins.begin(), m_vDownloadSkins.end(), DownloadNeedle); - if(std::distance(RangeBegin, RangeEnd) == 1) + const auto SkinDownloadIt = m_DownloadSkins.find(pName); + if(SkinDownloadIt != m_DownloadSkins.end()) { - if(RangeBegin->m_pTask && RangeBegin->m_pTask->State() == HTTP_DONE) + if(SkinDownloadIt->second->m_pTask && SkinDownloadIt->second->m_pTask->State() == HTTP_DONE) { char aPath[IO_MAX_PATH_LENGTH]; - str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", RangeBegin->m_aName); - Storage()->RenameFile(RangeBegin->m_aPath, aPath, IStorage::TYPE_SAVE); - LoadSkin(RangeBegin->m_aName, RangeBegin->m_pTask->m_Info); - RangeBegin->m_pTask = nullptr; + str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", SkinDownloadIt->second->GetName()); + Storage()->RenameFile(SkinDownloadIt->second->m_aPath, aPath, IStorage::TYPE_SAVE); + const auto *pSkin = LoadSkin(SkinDownloadIt->second->GetName(), SkinDownloadIt->second->m_pTask->m_Info); + SkinDownloadIt->second->m_pTask = nullptr; --m_DownloadingSkins; + return pSkin; } - if(RangeBegin->m_pTask && (RangeBegin->m_pTask->State() == HTTP_ERROR || RangeBegin->m_pTask->State() == HTTP_ABORTED)) + if(SkinDownloadIt->second->m_pTask && (SkinDownloadIt->second->m_pTask->State() == HTTP_ERROR || SkinDownloadIt->second->m_pTask->State() == HTTP_ABORTED)) { - RangeBegin->m_pTask = nullptr; + SkinDownloadIt->second->m_pTask = nullptr; --m_DownloadingSkins; } - return -1; + return nullptr; } - CDownloadSkin Skin; - str_copy(Skin.m_aName, pName); + CDownloadSkin Skin{pName}; char aUrl[IO_MAX_PATH_LENGTH]; char aEscapedName[256]; @@ -454,7 +450,8 @@ int CSkins::FindImpl(const char *pName) str_format(Skin.m_aPath, sizeof(Skin.m_aPath), "downloadedskins/%s", IStorage::FormatTmpPath(aBuf, sizeof(aBuf), pName)); Skin.m_pTask = std::make_shared(this, aUrl, Storage(), Skin.m_aPath); m_pClient->Engine()->AddJob(Skin.m_pTask); - m_vDownloadSkins.insert(std::lower_bound(m_vDownloadSkins.begin(), m_vDownloadSkins.end(), Skin), std::move(Skin)); + auto &&pDownloadSkin = std::make_unique(std::move(Skin)); + m_DownloadSkins.insert({pDownloadSkin->GetName(), std::move(pDownloadSkin)}); ++m_DownloadingSkins; - return -1; + return nullptr; } diff --git a/src/game/client/components/skins.h b/src/game/client/components/skins.h index d089ecab6..36fede652 100644 --- a/src/game/client/components/skins.h +++ b/src/game/client/components/skins.h @@ -3,14 +3,18 @@ #ifndef GAME_CLIENT_COMPONENTS_SKINS_H #define GAME_CLIENT_COMPONENTS_SKINS_H +#include #include #include #include -#include +#include +#include class CSkins : public CComponent { public: + CSkins() = default; + class CGetPngFile : public CHttpRequest { CSkins *m_pSkins; @@ -25,12 +29,18 @@ public: struct CDownloadSkin { - std::shared_ptr m_pTask; - char m_aPath[IO_MAX_PATH_LENGTH]; + private: char m_aName[24]; + public: + std::shared_ptr m_pTask; + char m_aPath[IO_MAX_PATH_LENGTH]; + CDownloadSkin(CDownloadSkin &&Other) = default; - CDownloadSkin() = default; + CDownloadSkin(const char *pName) + { + str_copy(m_aName, pName); + } ~CDownloadSkin() { @@ -42,6 +52,8 @@ public: bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); } CDownloadSkin &operator=(CDownloadSkin &&Other) = default; + + const char *GetName() const { return m_aName; } }; typedef std::function TSkinLoadedCBFunc; @@ -51,21 +63,22 @@ public: void Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc); int Num(); - const CSkin *Get(int Index); - int Find(const char *pName); + std::unordered_map> &GetSkinsUnsafe() { return m_Skins; } + const CSkin *FindOrNullptr(const char *pName); + const CSkin *Find(const char *pName); bool IsDownloadingSkins() { return m_DownloadingSkins; } private: - std::vector m_vSkins; - std::vector m_vDownloadSkins; + std::unordered_map> m_Skins; + std::unordered_map> m_DownloadSkins; size_t m_DownloadingSkins = 0; char m_aEventSkinPrefix[24]; bool LoadSkinPNG(CImageInfo &Info, const char *pName, const char *pPath, int DirType); - int LoadSkin(const char *pName, const char *pPath, int DirType); - int LoadSkin(const char *pName, CImageInfo &Info); - int FindImpl(const char *pName); + const CSkin *LoadSkin(const char *pName, const char *pPath, int DirType); + const CSkin *LoadSkin(const char *pName, CImageInfo &Info); + const CSkin *FindImpl(const char *pName); static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser); }; #endif diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 9e4de7a66..58fb1e505 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1009,15 +1009,16 @@ static CGameInfo GetGameInfo(const CNetObj_GameInfoEx *pInfoEx, int InfoExSize, bool FDDrace; if(Version < 1) { - Race = IsRace(pFallbackServerInfo); - FastCap = IsFastCap(pFallbackServerInfo); - FNG = IsFNG(pFallbackServerInfo); - DDRace = IsDDRace(pFallbackServerInfo); - DDNet = IsDDNet(pFallbackServerInfo); - BlockWorlds = IsBlockWorlds(pFallbackServerInfo); - City = IsCity(pFallbackServerInfo); - Vanilla = IsVanilla(pFallbackServerInfo); - Plus = IsPlus(pFallbackServerInfo); + const char *pGameType = pFallbackServerInfo->m_aGameType; + Race = str_find_nocase(pGameType, "race") || str_find_nocase(pGameType, "fastcap"); + FastCap = str_find_nocase(pGameType, "fastcap"); + FNG = str_find_nocase(pGameType, "fng"); + DDRace = str_find_nocase(pGameType, "ddrace") || str_find_nocase(pGameType, "mkrace"); + DDNet = str_find_nocase(pGameType, "ddracenet") || str_find_nocase(pGameType, "ddnet"); + BlockWorlds = str_startswith(pGameType, "bw ") || str_comp_nocase(pGameType, "bw") == 0; + City = str_find_nocase(pGameType, "city"); + Vanilla = str_comp(pGameType, "DM") == 0 || str_comp(pGameType, "TDM") == 0 || str_comp(pGameType, "CTF") == 0; + Plus = str_find(pGameType, "+"); FDDrace = false; } else @@ -1227,7 +1228,7 @@ void CGameClient::OnNewSnapshot() pClient->m_SkinInfo.m_Size = 64; // find new skin - const CSkin *pSkin = m_Skins.Get(m_Skins.Find(pClient->m_aSkinName)); + const CSkin *pSkin = m_Skins.Find(pClient->m_aSkinName); pClient->m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin; pClient->m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin; pClient->m_SkinInfo.m_SkinMetrics = pSkin->m_Metrics; @@ -3185,7 +3186,7 @@ void CGameClient::RefindSkins() Client.m_SkinInfo.m_ColorableRenderSkin.Reset(); if(Client.m_aSkinName[0] != '\0') { - const CSkin *pSkin = m_Skins.Get(m_Skins.Find(Client.m_aSkinName)); + const CSkin *pSkin = m_Skins.Find(Client.m_aSkinName); Client.m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin; Client.m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin; Client.UpdateRenderInfo(IsTeamPlay()); diff --git a/src/game/client/skin.h b/src/game/client/skin.h index e40341829..655166011 100644 --- a/src/game/client/skin.h +++ b/src/game/client/skin.h @@ -1,6 +1,7 @@ #ifndef GAME_CLIENT_SKIN_H #define GAME_CLIENT_SKIN_H #include +#include #include #include #include @@ -8,6 +9,10 @@ // do this better and nicer struct CSkin { +private: + char m_aName[24]; + +public: struct SSkinTextures { IGraphics::CTextureHandle m_Body; @@ -36,7 +41,6 @@ struct CSkin SSkinTextures m_OriginalSkin; SSkinTextures m_ColorableSkin; - char m_aName[24]; ColorRGBA m_BloodColor; template @@ -129,6 +133,15 @@ struct CSkin 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; } }; #endif