Finalize properties parsing system and load/save
This commit is contained in:
parent
4488d8bcf2
commit
ac693ed4e5
|
@ -6,7 +6,8 @@ using namespace Feather;
|
|||
int main()
|
||||
{
|
||||
ServerProperties properties("server.properties");
|
||||
printf("Starting server on port %d\n", properties.Get<int>("server-port"));
|
||||
properties.Save();
|
||||
printf("Starting server on port %d\n", properties.serverPort.GetValue());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#include "Properties.h"
|
||||
#include "../util/StringUtil.h"
|
||||
|
||||
static const string STRING_TRUE("true");
|
||||
static const string STRING_FALSE("false");
|
||||
|
||||
namespace Feather
|
||||
{
|
||||
template <>
|
||||
string Properties::Get<string>(string_view key)
|
||||
{
|
||||
return properties.at(string(key));
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Properties::Get<bool>(string_view key)
|
||||
{
|
||||
string value = Get<string>(key);
|
||||
if (StringUtil::iequal(value, STRING_TRUE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: complain about non-bool
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
int Properties::Get<int>(string_view key)
|
||||
{
|
||||
return std::stoi(Get<string>(key));
|
||||
}
|
||||
|
||||
template <>
|
||||
long Properties::Get<long>(string_view key)
|
||||
{
|
||||
return std::stol(Get<string>(key));
|
||||
}
|
||||
|
||||
template <>
|
||||
long long Properties::Get<long long>(string_view key)
|
||||
{
|
||||
return std::stoll(Get<string>(key));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::unordered_map;
|
||||
|
||||
namespace Feather
|
||||
{
|
||||
class Properties
|
||||
{
|
||||
public:
|
||||
template <typename T> T Get(string_view key);
|
||||
protected:
|
||||
unordered_map<string, string> properties;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
|
||||
#include "Properties.h"
|
||||
#include "ServerProperties.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::unordered_map;
|
||||
|
||||
namespace Feather
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class Property
|
||||
{
|
||||
public:
|
||||
Property(string_view key) : key(key) {}
|
||||
Property(string_view key, T defaultValue) : key(key), value(defaultValue) {}
|
||||
Property(string_view key, std::function<T(T)> op, T defaultValue) : key(key), op(op), value(defaultValue) {}
|
||||
|
||||
void Init(Properties *properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
SetValue(properties->Get<T>(key));
|
||||
}
|
||||
catch (std::out_of_range err)
|
||||
{
|
||||
// process default value from constructor
|
||||
SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetValue(T value)
|
||||
{
|
||||
if (op) {
|
||||
this->value = op(value);
|
||||
} else {
|
||||
this->value = value;
|
||||
}
|
||||
}
|
||||
virtual T GetValue() { return value; }
|
||||
|
||||
inline string ToString() { return std::to_string(value); }
|
||||
|
||||
string_view key;
|
||||
private:
|
||||
T value = T();
|
||||
std::function<T(T)> op;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline string Property<string>::ToString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline string Property<bool>::ToString()
|
||||
{
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
}
|
|
@ -3,15 +3,15 @@
|
|||
#include <fstream>
|
||||
#include <string_view>
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
|
||||
#include "../util/StringUtil.h"
|
||||
|
||||
static const string STRING_TRUE("true");
|
||||
static const string STRING_FALSE("false");
|
||||
|
||||
namespace Feather
|
||||
{
|
||||
ServerProperties::ServerProperties(const char* path)
|
||||
void ServerProperties::Load()
|
||||
{
|
||||
std::ifstream file;
|
||||
file.open(path);
|
||||
|
@ -47,45 +47,93 @@ namespace Feather
|
|||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
//for ( auto const& pair : properties )
|
||||
// std::cout << "[" << pair.first << "] = [" << pair.second << "]\n";
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
string ServerProperties::Get<string>(string_view key)
|
||||
else
|
||||
{
|
||||
return properties[string(key)];
|
||||
}
|
||||
|
||||
template <>
|
||||
bool ServerProperties::Get<bool>(string_view key)
|
||||
{
|
||||
string value = Get<string>(key);
|
||||
if (StringUtil::iequal(value, STRING_TRUE)) {
|
||||
return true;
|
||||
} else {
|
||||
// TODO: complain about non-bool
|
||||
return false;
|
||||
printf("Could not find %s\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
int ServerProperties::Get<int>(string_view key)
|
||||
void ServerProperties::Save()
|
||||
{
|
||||
return std::stoi(Get<string>(key));
|
||||
std::ofstream file;
|
||||
file.open(path);
|
||||
|
||||
file << "#Minecraft server properties" << std::endl;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
long ServerProperties::Get<long>(string_view key)
|
||||
{
|
||||
return std::stol(Get<string>(key));
|
||||
}
|
||||
// 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") << std::endl;
|
||||
|
||||
template <>
|
||||
long long ServerProperties::Get<long long>(string_view key)
|
||||
{
|
||||
return std::stoll(Get<string>(key));
|
||||
file << onlineMode.key << "=" << onlineMode.ToString() << std::endl;
|
||||
file << preventProxyConnections.key << "=" << preventProxyConnections.ToString() << std::endl;
|
||||
file << serverIp.key << "=" << serverIp.ToString() << std::endl;
|
||||
file << spawnAnimals.key << "=" << spawnAnimals.ToString() << std::endl;
|
||||
file << spawnNpcs.key << "=" << spawnNpcs.ToString() << std::endl;
|
||||
file << pvp.key << "=" << pvp.ToString() << std::endl;
|
||||
file << allowFlight.key << "=" << allowFlight.ToString() << std::endl;
|
||||
file << resourcePack.key << "=" << resourcePack.ToString() << std::endl;
|
||||
file << motd.key << "=" << motd.ToString() << std::endl;
|
||||
file << forceGameMode.key << "=" << forceGameMode.ToString() << std::endl;
|
||||
file << enforceWhitelist.key << "=" << enforceWhitelist.ToString() << std::endl;
|
||||
file << levelName.key << "=" << levelName.ToString() << std::endl;
|
||||
file << serverPort.key << "=" << serverPort.ToString() << std::endl;
|
||||
file << maxBuildHeight.key << "=" << maxBuildHeight.ToString() << std::endl;
|
||||
//file << announcePlayerAchievements.key << "=" << announcePlayerAchievements.ToString() << std::endl;
|
||||
file << enableQuery.key << "=" << enableQuery.ToString() << std::endl;
|
||||
file << queryPort.key << "=" << queryPort.ToString() << std::endl;
|
||||
file << enableRcon.key << "=" << enableRcon.ToString() << std::endl;
|
||||
file << rconPort.key << "=" << rconPort.ToString() << std::endl;
|
||||
file << rconPassword.key << "=" << rconPassword.ToString() << std::endl;
|
||||
//file << resourcePackHash.key << "=" << resourcePackHash.ToString() << std::endl;
|
||||
file << resourcePackSha1.key << "=" << resourcePackSha1.ToString() << std::endl;
|
||||
file << hardcore.key << "=" << hardcore.ToString() << std::endl;
|
||||
file << allowNether.key << "=" << allowNether.ToString() << std::endl;
|
||||
file << spawnMonsters.key << "=" << spawnMonsters.ToString() << std::endl;
|
||||
file << snooperEnabled.key << "=" << snooperEnabled.ToString() << std::endl;
|
||||
file << useNativeTransport.key << "=" << useNativeTransport.ToString() << std::endl;
|
||||
file << enableCommandBlock.key << "=" << enableCommandBlock.ToString() << std::endl;
|
||||
file << spawnProtection.key << "=" << spawnProtection.ToString() << std::endl;
|
||||
file << opPermissionLevel.key << "=" << opPermissionLevel.ToString() << std::endl;
|
||||
file << functionPermissionLevel.key << "=" << functionPermissionLevel.ToString() << std::endl;
|
||||
file << maxTickTime.key << "=" << maxTickTime.ToString() << std::endl;
|
||||
file << viewDistance.key << "=" << viewDistance.ToString() << std::endl;
|
||||
file << maxPlayers.key << "=" << maxPlayers.ToString() << std::endl;
|
||||
file << networkCompressionThreshold.key << "=" << networkCompressionThreshold.ToString() << std::endl;
|
||||
file << broadcastRconToOps.key << "=" << broadcastRconToOps.ToString() << std::endl;
|
||||
file << broadcastConsoleToOps.key << "=" << broadcastConsoleToOps.ToString() << std::endl;
|
||||
file << maxWorldSize.key << "=" << maxWorldSize.ToString() << std::endl;
|
||||
file << syncChunkWrites.key << "=" << syncChunkWrites.ToString() << std::endl;
|
||||
file << enableJmxMonitoring.key << "=" << enableJmxMonitoring.ToString() << std::endl;
|
||||
file << enableStatus.key << "=" << enableStatus.ToString() << std::endl;
|
||||
file << entityBroadcastRangePercentage.key << "=" << entityBroadcastRangePercentage.ToString() << std::endl;
|
||||
file << playerIdleTimeout.key << "=" << playerIdleTimeout.ToString() << std::endl;
|
||||
file << whiteList.key << "=" << whiteList.ToString() << std::endl;
|
||||
|
||||
file << std::endl;
|
||||
file.close();
|
||||
}
|
||||
}
|
|
@ -1,21 +1,127 @@
|
|||
#pragma once
|
||||
|
||||
#include "Properties.h"
|
||||
#include "Property.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::unordered_map;
|
||||
|
||||
namespace Feather
|
||||
{
|
||||
class ServerProperties
|
||||
class ServerProperties : public Properties
|
||||
{
|
||||
public:
|
||||
ServerProperties(const char* path);
|
||||
|
||||
template <typename T>
|
||||
T Get(string_view key);
|
||||
Property<bool> onlineMode = Property<bool>("online-mode", true);
|
||||
Property<bool> preventProxyConnections = Property<bool>("prevent-proxy-connections", false);
|
||||
Property<string> serverIp = Property<string>("server-ip", "");
|
||||
Property<bool> spawnAnimals = Property<bool>("spawn-animals", true);
|
||||
Property<bool> spawnNpcs = Property<bool>("spawn-npcs", true);
|
||||
Property<bool> pvp = Property<bool>("pvp", true);
|
||||
Property<bool> allowFlight = Property<bool>("allow-flight", false);
|
||||
Property<string> resourcePack = Property<string>("resource-pack", "");
|
||||
Property<string> motd = Property<string>("motd", "A Minecraft Server");
|
||||
Property<bool> forceGameMode = Property<bool>("force-gamemode", false);
|
||||
Property<bool> enforceWhitelist = Property<bool>("enforce-whitelist", false);
|
||||
//Property<Difficulty> difficulty = Property<Difficulty>("difficulty", DedicatedServerProperties.dispatchNumberOrString(Difficulty::byId, Difficulty::byName), Difficulty::getKey, Difficulty.EASY);
|
||||
//Property<GameType> gamemode = Property<GameType>("gamemode", DedicatedServerProperties.dispatchNumberOrString(GameType::byId, GameType::byName), GameType::getName, GameType.SURVIVAL);
|
||||
Property<string> levelName = Property<string>("level-name", "world");
|
||||
Property<int> serverPort = Property<int>("server-port", 25565);
|
||||
Property<int> maxBuildHeight = Property<int>("max-build-height", [](int n) { return std::clamp((n + 8) / 16 * 16, 64, 256); }, 256); // round to nearest 16, clamp to range [64, 256]
|
||||
// (REMOVED) Property<bool> announcePlayerAchievements = Property<bool>("announce-player-achievements");
|
||||
Property<bool> enableQuery = Property<bool>("enable-query", false);
|
||||
Property<int> queryPort = Property<int>("query.port", 25565);
|
||||
Property<bool> enableRcon = Property<bool>("enable-rcon", false);
|
||||
Property<int> rconPort = Property<int>("rcon.port", 25575);
|
||||
Property<string> rconPassword = Property<string>("rcon.password", "");
|
||||
// (REMOVED) Property<string> resourcePackHash = Property<string>("resource-pack-hash");
|
||||
Property<string> resourcePackSha1 = Property<string>("resource-pack-sha1", "");
|
||||
Property<bool> hardcore = Property<bool>("hardcore", false);
|
||||
Property<bool> allowNether = Property<bool>("allow-nether", true);
|
||||
Property<bool> spawnMonsters = Property<bool>("spawn-monsters", true);
|
||||
|
||||
Property<bool> snooperEnabled = Property<bool>("snooper-enabled", true);
|
||||
Property<bool> useNativeTransport = Property<bool>("use-native-transport", true);
|
||||
Property<bool> enableCommandBlock = Property<bool>("enable-command-block", false);
|
||||
Property<int> spawnProtection = Property<int>("spawn-protection", 16);
|
||||
Property<int> opPermissionLevel = Property<int>("op-permission-level", 4);
|
||||
Property<int> functionPermissionLevel = Property<int>("function-permission-level", 2);
|
||||
Property<long> maxTickTime = Property<long>("max-tick-time");//, TimeUnit.MINUTES.toMillis(1L));
|
||||
Property<int> viewDistance = Property<int>("view-distance", 10);
|
||||
Property<int> maxPlayers = Property<int>("max-players", 20);
|
||||
Property<int> networkCompressionThreshold = Property<int>("network-compression-threshold", 256);
|
||||
Property<bool> broadcastRconToOps = Property<bool>("broadcast-rcon-to-ops", true);
|
||||
Property<bool> broadcastConsoleToOps = Property<bool>("broadcast-console-to-ops", true);
|
||||
Property<int> maxWorldSize = Property<int>("max-world-size", [](int n) { return std::clamp(n, 1, 29999984); }, 29999984);
|
||||
Property<bool> syncChunkWrites = Property<bool>("sync-chunk-writes", true);
|
||||
Property<bool> enableJmxMonitoring = Property<bool>("enable-jmx-monitoring", false);
|
||||
Property<bool> enableStatus = Property<bool>("enable-status", true);
|
||||
Property<int> entityBroadcastRangePercentage = Property<int>("entity-broadcast-range-percentage", [](int n) { return std::clamp(n, 10, 1000); }, 100);
|
||||
/*mutable*/ Property<int> playerIdleTimeout = Property<int>("player-idle-timeout", 0);
|
||||
/*mutable*/ Property<bool> whiteList = Property<bool>("white-list", false);
|
||||
//Property<WorldGenSettings> worldGenSettings = WorldGenSettings.create(properties);
|
||||
|
||||
ServerProperties(const char* path) : path(path)
|
||||
{
|
||||
Load();
|
||||
|
||||
onlineMode.Init(this);
|
||||
preventProxyConnections.Init(this);
|
||||
serverIp.Init(this);
|
||||
spawnAnimals.Init(this);
|
||||
spawnNpcs.Init(this);
|
||||
pvp.Init(this);
|
||||
allowFlight.Init(this);
|
||||
resourcePack.Init(this);
|
||||
motd.Init(this);
|
||||
forceGameMode.Init(this);
|
||||
enforceWhitelist.Init(this);
|
||||
levelName.Init(this);
|
||||
serverPort.Init(this);
|
||||
maxBuildHeight.Init(this);
|
||||
//announcePlayerAchievements.Init(this);
|
||||
enableQuery.Init(this);
|
||||
queryPort.Init(this);
|
||||
enableRcon.Init(this);
|
||||
rconPort.Init(this);
|
||||
rconPassword.Init(this);
|
||||
//resourcePackHash.Init(this);
|
||||
resourcePackSha1.Init(this);
|
||||
hardcore.Init(this);
|
||||
allowNether.Init(this);
|
||||
spawnMonsters.Init(this);
|
||||
snooperEnabled.Init(this);
|
||||
useNativeTransport.Init(this);
|
||||
enableCommandBlock.Init(this);
|
||||
spawnProtection.Init(this);
|
||||
opPermissionLevel.Init(this);
|
||||
functionPermissionLevel.Init(this);
|
||||
maxTickTime.Init(this);
|
||||
viewDistance.Init(this);
|
||||
maxPlayers.Init(this);
|
||||
networkCompressionThreshold.Init(this);
|
||||
broadcastRconToOps.Init(this);
|
||||
broadcastConsoleToOps.Init(this);
|
||||
maxWorldSize.Init(this);
|
||||
syncChunkWrites.Init(this);
|
||||
enableJmxMonitoring.Init(this);
|
||||
enableStatus.Init(this);
|
||||
entityBroadcastRangePercentage.Init(this);
|
||||
playerIdleTimeout.Init(this);
|
||||
whiteList.Init(this);
|
||||
|
||||
}
|
||||
|
||||
void Load();
|
||||
void Save();
|
||||
private:
|
||||
std::unordered_map<string, string> properties;
|
||||
const char* path;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue