#include "Common.h" #include "ServerProperties.h" #include #include #include #include #include #include #include #include "../util/StringUtil.h" namespace Feather::Config { void ServerProperties::Load() { std::ifstream file; file.open(path); Log::Info("Reading {}...", path); if (file.is_open()) { string line; while(std::getline(file, line)) { // trip whitespace StringUtil::trim(line); // skip comments if (line[0] == '#') continue; // key=value size_t pos = line.find('='); // java also accepts key:value if (pos == string::npos) pos = line.find(':'); if (pos == string::npos) continue; string key = line.substr(0, pos); StringUtil::trim(key); string value = line.substr(pos + 1); StringUtil::trim(value); properties.insert( {key, value} ); } file.close(); } else { Log::Warn("Could not find {}", path); } } void ServerProperties::Save() { std::ofstream file; file.open(path); file << "#Minecraft server properties\n"; auto time = std::time(nullptr); auto localTime = *std::localtime(&time); // The following code abbreviates a time zone like "Pacifc Daylight Time" // to a short form like "PDT". If the time zone is already abbreviated // then it won't change the abbreviation char timeZone[256]; strftime(timeZone, 256, "%Z", &localTime); char timeZoneAbbr[5]; int counter = 0; for (int i = 0; i < strlen(timeZone); i++) { char c = timeZone[i]; if (std::isupper(c)) { timeZoneAbbr[counter++] = c; // stop before last char to insert 0 if (counter >= 4) { timeZoneAbbr[counter] = 0; break; } } } // Ex: Thu Jul 23 01:43:47 PDT 2020 file << "#" << std::put_time(&localTime, "%a %b %d %H:%M:%S ") << timeZoneAbbr << std::put_time(&localTime, " %Y") << "\n"; file << onlineMode << "\n"; file << preventProxyConnections << "\n"; file << serverIp << "\n"; file << spawnAnimals << "\n"; file << spawnNpcs << "\n"; file << pvp << "\n"; file << allowFlight << "\n"; file << resourcePack << "\n"; file << motd << "\n"; file << forceGameMode << "\n"; file << enforceWhitelist << "\n"; file << levelName << "\n"; file << serverPort << "\n"; file << maxBuildHeight << "\n"; //file << announcePlayerAchievements << "\n"; file << enableQuery << "\n"; file << queryPort << "\n"; file << enableRcon << "\n"; file << rconPort << "\n"; file << rconPassword << "\n"; //file << resourcePackHash << "\n"; file << resourcePackSha1 << "\n"; file << hardcore << "\n"; file << allowNether << "\n"; file << spawnMonsters << "\n"; file << snooperEnabled << "\n"; file << useNativeTransport << "\n"; file << enableCommandBlock << "\n"; file << spawnProtection << "\n"; file << opPermissionLevel << "\n"; file << functionPermissionLevel << "\n"; file << maxTickTime << "\n"; file << viewDistance << "\n"; file << maxPlayers << "\n"; file << networkCompressionThreshold << "\n"; file << broadcastRconToOps << "\n"; file << broadcastConsoleToOps << "\n"; file << maxWorldSize << "\n"; file << syncChunkWrites << "\n"; file << enableJmxMonitoring << "\n"; file << enableStatus << "\n"; file << entityBroadcastRangePercentage << "\n"; file << playerIdleTimeout << "\n"; file << whiteList << "\n"; file << "\n"; file.close(); } }