Experimental moddownload
This commit is contained in:
parent
c5bb8547e0
commit
243ddc400d
@ -3,6 +3,229 @@
|
|||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
mg_mgr Download::Mgr;
|
mg_mgr Download::Mgr;
|
||||||
|
Download::ClientDownload Download::CLDownload;
|
||||||
|
|
||||||
|
#pragma region Client
|
||||||
|
|
||||||
|
void Download::InitiateClientDownload(std::string mod)
|
||||||
|
{
|
||||||
|
if (Download::CLDownload.Running) return;
|
||||||
|
|
||||||
|
Download::CLDownload.Mutex.lock();
|
||||||
|
Download::CLDownload.Progress = "Downloading mod";
|
||||||
|
Download::CLDownload.Mutex.unlock();
|
||||||
|
|
||||||
|
Command::Execute("openmenu popup_reconnectingtoparty", true);
|
||||||
|
|
||||||
|
Download::CLDownload.Running = true;
|
||||||
|
Download::CLDownload.Mod = mod;
|
||||||
|
Download::CLDownload.Target = Party::Target();
|
||||||
|
Download::CLDownload.Thread = std::thread(Download::ModDownloader, &Download::CLDownload);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Download::ParseModList(ClientDownload* download, std::string list)
|
||||||
|
{
|
||||||
|
if (!download) return false;
|
||||||
|
download->Files.clear();
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
json11::Json listData = json11::Json::parse(list, error);
|
||||||
|
|
||||||
|
|
||||||
|
if (!error.empty() || !listData.is_array()) return false;
|
||||||
|
|
||||||
|
for (auto& file : listData.array_items())
|
||||||
|
{
|
||||||
|
if (!file.is_object()) return false;
|
||||||
|
|
||||||
|
auto hash = file["hash"];
|
||||||
|
auto name = file["name"];
|
||||||
|
auto size = file["size"];
|
||||||
|
|
||||||
|
if (!hash.is_string() || !name.is_string() || !size.is_number()) return false;
|
||||||
|
|
||||||
|
Download::ClientDownload::File fileEntry;
|
||||||
|
fileEntry.Name = name.string_value();
|
||||||
|
fileEntry.Hash = hash.string_value();
|
||||||
|
fileEntry.Size = static_cast<size_t>(size.number_value());
|
||||||
|
|
||||||
|
if (!fileEntry.Name.empty())
|
||||||
|
{
|
||||||
|
download->Files.push_back(fileEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Download::DownloadHandler(mg_connection *nc, int ev, void* ev_data)
|
||||||
|
{
|
||||||
|
http_message* hm = reinterpret_cast<http_message*>(ev_data);
|
||||||
|
Download::FileDownload* fDownload = reinterpret_cast<Download::FileDownload*>(nc->mgr->user_data);
|
||||||
|
|
||||||
|
if (ev == MG_EV_CONNECT)
|
||||||
|
{
|
||||||
|
if (hm->message.p)
|
||||||
|
{
|
||||||
|
fDownload->downloading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev == MG_EV_RECV)
|
||||||
|
{
|
||||||
|
fDownload->receivedBytes += static_cast<size_t>(*reinterpret_cast<int*>(ev_data));
|
||||||
|
|
||||||
|
double progress = (100.0 / fDownload->file.Size) * fDownload->receivedBytes;
|
||||||
|
fDownload->download->Mutex.lock();
|
||||||
|
fDownload->download->Progress = fmt::sprintf("Downloading file (%d/%d) %s %d%%", fDownload->index + 1, fDownload->download->Files.size(), fDownload->file.Name.data(), static_cast<unsigned int>(progress));
|
||||||
|
fDownload->download->Mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev == MG_EV_HTTP_REPLY)
|
||||||
|
{
|
||||||
|
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||||
|
fDownload->buffer = std::string(hm->body.p, hm->body.len);
|
||||||
|
fDownload->downloading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Download::DownloadFile(ClientDownload* download, unsigned int index)
|
||||||
|
{
|
||||||
|
if (!download || download->Files.size() <= index) return false;
|
||||||
|
|
||||||
|
auto file = download->Files[index];
|
||||||
|
|
||||||
|
download->Mutex.lock();
|
||||||
|
download->Progress = fmt::sprintf("Downloading file (%d/%d) %s 0%%", index + 1, download->Files.size(), file.Name.data());
|
||||||
|
download->Mutex.unlock();
|
||||||
|
|
||||||
|
std::string path = download->Mod + "/" + file.Name;
|
||||||
|
if (Utils::IO::FileExists(path))
|
||||||
|
{
|
||||||
|
std::string data = Utils::IO::ReadFile(path);
|
||||||
|
|
||||||
|
if (data.size() == file.Size && Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(data), "") == file.Hash)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url = "http://" + download->Target.GetString() + "/file/" + file.Name;
|
||||||
|
|
||||||
|
Download::FileDownload fDownload;
|
||||||
|
fDownload.file = file;
|
||||||
|
fDownload.index = index;
|
||||||
|
fDownload.download = download;
|
||||||
|
fDownload.downloading = true;
|
||||||
|
fDownload.receivedBytes = 0;
|
||||||
|
|
||||||
|
download->Valid = true;
|
||||||
|
mg_mgr_init(&download->Mgr, &fDownload);
|
||||||
|
mg_connect_http(&download->Mgr, Download::DownloadHandler, url.data(), NULL, NULL);
|
||||||
|
|
||||||
|
while (fDownload.downloading)
|
||||||
|
{
|
||||||
|
mg_mgr_poll(&download->Mgr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_mgr_free(&download->Mgr);
|
||||||
|
download->Valid = false;
|
||||||
|
|
||||||
|
if (fDownload.buffer.size() != file.Size || Utils::String::DumpHex(Utils::Cryptography::SHA256::Compute(fDownload.buffer), "") != file.Hash)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::IO::CreateDirectory(download->Mod);
|
||||||
|
Utils::IO::WriteFile(path, fDownload.buffer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Download::ModDownloader(ClientDownload* download)
|
||||||
|
{
|
||||||
|
if (!download) download = &Download::CLDownload;
|
||||||
|
|
||||||
|
std::string host = "http://" + download->Target.GetString();
|
||||||
|
std::string list = Utils::WebIO("IW4x", host + "/list").SetTimeout(5000)->Get();
|
||||||
|
|
||||||
|
if (list.empty())
|
||||||
|
{
|
||||||
|
download->Thread.detach();
|
||||||
|
download->Clear();
|
||||||
|
|
||||||
|
QuickPatch::Once([] ()
|
||||||
|
{
|
||||||
|
Party::ConnectError("Failed to download the modlist!");
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Download::ParseModList(download, list))
|
||||||
|
{
|
||||||
|
download->Thread.detach();
|
||||||
|
download->Clear();
|
||||||
|
|
||||||
|
QuickPatch::Once([] ()
|
||||||
|
{
|
||||||
|
Party::ConnectError("Failed to parse the modlist!");
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < download->Files.size(); ++i)
|
||||||
|
{
|
||||||
|
if (!Download::DownloadFile(download, i))
|
||||||
|
{
|
||||||
|
Dvar::Var("partyend_reason").Set(fmt::sprintf("Failed to download file: %s!", download->Files[i].Name.data()));
|
||||||
|
|
||||||
|
download->Thread.detach();
|
||||||
|
download->Clear();
|
||||||
|
|
||||||
|
QuickPatch::Once([] ()
|
||||||
|
{
|
||||||
|
Localization::ClearTemp();
|
||||||
|
Command::Execute("closemenu popup_reconnectingtoparty");
|
||||||
|
Command::Execute("openmenu menu_xboxlive_partyended");
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string mod = download->Mod;
|
||||||
|
|
||||||
|
download->Thread.detach();
|
||||||
|
download->Clear();
|
||||||
|
|
||||||
|
// Run this on the main thread
|
||||||
|
QuickPatch::Once([] ()
|
||||||
|
{
|
||||||
|
auto fsGame = Dvar::Var("fs_game");
|
||||||
|
fsGame.Set(mod);
|
||||||
|
fsGame.Get<Game::dvar_t*>()->pad2[0] = 1;
|
||||||
|
|
||||||
|
mod.clear();
|
||||||
|
|
||||||
|
Localization::ClearTemp();
|
||||||
|
Command::Execute("closemenu popup_reconnectingtoparty", true);
|
||||||
|
|
||||||
|
if (Dvar::Var("cl_modVidRestart").Get<bool>())
|
||||||
|
{
|
||||||
|
Command::Execute("vid_restart", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::Execute("reconnect", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Server
|
||||||
|
|
||||||
bool Download::IsClient(mg_connection *nc)
|
bool Download::IsClient(mg_connection *nc)
|
||||||
{
|
{
|
||||||
@ -283,6 +506,8 @@ namespace Components
|
|||||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
Download::Download()
|
Download::Download()
|
||||||
{
|
{
|
||||||
if (Dedicated::IsEnabled())
|
if (Dedicated::IsEnabled())
|
||||||
@ -308,12 +533,22 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Utils::Hook(0x5AC6E9, [] ()
|
// Utils::Hook(0x5AC6E9, [] ()
|
||||||
{
|
// {
|
||||||
// TODO: Perform moddownload here
|
// // TODO: Perform moddownload here
|
||||||
|
//
|
||||||
|
// Game::CL_DownloadsComplete(0);
|
||||||
|
// }, HOOK_CALL).Install()->Quick();
|
||||||
|
|
||||||
Game::CL_DownloadsComplete(0);
|
QuickPatch::OnFrame([]
|
||||||
}, HOOK_CALL).Install()->Quick();
|
{
|
||||||
|
if (Download::CLDownload.Running)
|
||||||
|
{
|
||||||
|
Download::CLDownload.Mutex.lock();
|
||||||
|
Localization::SetTemp("MENU_RECONNECTING_TO_PARTY", Download::CLDownload.Progress);
|
||||||
|
Download::CLDownload.Mutex.unlock();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +560,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Download::CLDownload.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,16 +10,79 @@ namespace Components
|
|||||||
const char* GetName() { return "Download"; };
|
const char* GetName() { return "Download"; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void InitiateClientDownload(std::string mod);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class ClientDownload
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientDownload() : Valid(false), Running(false) {}
|
||||||
|
~ClientDownload() { this->Clear(); }
|
||||||
|
|
||||||
|
bool Running;
|
||||||
|
bool Valid;
|
||||||
|
mg_mgr Mgr;
|
||||||
|
Network::Address Target;
|
||||||
|
std::string Mod;
|
||||||
|
std::mutex Mutex;
|
||||||
|
std::thread Thread;
|
||||||
|
std::string Progress;
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string Name;
|
||||||
|
std::string Hash;
|
||||||
|
size_t Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<File> Files;
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
this->Running = false;
|
||||||
|
this->Mod.clear();
|
||||||
|
this->Files.clear();
|
||||||
|
|
||||||
|
if (this->Valid)
|
||||||
|
{
|
||||||
|
this->Valid = false;
|
||||||
|
mg_mgr_free(&(this->Mgr));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Mutex.lock();
|
||||||
|
this->Progress.clear();
|
||||||
|
this->Mutex.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileDownload
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ClientDownload* download;
|
||||||
|
ClientDownload::File file;
|
||||||
|
|
||||||
|
bool downloading;
|
||||||
|
unsigned int index;
|
||||||
|
std::string buffer;
|
||||||
|
size_t receivedBytes;
|
||||||
|
};
|
||||||
|
|
||||||
static mg_mgr Mgr;
|
static mg_mgr Mgr;
|
||||||
|
static ClientDownload CLDownload;
|
||||||
|
|
||||||
static void EventHandler(mg_connection *nc, int ev, void *ev_data);
|
static void EventHandler(mg_connection *nc, int ev, void *ev_data);
|
||||||
static void ListHandler(mg_connection *nc, int ev, void *ev_data);
|
static void ListHandler(mg_connection *nc, int ev, void *ev_data);
|
||||||
static void FileHandler(mg_connection *nc, int ev, void *ev_data);
|
static void FileHandler(mg_connection *nc, int ev, void *ev_data);
|
||||||
static void InfoHandler(mg_connection *nc, int ev, void *ev_data);
|
static void InfoHandler(mg_connection *nc, int ev, void *ev_data);
|
||||||
|
static void DownloadHandler(mg_connection *nc, int ev, void *ev_data);
|
||||||
|
|
||||||
static bool IsClient(mg_connection *nc);
|
static bool IsClient(mg_connection *nc);
|
||||||
static Game::client_t* GetClient(mg_connection *nc);
|
static Game::client_t* GetClient(mg_connection *nc);
|
||||||
static void Forbid(mg_connection *nc);
|
static void Forbid(mg_connection *nc);
|
||||||
|
|
||||||
|
static void ModDownloader(ClientDownload* download);
|
||||||
|
static bool ParseModList(ClientDownload* download, std::string list);
|
||||||
|
static bool DownloadFile(ClientDownload* download, unsigned int index);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ namespace Components
|
|||||||
|
|
||||||
void Party::ConnectError(std::string message)
|
void Party::ConnectError(std::string message)
|
||||||
{
|
{
|
||||||
|
Localization::ClearTemp();
|
||||||
Command::Execute("closemenu popup_reconnectingtoparty");
|
Command::Execute("closemenu popup_reconnectingtoparty");
|
||||||
Dvar::Var("partyend_reason").Set(message);
|
Dvar::Var("partyend_reason").Set(message);
|
||||||
Command::Execute("openmenu menu_xboxlive_partyended");
|
Command::Execute("openmenu menu_xboxlive_partyended");
|
||||||
@ -354,8 +355,9 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// Invalidate handler for future packets
|
// Invalidate handler for future packets
|
||||||
Party::Container.Valid = false;
|
Party::Container.Valid = false;
|
||||||
|
Party::Container.Info = info;
|
||||||
|
|
||||||
int matchType = atoi(info.Get("matchtype").data());
|
Party::Container.MatchType = atoi(info.Get("matchtype").data());
|
||||||
uint32_t securityLevel = static_cast<uint32_t>(atoi(info.Get("securityLevel").data()));
|
uint32_t securityLevel = static_cast<uint32_t>(atoi(info.Get("securityLevel").data()));
|
||||||
|
|
||||||
if (info.Get("challenge") != Party::Container.Challenge)
|
if (info.Get("challenge") != Party::Container.Challenge)
|
||||||
@ -368,48 +370,55 @@ namespace Components
|
|||||||
Command::Execute("closemenu popup_reconnectingtoparty");
|
Command::Execute("closemenu popup_reconnectingtoparty");
|
||||||
Auth::IncreaseSecurityLevel(securityLevel, "reconnect");
|
Auth::IncreaseSecurityLevel(securityLevel, "reconnect");
|
||||||
}
|
}
|
||||||
else if (!matchType)
|
else if (!Party::Container.MatchType)
|
||||||
{
|
{
|
||||||
Party::ConnectError("Server is not hosting a match.");
|
Party::ConnectError("Server is not hosting a match.");
|
||||||
}
|
}
|
||||||
// Connect
|
else if(Party::Container.MatchType > 2 || Party::Container.MatchType < 0)
|
||||||
else if (matchType == 1) // Party
|
|
||||||
{
|
{
|
||||||
// Send playlist request
|
Party::ConnectError("Invalid join response: Unknown matchtype");
|
||||||
Party::Container.RequestTime = Game::Sys_Milliseconds();
|
|
||||||
Party::Container.AwaitingPlaylist = true;
|
|
||||||
Network::SendCommand(address, "getplaylist");
|
|
||||||
|
|
||||||
// This is not a safe method
|
|
||||||
// TODO: Fix actual error!
|
|
||||||
if (Game::CL_IsCgameInitialized())
|
|
||||||
{
|
|
||||||
Command::Execute("disconnect", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (matchType == 2) // Match
|
else if(!info.Get("fs_game").empty() && Dvar::Var("fs_game").Get<std::string>() != info.Get("fs_game"))
|
||||||
{
|
{
|
||||||
if (atoi(info.Get("clients").data()) >= atoi(info.Get("sv_maxclients").data()))
|
Command::Execute("closemenu popup_reconnectingtoparty");
|
||||||
{
|
Download::InitiateClientDownload(info.Get("fs_game"));
|
||||||
Party::ConnectError("@EXE_SERVERISFULL");
|
|
||||||
}
|
|
||||||
if (info.Get("mapname") == "" || info.Get("gametype") == "")
|
|
||||||
{
|
|
||||||
Party::ConnectError("Invalid map or gametype.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dvar::Var("xblive_privateserver").Set(true);
|
|
||||||
|
|
||||||
Game::Menus_CloseAll(Game::uiContext);
|
|
||||||
|
|
||||||
Game::_XSESSION_INFO hostInfo;
|
|
||||||
Game::CL_ConnectFromParty(0, &hostInfo, *address.Get(), 0, 0, info.Get("mapname").data(), info.Get("gametype").data());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Party::ConnectError("Invalid join response: Unknown matchtype");
|
if (Party::Container.MatchType == 1) // Party
|
||||||
|
{
|
||||||
|
// Send playlist request
|
||||||
|
Party::Container.RequestTime = Game::Sys_Milliseconds();
|
||||||
|
Party::Container.AwaitingPlaylist = true;
|
||||||
|
Network::SendCommand(Party::Container.Target, "getplaylist");
|
||||||
|
|
||||||
|
// This is not a safe method
|
||||||
|
// TODO: Fix actual error!
|
||||||
|
if (Game::CL_IsCgameInitialized())
|
||||||
|
{
|
||||||
|
Command::Execute("disconnect", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Party::Container.MatchType == 2) // Match
|
||||||
|
{
|
||||||
|
if (atoi(Party::Container.Info.Get("clients").data()) >= atoi(Party::Container.Info.Get("sv_maxclients").data()))
|
||||||
|
{
|
||||||
|
Party::ConnectError("@EXE_SERVERISFULL");
|
||||||
|
}
|
||||||
|
if (Party::Container.Info.Get("mapname") == "" || Party::Container.Info.Get("gametype") == "")
|
||||||
|
{
|
||||||
|
Party::ConnectError("Invalid map or gametype.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dvar::Var("xblive_privateserver").Set(true);
|
||||||
|
|
||||||
|
Game::Menus_CloseAll(Game::uiContext);
|
||||||
|
|
||||||
|
Game::_XSESSION_INFO hostInfo;
|
||||||
|
Game::CL_ConnectFromParty(0, &hostInfo, *Party::Container.Target.Get(), 0, 0, Party::Container.Info.Get("mapname").data(), Party::Container.Info.Get("gametype").data());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ namespace Components
|
|||||||
static void PlaylistContinue();
|
static void PlaylistContinue();
|
||||||
static void PlaylistError(std::string error);
|
static void PlaylistError(std::string error);
|
||||||
|
|
||||||
|
static void ConnectError(std::string message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class JoinContainer
|
class JoinContainer
|
||||||
{
|
{
|
||||||
@ -27,6 +29,9 @@ namespace Components
|
|||||||
std::string Challenge;
|
std::string Challenge;
|
||||||
DWORD JoinTime;
|
DWORD JoinTime;
|
||||||
bool Valid;
|
bool Valid;
|
||||||
|
int MatchType;
|
||||||
|
|
||||||
|
Utils::InfoString Info;
|
||||||
|
|
||||||
// Party-specific stuff
|
// Party-specific stuff
|
||||||
DWORD RequestTime;
|
DWORD RequestTime;
|
||||||
@ -40,8 +45,6 @@ namespace Components
|
|||||||
|
|
||||||
static Game::dvar_t* RegisterMinPlayers(const char* name, int value, int min, int max, Game::dvar_flag flag, const char* description);
|
static Game::dvar_t* RegisterMinPlayers(const char* name, int value, int min, int max, Game::dvar_flag flag, const char* description);
|
||||||
|
|
||||||
static void ConnectError(std::string message);
|
|
||||||
|
|
||||||
static DWORD UIDvarIntStub(char* dvar);
|
static DWORD UIDvarIntStub(char* dvar);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace Utils
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = static_cast<int>(this->TokenString.size() - 1); i >= 0; i--)
|
for (int i = static_cast<int>(this->TokenString.size() - 1); i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (this->TokenString[i] == 0xFF)
|
if (this->TokenString[i] == 0xFF)
|
||||||
{
|
{
|
||||||
|
@ -47,5 +47,40 @@ namespace Utils
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateDirectory(std::string dir)
|
||||||
|
{
|
||||||
|
char opath[MAX_PATH];
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
strncpy_s(opath, dir.data(), sizeof(opath));
|
||||||
|
len = strlen(opath);
|
||||||
|
|
||||||
|
if (opath[len - 1] == L'/')
|
||||||
|
{
|
||||||
|
opath[len - 1] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = opath; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p == L'/' || *p == L'\\')
|
||||||
|
{
|
||||||
|
*p = L'\0';
|
||||||
|
|
||||||
|
if (_access(opath, 0))
|
||||||
|
{
|
||||||
|
_mkdir(opath);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = L'\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_access(opath, 0))
|
||||||
|
{
|
||||||
|
_mkdir(opath);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,6 @@ namespace Utils
|
|||||||
bool FileExists(std::string file);
|
bool FileExists(std::string file);
|
||||||
void WriteFile(std::string file, std::string data);
|
void WriteFile(std::string file, std::string data);
|
||||||
std::string ReadFile(std::string file);
|
std::string ReadFile(std::string file);
|
||||||
|
void CreateDirectory(std::string dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,10 +104,26 @@ namespace Utils
|
|||||||
WebIO::m_sUrl.document = server.substr(pos);
|
WebIO::m_sUrl.document = server.substr(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebIO::m_sUrl.port.clear();
|
||||||
|
|
||||||
|
pos = WebIO::m_sUrl.server.find(":");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
WebIO::m_sUrl.port = WebIO::m_sUrl.server.substr(pos + 1);
|
||||||
|
WebIO::m_sUrl.server = WebIO::m_sUrl.server.substr(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
WebIO::m_sUrl.raw.clear();
|
WebIO::m_sUrl.raw.clear();
|
||||||
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.protocol);
|
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.protocol);
|
||||||
WebIO::m_sUrl.raw.append("://");
|
WebIO::m_sUrl.raw.append("://");
|
||||||
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.server);
|
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.server);
|
||||||
|
|
||||||
|
if (!WebIO::m_sUrl.port.empty())
|
||||||
|
{
|
||||||
|
WebIO::m_sUrl.raw.append(":");
|
||||||
|
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.port);
|
||||||
|
}
|
||||||
|
|
||||||
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.document);
|
WebIO::m_sUrl.raw.append(WebIO::m_sUrl.document);
|
||||||
|
|
||||||
WebIO::m_isFTP = (WebIO::m_sUrl.protocol == "ftp");
|
WebIO::m_isFTP = (WebIO::m_sUrl.protocol == "ftp");
|
||||||
@ -217,6 +233,11 @@ namespace Utils
|
|||||||
wPort = INTERNET_DEFAULT_HTTPS_PORT;
|
wPort = INTERNET_DEFAULT_HTTPS_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!WebIO::m_sUrl.port.empty())
|
||||||
|
{
|
||||||
|
wPort = static_cast<WORD>(atoi(WebIO::m_sUrl.port.data()));
|
||||||
|
}
|
||||||
|
|
||||||
const char* username = (WebIO::m_username.size() ? WebIO::m_username.data() : NULL);
|
const char* username = (WebIO::m_username.size() ? WebIO::m_username.data() : NULL);
|
||||||
const char* password = (WebIO::m_password.size() ? WebIO::m_password.data() : NULL);
|
const char* password = (WebIO::m_password.size() ? WebIO::m_password.data() : NULL);
|
||||||
WebIO::m_hConnect = InternetConnectA(WebIO::m_hSession, WebIO::m_sUrl.server.data(), wPort, username, password, dwService, dwFlag, 0);
|
WebIO::m_hConnect = InternetConnectA(WebIO::m_hSession, WebIO::m_sUrl.server.data(), wPort, username, password, dwService, dwFlag, 0);
|
||||||
|
@ -74,6 +74,7 @@ namespace Utils
|
|||||||
std::string protocol;
|
std::string protocol;
|
||||||
std::string server;
|
std::string server;
|
||||||
std::string document;
|
std::string document;
|
||||||
|
std::string port;
|
||||||
std::string raw;
|
std::string raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user