mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-23 19:59:16 +01:00
-fixed downloading covers. it works for me although occasionally stalls during downloading a cover. it could be my home network dropping the connection. Also i didn't try downloading more than 4 covers.
-fixed downloading wiitdb.zip. -downloading banners should work but no one has them hosted anywhere. larsenv has them hosted on github but its https which doesn't work. it must be http. -downloading cheats broken still.
This commit is contained in:
parent
a566176433
commit
52ea6f6b99
BIN
out/boot.dol
BIN
out/boot.dol
Binary file not shown.
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
@ -15,7 +15,6 @@
|
|||||||
#include "channel/nand_save.hpp"
|
#include "channel/nand_save.hpp"
|
||||||
#include "gc/gc.hpp"
|
#include "gc/gc.hpp"
|
||||||
#include "hw/Gekko.h"
|
#include "hw/Gekko.h"
|
||||||
#include "gui/GameTDB.hpp"
|
|
||||||
#include "gui/WiiMovie.hpp"
|
#include "gui/WiiMovie.hpp"
|
||||||
#include "loader/alt_ios.h"
|
#include "loader/alt_ios.h"
|
||||||
#include "loader/cios.h"
|
#include "loader/cios.h"
|
||||||
@ -1649,7 +1648,7 @@ void CMenu::_addUserLabels(s16 *ids, u32 start, u32 size, const char *domain)
|
|||||||
|
|
||||||
void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
|
void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
|
||||||
{
|
{
|
||||||
if(m_thrdWorking)
|
/*if(m_thrdWorking)
|
||||||
{
|
{
|
||||||
if(!MusicPlayer.IsStopped())
|
if(!MusicPlayer.IsStopped())
|
||||||
MusicPlayer.Stop();
|
MusicPlayer.Stop();
|
||||||
@ -1662,7 +1661,7 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting)
|
|||||||
m_btnMgr.draw();
|
m_btnMgr.draw();
|
||||||
m_vid.render();
|
m_vid.render();
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
if(withCF)
|
if(withCF)
|
||||||
CoverFlow.tick();
|
CoverFlow.tick();
|
||||||
m_btnMgr.tick();
|
m_btnMgr.tick();
|
||||||
|
@ -402,10 +402,6 @@ private:
|
|||||||
s16 m_downloadBtnKOs;
|
s16 m_downloadBtnKOs;
|
||||||
s16 m_downloadBtnZHCNs;
|
s16 m_downloadBtnZHCNs;
|
||||||
s16 m_downloadBtnAUs;
|
s16 m_downloadBtnAUs;
|
||||||
static void * _versionDownloaderInit(void *obj);
|
|
||||||
static void * _versionTxtDownloaderInit(void *obj);
|
|
||||||
s8 _versionDownloader();
|
|
||||||
s8 _versionTxtDownloader();
|
|
||||||
//Game menu
|
//Game menu
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -1156,10 +1152,7 @@ private:
|
|||||||
void _setThrdMsg(const wstringEx &msg, float progress);
|
void _setThrdMsg(const wstringEx &msg, float progress);
|
||||||
void _setDumpMsg(const wstringEx &msg, float progress, float fileprog);
|
void _setDumpMsg(const wstringEx &msg, float progress, float fileprog);
|
||||||
int _coverDownloader(bool missingOnly);
|
int _coverDownloader(bool missingOnly);
|
||||||
static void * _coverDownloaderAll(void *obj);
|
void _downloadProgress(void *obj, int size, int position);
|
||||||
static void * _coverDownloaderMissing(void *obj);
|
|
||||||
static bool _downloadProgress(void *obj, int size, int position);
|
|
||||||
static void * _gametdbDownloader(void *obj);
|
|
||||||
int _gametdbDownloaderAsync();
|
int _gametdbDownloaderAsync();
|
||||||
|
|
||||||
static s32 _networkComplete(s32 result, void *usrData);
|
static s32 _networkComplete(s32 result, void *usrData);
|
||||||
@ -1193,7 +1186,7 @@ private:
|
|||||||
void _listEmuNands(const char *path, vector<string> &emuNands);
|
void _listEmuNands(const char *path, vector<string> &emuNands);
|
||||||
|
|
||||||
static void * _downloadCheatFileAsync(void *obj);
|
static void * _downloadCheatFileAsync(void *obj);
|
||||||
static void * _downloadBannerAsync(void *obj);
|
int _downloadBannerAsync();
|
||||||
static void * _downloadUrlAsync(void *obj);
|
static void * _downloadUrlAsync(void *obj);
|
||||||
|
|
||||||
void _playGameSound(void);
|
void _playGameSound(void);
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
#include "lockMutex.hpp"
|
#include "lockMutex.hpp"
|
||||||
#include "network/http.h"
|
#include "network/http.h"
|
||||||
|
|
||||||
#define GECKOURL "http://geckocodes.org/codes/%c/%s.txt"
|
//#define GECKOURL "http://geckocodes.org/codes/%c/%s.txt"
|
||||||
|
#define GECKOURL "http://geckocodes.org/txt.php?txt=%s"
|
||||||
#define CHEATSPERPAGE 4
|
#define CHEATSPERPAGE 4
|
||||||
|
|
||||||
u8 m_cheatSettingsPage = 0;
|
u8 m_cheatSettingsPage = 0;
|
||||||
@ -42,27 +43,27 @@ void * CMenu::_downloadCheatFileAsync(void *obj)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 bufferSize = 0x080000; // Maximum download size 512kb
|
/*u32 bufferSize = 0x080000; // Maximum download size 512kb
|
||||||
u8 *buffer = (u8*)MEM2_alloc(bufferSize);
|
u8 *buffer = (u8*)MEM2_alloc(bufferSize);
|
||||||
if(buffer == NULL)
|
if(buffer == NULL)
|
||||||
{
|
{
|
||||||
m->m_thrdWorking = false;
|
m->m_thrdWorking = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const char *id = CoverFlow.getId();
|
const char *id = CoverFlow.getId();
|
||||||
char type = id[0] == 'S' ? 'R' : id[0];
|
//char type = id[0] == 'S' ? 'R' : id[0];
|
||||||
|
|
||||||
block cheatfile = downloadfile(buffer, bufferSize, fmt(GECKOURL, type, id), CMenu::_downloadProgress, m);
|
block cheatfile = downloadfile(fmt(GECKOURL, id));
|
||||||
|
|
||||||
if (cheatfile.data != NULL && cheatfile.size > 65 && cheatfile.data[0] != '<')
|
if (cheatfile.data != NULL && cheatfile.size > 65 && cheatfile.data[0] != '<')
|
||||||
{
|
{
|
||||||
fsop_WriteFile(fmt("%s/%s.txt", m->m_txtCheatDir.c_str(), id), cheatfile.data, cheatfile.size);
|
fsop_WriteFile(fmt("%s/%s.txt", m->m_txtCheatDir.c_str(), id), cheatfile.data, cheatfile.size);
|
||||||
free(buffer);
|
//free(buffer);
|
||||||
m->m_thrdWorking = false;
|
m->m_thrdWorking = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(buffer);
|
//free(buffer);
|
||||||
m->m_thrdWorking = false;
|
m->m_thrdWorking = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,6 @@
|
|||||||
#include "gc/gc.hpp"
|
#include "gc/gc.hpp"
|
||||||
#include "gc/gcdisc.hpp"
|
#include "gc/gcdisc.hpp"
|
||||||
#include "gui/WiiMovie.hpp"
|
#include "gui/WiiMovie.hpp"
|
||||||
#include "gui/GameTDB.hpp"
|
|
||||||
#include "homebrew/homebrew.h"
|
#include "homebrew/homebrew.h"
|
||||||
#include "loader/alt_ios.h"
|
#include "loader/alt_ios.h"
|
||||||
#include "loader/wdvd.h"
|
#include "loader/wdvd.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ogc\lwp_watchdog.h>
|
#include <ogc/lwp_watchdog.h>
|
||||||
|
|
||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "sicksaxis-wrapper/sicksaxis-wrapper.h"
|
#include "sicksaxis-wrapper/sicksaxis-wrapper.h"
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "menu.hpp"
|
#include "menu.hpp"
|
||||||
#include "channel/nand.hpp"
|
#include "channel/nand.hpp"
|
||||||
#include "devicemounter/DeviceHandler.hpp"
|
#include "devicemounter/DeviceHandler.hpp"
|
||||||
#include "gui/GameTDB.hpp"
|
|
||||||
#include "loader/alt_ios.h"
|
#include "loader/alt_ios.h"
|
||||||
#include "loader/cios.h"
|
#include "loader/cios.h"
|
||||||
#include "loader/disc.h"
|
#include "loader/disc.h"
|
||||||
|
@ -47,7 +47,7 @@ void CMenu::_system()
|
|||||||
m_btnMgr.setProgress(m_downloadPBar, 0.f);
|
m_btnMgr.setProgress(m_downloadPBar, 0.f);
|
||||||
m_thrdStop = false;
|
m_thrdStop = false;
|
||||||
m_thrdWorking = true;
|
m_thrdWorking = true;
|
||||||
LWP_CreateThread(&thread, _versionTxtDownloaderInit, this, downloadStack, downloadStackSize, 40);
|
//LWP_CreateThread(&thread, _versionTxtDownloaderInit, this, downloadStack, downloadStackSize, 40);
|
||||||
}
|
}
|
||||||
if (m_showtimer > 0 && !m_thrdWorking)
|
if (m_showtimer > 0 && !m_thrdWorking)
|
||||||
{
|
{
|
||||||
@ -112,7 +112,7 @@ void CMenu::_system()
|
|||||||
m_data_update_url = fmt("%s/r%i/data.zip", ("http://nintendont.gxarena.com/banners"), newVer);
|
m_data_update_url = fmt("%s/r%i/data.zip", ("http://nintendont.gxarena.com/banners"), newVer);
|
||||||
|
|
||||||
m_showtimer = 120;
|
m_showtimer = 120;
|
||||||
LWP_CreateThread(&thread, _versionDownloaderInit, this, downloadStack, downloadStackSize, 40);
|
//LWP_CreateThread(&thread, _versionDownloaderInit, this, downloadStack, downloadStackSize, 40);
|
||||||
if (m_exit && !m_thrdWorking)
|
if (m_exit && !m_thrdWorking)
|
||||||
{
|
{
|
||||||
m_thrdStop = true;
|
m_thrdStop = true;
|
||||||
|
@ -351,7 +351,12 @@ void * CMenu::_pThread(void *obj)
|
|||||||
if(m->m_thrdUpdated)
|
if(m->m_thrdUpdated)
|
||||||
{
|
{
|
||||||
m->m_thrdUpdated = false;
|
m->m_thrdUpdated = false;
|
||||||
m->_addDiscProgress(m->m_thrdWritten, m->m_thrdTotal, obj);
|
m->_downloadProgress(obj, m->m_thrdTotal, m->m_thrdWritten);
|
||||||
|
if(m->m_thrdProgress > 0.f)
|
||||||
|
{
|
||||||
|
m_btnMgr.setText(m->m_wbfsLblMessage, wfmt(L"%i%%", (int)(m->m_thrdProgress * 100.f)));
|
||||||
|
m_btnMgr.setProgress(m->m_wbfsPBar, m->m_thrdProgress);
|
||||||
|
}
|
||||||
m->m_thrdDone = true;
|
m->m_thrdDone = true;
|
||||||
}
|
}
|
||||||
if(m->m_thrdMessageAdded)
|
if(m->m_thrdMessageAdded)
|
||||||
@ -359,11 +364,6 @@ void * CMenu::_pThread(void *obj)
|
|||||||
m->m_thrdMessageAdded = false;
|
m->m_thrdMessageAdded = false;
|
||||||
if(!m->m_thrdMessage.empty())
|
if(!m->m_thrdMessage.empty())
|
||||||
m_btnMgr.setText(m->m_wbfsLblDialog, m->m_thrdMessage);
|
m_btnMgr.setText(m->m_wbfsLblDialog, m->m_thrdMessage);
|
||||||
if(m->m_thrdProgress > 0.f)
|
|
||||||
{
|
|
||||||
m_btnMgr.setText(m->m_wbfsLblMessage, wfmt(L"%i%%", (int)(m->m_thrdProgress * 100.f)));
|
|
||||||
m_btnMgr.setProgress(m->m_wbfsPBar, m->m_thrdProgress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m->m_thrdWorking = false;
|
m->m_thrdWorking = false;
|
||||||
|
@ -63,7 +63,7 @@ void CMenu::_addDiscProgress(int status, int total, void *user_data)
|
|||||||
if(m.m_progress - m.m_thrdProgress >= 0.01f)
|
if(m.m_progress - m.m_thrdProgress >= 0.01f)
|
||||||
{
|
{
|
||||||
LWP_MutexLock(m.m_mutex);
|
LWP_MutexLock(m.m_mutex);
|
||||||
m._setThrdMsg(L"", m.m_progress);
|
m._setThrdMsg(L"...", m.m_progress);
|
||||||
LWP_MutexUnlock(m.m_mutex);
|
LWP_MutexUnlock(m.m_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ void add_game_to_card(const char *gameid)
|
|||||||
str_replace(url, "{KEY}", providers[i].key, MAX_URL_SIZE);
|
str_replace(url, "{KEY}", providers[i].key, MAX_URL_SIZE);
|
||||||
str_replace(url, "{ID6}", gameid, MAX_URL_SIZE);
|
str_replace(url, "{ID6}", gameid, MAX_URL_SIZE);
|
||||||
gprintf("Gamertag URL:\n%s\n", url);
|
gprintf("Gamertag URL:\n%s\n", url);
|
||||||
downloadfile(NULL, 0, url, NULL, NULL);
|
downloadfile(url);
|
||||||
}
|
}
|
||||||
MEM2_free(url);
|
MEM2_free(url);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <ogc/lwp_watchdog.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "gecko/gecko.hpp"
|
#include "gecko/gecko.hpp"
|
||||||
|
|
||||||
@ -12,26 +7,29 @@
|
|||||||
* to complete a request
|
* to complete a request
|
||||||
*/
|
*/
|
||||||
const struct block emptyblock = {0, NULL};
|
const struct block emptyblock = {0, NULL};
|
||||||
#define NET_BUFFER_SIZE 1024 //The maximum amount of bytes to send per net_write() call
|
//The maximum amount of bytes to send per net_write() call
|
||||||
#define TCP_TIMEOUT 4000 // 4 secs to receive
|
//#define NET_BUFFER_SIZE 1024
|
||||||
|
#define NET_BUFFER_SIZE 3600
|
||||||
|
|
||||||
|
static u8 retryloop = 0;
|
||||||
|
|
||||||
// Write our message to the server
|
// Write our message to the server
|
||||||
static s32 send_message(s32 server, char *msg)
|
static s32 send_message(s32 server, char *msg)
|
||||||
{
|
{
|
||||||
s32 bytes_transferred = 0, remaining = strlen(msg);
|
s32 bytes_transferred = 0, remaining = strlen(msg);
|
||||||
s64 t = gettime();
|
|
||||||
while (remaining)
|
while (remaining)
|
||||||
{
|
{
|
||||||
if((bytes_transferred = net_write(server, msg, remaining > NET_BUFFER_SIZE ? NET_BUFFER_SIZE : remaining)) > 0)
|
if((bytes_transferred = net_write(server, msg, remaining > NET_BUFFER_SIZE ? NET_BUFFER_SIZE : remaining)) > 0)
|
||||||
{
|
{
|
||||||
remaining -= bytes_transferred;
|
remaining -= bytes_transferred;
|
||||||
|
msg += bytes_transferred;
|
||||||
usleep (20 * 1000);
|
usleep (20 * 1000);
|
||||||
t = gettime();
|
|
||||||
}
|
}
|
||||||
else if(bytes_transferred < 0) return bytes_transferred;
|
else if(bytes_transferred < 0)
|
||||||
|
return bytes_transferred;
|
||||||
|
|
||||||
if(ticks_to_millisecs(diff_ticks(t, gettime())) > TCP_TIMEOUT)
|
else
|
||||||
break;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -43,7 +41,7 @@ static s32 send_message(s32 server, char *msg)
|
|||||||
* @param u32 the port to connect to on the server
|
* @param u32 the port to connect to on the server
|
||||||
* @return s32 The connection to the server (negative number if connection could not be established)
|
* @return s32 The connection to the server (negative number if connection could not be established)
|
||||||
*/
|
*/
|
||||||
static s32 server_connect(u32 ipaddress, u32 socket_port)
|
static s32 server_connect(u32 ipaddress, u16 socket_port)
|
||||||
{
|
{
|
||||||
//Initialize socket
|
//Initialize socket
|
||||||
s32 connection = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
s32 connection = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||||
@ -53,18 +51,25 @@ static s32 server_connect(u32 ipaddress, u32 socket_port)
|
|||||||
struct sockaddr_in connect_addr;
|
struct sockaddr_in connect_addr;
|
||||||
memset(&connect_addr, 0, sizeof(connect_addr));
|
memset(&connect_addr, 0, sizeof(connect_addr));
|
||||||
connect_addr.sin_family = AF_INET;
|
connect_addr.sin_family = AF_INET;
|
||||||
connect_addr.sin_port = socket_port;
|
connect_addr.sin_port = htons(socket_port);
|
||||||
connect_addr.sin_addr.s_addr= ipaddress;
|
connect_addr.sin_addr.s_addr= ipaddress;
|
||||||
|
|
||||||
//Attemt to open a connection on the socket
|
//Attemt to open a connection on the socket
|
||||||
if(net_connect(connection, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
|
if(net_connect(connection, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) == -1)
|
||||||
|
{
|
||||||
net_close(connection);
|
net_close(connection);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
//The amount of memory in bytes reserved initially to store the HTTP response in
|
//The amount of memory in bytes reserved initially to store the HTTP response in
|
||||||
//Be careful in increasing this number, reading from a socket on the Wii
|
//Be careful in increasing this number, reading from a socket on the Wii
|
||||||
|
//will fail if you request more than 20k or so
|
||||||
|
#define HTTP_BUFFER_SIZE 1024 * 5
|
||||||
|
|
||||||
|
//The amount of memory the buffer should expanded with if the buffer is full
|
||||||
#define HTTP_BUFFER_GROWTH 1024 * 5
|
#define HTTP_BUFFER_GROWTH 1024 * 5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,155 +79,223 @@ static s32 server_connect(u32 ipaddress, u32 socket_port)
|
|||||||
* @param s32 connection The connection identifier to suck the response out of
|
* @param s32 connection The connection identifier to suck the response out of
|
||||||
* @return block A 'block' struct (see http.h) in which the buffer is located
|
* @return block A 'block' struct (see http.h) in which the buffer is located
|
||||||
*/
|
*/
|
||||||
static struct block read_message(s32 connection, struct block buffer, bool (*f)(void *, int, int), void *ud)
|
struct block read_message(s32 connection)
|
||||||
{
|
{
|
||||||
static char tmpHdr[512];
|
//Create a block of memory to put in the response
|
||||||
bool hdr = false, fail = true;
|
struct block buffer;
|
||||||
u32 fileSize = 0, step = 0, offset = 0;
|
buffer.data = malloc(HTTP_BUFFER_SIZE);
|
||||||
s64 t = gettime();
|
buffer.size = HTTP_BUFFER_SIZE;
|
||||||
|
|
||||||
|
if (buffer.data == NULL)
|
||||||
|
{
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
|
||||||
//The offset variable always points to the first byte of memory that is free in the buffer
|
//The offset variable always points to the first byte of memory that is free in the buffer
|
||||||
while (true)
|
u32 offset = 0;
|
||||||
|
|
||||||
|
while(true)
|
||||||
{
|
{
|
||||||
if(ticks_to_millisecs(diff_ticks(t, gettime())) > TCP_TIMEOUT || buffer.size <= offset)
|
//Fill the buffer with a new batch of bytes from the connection,
|
||||||
break;
|
|
||||||
|
|
||||||
//Fill the buffer with a new batch of bytes from the connection,
|
|
||||||
//starting from where we left of in the buffer till the end of the buffer
|
//starting from where we left of in the buffer till the end of the buffer
|
||||||
u32 len = buffer.size - offset;
|
s32 bytes_read = net_read(connection, buffer.data + offset, buffer.size - offset);
|
||||||
s32 bytes_read = net_read(connection, buffer.data + offset, len > HTTP_BUFFER_GROWTH ? HTTP_BUFFER_GROWTH : len);
|
|
||||||
//Anything below 0 is an error in the connection
|
|
||||||
if(bytes_read > 0)
|
|
||||||
{
|
|
||||||
t = gettime ();
|
|
||||||
|
|
||||||
offset += bytes_read;
|
//Anything below 0 is an error in the connection
|
||||||
// Not enough memory
|
if(bytes_read < 0)
|
||||||
if(buffer.size <= offset) return emptyblock;
|
|
||||||
if(!hdr && offset >= sizeof tmpHdr)
|
|
||||||
{
|
|
||||||
hdr = true;
|
|
||||||
memcpy(tmpHdr, buffer.data, sizeof tmpHdr - 1);
|
|
||||||
tmpHdr[sizeof tmpHdr - 1] = 0;
|
|
||||||
const char *p = strstr(tmpHdr, "Content-Length:");
|
|
||||||
if(p != 0)
|
|
||||||
{
|
|
||||||
p += sizeof "Content-Length:";
|
|
||||||
fileSize = strtol(p, 0, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(step * HTTP_BUFFER_GROWTH < offset)
|
|
||||||
{
|
|
||||||
++step;
|
|
||||||
if(f != 0)
|
|
||||||
{
|
|
||||||
if((fileSize != 0 && !f(ud, fileSize, offset <= fileSize ? offset : fileSize)) ||
|
|
||||||
(fileSize == 0 && !f(ud, buffer.size, offset)))
|
|
||||||
return emptyblock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fail = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if(bytes_read < 0) fail = true;
|
//printf("Connection error from net_read() Errorcode: %i\n", bytes_read);
|
||||||
break; // Need to translate the error messages here instead of just breaking.
|
return emptyblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
//No more bytes were read into the buffer,
|
||||||
|
//we assume this means the HTTP response is done
|
||||||
|
if(bytes_read == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += bytes_read;
|
||||||
|
|
||||||
|
//Check if we have enough buffer left over,
|
||||||
|
//if not expand it with an additional HTTP_BUFFER_GROWTH worth of bytes
|
||||||
|
if (offset >= buffer.size)
|
||||||
|
{
|
||||||
|
buffer.size += HTTP_BUFFER_GROWTH;
|
||||||
|
u8 * tmp = realloc(buffer.data, buffer.size);
|
||||||
|
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
free(buffer.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
buffer.data = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fail) return emptyblock;
|
|
||||||
//At the end of above loop offset should be precisely the amount of bytes that were read from the connection
|
//At the end of above loop offset should be precisely the amount of bytes that were read from the connection
|
||||||
buffer.size = offset;
|
buffer.size = offset;
|
||||||
|
|
||||||
|
//Shrink the size of the buffer so the data fits exactly in it
|
||||||
|
buffer.data = realloc(buffer.data, buffer.size);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Downloads the contents of a URL to memory
|
/* Downloads the contents of a URL to memory
|
||||||
* This method is not threadsafe (because networking is not threadsafe on the Wii) */
|
* This method is not threadsafe (because networking is not threadsafe on the Wii) */
|
||||||
struct block downloadfile(u8 *buffer, u32 bufferSize, const char *url, bool (*f)(void *, int, int), void *ud)
|
struct block downloadfile(const char *url)
|
||||||
{
|
{
|
||||||
//Check if the url starts with "http://", if not it is not considered a valid url
|
//Check if the url starts with "http://", if not it is not considered a valid url
|
||||||
if(strncmp(url, "http://", strlen("http://")) != 0) return emptyblock;
|
if(strncmp(url, "http://", strlen("http://")) != 0)
|
||||||
|
return emptyblock;
|
||||||
|
|
||||||
//Locate the path part of the url by searching for '/' past "http://"
|
//Locate the path part of the url by searching for '/' past "http://"
|
||||||
char *path = strchr(url + strlen("http://"), '/');
|
char *path = strchr(url + strlen("http://"), '/');
|
||||||
if(path == NULL) return emptyblock;
|
if(path == NULL)
|
||||||
|
return emptyblock;
|
||||||
|
|
||||||
//Extract the domain part out of the url
|
//Extract the domain part out of the url
|
||||||
int domainlength = path - url - strlen("http://");
|
int domainlength = path - url - strlen("http://");
|
||||||
if(domainlength == 0) return emptyblock;
|
if(domainlength == 0)
|
||||||
|
return emptyblock;
|
||||||
|
|
||||||
char domain[domainlength + 1];
|
char domain[domainlength + 1];
|
||||||
strncpy(domain, url + strlen("http://"), domainlength);
|
strlcpy(domain, url + strlen("http://"), domainlength + 1);
|
||||||
domain[domainlength] = '\0';
|
|
||||||
|
|
||||||
//Parsing of the URL is done, start making an actual connection
|
//Parsing of the URL is done, start making an actual connection
|
||||||
u32 ipaddress = getipbynamecached(domain);
|
u32 ipaddress = getipbynamecached(domain);
|
||||||
if(ipaddress == 0) return emptyblock;
|
if(ipaddress == 0)
|
||||||
|
return emptyblock;
|
||||||
|
|
||||||
s32 connection = server_connect(ipaddress, 80);
|
s32 connection = server_connect(ipaddress, 80);
|
||||||
if(connection < 0) return emptyblock;
|
if(connection < 0)
|
||||||
|
return emptyblock;
|
||||||
|
|
||||||
//Form a nice request header to send to the webserver
|
//Form a nice request header to send to the webserver
|
||||||
char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: WiiFlow 2.1\r\n\r\n";;
|
char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: WiiFlow 2.1\r\n\r\n";
|
||||||
char header[strlen(headerformat) + strlen(domain) + strlen(path)];
|
char header[strlen(headerformat) + strlen(domain) + strlen(path)];
|
||||||
sprintf(header, headerformat, path, domain);
|
sprintf(header, headerformat, path, domain);
|
||||||
|
|
||||||
//Do the request and get the response
|
//Do the request and get the response
|
||||||
send_message(connection, header);
|
send_message(connection, header);
|
||||||
if (bufferSize == 0) return emptyblock;
|
struct block response = read_message(connection);
|
||||||
struct block buf;
|
|
||||||
buf.data = buffer;
|
|
||||||
buf.size = bufferSize;
|
|
||||||
struct block response = read_message(connection, buf, f, ud);
|
|
||||||
net_close(connection);
|
net_close(connection);
|
||||||
|
|
||||||
//Search for the 4-character sequence \r\n\r\n in the response which signals the start of the http payload (file)
|
//Search for the 4-character sequence \r\n\r\n in the response which signals the start of the http payload (file)
|
||||||
unsigned char *filestart = NULL;
|
unsigned char *filestart = NULL;
|
||||||
u32 filesize = 0;
|
u32 filesize = 0;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
char newURL[512];
|
||||||
|
bool redirect = false;
|
||||||
|
|
||||||
for(i = 3; i < response.size; i++)
|
for(i = 3; i < response.size; i++)
|
||||||
{
|
{
|
||||||
if(response.data[i] == '\n' &&
|
if(response.data[i] == '\n' && response.data[i-1] == '\r' && response.data[i-2] == '\n' && response.data[i-3] == '\r')
|
||||||
response.data[i-1] == '\r' &&
|
|
||||||
response.data[i-2] == '\n' &&
|
|
||||||
response.data[i-3] == '\r')
|
|
||||||
{
|
{
|
||||||
filestart = response.data + i + 1;
|
filestart = response.data + i + 1;
|
||||||
filesize = response.size - i - 1;
|
filesize = response.size - i - 1;
|
||||||
break;
|
|
||||||
}
|
// Check the HTTP response code
|
||||||
}
|
if (response.size > 10 && strncmp((char*)response.data, "HTTP/", 5)==0)
|
||||||
|
|
||||||
if(response.size == 0 || response.data == NULL) return emptyblock;
|
|
||||||
|
|
||||||
// Check for the headers
|
|
||||||
char httpCode[3];
|
|
||||||
memcpy(httpCode, &response.data[9], 3);
|
|
||||||
int retCode = atoi(httpCode);
|
|
||||||
|
|
||||||
switch(retCode)
|
|
||||||
{
|
|
||||||
case 301:
|
|
||||||
case 302:
|
|
||||||
case 307: // Moved
|
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
char redirectedTo[255];
|
char htstat[i];
|
||||||
if(findHeader((char *) response.data, (filestart - response.data), "Location", redirectedTo, 255) == 0) {
|
strncpy(htstat, (char*)response.data, i);
|
||||||
return downloadfile(buffer, bufferSize, (char *) redirectedTo, f, ud);
|
htstat[i] = 0;
|
||||||
|
char *codep;
|
||||||
|
codep = strchr(htstat, ' ');
|
||||||
|
if (codep)
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
if (sscanf(codep+1, "%d", &code) == 1)
|
||||||
|
{
|
||||||
|
//gprintf("HTTP response code: %d\n", code);
|
||||||
|
if (code == 302) // 302 FOUND (redirected link)
|
||||||
|
{
|
||||||
|
char *ptr = strcasestr((char*)response.data, "Location: ");
|
||||||
|
if(ptr)
|
||||||
|
{
|
||||||
|
ptr += strlen("Location: ");
|
||||||
|
strncpy(newURL, ptr, sizeof(newURL));
|
||||||
|
*(strchr(newURL, '\r'))=0;
|
||||||
|
|
||||||
|
redirect = true;
|
||||||
|
//gprintf("New URL to download = %s \n", newURL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//gprintf("HTTP ERROR: %s\n", htstat);
|
||||||
|
free(response.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (code >= 400) // Not found
|
||||||
|
{
|
||||||
|
//gprintf("HTTP ERROR: %s\n", htstat);
|
||||||
|
free(response.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return emptyblock;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
case 404: // Error, file not found!
|
|
||||||
return emptyblock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(redirect)
|
||||||
|
{
|
||||||
|
// Prevent endless loop
|
||||||
|
retryloop++;
|
||||||
|
if(retryloop > 3)
|
||||||
|
{
|
||||||
|
retryloop = 0;
|
||||||
|
free(response.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct block redirected = downloadfile(newURL);
|
||||||
|
|
||||||
|
// copy the newURL data into the original data
|
||||||
|
u8 * tmp = realloc(response.data, redirected.size);
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
//gprintf("Could not allocate enough memory for new URL. Download canceled.\n");
|
||||||
|
free(response.data);
|
||||||
|
free(redirected.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
response.data = tmp;
|
||||||
|
memcpy(response.data, redirected.data, redirected.size);
|
||||||
|
|
||||||
|
// Set filestart's new size based on redirected file
|
||||||
|
filestart = response.data;
|
||||||
|
filesize = redirected.size;
|
||||||
|
free(redirected.data);
|
||||||
|
|
||||||
|
}
|
||||||
|
retryloop = 0;
|
||||||
|
|
||||||
if(filestart == NULL) return emptyblock;
|
if(filestart == NULL)
|
||||||
|
{
|
||||||
|
free(response.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
|
||||||
//Copy the file part of the response into a new memoryblock to return
|
//Copy the file part of the response into a new memoryblock to return
|
||||||
struct block file;
|
struct block file;
|
||||||
file.data = filestart;
|
file.data = malloc(filesize);
|
||||||
file.size = filesize;
|
file.size = filesize;
|
||||||
|
|
||||||
|
if (file.data == NULL)
|
||||||
|
{
|
||||||
|
//printf("No more memory to copy file from HTTP response\n");
|
||||||
|
free(response.data);
|
||||||
|
return emptyblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(file.data, filestart, filesize);
|
||||||
|
|
||||||
|
//Dispose of the original response
|
||||||
|
free(response.data);
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ struct block
|
|||||||
|
|
||||||
extern const struct block emptyblock;
|
extern const struct block emptyblock;
|
||||||
|
|
||||||
struct block downloadfile(u8 *buffer, u32 bufferSize, const char *url, bool (*f)(void *, int, int), void *ud);
|
struct block downloadfile(const char *url);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ dl5=Download
|
|||||||
dl6=Download
|
dl6=Download
|
||||||
dl8=Covers
|
dl8=Covers
|
||||||
dlmsg1=Initializing network...
|
dlmsg1=Initializing network...
|
||||||
dlmsg10=Making %s
|
dlmsg10=Making %s.wfc
|
||||||
dlmsg11=Downloading...
|
dlmsg11=Downloading...
|
||||||
dlmsg12=Download failed
|
dlmsg12=Download failed
|
||||||
dlmsg13=Saving...
|
dlmsg13=Saving...
|
||||||
@ -248,13 +248,14 @@ dlmsg20=No version information found.
|
|||||||
dlmsg21=WiiFlow will now exit to allow the update to take effect.
|
dlmsg21=WiiFlow will now exit to allow the update to take effect.
|
||||||
dlmsg22=Updating application directory...
|
dlmsg22=Updating application directory...
|
||||||
dlmsg23=Updating data directory...
|
dlmsg23=Updating data directory...
|
||||||
dlmsg24=Extracting...
|
dlmsg24=Extracting %s
|
||||||
dlmsg25=Extraction must have failed! Renaming the backup to boot.dol
|
dlmsg25=Extraction must have failed! Renaming the backup to boot.dol
|
||||||
dlmsg26=Updating cache...
|
dlmsg26=Updating cache...
|
||||||
dlmsg27=Not enough memory!
|
dlmsg27=Not enough memory!
|
||||||
dlmsg28=Running FTP Server on %s:%u
|
dlmsg28=Running FTP Server on %s:%u
|
||||||
dlmsg29=FTP Server is currently stopped.
|
dlmsg29=FTP Server is currently stopped.
|
||||||
dlmsg3=Downloading from %s
|
dlmsg3=Downloading %i/%i from %s
|
||||||
|
dlmsg30=No covers missing.
|
||||||
dlmsg4=Saving %s
|
dlmsg4=Saving %s
|
||||||
dlmsg5=%i/%i files downloaded
|
dlmsg5=%i/%i files downloaded
|
||||||
dlmsg6=Canceling...
|
dlmsg6=Canceling...
|
||||||
|
Loading…
Reference in New Issue
Block a user