Skip to content

Commit a94bcfa

Browse files
committed
Resource download fix.
1 parent d61257c commit a94bcfa

5 files changed

Lines changed: 86 additions & 119 deletions

File tree

src/game/client/components/resource.cpp

Lines changed: 39 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,6 @@ void CClientResManager::RenderImageEntity(const CNetObj_CustomImageEntity *pPrev
7070
Graphics()->QuadsEnd();
7171
}
7272

73-
void CClientResManager::OnMapLoad()
74-
{
75-
for(int i = 0; i < m_lResources.size(); i++)
76-
{
77-
if(m_lResources[i].m_Sample.IsValid())
78-
m_pClient->m_pSounds->UnloadSample(&m_lResources[i].m_Sample);
79-
if(m_lResources[i].m_Texture.IsValid())
80-
Graphics()->UnloadTexture(&m_lResources[i].m_Texture);
81-
}
82-
m_lResources.clear();
83-
}
84-
8573
void CClientResManager::OnRender()
8674
{
8775
int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT);
@@ -122,15 +110,11 @@ void CClientResManager::OnMessage(int MsgType, void *pRawMsg)
122110
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "resource", "invalid resource size");
123111
return;
124112
}
113+
114+
if(FindResource(*static_cast<const Uuid *>(pMsg->m_Uuid))) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
125115
{
126-
CClientResource TargetRes;
127-
TargetRes.m_Uuid = *static_cast<const Uuid *>(pMsg->m_Uuid);
128-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), TargetRes);
129-
if(!r.empty()) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
130-
{
131-
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "resource", "invalid resource uuid");
132-
return;
133-
}
116+
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "resource", "invalid resource uuid");
117+
return;
134118
}
135119
CClientResource Resource;
136120
str_copy(Resource.m_aName, pMsg->m_Name, sizeof(Resource.m_aName));
@@ -146,6 +130,7 @@ void CClientResManager::OnMessage(int MsgType, void *pRawMsg)
146130
mem_copy(&Resource.m_Sha256, pMsg->m_Sha256, sizeof(SHA256_DIGEST));
147131
FormatResourcePath(Resource.m_aPath, sizeof(Resource.m_aPath), Resource.m_aName, false, &Resource.m_Sha256, &Resource.m_Crc);
148132
FormatResourcePath(Resource.m_aTempPath, sizeof(Resource.m_aTempPath), Resource.m_aName, true, &Resource.m_Sha256, &Resource.m_Crc);
133+
Resource.m_DownloadTemp = 0;
149134

150135
int Index = m_lResources.add(Resource);
151136
if(!LoadResource(&m_lResources[Index]))
@@ -158,41 +143,38 @@ void CClientResManager::OnMessage(int MsgType, void *pRawMsg)
158143
{
159144
CNetMsg_Sv_CustomResourceData *pMsg = (CNetMsg_Sv_CustomResourceData *) pRawMsg;
160145
Uuid TargetResource = *static_cast<const Uuid *>(pMsg->m_Uuid);
161-
162-
CClientResource TargetRes;
163-
TargetRes.m_Uuid = TargetResource;
164-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), TargetRes);
165-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
146+
CClientResource *pResource = FindResource(TargetResource);
147+
if(!pResource)
166148
return;
167-
168-
CClientResource &Resource = r.front();
169-
Resource.m_DownloadedSize += pMsg->m_DataSize;
170-
if(Resource.m_DownloadedSize > Resource.m_DataSize)
149+
pResource->m_DownloadedSize += pMsg->m_DataSize;
150+
if(pResource->m_DownloadedSize > pResource->m_DataSize)
171151
{
172-
io_close(Resource.m_DownloadTemp);
173-
Storage()->RemoveFile(Resource.m_aTempPath, IStorage::TYPE_SAVE);
174-
m_lResources.remove(Resource);
152+
io_close(pResource->m_DownloadTemp);
153+
pResource->m_DownloadTemp = 0;
154+
Storage()->RemoveFile(pResource->m_aTempPath, IStorage::TYPE_SAVE);
155+
m_lResources.remove(*pResource);
175156
return; // invalid!
176157
}
177-
io_write(Resource.m_DownloadTemp, pMsg->m_Data, pMsg->m_DataSize);
178-
if(Resource.m_DownloadedSize == Resource.m_DataSize)
158+
io_write(pResource->m_DownloadTemp, pMsg->m_Data, pMsg->m_DataSize);
159+
if(pResource->m_DownloadedSize == pResource->m_DataSize)
179160
{
180161
char aBuf[128];
181-
str_format(aBuf, sizeof(aBuf), Localize("Resource '%s': download complete"), Resource.m_aName);
162+
str_format(aBuf, sizeof(aBuf), Localize("Resource '%s': download complete"), pResource->m_aName);
182163
UI()->DoToast(aBuf);
183-
io_close(Resource.m_DownloadTemp);
164+
io_close(pResource->m_DownloadTemp);
165+
pResource->m_DownloadTemp = 0;
184166

185-
Storage()->RemoveFile(Resource.m_aPath, IStorage::TYPE_SAVE);
186-
Storage()->RenameFile(Resource.m_aTempPath, Resource.m_aPath, IStorage::TYPE_SAVE);
167+
Storage()->RemoveFile(pResource->m_aPath, IStorage::TYPE_SAVE);
168+
Storage()->RenameFile(pResource->m_aTempPath, pResource->m_aPath, IStorage::TYPE_SAVE);
187169

188-
if(!LoadResource(&Resource))
170+
if(!LoadResource(pResource))
189171
{
190-
Storage()->RemoveFile(Resource.m_aPath, IStorage::TYPE_SAVE);
191-
m_lResources.remove(Resource);
172+
Storage()->RemoveFile(pResource->m_aPath, IStorage::TYPE_SAVE);
173+
m_lResources.remove(*pResource);
192174
return; // invalid!
193175
}
194176
}
195-
else if((pMsg->m_ChunkIndex + 1) % Resource.m_ChunkPerRequest == 0)
177+
else if((pMsg->m_ChunkIndex + 1) % pResource->m_ChunkPerRequest == 0)
196178
RequestDownload(&TargetResource);
197179
}
198180
}
@@ -220,42 +202,28 @@ void CClientResManager::OnStateChange(int NewState, int OldState)
220202
}
221203
}
222204

223-
bool CClientResManager::IsResourceSound(Uuid ResID)
205+
CClientResManager::CClientResource *CClientResManager::FindResource(Uuid ResourceID)
224206
{
225-
CClientResource Res;
226-
Res.m_Uuid = ResID;
227-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), Res);
228-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
229-
return false;
230-
return r.front().m_Type == RESOURCE_SOUND;
231-
}
232-
233-
bool CClientResManager::IsResourceImage(Uuid ResID)
234-
{
235-
CClientResource Res;
236-
Res.m_Uuid = ResID;
237-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), Res);
238-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
239-
return false;
240-
return r.front().m_Type == RESOURCE_IMAGE;
207+
for(int i = 0; i < m_lResources.size(); i++)
208+
{
209+
if(m_lResources[i].m_Uuid == ResourceID)
210+
return &m_lResources[i];
211+
}
212+
return nullptr;
241213
}
242214

243215
ISound::CSampleHandle CClientResManager::GetResourceSample(Uuid ResID)
244216
{
245-
CClientResource Res;
246-
Res.m_Uuid = ResID;
247-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), Res);
248-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
249-
return ISound::CSampleHandle();
250-
return r.front().m_Sample;
217+
CClientResource *pResource = FindResource(ResID);
218+
if(pResource)
219+
return pResource->m_Sample;
220+
return ISound::CSampleHandle();
251221
}
252222

253223
IGraphics::CTextureHandle CClientResManager::GetResourceTexture(Uuid ResID)
254224
{
255-
CClientResource Res;
256-
Res.m_Uuid = ResID;
257-
sorted_array<CClientResource>::range r = ::find_binary(m_lResources.all(), Res);
258-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
259-
return IGraphics::CTextureHandle();
260-
return r.front().m_Texture;
225+
CClientResource *pResource = FindResource(ResID);
226+
if(pResource)
227+
return pResource->m_Texture;
228+
return IGraphics::CTextureHandle();
261229
}

src/game/client/components/resource.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef GAME_CLIENT_COMPONENTS_RESOURCE_H
22
#define GAME_CLIENT_COMPONENTS_RESOURCE_H
33

4-
#include <base/tl/sorted_array.h>
4+
#include <base/tl/array.h>
55
#include <base/uuid.h>
66
#include <engine/graphics.h>
77
#include <engine/sound.h>
@@ -21,20 +21,18 @@ class CClientResManager : public CComponent
2121
IOHANDLE m_DownloadTemp;
2222
};
2323

24-
sorted_array<CClientResource> m_lResources;
24+
array<CClientResource> m_lResources;
2525
void RequestDownload(const Uuid *pRequest);
2626
bool LoadResource(CClientResource *pResource);
2727

2828
void RenderImageEntity(const CNetObj_CustomImageEntity *pPrev, const CNetObj_CustomImageEntity *pCur);
2929
public:
3030
CClientResManager();
31-
virtual void OnMapLoad();
3231
virtual void OnRender();
3332
virtual void OnMessage(int MsgType, void *pRawMsg);
3433
virtual void OnStateChange(int NewState, int OldState);
34+
CClientResource *FindResource(Uuid ResourceID);
3535

36-
bool IsResourceSound(Uuid ResID);
37-
bool IsResourceImage(Uuid ResID);
3836
ISound::CSampleHandle GetResourceSample(Uuid ResID);
3937
IGraphics::CTextureHandle GetResourceTexture(Uuid ResID);
4038
};

src/game/server/gamecontext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ void CGameContext::CreateSound(vec2 Pos, int Sound, int64 Mask)
186186

187187
void CGameContext::CreateCustomSound(vec2 Pos, Uuid Sound, int64 Mask)
188188
{
189-
if(!ResourceManager()->IsResourceSound(Sound))
189+
if(!ResourceManager()->FindResource(Sound))
190190
return;
191191

192192
// create a sound
@@ -557,6 +557,7 @@ void CGameContext::OnTick()
557557
{
558558
m_apPlayers[i]->Tick();
559559
m_apPlayers[i]->PostTick();
560+
m_ResourceManager.TrySendResourceInfo(i);
560561
}
561562
}
562563

src/game/server/resource.cpp

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ IServer *CServerResManager::Server() { return m_pGameContext->Server(); }
1111
IStorage *CServerResManager::Storage() { return m_pGameContext->Storage(); }
1212
CConfig *CServerResManager::Config() { return m_pGameContext->Config(); }
1313

14+
CServerResManager::CServerResource *CServerResManager::FindResource(Uuid ResourceID)
15+
{
16+
for(int i = 0; i < m_lResources.size(); i++)
17+
{
18+
if(m_lResources[i].m_Uuid == ResourceID)
19+
return &m_lResources[i];
20+
}
21+
return nullptr;
22+
}
23+
1424
CServerResManager::CServerResManager()
1525
{
1626
}
@@ -28,14 +38,10 @@ void CServerResManager::Init(CGameContext *pGameContext)
2838

2939
void CServerResManager::SendResourceData(int ClientID, const Uuid RequestUuid)
3040
{
31-
CServerResource Res;
32-
Res.m_Uuid = RequestUuid;
33-
sorted_array<CServerResource>::range r = ::find_binary(m_lResources.all(), Res);
34-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
35-
return;
36-
3741
int ChunkSize = CResource::CHUNK_SIZE;
38-
CServerResource *pTarget = &r.front();
42+
CServerResource *pTarget = FindResource(RequestUuid);
43+
if(!pTarget)
44+
return;
3945

4046
// send resource chunks, copied from map download
4147
for(int i = 0; i < Config()->m_SvResDownloadSpeed && pTarget->m_aDownloadChunks[ClientID] >= 0; ++i)
@@ -105,20 +111,7 @@ void CServerResManager::OnClientEnter(int ClientID)
105111
{
106112
if(Server()->GetClientVersion(ClientID) < 0x0706)
107113
return;
108-
for(int i = 0; i < m_lResources.size(); i++)
109-
{
110-
CNetMsg_Sv_CustomResource Resource;
111-
Resource.m_Uuid = &m_lResources[i].m_Uuid;
112-
Resource.m_Type = m_lResources[i].m_Type;
113-
Resource.m_Name = m_lResources[i].m_aName;
114-
Resource.m_Crc = m_lResources[i].m_Crc;
115-
Resource.m_Sha256 = &m_lResources[i].m_Sha256;
116-
Resource.m_Size = m_lResources[i].m_DataSize;
117-
Resource.m_ChunkPerRequest = m_ChunksPerRequest;
118-
Server()->SendPackMsg(&Resource, MSGFLAG_VITAL | MSGFLAG_FLUSH | MSGFLAG_NORECORD, ClientID);
119-
120-
m_lResources[i].m_aDownloadChunks[ClientID] = 0;
121-
}
114+
m_aResourceSendIndex[ClientID] = 0;
122115
}
123116

124117
void CServerResManager::Clear()
@@ -129,24 +122,30 @@ void CServerResManager::Clear()
129122
mem_free(m_lResources[i].m_pData);
130123
m_lResources[i].m_pData = 0;
131124
}
125+
for(int i = 0; i < MAX_CLIENTS; i++)
126+
{
127+
m_aResourceSendIndex[i] = -1;
128+
}
132129
}
133130

134-
bool CServerResManager::IsResourceSound(Uuid ResID)
131+
void CServerResManager::TrySendResourceInfo(int ClientID)
135132
{
136-
CServerResource Res;
137-
Res.m_Uuid = ResID;
138-
sorted_array<CServerResource>::range r = ::find_binary(m_lResources.all(), Res);
139-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
140-
return false;
141-
return r.front().m_Type == RESOURCE_SOUND;
142-
}
133+
if(!GameServer()->m_apPlayers[ClientID])
134+
return;
143135

144-
bool CServerResManager::IsResourceImage(Uuid ResID)
145-
{
146-
CServerResource Res;
147-
Res.m_Uuid = ResID;
148-
sorted_array<CServerResource>::range r = ::find_binary(m_lResources.all(), Res);
149-
if(r.empty() || r.size() > 1) // there couldn't be uuid collision, if that happened, then the server-side resource name must be wrong.
150-
return false;
151-
return r.front().m_Type == RESOURCE_IMAGE;
136+
int Index = m_aResourceSendIndex[ClientID];
137+
if(Index < 0 || Index >= m_lResources.size())
138+
return;
139+
CNetMsg_Sv_CustomResource Resource;
140+
Resource.m_Uuid = &m_lResources[Index].m_Uuid;
141+
Resource.m_Type = m_lResources[Index].m_Type;
142+
Resource.m_Name = m_lResources[Index].m_aName;
143+
Resource.m_Crc = m_lResources[Index].m_Crc;
144+
Resource.m_Sha256 = &m_lResources[Index].m_Sha256;
145+
Resource.m_Size = m_lResources[Index].m_DataSize;
146+
Resource.m_ChunkPerRequest = m_ChunksPerRequest;
147+
Server()->SendPackMsg(&Resource, MSGFLAG_VITAL | MSGFLAG_FLUSH | MSGFLAG_NORECORD, ClientID);
148+
149+
m_lResources[Index].m_aDownloadChunks[ClientID] = 0;
150+
m_aResourceSendIndex[ClientID]++;
152151
}

src/game/server/resource.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef GAME_SERVER_RESOURCE_H
22
#define GAME_SERVER_RESOURCE_H
33

4-
#include <base/tl/sorted_array.h>
4+
#include <base/tl/array.h>
55
#include <game/resource.h>
66

77
class CServerResManager
@@ -18,8 +18,10 @@ class CServerResManager
1818
int m_aDownloadChunks[MAX_CLIENTS];
1919
};
2020

21-
sorted_array<CServerResource> m_lResources;
21+
int m_aResourceSendIndex[MAX_CLIENTS];
22+
array<CServerResource> m_lResources;
2223
int m_ChunksPerRequest;
24+
2325
public:
2426
CServerResManager();
2527
~CServerResManager();
@@ -29,9 +31,8 @@ class CServerResManager
2931
void SendResourceData(int ClientID, const Uuid RequestUuid);
3032
void OnClientEnter(int ClientID);
3133
void Clear();
32-
33-
bool IsResourceSound(Uuid ResID);
34-
bool IsResourceImage(Uuid ResID);
34+
void TrySendResourceInfo(int ClientID);
35+
CServerResource *FindResource(Uuid ResourceID);
3536
};
3637

3738
#endif // GAME_SERVER_RESOURCE_H

0 commit comments

Comments
 (0)