1 #include "pr-downloader.h"
2 #include "Downloader/IDownloader.h"
3 #include "FileSystem/FileSystem.h"
4 #include "Logger.h"
5 
6 #include <string.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 
10 
11 static bool fetchDepends = true;
12 
download_engine(std::list<IDownload * > & dllist)13 bool download_engine(std::list<IDownload*>& dllist)
14 {
15 	httpDownload->download(dllist);
16 	bool res = true;
17 	std::list<IDownload*>::iterator it;
18 	for (it = dllist.begin(); it!=dllist.end(); ++it) {
19 		if (!fileSystem->extractEngine((*it)->name, (*it)->version))
20 			res = false;
21 	}
22 	return res;
23 }
24 
25 //helper function
GetIDownloadByID(std::list<IDownload * > & dllist,int id)26 IDownload* GetIDownloadByID(std::list<IDownload*>& dllist, int id)
27 {
28 	std::list<IDownload*>::iterator it;
29 	int pos=0;
30 	for(it=dllist.begin(); it!=dllist.end(); ++it) {
31 		if (pos==id) {
32 			return *it;
33 		}
34 		pos++;
35 	}
36 	LOG_ERROR("%s: Couln't find dl %d", __FUNCTION__, id);
37 	return NULL;
38 }
39 
getCat(category cat)40 IDownload::category getCat(category cat) //FIXME: unify enums, see IDownload::category
41 {
42 	switch (cat) {
43 	case CAT_MAP:
44 		return IDownload::CAT_MAPS;
45 	case CAT_GAME:
46 		return IDownload::CAT_GAMES;
47 	case CAT_ENGINE:
48 #ifdef WIN32
49 		return IDownload::CAT_ENGINE_WINDOWS;
50 #elif defined(__APPLE__)
51 		return IDownload::CAT_ENGINE_MACOSX;
52 #elif defined(__x86_64__)
53 		return IDownload::CAT_ENGINE_LINUX64;
54 #else
55 		return IDownload::CAT_ENGINE_LINUX;
56 #endif
57 
58 	case CAT_ANY:
59 		return IDownload::CAT_NONE;
60 	default:
61 		LOG_ERROR("Invalid category: %d", cat);
62 	}
63 	return IDownload::CAT_NONE;
64 }
65 
isEngineDownload(IDownload::category cat)66 bool isEngineDownload(IDownload::category cat)
67 {
68 	return (cat == IDownload::CAT_ENGINE_LINUX)   ||
69 	       (cat == IDownload::CAT_ENGINE_LINUX64) ||
70 	       (cat == IDownload::CAT_ENGINE_MACOSX)  ||
71 	       (cat == IDownload::CAT_ENGINE_WINDOWS);
72 }
73 
74 
75 std::list<IDownload*> searchres;
76 downloadtype typ;
77 
search(downloadtype type,category cat,const char * name,std::list<IDownload * > & searchres)78 bool search(downloadtype type, category cat, const char* name, std::list<IDownload*>& searchres)
79 {
80 	IDownload::category icat = getCat(cat);
81 	if (isEngineDownload(icat)) { //engine downloads only work with http
82 		type = DL_ENGINE;
83 		LOG_ERROR("engine dl");
84 	}
85 	typ = type;
86 	std::string searchname = name;
87 
88 	switch(type) {
89 	case DL_RAPID:
90 		return rapidDownload->search(searchres, searchname.c_str(), icat);
91 	case DL_HTTP:
92 	case DL_ENGINE:
93 		return httpDownload->search(searchres, searchname.c_str(), icat);
94 	case DL_PLASMA:
95 		return plasmaDownload->search(searchres, searchname.c_str(), icat);
96 	case DL_ANY:
97 		rapidDownload->search(searchres, searchname.c_str(), icat);
98 		if (!searchres.empty()) {
99 			typ = DL_RAPID;
100 			break;
101 		}
102 		typ = DL_HTTP;
103 		httpDownload->search(searchres, searchname.c_str(), icat);
104 		if (!searchres.empty()) {
105 			break;
106 		}
107 		//last try, use plasma
108 		return plasmaDownload->search(searchres, searchname.c_str(), icat);
109 	default:
110 		LOG_ERROR("%s: type invalid", __FUNCTION__);
111 		return false;
112 	}
113 	return true;
114 }
115 
DownloadSearch(downloadtype type,category cat,const char * name)116 int DownloadSearch(downloadtype type, category cat, const char* name)
117 {
118 	IDownloader::freeResult(searchres);
119 	search(type, cat, name, searchres);
120 	return searchres.size();
121 }
122 
DownloadGetSearchInfo(int id,downloadInfo & info)123 bool DownloadGetSearchInfo(int id, downloadInfo& info)
124 {
125 	IDownload* dl = GetIDownloadByID(searchres, id);
126 	if (dl!=NULL) {
127 		strncpy(info.filename, dl->name.c_str(), NAME_LEN-1); // -1 because of 0 termination
128 		return true;
129 	}
130 	return false;
131 }
132 
DownloadInit()133 void DownloadInit()
134 {
135 	IDownloader::Initialize();
136 }
137 
DownloadShutdown()138 void DownloadShutdown()
139 {
140 	IDownloader::freeResult(searchres);
141 	IDownloader::Shutdown();
142 	CFileSystem::Shutdown();
143 }
144 
DownloadSetConfig(CONFIG type,const void * value)145 bool DownloadSetConfig(CONFIG type, const void* value)
146 {
147 	switch(type) {
148 	case CONFIG_FILESYSTEM_WRITEPATH:
149 		fileSystem->setWritePath((const char*)value);
150 		return true;
151 	case CONFIG_FETCH_DEPENDS:
152 		fetchDepends = (const bool*) value;
153 		return true;
154 	}
155 	return false;
156 }
157 
DownloadGetConfig(CONFIG type,const void ** value)158 bool DownloadGetConfig(CONFIG type, const void** value)
159 {
160 	switch(type) {
161 	case CONFIG_FILESYSTEM_WRITEPATH:
162 		*value = fileSystem->getSpringDir().c_str();
163 		return true;
164 	case CONFIG_FETCH_DEPENDS:
165 		*value = (const bool*)fetchDepends;
166 		return true;
167 	}
168 	return false;
169 }
170 
171 std::list<int> downloads;
172 
DownloadAdd(unsigned int id)173 bool DownloadAdd(unsigned int id)
174 {
175 	if ((id>searchres.size())) {
176 		LOG_ERROR("%s Invalid id %d", __FUNCTION__, id);
177 		return false;
178 	}
179 	downloads.push_back(id);
180 	return true;
181 }
182 
addDepends(std::list<IDownload * > & dls)183 bool addDepends(std::list<IDownload*>& dls)
184 {
185 	std::list<IDownload*>::iterator it;
186 	for (it = dls.begin(); it != dls.end(); ++it) {
187 		if ((*it)->depend.empty()) {
188 			continue;
189 		}
190 		std::list<std::string>::iterator stit;
191 		for (stit = (*it)->depend.begin(); stit != (*it)->depend.end(); ++stit) {
192 			std::list<IDownload*> depends;
193 			const std::string& depend = (*stit);
194 			search(DL_ANY, CAT_ANY, depend.c_str(), depends);
195 			LOG_INFO("Adding depend %s", depend.c_str());
196 			dls.merge(depends);
197 		}
198 	}
199 	return true;
200 }
201 
DownloadStart()202 bool DownloadStart()
203 {
204 	bool res = true;
205 	std::list<IDownload*> dls;
206 	std::list<int>::iterator it;
207 	for (it = downloads.begin(); it != downloads.end(); ++it) {
208 		IDownload* dl = GetIDownloadByID(searchres, *it);
209 		if (dl == NULL) {
210 			continue;
211 		}
212 		dls.push_back(dl);
213 	}
214 	if (fetchDepends) {
215 		addDepends(dls);
216 	}
217 
218 	if (dls.empty()) {
219 		LOG_DEBUG("Nothing to do, did you forget to call DownloadAdd()?");
220 		return res;
221 	}
222 
223 	switch (typ) {
224 	case DL_RAPID:
225 	case DL_HTTP:
226 		if(!rapidDownload->download(dls))
227 			res = false;
228 		if (!httpDownload->download(dls,1))
229 			res = false;
230 		break;
231 	case DL_ENGINE:
232 		if (!download_engine(dls))
233 			res = false;
234 		break;
235 	default:
236 		LOG_ERROR("%s():%d  Invalid type specified: %d %d", __FUNCTION__, __LINE__, typ, downloads.size());
237 		res = false;
238 	}
239 
240 	IDownloader::freeResult(searchres);
241 	dls.clear();
242 	return res;
243 }
244 
DownloadRapidValidate(bool deletebroken)245 bool DownloadRapidValidate(bool deletebroken)
246 {
247 	std::string path = fileSystem->getSpringDir();
248 	path += PATH_DELIMITER;
249 	path += "pool";
250 	return fileSystem->validatePool(path, deletebroken);
251 }
252 
DownloadDumpSDP(const char * path)253 bool DownloadDumpSDP(const char* path)
254 {
255 	return fileSystem->dumpSDP(path);
256 }
257 
DownloadDisableLogging(bool disableLogging)258 void DownloadDisableLogging(bool disableLogging)
259 {
260 	LOG_DISABLE(disableLogging);
261 }
262 
263