Quote:
Yes the autodownload feature would be nice, but that would require appending to the server protocol. I'll have to look at the QW source to see how much it can be adapted.
Sput, what if it were implemented
ANOTHER WAY. In fact, in my opinion a better way.
In JoeQuake, if you open a .dz demo, it invokes dzip.exe to extract the file.
So ...
1. Server tells the client what map. QuakeC sends a command "MAPSOURCE
ftp://ftp.runecentral.com/quake/maps" that modified clients understand to be where they can get the map if they don't have it.
2. Client says "hey, I don't have that map".
3. Modified client recognizes MAPSOURCE command and downloads the file from the indicated repository
ftp://ftp.runecentral.com/quake/maps/aerowalk.zip as indicated by MAPSOURCE command and uses DZIP.EXE to decompress it into quake\id1\maps. Then client reconnects after the install is complete.
3b. Unmodified GLQuake client doesn't know what that command is and just does the usual.
Result: Modified Quakes download and unzip + install maps, unmodified clients do the usual and complain about the missing map.
The method would save server load by having the option of directing to somewhere else to consume bandwidth and also have the advantage of using compression, something QuakeWorld does not utilize to my knowledge.
(I'm using Rune Central's archive as an example. For $5 per year, a static B account at
http://www.e-rice.net could hold numerous maps. A Static B account comes with 50 MB and 5 Gig transfer, $15 per year gets 150 MB and 15 GB transfer. Is it reliable?
http://www.singed.net is hosted on E-Rice.net and so was TLTQ.com )
C++ API
C++ API; InternetOpenUrl ... uses Winsock; in MSDN library wrote:
HINTERNET InternetOpenUrl(
IN HINTERNET hInternetSession,
IN LPCSTR lpszUrl,
IN LPCSTR lpszHeaders,
IN DWORD dwHeadersLength,
IN DWORD dwFlags,
IN DWORD dwContext
);
-->
DWORD WINAPI ThreadFunc(void *param)
{ int i=(int)param;
HINTERNET hif = InternetOpenUrl(hisess,url.c_str(),NULL,0, _ INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE|INTERNET_FLAG_PRAGMA_NOCACHE,0);
if (tabort) return 0;
if (hif==0)
{ void *msg; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM| _ FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&msg,0,NULL);
wstring err1((wchar_t*)msg); LocalFree(msg);
wchar_t msg2[1024]; DWORD code,size=1024; InternetGetLastResponseInfo(&code,msg2,&size);
wstring err2(msg2);
terr=L"Couldn't download '"+url+L"' - "+err1+L" - "+err2;
return 0;
}
pos[i]=0; while (true)
{ DWORD red; BOOL res = InternetReadFile(hif,&buf[i][pos[i]],102400-pos[i],&red);
if (tabort) return 0;
if (!res || red==0) break;
pos[i]+=red; if (pos[i]==102400) {terr=L"Exceeded my programming: "+url; pos[i]=102399;}
}
buf[i][pos[i]]=0;
InternetCloseHandle(hif);
if (tabort) return 0;
return 1;
}
Source:
http://www.wischik.com/lu/programmer/divoff.zip