Browse Source

Clean up server-side translations, remove global variable (#10075)

rubenwardy 3 years ago
parent
commit
9ec75d7765
9 changed files with 50 additions and 65 deletions
  1. 2 7
      src/client/client.cpp
  2. 15 0
      src/filesys.cpp
  3. 2 0
      src/filesys.h
  4. 3 3
      src/script/lua_api/l_env.cpp
  5. 22 31
      src/server.cpp
  6. 5 2
      src/server.h
  7. 1 9
      src/serverlist.cpp
  8. 0 8
      src/translation.cpp
  9. 0 5
      src/translation.h

+ 2 - 7
src/client/client.cpp

@@ -238,18 +238,13 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo
 		infostream << "Client::scanModSubfolder(): Loading \"" << real_path
 				<< "\" as \"" << vfs_path << "\"." << std::endl;
 
-		std::ifstream is(real_path, std::ios::binary | std::ios::ate);
-		if(!is.good()) {
+		std::string contents;
+		if (!fs::ReadFile(real_path, contents)) {
 			errorstream << "Client::scanModSubfolder(): Can't read file \""
 					<< real_path << "\"." << std::endl;
 			continue;
 		}
-		auto size = is.tellg();
-		std::string contents(size, '\0');
-		is.seekg(0);
-		is.read(&contents[0], size);
 
-		infostream << "  size: " << size << " bytes" << std::endl;
 		m_mod_vfs.emplace(vfs_path, contents);
 	}
 }

+ 15 - 0
src/filesys.cpp

@@ -750,6 +750,21 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
 	return true;
 }
 
+bool ReadFile(const std::string &path, std::string &out)
+{
+	std::ifstream is(path, std::ios::binary | std::ios::ate);
+	if (!is.good()) {
+		return false;
+	}
+
+	auto size = is.tellg();
+	out.resize(size);
+	is.seekg(0);
+	is.read(&out[0], size);
+
+	return true;
+}
+
 bool Rename(const std::string &from, const std::string &to)
 {
 	return rename(from.c_str(), to.c_str()) == 0;

+ 2 - 0
src/filesys.h

@@ -128,6 +128,8 @@ const char *GetFilenameFromPath(const char *path);
 
 bool safeWriteToFile(const std::string &path, const std::string &content);
 
+bool ReadFile(const std::string &path, std::string &out);
+
 bool Rename(const std::string &from, const std::string &to);
 
 } // namespace fs

+ 3 - 3
src/script/lua_api/l_env.cpp

@@ -1340,9 +1340,9 @@ int ModApiEnvMod::l_get_translated_string(lua_State * L)
 	GET_ENV_PTR;
 	std::string lang_code = luaL_checkstring(L, 1);
 	std::string string = luaL_checkstring(L, 2);
-	getServer(L)->loadTranslationLanguage(lang_code);
-	string = wide_to_utf8(translate_string(utf8_to_wide(string),
-			&(*g_server_translations)[lang_code]));
+
+	auto *translations = getServer(L)->getTranslationLanguage(lang_code);
+	string = wide_to_utf8(translate_string(utf8_to_wide(string), translations));
 	lua_pushstring(L, string.c_str());
 	return 1;
 }

+ 22 - 31
src/server.cpp

@@ -2451,31 +2451,14 @@ bool Server::addMediaFile(const std::string &filename,
 	// Ok, attempt to load the file and add to cache
 
 	// Read data
-	std::ifstream fis(filepath.c_str(), std::ios_base::binary);
-	if (!fis.good()) {
-		errorstream << "Server::addMediaFile(): Could not open \""
-				<< filename << "\" for reading" << std::endl;
-		return false;
-	}
 	std::string filedata;
-	bool bad = false;
-	for (;;) {
-		char buf[1024];
-		fis.read(buf, sizeof(buf));
-		std::streamsize len = fis.gcount();
-		filedata.append(buf, len);
-		if (fis.eof())
-			break;
-		if (!fis.good()) {
-			bad = true;
-			break;
-		}
-	}
-	if (bad) {
-		errorstream << "Server::addMediaFile(): Failed to read \""
-				<< filename << "\"" << std::endl;
+	if (!fs::ReadFile(filepath, filedata)) {
+		errorstream << "Server::addMediaFile(): Failed to open \""
+					<< filename << "\" for reading" << std::endl;
 		return false;
-	} else if (filedata.empty()) {
+	}
+
+	if (filedata.empty()) {
 		errorstream << "Server::addMediaFile(): Empty file \""
 				<< filepath << "\"" << std::endl;
 		return false;
@@ -3890,19 +3873,27 @@ void Server::broadcastModChannelMessage(const std::string &channel,
 	}
 }
 
-void Server::loadTranslationLanguage(const std::string &lang_code)
+Translations *Server::getTranslationLanguage(const std::string &lang_code)
 {
-	if (g_server_translations->count(lang_code))
-		return; // Already loaded
+	if (lang_code.empty())
+		return nullptr;
+
+	auto it = server_translations.find(lang_code);
+	if (it != server_translations.end())
+		return &it->second; // Already loaded
+
+	// [] will create an entry
+	auto *translations = &server_translations[lang_code];
 
 	std::string suffix = "." + lang_code + ".tr";
 	for (const auto &i : m_media) {
 		if (str_ends_with(i.first, suffix)) {
-			std::ifstream t(i.second.path);
-			std::string data((std::istreambuf_iterator<char>(t)),
-			std::istreambuf_iterator<char>());
-
-			(*g_server_translations)[lang_code].loadTranslation(data);
+			std::string data;
+			if (fs::ReadFile(i.second.path, data)) {
+				translations->loadTranslation(data);
+			}
 		}
 	}
+
+	return translations;
 }

+ 5 - 2
src/server.h

@@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serverenvironment.h"
 #include "clientiface.h"
 #include "chatmessage.h"
+#include "translation.h"
 #include <string>
 #include <list>
 #include <map>
@@ -343,8 +344,8 @@ public:
 	// Send block to specific player only
 	bool SendBlock(session_t peer_id, const v3s16 &blockpos);
 
-	// Load translations for a language
-	void loadTranslationLanguage(const std::string &lang_code);
+	// Get or load translations for a language
+	Translations *getTranslationLanguage(const std::string &lang_code);
 
 	// Bind address
 	Address m_bind_addr;
@@ -557,6 +558,8 @@ private:
 	// Mods
 	std::unique_ptr<ServerModManager> m_modmgr;
 
+	std::unordered_map<std::string, Translations> server_translations;
+
 	/*
 		Threads
 	*/

+ 1 - 9
src/serverlist.cpp

@@ -52,15 +52,7 @@ std::vector<ServerListSpec> getLocal()
 {
 	std::string path = ServerList::getFilePath();
 	std::string liststring;
-	if (fs::PathExists(path)) {
-		std::ifstream istream(path.c_str());
-		if (istream.is_open()) {
-			std::ostringstream ostream;
-			ostream << istream.rdbuf();
-			liststring = ostream.str();
-			istream.close();
-		}
-	}
+	fs::ReadFile(path, liststring);
 
 	return deSerialize(liststring);
 }

+ 0 - 8
src/translation.cpp

@@ -29,14 +29,6 @@ Translations client_translations;
 Translations *g_client_translations = &client_translations;
 #endif
 
-// Per language server translations
-std::unordered_map<std::string,Translations> server_translations;
-std::unordered_map<std::string,Translations> *g_server_translations = &server_translations;
-
-Translations::~Translations()
-{
-	clear();
-}
 
 void Translations::clear()
 {

+ 0 - 5
src/translation.h

@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 
 class Translations;
-extern std::unordered_map<std::string, Translations> *g_server_translations;
 #ifndef SERVER
 extern Translations *g_client_translations;
 #endif
@@ -31,10 +30,6 @@ extern Translations *g_client_translations;
 class Translations
 {
 public:
-	Translations() = default;
-
-	~Translations();
-
 	void loadTranslation(const std::string &data);
 	void clear();
 	const std::wstring &getTranslation(