Add arena file to download + fixes
This commit is contained in:
parent
7a5798d247
commit
e62fc74d98
@ -174,7 +174,7 @@ namespace download
|
|||||||
const auto& result = data.value();
|
const auto& result = data.value();
|
||||||
if (result.code != CURLE_OK)
|
if (result.code != CURLE_OK)
|
||||||
{
|
{
|
||||||
menu_error(utils::string::va("Download failed: %s (%i)\n", result.code, curl_easy_strerror(result.code)));
|
menu_error(utils::string::va("Download failed: %s (%i)\n", curl_easy_strerror(result.code), result.code));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,8 +225,8 @@ namespace fastfiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto& usermap_value = usermap.value();
|
const auto& usermap_value = usermap.value();
|
||||||
const auto usermap_file = utils::string::va("%s.ff", usermap_value.data());
|
const std::string usermap_file = utils::string::va("%s.ff", usermap_value.data());
|
||||||
const auto usermap_load_file = utils::string::va("%s_load.ff", usermap_value.data());
|
const std::string usermap_load_file = utils::string::va("%s_load.ff", usermap_value.data());
|
||||||
|
|
||||||
if (mapname == usermap_file || mapname == usermap_load_file)
|
if (mapname == usermap_file || mapname == usermap_load_file)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,20 @@ namespace party
|
|||||||
std::string sv_motd;
|
std::string sv_motd;
|
||||||
int sv_maxclients;
|
int sv_maxclients;
|
||||||
|
|
||||||
|
struct usermap_file
|
||||||
|
{
|
||||||
|
std::string extension;
|
||||||
|
std::string name;
|
||||||
|
bool optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<usermap_file> usermap_files =
|
||||||
|
{
|
||||||
|
{".ff", "usermaphash", false},
|
||||||
|
{"_load.ff", "usermaploadhash", true},
|
||||||
|
{".arena", "usermaparenahash", true},
|
||||||
|
};
|
||||||
|
|
||||||
void perform_game_initialization()
|
void perform_game_initialization()
|
||||||
{
|
{
|
||||||
command::execute("onlinegame 1", true);
|
command::execute("onlinegame 1", true);
|
||||||
@ -161,7 +175,7 @@ namespace party
|
|||||||
cl_disconnect_hook.invoke<void>(show_main_menu);
|
cl_disconnect_hook.invoke<void>(show_main_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> get_file_hash(const std::string& file)
|
std::string get_file_hash(const std::string& file)
|
||||||
{
|
{
|
||||||
if (!utils::io::file_exists(file))
|
if (!utils::io::file_exists(file))
|
||||||
{
|
{
|
||||||
@ -170,7 +184,12 @@ namespace party
|
|||||||
|
|
||||||
const auto data = utils::io::read_file(file);
|
const auto data = utils::io::read_file(file);
|
||||||
const auto sha = utils::cryptography::sha1::compute(data, true);
|
const auto sha = utils::cryptography::sha1::compute(data, true);
|
||||||
return {sha};
|
return sha;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_usermap_file_path(const std::string& mapname, const std::string& extension)
|
||||||
|
{
|
||||||
|
return utils::string::va("usermaps\\%s\\%s%s", mapname.data(), mapname.data(), extension.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_download_map(const utils::info_string& info, std::vector<download::file_t>& files)
|
void check_download_map(const utils::info_string& info, std::vector<download::file_t>& files)
|
||||||
@ -186,40 +205,52 @@ namespace party
|
|||||||
throw std::runtime_error(utils::string::va("Invalid server mapname value %s\n", mapname.data()));
|
throw std::runtime_error(utils::string::va("Invalid server mapname value %s\n", mapname.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto check_file = [&](const std::string& key, const std::string& ext, bool optional)
|
const auto check_file = [&](const std::string& ext, const std::string& name, bool optional)
|
||||||
{
|
{
|
||||||
const auto filename = utils::string::va("usermaps/%s/%s%s", mapname.data(), mapname.data(), ext.data());
|
const std::string filename = utils::string::va("usermaps/%s/%s%s", mapname.data(), mapname.data(), ext.data());
|
||||||
const auto source_hash = info.get(key);
|
const auto source_hash = info.get(name);
|
||||||
if (source_hash.empty())
|
if (source_hash.empty())
|
||||||
{
|
{
|
||||||
if (!optional)
|
if (!optional)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va("Server %s is empty", key.data()));
|
throw std::runtime_error(utils::string::va("Server %s is empty", name.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto hash = get_file_hash(filename);
|
const auto hash = get_file_hash(filename);
|
||||||
if (!hash.has_value() || hash.value() != source_hash)
|
if (hash != source_hash)
|
||||||
{
|
{
|
||||||
files.emplace_back(filename, source_hash);
|
files.emplace_back(filename, source_hash);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
check_file("usermaphash", ".ff", false);
|
for (const auto& [ext, name, opt] : usermap_files)
|
||||||
check_file("usermaploadhash", "_load.ff", true);
|
{
|
||||||
|
check_file(ext, name, opt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_download_mod(const utils::info_string& info, std::vector<download::file_t>& files)
|
bool check_download_mod(const utils::info_string& info, std::vector<download::file_t>& files)
|
||||||
{
|
{
|
||||||
|
static const auto fs_game = game::Dvar_FindVar("fs_game");
|
||||||
|
const auto client_fs_game = utils::string::to_lower(fs_game->current.string);
|
||||||
const auto server_fs_game = utils::string::to_lower(info.get("fs_game"));
|
const auto server_fs_game = utils::string::to_lower(info.get("fs_game"));
|
||||||
if (server_fs_game.empty())
|
|
||||||
|
if (server_fs_game.empty() && client_fs_game.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server_fs_game.empty() && !client_fs_game.empty())
|
||||||
|
{
|
||||||
|
game::Dvar_SetFromStringByNameFromSource("fs_game", "",
|
||||||
|
game::DVAR_SOURCE_INTERNAL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!server_fs_game.starts_with("mods/") || server_fs_game.contains('.') || server_fs_game.contains("::"))
|
if (!server_fs_game.starts_with("mods/") || server_fs_game.contains('.') || server_fs_game.contains("::"))
|
||||||
{
|
{
|
||||||
throw std::runtime_error(utils::string::va("Invalid server fs_game value %s\n", server_fs_game.data()));
|
throw std::runtime_error(utils::string::va("Invalid server fs_game value %s\n", server_fs_game.data()));
|
||||||
@ -231,9 +262,6 @@ namespace party
|
|||||||
throw std::runtime_error("Connection failed: Server mod hash is empty.");
|
throw std::runtime_error("Connection failed: Server mod hash is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const auto fs_game = game::Dvar_FindVar("fs_game");
|
|
||||||
const auto client_fs_game = utils::string::to_lower(fs_game->current.string);
|
|
||||||
|
|
||||||
const auto mod_path = server_fs_game + "/mod.ff";
|
const auto mod_path = server_fs_game + "/mod.ff";
|
||||||
auto has_to_download = !utils::io::file_exists(mod_path);
|
auto has_to_download = !utils::io::file_exists(mod_path);
|
||||||
|
|
||||||
@ -300,16 +328,24 @@ namespace party
|
|||||||
|
|
||||||
void set_new_map(const char* mapname, const char* gametype, game::msg_t* msg)
|
void set_new_map(const char* mapname, const char* gametype, game::msg_t* msg)
|
||||||
{
|
{
|
||||||
char buffer[0x400] = {0};
|
if (game::SV_Loaded() || fastfiles::is_stock_map(mapname))
|
||||||
// dont bother disconnecting just to update the usermap loadscreen
|
|
||||||
const std::string usermap_hash = game::MSG_ReadStringLine(msg,
|
|
||||||
buffer, static_cast<unsigned int>(sizeof(buffer)));
|
|
||||||
|
|
||||||
if (!game::SV_Loaded() && !fastfiles::is_stock_map(mapname))
|
|
||||||
{
|
{
|
||||||
const auto filename = utils::string::va("usermaps\\%s\\%s.ff", mapname, mapname);
|
utils::hook::invoke<void>(0x13AAD0_b, mapname, gametype);
|
||||||
const auto hash = get_file_hash(filename);
|
return;
|
||||||
if (!hash.has_value() || (usermap_hash.empty() || hash.value() != usermap_hash))
|
}
|
||||||
|
|
||||||
|
for (const auto& [ext, key, opt] : usermap_files)
|
||||||
|
{
|
||||||
|
char buffer[0x100] = {0};
|
||||||
|
const std::string source_hash = game::MSG_ReadStringLine(msg,
|
||||||
|
buffer, static_cast<unsigned int>(sizeof(buffer)));
|
||||||
|
|
||||||
|
const auto path = get_usermap_file_path(mapname, ext);
|
||||||
|
const auto hash = get_file_hash(path);
|
||||||
|
|
||||||
|
console::debug("%s %s %s != %s\n", ext.data(), key.data(), hash.data(), source_hash.data());
|
||||||
|
|
||||||
|
if ((!source_hash.empty() && hash != source_hash) || (source_hash.empty() && !opt))
|
||||||
{
|
{
|
||||||
command::execute("disconnect");
|
command::execute("disconnect");
|
||||||
scheduler::once([]
|
scheduler::once([]
|
||||||
@ -355,26 +391,41 @@ namespace party
|
|||||||
return net_out_of_band_print_hook.invoke<void>(sock, addr, data);
|
return net_out_of_band_print_hook.invoke<void>(sock, addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[0x400] = {0};
|
std::string buffer{};
|
||||||
const auto is_usermap = fastfiles::usermap_exists(current_sv_mapname);
|
const auto line = [&](const std::string& data_)
|
||||||
std::string hash{};
|
|
||||||
if (is_usermap)
|
|
||||||
{
|
{
|
||||||
const auto filename = utils::string::va("usermaps\\%s\\%s.ff",
|
buffer.append(data_);
|
||||||
current_sv_mapname.data(), current_sv_mapname.data());
|
buffer.append("\n");
|
||||||
const auto hash_value = get_file_hash(filename);
|
};
|
||||||
if (hash_value.has_value())
|
|
||||||
|
const auto* sv_gametype = game::Dvar_FindVar("g_gametype");
|
||||||
|
line("loadingnewmap");
|
||||||
|
line(current_sv_mapname);
|
||||||
|
line(sv_gametype->current.string);
|
||||||
|
|
||||||
|
const auto add_hash = [&](const std::string extension)
|
||||||
|
{
|
||||||
|
const auto filename = get_usermap_file_path(current_sv_mapname, extension);
|
||||||
|
const auto hash = get_file_hash(filename);
|
||||||
|
line(hash);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto is_usermap = fastfiles::usermap_exists(current_sv_mapname);
|
||||||
|
for (const auto& [ext, key, opt] : usermap_files)
|
||||||
|
{
|
||||||
|
if (is_usermap)
|
||||||
{
|
{
|
||||||
hash = hash_value.value();
|
add_hash(ext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* sv_gametype = game::Dvar_FindVar("g_gametype");
|
console::debug("%i %s\n", is_usermap, buffer.data());
|
||||||
|
|
||||||
sprintf_s(buffer, sizeof(buffer),
|
net_out_of_band_print_hook.invoke<void>(sock, addr, buffer.data());
|
||||||
"loadingnewmap\n%s\n%s\n%s", current_sv_mapname.data(), sv_gametype->current.string, hash.data());
|
|
||||||
|
|
||||||
net_out_of_band_print_hook.invoke<void>(sock, addr, buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,18 +887,16 @@ namespace party
|
|||||||
|
|
||||||
if (!fastfiles::is_stock_map(mapname))
|
if (!fastfiles::is_stock_map(mapname))
|
||||||
{
|
{
|
||||||
const auto hash = get_file_hash(
|
const auto add_hash = [&](const std::string& extension, const std::string& name)
|
||||||
utils::string::va("usermaps\\%s\\%s.ff", mapname.data(), mapname.data()));
|
|
||||||
if (hash.has_value())
|
|
||||||
{
|
{
|
||||||
info.set("usermaphash", hash.value());
|
const auto path = get_usermap_file_path(mapname, extension);
|
||||||
}
|
const auto hash = get_file_hash(path);
|
||||||
|
info.set(name, hash);
|
||||||
|
};
|
||||||
|
|
||||||
const auto load_file_hash = get_file_hash(
|
for (const auto& [ext, name, opt] : usermap_files)
|
||||||
utils::string::va("usermaps\\%s\\%s_load.ff", mapname.data(), mapname.data()));
|
|
||||||
if (load_file_hash.has_value())
|
|
||||||
{
|
{
|
||||||
info.set("usermaploadhash", load_file_hash.value());
|
add_hash(ext, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,10 +906,7 @@ namespace party
|
|||||||
if (!fs_game.empty())
|
if (!fs_game.empty())
|
||||||
{
|
{
|
||||||
const auto hash = get_file_hash(utils::string::va("%s/mod.ff", fs_game.data()));
|
const auto hash = get_file_hash(utils::string::va("%s/mod.ff", fs_game.data()));
|
||||||
if (hash.has_value())
|
info.set("modHash", hash);
|
||||||
{
|
|
||||||
info.set("modHash", hash.value());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
network::send(target, "infoResponse", info.build(), '\n');
|
network::send(target, "infoResponse", info.build(), '\n');
|
||||||
|
Loading…
Reference in New Issue
Block a user