dedicated_room: load and save ban list

The ban list is stored in a format so-called CitraRoom-BanList-1 and just first stores username ban list, one entry per line, then an empty line and then store the ip ban list.
This commit is contained in:
zhupengfei 2018-11-24 16:26:52 +08:00
parent deb398d190
commit bd29f1facb
No known key found for this signature in database
GPG Key ID: DD129E108BD09378

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <chrono>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex>
@ -27,10 +28,12 @@
#include "common/common_types.h"
#include "common/detached_tasks.h"
#include "common/scm_rev.h"
#include "common/string_util.h"
#include "core/announce_multiplayer_session.h"
#include "core/core.h"
#include "core/settings.h"
#include "network/network.h"
#include "network/room.h"
#include "network/verify_user.h"
#ifdef ENABLE_WEB_SERVICE
@ -50,6 +53,7 @@ static void PrintHelp(const char* argv0) {
"--username The username used for announce\n"
"--token The token used for announce\n"
"--web-api-url Citra Web API url\n"
"--ban-list-file The file for storing the room ban list\n"
"-h, --help Display this help and exit\n"
"-v, --version Output version information and exit\n";
}
@ -59,6 +63,71 @@ static void PrintVersion() {
<< " Libnetwork: " << Network::network_version << std::endl;
}
/// The magic text at the beginning of a citra-room ban list file.
static constexpr char BanListMagic[] = "CitraRoom-BanList-1";
static Network::Room::BanList LoadBanList(const std::string& path) {
std::ifstream file;
OpenFStream(file, path, std::ios_base::in);
if (!file || file.eof()) {
std::cout << "Could not open ban list!\n\n";
return {};
}
std::string magic;
std::getline(file, magic);
if (magic != BanListMagic) {
std::cout << "Ban list is not valid!\n\n";
return {};
}
// false = username ban list, true = ip ban list
bool ban_list_type = false;
Network::Room::UsernameBanList username_ban_list;
Network::Room::IPBanList ip_ban_list;
while (!file.eof()) {
std::string line;
std::getline(file, line);
line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
line = Common::StripSpaces(line);
if (line.empty()) {
// An empty line marks start of the IP ban list
ban_list_type = true;
continue;
}
if (ban_list_type) {
ip_ban_list.emplace_back(line);
} else {
username_ban_list.emplace_back(line);
}
}
return {username_ban_list, ip_ban_list};
}
static void SaveBanList(const Network::Room::BanList& ban_list, const std::string& path) {
std::ofstream file;
OpenFStream(file, path, std::ios_base::out);
if (!file) {
std::cout << "Could not save ban list!\n\n";
return;
}
file << BanListMagic << "\n";
// Username ban list
for (const auto& username : ban_list.first) {
file << username << "\n";
}
file << "\n";
// IP ban list
for (const auto& ip : ban_list.second) {
file << ip << "\n";
}
file.flush();
}
/// Application entry point
int main(int argc, char** argv) {
Common::DetachedTasks detached_tasks;
@ -75,6 +144,7 @@ int main(int argc, char** argv) {
std::string username;
std::string token;
std::string web_api_url;
std::string ban_list_file;
u64 preferred_game_id = 0;
u32 port = Network::DefaultRoomPort;
u32 max_members = 16;
@ -90,6 +160,7 @@ int main(int argc, char** argv) {
{"username", required_argument, 0, 'u'},
{"token", required_argument, 0, 't'},
{"web-api-url", required_argument, 0, 'a'},
{"ban-list-file", required_argument, 0, 'b'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{0, 0, 0, 0},
@ -129,6 +200,9 @@ int main(int argc, char** argv) {
case 'a':
web_api_url.assign(optarg);
break;
case 'b':
ban_list_file.assign(optarg);
break;
case 'h':
PrintHelp(argv[0]);
return 0;
@ -164,6 +238,10 @@ int main(int argc, char** argv) {
PrintHelp(argv[0]);
return -1;
}
if (ban_list_file.empty()) {
std::cout << "Ban list file not set!\nThis should get set to load and save room ban "
"list.\nSet with --ban-list-file <file>\n\n";
}
bool announce = true;
if (username.empty()) {
announce = false;
@ -184,6 +262,12 @@ int main(int argc, char** argv) {
Settings::values.citra_token = token;
}
// Load the ban list
Network::Room::BanList ban_list;
if (!ban_list_file.empty()) {
ban_list = LoadBanList(ban_list_file);
}
std::unique_ptr<Network::VerifyUser::Backend> verify_backend;
if (announce) {
#ifdef ENABLE_WEB_SERVICE
@ -199,8 +283,8 @@ int main(int argc, char** argv) {
Network::Init();
if (std::shared_ptr<Network::Room> room = Network::GetRoom().lock()) {
if (!room->Create(room_name, room_description, "", port, password, max_members,
preferred_game, preferred_game_id, std::move(verify_backend))) {
if (!room->Create(room_name, room_description, "", port, password, max_members, username,
preferred_game, preferred_game_id, std::move(verify_backend), ban_list)) {
std::cout << "Failed to create room: \n\n";
return -1;
}
@ -217,6 +301,10 @@ int main(int argc, char** argv) {
announce_session->Stop();
}
announce_session.reset();
// Save the ban list
if (!ban_list_file.empty()) {
SaveBanList(room->GetBanList(), ban_list_file);
}
room->Destroy();
Network::Shutdown();
return 0;
@ -227,6 +315,10 @@ int main(int argc, char** argv) {
announce_session->Stop();
}
announce_session.reset();
// Save the ban list
if (!ban_list_file.empty()) {
SaveBanList(room->GetBanList(), ban_list_file);
}
room->Destroy();
}
Network::Shutdown();