mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
update: add basically all configuration options that are implemented in the classes to server.properties
This commit is contained in:
parent
b8d62896dd
commit
31bfb7e428
|
|
@ -8,6 +8,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace ServerRuntime
|
namespace ServerRuntime
|
||||||
|
|
@ -21,19 +22,52 @@ struct ServerPropertyDefault
|
||||||
static const char *kServerPropertiesPath = "server.properties";
|
static const char *kServerPropertiesPath = "server.properties";
|
||||||
static const size_t kMaxSaveIdLength = 31;
|
static const size_t kMaxSaveIdLength = 31;
|
||||||
|
|
||||||
|
static const int kDefaultServerPort = 25565;
|
||||||
|
static const int kDefaultMaxPlayers = 8;
|
||||||
|
static const int kMaxDedicatedPlayers = 8;
|
||||||
|
static const int kDefaultAutosaveIntervalSeconds = 60;
|
||||||
|
|
||||||
static const ServerPropertyDefault kServerPropertyDefaults[] =
|
static const ServerPropertyDefault kServerPropertyDefaults[] =
|
||||||
{
|
{
|
||||||
{ "level-name", "world" },
|
{ "allow-flight", "true" },
|
||||||
{ "level-id", "world" },
|
{ "allow-nether", "true" },
|
||||||
{ "level-type", "default" },
|
{ "autosave-interval", "60" },
|
||||||
|
{ "bedrock-fog", "true" },
|
||||||
|
{ "bonus-chest", "false" },
|
||||||
|
{ "difficulty", "1" },
|
||||||
|
{ "disable-saving", "false" },
|
||||||
|
{ "do-daylight-cycle", "true" },
|
||||||
|
{ "do-mob-loot", "true" },
|
||||||
|
{ "do-mob-spawning", "true" },
|
||||||
|
{ "do-tile-drops", "true" },
|
||||||
|
{ "fire-spreads", "true" },
|
||||||
|
{ "friends-of-friends", "false" },
|
||||||
{ "gamemode", "0" },
|
{ "gamemode", "0" },
|
||||||
|
{ "gamertags", "true" },
|
||||||
|
{ "generate-structures", "true" },
|
||||||
|
{ "host-can-be-invisible", "true" },
|
||||||
|
{ "host-can-change-hunger", "true" },
|
||||||
|
{ "host-can-fly", "true" },
|
||||||
|
{ "keep-inventory", "false" },
|
||||||
|
{ "level-id", "world" },
|
||||||
|
{ "level-name", "world" },
|
||||||
|
{ "level-seed", "" },
|
||||||
|
{ "level-type", "default" },
|
||||||
|
{ "log-level", "info" },
|
||||||
{ "max-build-height", "256" },
|
{ "max-build-height", "256" },
|
||||||
{ "spawn-animals", "true" },
|
{ "max-players", "8" },
|
||||||
{ "spawn-npcs", "true" },
|
{ "mob-griefing", "true" },
|
||||||
{ "spawn-monsters", "true" },
|
{ "motd", "A Minecraft Server" },
|
||||||
|
{ "natural-regeneration", "true" },
|
||||||
{ "pvp", "true" },
|
{ "pvp", "true" },
|
||||||
{ "server-ip", "" },
|
{ "server-ip", "0.0.0.0" },
|
||||||
{ "motd", "A Minecraft Server" }
|
{ "server-name", "DedicatedServer" },
|
||||||
|
{ "server-port", "25565" },
|
||||||
|
{ "spawn-animals", "true" },
|
||||||
|
{ "spawn-monsters", "true" },
|
||||||
|
{ "spawn-npcs", "true" },
|
||||||
|
{ "tnt", "true" },
|
||||||
|
{ "trust-players", "true" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string TrimAscii(const std::string &value)
|
static std::string TrimAscii(const std::string &value)
|
||||||
|
|
@ -53,6 +87,134 @@ static std::string TrimAscii(const std::string &value)
|
||||||
return value.substr(start, end - start);
|
return value.substr(start, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string ToLowerAscii(const std::string &value)
|
||||||
|
{
|
||||||
|
std::string lowered = value;
|
||||||
|
for (size_t i = 0; i < lowered.length(); ++i)
|
||||||
|
{
|
||||||
|
unsigned char ch = (unsigned char)lowered[i];
|
||||||
|
lowered[i] = (char)std::tolower(ch);
|
||||||
|
}
|
||||||
|
return lowered;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string BoolToString(bool value)
|
||||||
|
{
|
||||||
|
return value ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string IntToString(int value)
|
||||||
|
{
|
||||||
|
char buffer[32] = {};
|
||||||
|
sprintf_s(buffer, sizeof(buffer), "%d", value);
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string Int64ToString(__int64 value)
|
||||||
|
{
|
||||||
|
char buffer[64] = {};
|
||||||
|
_i64toa_s(value, buffer, sizeof(buffer), 10);
|
||||||
|
return std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ClampInt(int value, int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
if (value < minValue)
|
||||||
|
{
|
||||||
|
return minValue;
|
||||||
|
}
|
||||||
|
if (value > maxValue)
|
||||||
|
{
|
||||||
|
return maxValue;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParseBool(const std::string &value, bool *outValue)
|
||||||
|
{
|
||||||
|
if (outValue == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string lowered = ToLowerAscii(TrimAscii(value));
|
||||||
|
if (lowered == "true" || lowered == "1" || lowered == "yes" || lowered == "on")
|
||||||
|
{
|
||||||
|
*outValue = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (lowered == "false" || lowered == "0" || lowered == "no" || lowered == "off")
|
||||||
|
{
|
||||||
|
*outValue = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParseInt(const std::string &value, int *outValue)
|
||||||
|
{
|
||||||
|
if (outValue == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string trimmed = TrimAscii(value);
|
||||||
|
if (trimmed.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *end = NULL;
|
||||||
|
long parsed = strtol(trimmed.c_str(), &end, 10);
|
||||||
|
if (end == trimmed.c_str() || *end != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outValue = (int)parsed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParseInt64(const std::string &value, __int64 *outValue)
|
||||||
|
{
|
||||||
|
if (outValue == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string trimmed = TrimAscii(value);
|
||||||
|
if (trimmed.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *end = NULL;
|
||||||
|
__int64 parsed = _strtoi64(trimmed.c_str(), &end, 10);
|
||||||
|
if (end == trimmed.c_str() || *end != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outValue = parsed;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string LogLevelToPropertyValue(EServerLogLevel level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case eServerLogLevel_Debug:
|
||||||
|
return "debug";
|
||||||
|
case eServerLogLevel_Warn:
|
||||||
|
return "warn";
|
||||||
|
case eServerLogLevel_Error:
|
||||||
|
return "error";
|
||||||
|
case eServerLogLevel_Info:
|
||||||
|
default:
|
||||||
|
return "info";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任意文字列を保存先IDとして安全な形式に正規化する
|
* 任意文字列を保存先IDとして安全な形式に正規化する
|
||||||
*
|
*
|
||||||
|
|
@ -222,7 +384,7 @@ static bool WriteServerPropertiesFile(const char *filePath, const std::unordered
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(outFile, "# Minecraft server properties\n");
|
fprintf(outFile, "# Minecraft server properties\n");
|
||||||
fprintf(outFile, "# Auto-generated when missing\n");
|
fprintf(outFile, "# Auto-generated and normalized when missing\n");
|
||||||
|
|
||||||
std::map<std::string, std::string> sortedProperties(properties.begin(), properties.end());
|
std::map<std::string, std::string> sortedProperties(properties.begin(), properties.end());
|
||||||
for (std::map<std::string, std::string>::const_iterator it = sortedProperties.begin(); it != sortedProperties.end(); ++it)
|
for (std::map<std::string, std::string>::const_iterator it = sortedProperties.begin(); it != sortedProperties.end(); ++it)
|
||||||
|
|
@ -234,6 +396,203 @@ static bool WriteServerPropertiesFile(const char *filePath, const std::unordered
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ReadNormalizedBoolProperty(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
bool defaultValue,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string raw = TrimAscii((*properties)[key]);
|
||||||
|
bool value = defaultValue;
|
||||||
|
if (!TryParseBool(raw, &value))
|
||||||
|
{
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string normalized = BoolToString(value);
|
||||||
|
if (raw != normalized)
|
||||||
|
{
|
||||||
|
(*properties)[key] = normalized;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReadNormalizedIntProperty(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
int defaultValue,
|
||||||
|
int minValue,
|
||||||
|
int maxValue,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string raw = TrimAscii((*properties)[key]);
|
||||||
|
int value = defaultValue;
|
||||||
|
if (!TryParseInt(raw, &value))
|
||||||
|
{
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
value = ClampInt(value, minValue, maxValue);
|
||||||
|
|
||||||
|
std::string normalized = IntToString(value);
|
||||||
|
if (raw != normalized)
|
||||||
|
{
|
||||||
|
(*properties)[key] = normalized;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ReadNormalizedStringProperty(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
const std::string &defaultValue,
|
||||||
|
size_t maxLength,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string value = TrimAscii((*properties)[key]);
|
||||||
|
if (value.empty())
|
||||||
|
{
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
if (maxLength > 0 && value.length() > maxLength)
|
||||||
|
{
|
||||||
|
value.resize(maxLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != (*properties)[key])
|
||||||
|
{
|
||||||
|
(*properties)[key] = value;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ReadNormalizedOptionalInt64Property(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
__int64 *outValue,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string raw = TrimAscii((*properties)[key]);
|
||||||
|
if (raw.empty())
|
||||||
|
{
|
||||||
|
if ((*properties)[key] != "")
|
||||||
|
{
|
||||||
|
(*properties)[key] = "";
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
__int64 parsed = 0;
|
||||||
|
if (!TryParseInt64(raw, &parsed))
|
||||||
|
{
|
||||||
|
(*properties)[key] = "";
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string normalized = Int64ToString(parsed);
|
||||||
|
if (raw != normalized)
|
||||||
|
{
|
||||||
|
(*properties)[key] = normalized;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outValue != NULL)
|
||||||
|
{
|
||||||
|
*outValue = parsed;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EServerLogLevel ReadNormalizedLogLevelProperty(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
EServerLogLevel defaultValue,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string raw = TrimAscii((*properties)[key]);
|
||||||
|
EServerLogLevel value = defaultValue;
|
||||||
|
if (!TryParseServerLogLevel(raw.c_str(), &value))
|
||||||
|
{
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string normalized = LogLevelToPropertyValue(value);
|
||||||
|
if (raw != normalized)
|
||||||
|
{
|
||||||
|
(*properties)[key] = normalized;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string ReadNormalizedLevelTypeProperty(
|
||||||
|
std::unordered_map<std::string, std::string> *properties,
|
||||||
|
const char *key,
|
||||||
|
bool *outIsFlat,
|
||||||
|
bool *shouldWrite)
|
||||||
|
{
|
||||||
|
std::string raw = TrimAscii((*properties)[key]);
|
||||||
|
std::string lowered = ToLowerAscii(raw);
|
||||||
|
|
||||||
|
bool isFlat = false;
|
||||||
|
std::string normalized = "default";
|
||||||
|
if (lowered == "flat" || lowered == "superflat" || lowered == "1")
|
||||||
|
{
|
||||||
|
isFlat = true;
|
||||||
|
normalized = "flat";
|
||||||
|
}
|
||||||
|
else if (lowered == "default" || lowered == "normal" || lowered == "0")
|
||||||
|
{
|
||||||
|
isFlat = false;
|
||||||
|
normalized = "default";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw != normalized)
|
||||||
|
{
|
||||||
|
(*properties)[key] = normalized;
|
||||||
|
if (shouldWrite != NULL)
|
||||||
|
{
|
||||||
|
*shouldWrite = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outIsFlat != NULL)
|
||||||
|
{
|
||||||
|
*outIsFlat = isFlat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 実効的なワールド設定を読み込み、欠損/不正を補正して返す
|
* 実効的なワールド設定を読み込み、欠損/不正を補正して返す
|
||||||
*
|
*
|
||||||
|
|
@ -313,6 +672,50 @@ ServerPropertiesConfig LoadServerPropertiesConfig()
|
||||||
merged["level-name"] = worldName;
|
merged["level-name"] = worldName;
|
||||||
merged["level-id"] = worldSaveId;
|
merged["level-id"] = worldSaveId;
|
||||||
|
|
||||||
|
config.worldName = Utf8ToWide(worldName.c_str());
|
||||||
|
config.worldSaveId = worldSaveId;
|
||||||
|
|
||||||
|
config.serverPort = ReadNormalizedIntProperty(&merged, "server-port", kDefaultServerPort, 1, 65535, &shouldWrite);
|
||||||
|
config.serverIp = ReadNormalizedStringProperty(&merged, "server-ip", "0.0.0.0", 255, &shouldWrite);
|
||||||
|
config.serverName = ReadNormalizedStringProperty(&merged, "server-name", "DedicatedServer", 16, &shouldWrite);
|
||||||
|
config.maxPlayers = ReadNormalizedIntProperty(&merged, "max-players", kDefaultMaxPlayers, 1, kMaxDedicatedPlayers, &shouldWrite);
|
||||||
|
config.seed = 0;
|
||||||
|
config.hasSeed = ReadNormalizedOptionalInt64Property(&merged, "level-seed", &config.seed, &shouldWrite);
|
||||||
|
config.logLevel = ReadNormalizedLogLevelProperty(&merged, "log-level", eServerLogLevel_Info, &shouldWrite);
|
||||||
|
config.autosaveIntervalSeconds = ReadNormalizedIntProperty(&merged, "autosave-interval", kDefaultAutosaveIntervalSeconds, 5, 3600, &shouldWrite);
|
||||||
|
|
||||||
|
config.difficulty = ReadNormalizedIntProperty(&merged, "difficulty", 1, 0, 3, &shouldWrite);
|
||||||
|
config.gameMode = ReadNormalizedIntProperty(&merged, "gamemode", 0, 0, 1, &shouldWrite);
|
||||||
|
config.levelType = ReadNormalizedLevelTypeProperty(&merged, "level-type", &config.levelTypeFlat, &shouldWrite);
|
||||||
|
config.generateStructures = ReadNormalizedBoolProperty(&merged, "generate-structures", true, &shouldWrite);
|
||||||
|
config.bonusChest = ReadNormalizedBoolProperty(&merged, "bonus-chest", false, &shouldWrite);
|
||||||
|
config.pvp = ReadNormalizedBoolProperty(&merged, "pvp", true, &shouldWrite);
|
||||||
|
config.trustPlayers = ReadNormalizedBoolProperty(&merged, "trust-players", true, &shouldWrite);
|
||||||
|
config.fireSpreads = ReadNormalizedBoolProperty(&merged, "fire-spreads", true, &shouldWrite);
|
||||||
|
config.tnt = ReadNormalizedBoolProperty(&merged, "tnt", true, &shouldWrite);
|
||||||
|
config.spawnAnimals = ReadNormalizedBoolProperty(&merged, "spawn-animals", true, &shouldWrite);
|
||||||
|
config.spawnNpcs = ReadNormalizedBoolProperty(&merged, "spawn-npcs", true, &shouldWrite);
|
||||||
|
config.spawnMonsters = ReadNormalizedBoolProperty(&merged, "spawn-monsters", true, &shouldWrite);
|
||||||
|
config.allowFlight = ReadNormalizedBoolProperty(&merged, "allow-flight", true, &shouldWrite);
|
||||||
|
config.allowNether = ReadNormalizedBoolProperty(&merged, "allow-nether", true, &shouldWrite);
|
||||||
|
config.friendsOfFriends = ReadNormalizedBoolProperty(&merged, "friends-of-friends", false, &shouldWrite);
|
||||||
|
config.gamertags = ReadNormalizedBoolProperty(&merged, "gamertags", true, &shouldWrite);
|
||||||
|
config.bedrockFog = ReadNormalizedBoolProperty(&merged, "bedrock-fog", true, &shouldWrite);
|
||||||
|
config.hostCanFly = ReadNormalizedBoolProperty(&merged, "host-can-fly", true, &shouldWrite);
|
||||||
|
config.hostCanChangeHunger = ReadNormalizedBoolProperty(&merged, "host-can-change-hunger", true, &shouldWrite);
|
||||||
|
config.hostCanBeInvisible = ReadNormalizedBoolProperty(&merged, "host-can-be-invisible", true, &shouldWrite);
|
||||||
|
config.disableSaving = ReadNormalizedBoolProperty(&merged, "disable-saving", false, &shouldWrite);
|
||||||
|
config.mobGriefing = ReadNormalizedBoolProperty(&merged, "mob-griefing", true, &shouldWrite);
|
||||||
|
config.keepInventory = ReadNormalizedBoolProperty(&merged, "keep-inventory", false, &shouldWrite);
|
||||||
|
config.doMobSpawning = ReadNormalizedBoolProperty(&merged, "do-mob-spawning", true, &shouldWrite);
|
||||||
|
config.doMobLoot = ReadNormalizedBoolProperty(&merged, "do-mob-loot", true, &shouldWrite);
|
||||||
|
config.doTileDrops = ReadNormalizedBoolProperty(&merged, "do-tile-drops", true, &shouldWrite);
|
||||||
|
config.naturalRegeneration = ReadNormalizedBoolProperty(&merged, "natural-regeneration", true, &shouldWrite);
|
||||||
|
config.doDaylightCycle = ReadNormalizedBoolProperty(&merged, "do-daylight-cycle", true, &shouldWrite);
|
||||||
|
|
||||||
|
config.maxBuildHeight = ReadNormalizedIntProperty(&merged, "max-build-height", 256, 64, 256, &shouldWrite);
|
||||||
|
config.motd = ReadNormalizedStringProperty(&merged, "motd", "A Minecraft Server", 255, &shouldWrite);
|
||||||
|
|
||||||
if (shouldWrite)
|
if (shouldWrite)
|
||||||
{
|
{
|
||||||
if (WriteServerPropertiesFile(kServerPropertiesPath, merged))
|
if (WriteServerPropertiesFile(kServerPropertiesPath, merged))
|
||||||
|
|
@ -325,8 +728,6 @@ ServerPropertiesConfig LoadServerPropertiesConfig()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.worldName = Utf8ToWide(worldName.c_str());
|
|
||||||
config.worldSaveId = worldSaveId;
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -355,7 +756,7 @@ bool SaveServerPropertiesConfig(const ServerPropertiesConfig &config)
|
||||||
std::string worldName = TrimAscii(WideToUtf8(config.worldName));
|
std::string worldName = TrimAscii(WideToUtf8(config.worldName));
|
||||||
if (worldName.empty())
|
if (worldName.empty())
|
||||||
{
|
{
|
||||||
worldName = "world"; // フォルト名
|
worldName = "world"; // デフォルト名
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string worldSaveId = TrimAscii(config.worldSaveId);
|
std::string worldSaveId = TrimAscii(config.worldSaveId);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "ServerLogger.h"
|
||||||
|
|
||||||
namespace ServerRuntime
|
namespace ServerRuntime
|
||||||
{
|
{
|
||||||
|
|
@ -13,6 +14,58 @@ namespace ServerRuntime
|
||||||
std::wstring worldName;
|
std::wstring worldName;
|
||||||
/** world save id `level-id` */
|
/** world save id `level-id` */
|
||||||
std::string worldSaveId;
|
std::string worldSaveId;
|
||||||
|
|
||||||
|
/** `server-port` */
|
||||||
|
int serverPort;
|
||||||
|
/** `server-ip` */
|
||||||
|
std::string serverIp;
|
||||||
|
/** `server-name` (max 16 chars at runtime) */
|
||||||
|
std::string serverName;
|
||||||
|
/** `max-players` */
|
||||||
|
int maxPlayers;
|
||||||
|
/** `level-seed` is explicitly set */
|
||||||
|
bool hasSeed;
|
||||||
|
/** `level-seed` */
|
||||||
|
__int64 seed;
|
||||||
|
/** `log-level` */
|
||||||
|
EServerLogLevel logLevel;
|
||||||
|
/** `autosave-interval` (seconds) */
|
||||||
|
int autosaveIntervalSeconds;
|
||||||
|
|
||||||
|
/** host options / game settings */
|
||||||
|
int difficulty;
|
||||||
|
int gameMode;
|
||||||
|
bool levelTypeFlat;
|
||||||
|
bool generateStructures;
|
||||||
|
bool bonusChest;
|
||||||
|
bool pvp;
|
||||||
|
bool trustPlayers;
|
||||||
|
bool fireSpreads;
|
||||||
|
bool tnt;
|
||||||
|
bool spawnAnimals;
|
||||||
|
bool spawnNpcs;
|
||||||
|
bool spawnMonsters;
|
||||||
|
bool allowFlight;
|
||||||
|
bool allowNether;
|
||||||
|
bool friendsOfFriends;
|
||||||
|
bool gamertags;
|
||||||
|
bool bedrockFog;
|
||||||
|
bool hostCanFly;
|
||||||
|
bool hostCanChangeHunger;
|
||||||
|
bool hostCanBeInvisible;
|
||||||
|
bool disableSaving;
|
||||||
|
bool mobGriefing;
|
||||||
|
bool keepInventory;
|
||||||
|
bool doMobSpawning;
|
||||||
|
bool doMobLoot;
|
||||||
|
bool doTileDrops;
|
||||||
|
bool naturalRegeneration;
|
||||||
|
bool doDaylightCycle;
|
||||||
|
|
||||||
|
/** other MinecraftServer runtime settings */
|
||||||
|
int maxBuildHeight;
|
||||||
|
std::string levelType;
|
||||||
|
std::string motd;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
#include "Minecraft.h"
|
#include "Minecraft.h"
|
||||||
#include "MinecraftServer.h"
|
#include "MinecraftServer.h"
|
||||||
#include "Options.h"
|
|
||||||
#include "..\ServerLogger.h"
|
#include "..\ServerLogger.h"
|
||||||
#include "..\ServerProperties.h"
|
#include "..\ServerProperties.h"
|
||||||
#include "..\WorldManager.h"
|
#include "..\WorldManager.h"
|
||||||
|
|
@ -62,7 +61,7 @@ struct DedicatedServerConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
static volatile bool g_shutdownRequested = false;
|
static volatile bool g_shutdownRequested = false;
|
||||||
static const DWORD kAutosaveIntervalMs = 60 * 1000;
|
static const DWORD kDefaultAutosaveIntervalMs = 60 * 1000;
|
||||||
static const int kServerActionPad = 0;
|
static const int kServerActionPad = 0;
|
||||||
|
|
||||||
static BOOL WINAPI ConsoleCtrlHandlerProc(DWORD ctrlType)
|
static BOOL WINAPI ConsoleCtrlHandlerProc(DWORD ctrlType)
|
||||||
|
|
@ -98,13 +97,13 @@ static int WaitForServerStoppedThreadProc(void *)
|
||||||
static void PrintUsage()
|
static void PrintUsage()
|
||||||
{
|
{
|
||||||
ServerRuntime::LogInfo("usage", "Minecraft.Server.exe [options]");
|
ServerRuntime::LogInfo("usage", "Minecraft.Server.exe [options]");
|
||||||
ServerRuntime::LogInfo("usage", " -port <1-65535> Listen TCP port (default: 25565)");
|
ServerRuntime::LogInfo("usage", " -port <1-65535> Listen TCP port (default: server.properties:server-port)");
|
||||||
ServerRuntime::LogInfo("usage", " -ip <addr> Bind address (default: 0.0.0.0)");
|
ServerRuntime::LogInfo("usage", " -ip <addr> Bind address (default: server.properties:server-ip)");
|
||||||
ServerRuntime::LogInfo("usage", " -bind <addr> Alias of -ip");
|
ServerRuntime::LogInfo("usage", " -bind <addr> Alias of -ip");
|
||||||
ServerRuntime::LogInfo("usage", " -name <name> Host display name (max 16 chars)");
|
ServerRuntime::LogInfo("usage", " -name <name> Host display name (max 16 chars, default: server.properties:server-name)");
|
||||||
ServerRuntime::LogInfo("usage", " -maxplayers <1-8> Public slots (default: 8)");
|
ServerRuntime::LogInfo("usage", " -maxplayers <1-8> Public slots (default: server.properties:max-players)");
|
||||||
ServerRuntime::LogInfo("usage", " -seed <int64> World seed");
|
ServerRuntime::LogInfo("usage", " -seed <int64> World seed (overrides server.properties:level-seed)");
|
||||||
ServerRuntime::LogInfo("usage", " -loglevel <level> debug|info|warn|error (default: info)");
|
ServerRuntime::LogInfo("usage", " -loglevel <level> debug|info|warn|error (default: server.properties:log-level)");
|
||||||
ServerRuntime::LogInfo("usage", " -help Show this help");
|
ServerRuntime::LogInfo("usage", " -help Show this help");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,6 +231,30 @@ static void SetExeWorkingDirectory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ApplyServerPropertiesToDedicatedConfig(const ServerPropertiesConfig &serverProperties, DedicatedServerConfig *config)
|
||||||
|
{
|
||||||
|
if (config == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->port = serverProperties.serverPort;
|
||||||
|
strncpy_s(
|
||||||
|
config->bindIP,
|
||||||
|
sizeof(config->bindIP),
|
||||||
|
serverProperties.serverIp.empty() ? "0.0.0.0" : serverProperties.serverIp.c_str(),
|
||||||
|
_TRUNCATE);
|
||||||
|
strncpy_s(
|
||||||
|
config->name,
|
||||||
|
sizeof(config->name),
|
||||||
|
serverProperties.serverName.empty() ? "DedicatedServer" : serverProperties.serverName.c_str(),
|
||||||
|
_TRUNCATE);
|
||||||
|
config->maxPlayers = serverProperties.maxPlayers;
|
||||||
|
config->logLevel = serverProperties.logLevel;
|
||||||
|
config->hasSeed = serverProperties.hasSeed;
|
||||||
|
config->seed = serverProperties.seed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 非同期処理進行に必須なコアサブシステムを1フレーム分進める
|
* 非同期処理進行に必須なコアサブシステムを1フレーム分進める
|
||||||
*
|
*
|
||||||
|
|
@ -274,6 +297,13 @@ int main(int argc, char **argv)
|
||||||
config.hasSeed = false;
|
config.hasSeed = false;
|
||||||
config.showHelp = false;
|
config.showHelp = false;
|
||||||
|
|
||||||
|
SetConsoleCtrlHandler(ConsoleCtrlHandlerProc, TRUE);
|
||||||
|
SetExeWorkingDirectory();
|
||||||
|
|
||||||
|
// server.properties の値をベース設定として読み込み、CLI で必要に応じて上書きする
|
||||||
|
ServerPropertiesConfig serverProperties = LoadServerPropertiesConfig();
|
||||||
|
ApplyServerPropertiesToDedicatedConfig(serverProperties, &config);
|
||||||
|
|
||||||
if (!ParseCommandLine(argc, argv, &config))
|
if (!ParseCommandLine(argc, argv, &config))
|
||||||
{
|
{
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
|
|
@ -287,8 +317,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
SetServerLogLevel(config.logLevel);
|
SetServerLogLevel(config.logLevel);
|
||||||
LogStartupStep("initializing process state");
|
LogStartupStep("initializing process state");
|
||||||
SetConsoleCtrlHandler(ConsoleCtrlHandlerProc, TRUE);
|
|
||||||
SetExeWorkingDirectory();
|
|
||||||
|
|
||||||
g_iScreenWidth = 1280;
|
g_iScreenWidth = 1280;
|
||||||
g_iScreenHeight = 720;
|
g_iScreenHeight = 720;
|
||||||
|
|
@ -378,35 +406,40 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.InitGameSettings();
|
app.InitGameSettings();
|
||||||
if (minecraft->options != NULL)
|
|
||||||
{
|
|
||||||
minecraft->options->set(Options::Option::MUSIC, 0.0f);
|
|
||||||
minecraft->options->set(Options::Option::SOUND, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftServer::resetFlags();
|
MinecraftServer::resetFlags();
|
||||||
app.SetTutorialMode(false);
|
app.SetTutorialMode(false);
|
||||||
app.SetCorruptSaveDeleted(false);
|
app.SetCorruptSaveDeleted(false);
|
||||||
app.SetGameHostOption(eGameHostOption_Difficulty, 1);
|
app.SetGameHostOption(eGameHostOption_Difficulty, serverProperties.difficulty);
|
||||||
app.SetGameHostOption(eGameHostOption_FriendsOfFriends, 0);
|
app.SetGameHostOption(eGameHostOption_FriendsOfFriends, serverProperties.friendsOfFriends ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_Gamertags, 1);
|
app.SetGameHostOption(eGameHostOption_Gamertags, serverProperties.gamertags ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_BedrockFog, 1);
|
app.SetGameHostOption(eGameHostOption_BedrockFog, serverProperties.bedrockFog ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_GameType, 0);
|
app.SetGameHostOption(eGameHostOption_GameType, serverProperties.gameMode);
|
||||||
app.SetGameHostOption(eGameHostOption_LevelType, 0);
|
app.SetGameHostOption(eGameHostOption_LevelType, serverProperties.levelTypeFlat ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_Structures, 1);
|
app.SetGameHostOption(eGameHostOption_Structures, serverProperties.generateStructures ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_BonusChest, 0);
|
app.SetGameHostOption(eGameHostOption_BonusChest, serverProperties.bonusChest ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_PvP, 1);
|
app.SetGameHostOption(eGameHostOption_PvP, serverProperties.pvp ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_TrustPlayers, 1);
|
app.SetGameHostOption(eGameHostOption_TrustPlayers, serverProperties.trustPlayers ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_FireSpreads, 1);
|
app.SetGameHostOption(eGameHostOption_FireSpreads, serverProperties.fireSpreads ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_TNT, 1);
|
app.SetGameHostOption(eGameHostOption_TNT, serverProperties.tnt ? 1 : 0);
|
||||||
app.SetGameHostOption(eGameHostOption_HostCanFly, 1);
|
app.SetGameHostOption(
|
||||||
app.SetGameHostOption(eGameHostOption_HostCanChangeHunger, 1);
|
eGameHostOption_CheatsEnabled,
|
||||||
app.SetGameHostOption(eGameHostOption_HostCanBeInvisible, 1);
|
(serverProperties.hostCanFly || serverProperties.hostCanChangeHunger || serverProperties.hostCanBeInvisible) ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_HostCanFly, serverProperties.hostCanFly ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_HostCanChangeHunger, serverProperties.hostCanChangeHunger ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_HostCanBeInvisible, serverProperties.hostCanBeInvisible ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_DisableSaving, serverProperties.disableSaving ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_MobGriefing, serverProperties.mobGriefing ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_KeepInventory, serverProperties.keepInventory ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_DoMobSpawning, serverProperties.doMobSpawning ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_DoMobLoot, serverProperties.doMobLoot ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_DoTileDrops, serverProperties.doTileDrops ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_NaturalRegeneration, serverProperties.naturalRegeneration ? 1 : 0);
|
||||||
|
app.SetGameHostOption(eGameHostOption_DoDaylightCycle, serverProperties.doDaylightCycle ? 1 : 0);
|
||||||
|
|
||||||
StorageManager.SetSaveDisabled(false);
|
StorageManager.SetSaveDisabled(serverProperties.disableSaving);
|
||||||
// server.properties から world 名と固定 save-id を取得し、
|
// server.properties から world 名と固定 save-id を取得し、
|
||||||
// WorldManager にロード/新規作成判定を委譲する
|
// WorldManager にロード/新規作成判定を委譲する
|
||||||
ServerPropertiesConfig serverProperties = LoadServerPropertiesConfig();
|
|
||||||
std::wstring targetWorldName = serverProperties.worldName;
|
std::wstring targetWorldName = serverProperties.worldName;
|
||||||
if (targetWorldName.empty())
|
if (targetWorldName.empty())
|
||||||
{
|
{
|
||||||
|
|
@ -491,7 +524,12 @@ int main(int argc, char **argv)
|
||||||
LogWorldIO("initial save completed");
|
LogWorldIO("initial save completed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DWORD nextAutosaveTick = GetTickCount() + kAutosaveIntervalMs;
|
DWORD autosaveIntervalMs = kDefaultAutosaveIntervalMs;
|
||||||
|
if (serverProperties.autosaveIntervalSeconds > 0)
|
||||||
|
{
|
||||||
|
autosaveIntervalMs = (DWORD)(serverProperties.autosaveIntervalSeconds * 1000);
|
||||||
|
}
|
||||||
|
DWORD nextAutosaveTick = GetTickCount() + autosaveIntervalMs;
|
||||||
bool autosaveRequested = false;
|
bool autosaveRequested = false;
|
||||||
|
|
||||||
while (!g_shutdownRequested && !app.m_bShutdown)
|
while (!g_shutdownRequested && !app.m_bShutdown)
|
||||||
|
|
@ -519,7 +557,7 @@ int main(int argc, char **argv)
|
||||||
app.SetXuiServerAction(kServerActionPad, eXuiServerAction_AutoSaveGame);
|
app.SetXuiServerAction(kServerActionPad, eXuiServerAction_AutoSaveGame);
|
||||||
autosaveRequested = true;
|
autosaveRequested = true;
|
||||||
}
|
}
|
||||||
nextAutosaveTick = now + kAutosaveIntervalMs;
|
nextAutosaveTick = now + autosaveIntervalMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue