make timescale a server command and add a tickrate command
This commit is contained in:
parent
5f01d2d4d7
commit
5ca42599ef
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"directives" : "",
|
"directives" : "",
|
||||||
"pickupDistance" : 0.5,
|
"pickupDistance" : 0.5,
|
||||||
"afterTakenLife" : 2.5,
|
"afterTakenLife" : 0.75,
|
||||||
"overheadTime" : 0.5,
|
"overheadTime" : 0.5,
|
||||||
"overheadApproach" : 2000,
|
"overheadApproach" : 2000,
|
||||||
"overheadRandomizedDistance" : 0.25
|
"overheadRandomizedDistance" : 0.25
|
||||||
|
@ -147,7 +147,7 @@ void Clock::setMilliseconds(int64_t millis) {
|
|||||||
|
|
||||||
void Clock::adjustTime(double timeAdjustment) {
|
void Clock::adjustTime(double timeAdjustment) {
|
||||||
RecursiveMutexLocker locker(m_mutex);
|
RecursiveMutexLocker locker(m_mutex);
|
||||||
setTime(time() + timeAdjustment);
|
setTime(max<double>(0.0, time() + timeAdjustment));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clock::adjustMilliseconds(int64_t millisAdjustment) {
|
void Clock::adjustMilliseconds(int64_t millisAdjustment) {
|
||||||
|
@ -51,8 +51,7 @@ ClientCommandProcessor::ClientCommandProcessor(UniverseClientPtr universeClient,
|
|||||||
{"maketechavailable", bind(&ClientCommandProcessor::makeTechAvailable, this, _1)},
|
{"maketechavailable", bind(&ClientCommandProcessor::makeTechAvailable, this, _1)},
|
||||||
{"enabletech", bind(&ClientCommandProcessor::enableTech, this, _1)},
|
{"enabletech", bind(&ClientCommandProcessor::enableTech, this, _1)},
|
||||||
{"upgradeship", bind(&ClientCommandProcessor::upgradeShip, this, _1)},
|
{"upgradeship", bind(&ClientCommandProcessor::upgradeShip, this, _1)},
|
||||||
{"swap", bind(&ClientCommandProcessor::swap, this, _1)},
|
{"swap", bind(&ClientCommandProcessor::swap, this, _1)}
|
||||||
{"timescale", bind(&ClientCommandProcessor::timeScale, this, _1)}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +380,7 @@ String ClientCommandProcessor::makeTechAvailable(String const& argumentsString)
|
|||||||
return "You must be an admin to use this command.";
|
return "You must be an admin to use this command.";
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
return "Not enouch arguments to /maketechavailable";
|
return "Not enough arguments to /maketechavailable";
|
||||||
|
|
||||||
m_universeClient->mainPlayer()->techs()->makeAvailable(arguments.at(0));
|
m_universeClient->mainPlayer()->techs()->makeAvailable(arguments.at(0));
|
||||||
return strf("Added {} to player's visible techs", arguments.at(0));
|
return strf("Added {} to player's visible techs", arguments.at(0));
|
||||||
@ -393,7 +392,7 @@ String ClientCommandProcessor::enableTech(String const& argumentsString) {
|
|||||||
return "You must be an admin to use this command.";
|
return "You must be an admin to use this command.";
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
return "Not enouch arguments to /enabletech";
|
return "Not enough arguments to /enabletech";
|
||||||
|
|
||||||
m_universeClient->mainPlayer()->techs()->makeAvailable(arguments.at(0));
|
m_universeClient->mainPlayer()->techs()->makeAvailable(arguments.at(0));
|
||||||
m_universeClient->mainPlayer()->techs()->enable(arguments.at(0));
|
m_universeClient->mainPlayer()->techs()->enable(arguments.at(0));
|
||||||
@ -406,7 +405,7 @@ String ClientCommandProcessor::upgradeShip(String const& argumentsString) {
|
|||||||
return "You must be an admin to use this command.";
|
return "You must be an admin to use this command.";
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
return "Not enouch arguments to /upgradeship";
|
return "Not enough arguments to /upgradeship";
|
||||||
|
|
||||||
auto shipUpgrades = Json::parseJson(arguments.at(0));
|
auto shipUpgrades = Json::parseJson(arguments.at(0));
|
||||||
m_universeClient->rpcInterface()->invokeRemote("ship.applyShipUpgrades", shipUpgrades);
|
m_universeClient->rpcInterface()->invokeRemote("ship.applyShipUpgrades", shipUpgrades);
|
||||||
@ -417,7 +416,7 @@ String ClientCommandProcessor::swap(String const& argumentsString) {
|
|||||||
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
return "Not enouch arguments to /swap";
|
return "Not enough arguments to /swap";
|
||||||
|
|
||||||
if (m_universeClient->switchPlayer(arguments[0]))
|
if (m_universeClient->switchPlayer(arguments[0]))
|
||||||
return "Successfully swapped player";
|
return "Successfully swapped player";
|
||||||
@ -425,14 +424,4 @@ String ClientCommandProcessor::swap(String const& argumentsString) {
|
|||||||
return "Failed to swap player";
|
return "Failed to swap player";
|
||||||
}
|
}
|
||||||
|
|
||||||
String ClientCommandProcessor::timeScale(String const& argumentsString) {
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
|
||||||
return "Not enouch arguments to /timescale";
|
|
||||||
|
|
||||||
GlobalTimescale = clamp(lexicalCast<float>(arguments[0]), 0.001f, 256.0f);
|
|
||||||
return strf("Set application timescale to {:6.6f}x", GlobalTimescale);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ private:
|
|||||||
String enableTech(String const& argumentsString);
|
String enableTech(String const& argumentsString);
|
||||||
String upgradeShip(String const& argumentsString);
|
String upgradeShip(String const& argumentsString);
|
||||||
String swap(String const& argumentsString);
|
String swap(String const& argumentsString);
|
||||||
String timeScale(String const& argumentsString);
|
|
||||||
|
|
||||||
UniverseClientPtr m_universeClient;
|
UniverseClientPtr m_universeClient;
|
||||||
CinematicPtr m_cinematicOverlay;
|
CinematicPtr m_cinematicOverlay;
|
||||||
|
@ -193,22 +193,56 @@ String CommandProcessor::warpRandom(ConnectionId connectionId, String const& typ
|
|||||||
return strf("warping to {}", *target);
|
return strf("warping to {}", *target);
|
||||||
}
|
}
|
||||||
|
|
||||||
String CommandProcessor::timewarp(ConnectionId connectionId, String const& argumentString) {
|
String CommandProcessor::timewarp(ConnectionId connectionId, String const& argumentsString) {
|
||||||
if (auto errorMsg = adminCheck(connectionId, "do the time warp again"))
|
if (auto errorMsg = adminCheck(connectionId, "do the time warp again"))
|
||||||
return *errorMsg;
|
return *errorMsg;
|
||||||
|
|
||||||
|
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
||||||
|
if (arguments.empty())
|
||||||
|
return "Not enough arguments to /timewarp";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto time = lexicalCast<double>(argumentString);
|
auto time = lexicalCast<double>(arguments.at(0));
|
||||||
if (time < 0)
|
if (time == 0.0)
|
||||||
|
return "You suck at time travel.";
|
||||||
|
else if (time < 0.0 && (arguments.size() < 2 || arguments[1] != "please"))
|
||||||
return "Great Scott! We can't go back in time!";
|
return "Great Scott! We can't go back in time!";
|
||||||
|
|
||||||
m_universe->universeClock()->adjustTime(time);
|
m_universe->universeClock()->adjustTime(time);
|
||||||
return "It's just a jump to the left...";
|
return strf("It's just a jump to the {}...", time > 0.0 ? "left" : "right");
|
||||||
} catch (BadLexicalCast const&) {
|
} catch (BadLexicalCast const&) {
|
||||||
return strf("Could not parse the argument {} as a time adjustment", argumentString);
|
return strf("Could not parse the argument {} as a time adjustment", arguments[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String CommandProcessor::timescale(ConnectionId connectionId, String const& argumentsString) {
|
||||||
|
if (auto errorMsg = adminCheck(connectionId, "mess with time"))
|
||||||
|
return *errorMsg;
|
||||||
|
|
||||||
|
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
||||||
|
|
||||||
|
if (arguments.empty())
|
||||||
|
return "Not enough arguments to /timescale";
|
||||||
|
|
||||||
|
float timescale = clamp(lexicalCast<float>(arguments[0]), 0.001f, 32.0f);
|
||||||
|
m_universe->setTimescale(timescale);
|
||||||
|
return strf("Set timescale to {:6.6f}x", timescale);
|
||||||
|
}
|
||||||
|
|
||||||
|
String CommandProcessor::tickrate(ConnectionId connectionId, String const& argumentsString) {
|
||||||
|
if (auto errorMsg = adminCheck(connectionId, "change the tick rate"))
|
||||||
|
return *errorMsg;
|
||||||
|
|
||||||
|
auto arguments = m_parser.tokenizeToStringList(argumentsString);
|
||||||
|
|
||||||
|
if (arguments.empty())
|
||||||
|
return "Not enough arguments to /tickrate";
|
||||||
|
|
||||||
|
unsigned tickRate = clamp<unsigned>(lexicalCast<unsigned>(arguments[0]), 5, 500);
|
||||||
|
m_universe->setTickRate(tickRate);
|
||||||
|
return strf("Set tick rate to {}Hz", tickRate);
|
||||||
|
}
|
||||||
|
|
||||||
String CommandProcessor::setTileProtection(ConnectionId connectionId, String const& argumentString) {
|
String CommandProcessor::setTileProtection(ConnectionId connectionId, String const& argumentString) {
|
||||||
if (auto errorMsg = adminCheck(connectionId, "modify world properties")) {
|
if (auto errorMsg = adminCheck(connectionId, "modify world properties")) {
|
||||||
return *errorMsg;
|
return *errorMsg;
|
||||||
@ -272,7 +306,7 @@ String CommandProcessor::spawnItem(ConnectionId connectionId, String const& argu
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "Not enough arguments to /spawnitem";
|
return "Not enough arguments to /spawnitem";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -321,7 +355,7 @@ String CommandProcessor::spawnTreasure(ConnectionId connectionId, String const&
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "Not enough arguments to /spawntreasure";
|
return "Not enough arguments to /spawntreasure";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -532,7 +566,7 @@ String CommandProcessor::kick(ConnectionId connectionId, String const& argumentS
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "No player specified";
|
return "No player specified";
|
||||||
|
|
||||||
auto toKick = playerCidFromCommand(arguments[0], m_universe);
|
auto toKick = playerCidFromCommand(arguments[0], m_universe);
|
||||||
@ -557,7 +591,7 @@ String CommandProcessor::ban(ConnectionId connectionId, String const& argumentSt
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "No player specified";
|
return "No player specified";
|
||||||
|
|
||||||
auto toKick = playerCidFromCommand(arguments[0], m_universe);
|
auto toKick = playerCidFromCommand(arguments[0], m_universe);
|
||||||
@ -605,7 +639,7 @@ String CommandProcessor::unbanIp(ConnectionId connectionId, String const& argume
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "No IP specified";
|
return "No IP specified";
|
||||||
|
|
||||||
bool success = m_universe->unbanIp(arguments[0]);
|
bool success = m_universe->unbanIp(arguments[0]);
|
||||||
@ -622,7 +656,7 @@ String CommandProcessor::unbanUuid(ConnectionId connectionId, String const& argu
|
|||||||
|
|
||||||
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
auto arguments = m_parser.tokenizeToStringList(argumentString);
|
||||||
|
|
||||||
if (arguments.size() == 0)
|
if (arguments.empty())
|
||||||
return "No UUID specified";
|
return "No UUID specified";
|
||||||
|
|
||||||
bool success = m_universe->unbanUuid(arguments[0]);
|
bool success = m_universe->unbanUuid(arguments[0]);
|
||||||
@ -868,121 +902,88 @@ Maybe<ConnectionId> CommandProcessor::playerCidFromCommand(String const& player,
|
|||||||
return universe->findNick(player);
|
return universe->findNick(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//wow, wtf. TODO: replace with hashmap
|
||||||
String CommandProcessor::handleCommand(ConnectionId connectionId, String const& command, String const& argumentString) {
|
String CommandProcessor::handleCommand(ConnectionId connectionId, String const& command, String const& argumentString) {
|
||||||
if (command == "admin") {
|
if (command == "admin") {
|
||||||
return admin(connectionId, argumentString);
|
return admin(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "timewarp") {
|
} else if (command == "timewarp") {
|
||||||
return timewarp(connectionId, argumentString);
|
return timewarp(connectionId, argumentString);
|
||||||
|
} else if (command == "timescale") {
|
||||||
|
return timescale(connectionId, argumentString);
|
||||||
|
} else if (command == "tickrate") {
|
||||||
|
return tickrate(connectionId, argumentString);
|
||||||
} else if (command == "settileprotection") {
|
} else if (command == "settileprotection") {
|
||||||
return setTileProtection(connectionId, argumentString);
|
return setTileProtection(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "setdungeonid") {
|
} else if (command == "setdungeonid") {
|
||||||
return setDungeonId(connectionId, argumentString);
|
return setDungeonId(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "setspawnpoint") {
|
} else if (command == "setspawnpoint") {
|
||||||
return setPlayerStart(connectionId, argumentString);
|
return setPlayerStart(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnitem") {
|
} else if (command == "spawnitem") {
|
||||||
return spawnItem(connectionId, argumentString);
|
return spawnItem(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawntreasure") {
|
} else if (command == "spawntreasure") {
|
||||||
return spawnTreasure(connectionId, argumentString);
|
return spawnTreasure(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnmonster") {
|
} else if (command == "spawnmonster") {
|
||||||
return spawnMonster(connectionId, argumentString);
|
return spawnMonster(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnnpc") {
|
} else if (command == "spawnnpc") {
|
||||||
return spawnNpc(connectionId, argumentString);
|
return spawnNpc(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnstagehand") {
|
} else if (command == "spawnstagehand") {
|
||||||
return spawnStagehand(connectionId, argumentString);
|
return spawnStagehand(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "clearstagehand") {
|
} else if (command == "clearstagehand") {
|
||||||
return clearStagehand(connectionId, argumentString);
|
return clearStagehand(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnvehicle") {
|
} else if (command == "spawnvehicle") {
|
||||||
return spawnVehicle(connectionId, argumentString);
|
return spawnVehicle(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "spawnliquid") {
|
} else if (command == "spawnliquid") {
|
||||||
return spawnLiquid(connectionId, argumentString);
|
return spawnLiquid(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "pvp") {
|
} else if (command == "pvp") {
|
||||||
return pvp(connectionId, argumentString);
|
return pvp(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "serverwhoami") {
|
} else if (command == "serverwhoami") {
|
||||||
return whoami(connectionId, argumentString);
|
return whoami(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "kick") {
|
} else if (command == "kick") {
|
||||||
return kick(connectionId, argumentString);
|
return kick(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "ban") {
|
} else if (command == "ban") {
|
||||||
return ban(connectionId, argumentString);
|
return ban(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "unbanip") {
|
} else if (command == "unbanip") {
|
||||||
return unbanIp(connectionId, argumentString);
|
return unbanIp(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "unbanuuid") {
|
} else if (command == "unbanuuid") {
|
||||||
return unbanUuid(connectionId, argumentString);
|
return unbanUuid(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "list") {
|
} else if (command == "list") {
|
||||||
return list(connectionId, argumentString);
|
return list(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "help") {
|
} else if (command == "help") {
|
||||||
return help(connectionId, argumentString);
|
return help(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "warp") {
|
} else if (command == "warp") {
|
||||||
return warp(connectionId, argumentString);
|
return warp(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "warprandom") {
|
} else if (command == "warprandom") {
|
||||||
return warpRandom(connectionId, argumentString);
|
return warpRandom(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "whereami") {
|
} else if (command == "whereami") {
|
||||||
return clientCoordinate(connectionId, argumentString);
|
return clientCoordinate(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "whereis") {
|
} else if (command == "whereis") {
|
||||||
return clientCoordinate(connectionId, argumentString);
|
return clientCoordinate(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "serverreload") {
|
} else if (command == "serverreload") {
|
||||||
return serverReload(connectionId, argumentString);
|
return serverReload(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "eval") {
|
} else if (command == "eval") {
|
||||||
return eval(connectionId, argumentString);
|
return eval(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "entityeval") {
|
} else if (command == "entityeval") {
|
||||||
return entityEval(connectionId, argumentString);
|
return entityEval(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "enablespawning") {
|
} else if (command == "enablespawning") {
|
||||||
return enableSpawning(connectionId, argumentString);
|
return enableSpawning(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "disablespawning") {
|
} else if (command == "disablespawning") {
|
||||||
return disableSpawning(connectionId, argumentString);
|
return disableSpawning(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "placedungeon") {
|
} else if (command == "placedungeon") {
|
||||||
return placeDungeon(connectionId, argumentString);
|
return placeDungeon(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "setuniverseflag") {
|
} else if (command == "setuniverseflag") {
|
||||||
return setUniverseFlag(connectionId, argumentString);
|
return setUniverseFlag(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "resetuniverseflags") {
|
} else if (command == "resetuniverseflags") {
|
||||||
return resetUniverseFlags(connectionId, argumentString);
|
return resetUniverseFlags(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "addbiomeregion") {
|
} else if (command == "addbiomeregion") {
|
||||||
return addBiomeRegion(connectionId, argumentString);
|
return addBiomeRegion(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "expandbiomeregion") {
|
} else if (command == "expandbiomeregion") {
|
||||||
return expandBiomeRegion(connectionId, argumentString);
|
return expandBiomeRegion(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "updateplanettype") {
|
} else if (command == "updateplanettype") {
|
||||||
return updatePlanetType(connectionId, argumentString);
|
return updatePlanetType(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (command == "setenvironmentbiome") {
|
} else if (command == "setenvironmentbiome") {
|
||||||
return setEnvironmentBiome(connectionId, argumentString);
|
return setEnvironmentBiome(connectionId, argumentString);
|
||||||
|
|
||||||
} else if (auto res = m_scriptComponent.invoke("command", command, connectionId, jsonFromStringList(m_parser.tokenizeToStringList(argumentString)))) {
|
} else if (auto res = m_scriptComponent.invoke("command", command, connectionId, jsonFromStringList(m_parser.tokenizeToStringList(argumentString)))) {
|
||||||
return toString(*res);
|
return toString(*res);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return strf("No such command {}", command);
|
return strf("No such command {}", command);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ private:
|
|||||||
String warp(ConnectionId connectionId, String const& argumentString);
|
String warp(ConnectionId connectionId, String const& argumentString);
|
||||||
String warpRandom(ConnectionId connectionId, String const& argumentString);
|
String warpRandom(ConnectionId connectionId, String const& argumentString);
|
||||||
String timewarp(ConnectionId connectionId, String const& argumentString);
|
String timewarp(ConnectionId connectionId, String const& argumentString);
|
||||||
|
String timescale(ConnectionId connectionId, String const& argumentString);
|
||||||
|
String tickrate(ConnectionId connectionId, String const& argumentString);
|
||||||
String setTileProtection(ConnectionId connectionId, String const& argumentString);
|
String setTileProtection(ConnectionId connectionId, String const& argumentString);
|
||||||
String setDungeonId(ConnectionId connectionId, String const& argumentString);
|
String setDungeonId(ConnectionId connectionId, String const& argumentString);
|
||||||
String setPlayerStart(ConnectionId connectionId, String const& argumentString);
|
String setPlayerStart(ConnectionId connectionId, String const& argumentString);
|
||||||
|
@ -304,14 +304,25 @@ void PlanetTypeUpdatePacket::write(DataStream& ds) const {
|
|||||||
|
|
||||||
PausePacket::PausePacket() {}
|
PausePacket::PausePacket() {}
|
||||||
|
|
||||||
PausePacket::PausePacket(bool pause) : pause(std::move(pause)) {}
|
PausePacket::PausePacket(bool pause, float timescale) : pause(pause), timescale(timescale) {}
|
||||||
|
|
||||||
|
void PausePacket::readLegacy(DataStream& ds) {
|
||||||
|
ds.read(pause);
|
||||||
|
timescale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void PausePacket::read(DataStream& ds) {
|
void PausePacket::read(DataStream& ds) {
|
||||||
ds.read(pause);
|
readLegacy(ds);
|
||||||
|
ds.read(timescale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PausePacket::writeLegacy(DataStream& ds) const {
|
||||||
|
ds.write(pause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PausePacket::write(DataStream& ds) const {
|
void PausePacket::write(DataStream& ds) const {
|
||||||
ds.write(pause);
|
writeLegacy(ds);
|
||||||
|
ds.write(timescale);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfoPacket::ServerInfoPacket() {}
|
ServerInfoPacket::ServerInfoPacket() {}
|
||||||
|
@ -226,6 +226,7 @@ struct UniverseTimeUpdatePacket : PacketBase<PacketType::UniverseTimeUpdate> {
|
|||||||
void write(DataStream& ds) const override;
|
void write(DataStream& ds) const override;
|
||||||
|
|
||||||
double universeTime;
|
double universeTime;
|
||||||
|
float timescale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CelestialResponsePacket : PacketBase<PacketType::CelestialResponse> {
|
struct CelestialResponsePacket : PacketBase<PacketType::CelestialResponse> {
|
||||||
@ -262,12 +263,15 @@ struct PlanetTypeUpdatePacket : PacketBase<PacketType::PlanetTypeUpdate> {
|
|||||||
|
|
||||||
struct PausePacket : PacketBase<PacketType::Pause> {
|
struct PausePacket : PacketBase<PacketType::Pause> {
|
||||||
PausePacket();
|
PausePacket();
|
||||||
PausePacket(bool pause);
|
PausePacket(bool pause, float timescale = 1.0f);
|
||||||
|
|
||||||
|
void readLegacy(DataStream& ds) override;
|
||||||
void read(DataStream& ds) override;
|
void read(DataStream& ds) override;
|
||||||
|
void writeLegacy(DataStream& ds) const override;
|
||||||
void write(DataStream& ds) const override;
|
void write(DataStream& ds) const override;
|
||||||
|
|
||||||
bool pause;
|
bool pause;
|
||||||
|
float timescale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerInfoPacket : PacketBase<PacketType::ServerInfo> {
|
struct ServerInfoPacket : PacketBase<PacketType::ServerInfo> {
|
||||||
|
@ -91,7 +91,7 @@ void SystemWorldServerThread::update() {
|
|||||||
p.second(m_systemWorld->clientShip(p.first).get());
|
p.second(m_systemWorld->clientShip(p.first).get());
|
||||||
|
|
||||||
if (!m_pause || *m_pause == false)
|
if (!m_pause || *m_pause == false)
|
||||||
m_systemWorld->update(SystemWorldTimestep);
|
m_systemWorld->update(SystemWorldTimestep * GlobalTimescale);
|
||||||
m_triggerStorage = m_systemWorld->triggeredStorage();
|
m_triggerStorage = m_systemWorld->triggeredStorage();
|
||||||
|
|
||||||
// important to set destinations before getting locations
|
// important to set destinations before getting locations
|
||||||
|
@ -164,6 +164,7 @@ void UniverseClient::disconnect() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalTimescale = 1.0f;
|
||||||
reset();
|
reset();
|
||||||
m_mainPlayer = {};
|
m_mainPlayer = {};
|
||||||
}
|
}
|
||||||
@ -675,6 +676,7 @@ void UniverseClient::handlePackets(List<PacketPtr> const& packets) {
|
|||||||
m_celestialDatabase->invalidateCacheFor(planetTypeUpdate->coordinate);
|
m_celestialDatabase->invalidateCacheFor(planetTypeUpdate->coordinate);
|
||||||
} else if (auto pausePacket = as<PausePacket>(packet)) {
|
} else if (auto pausePacket = as<PausePacket>(packet)) {
|
||||||
setPause(pausePacket->pause);
|
setPause(pausePacket->pause);
|
||||||
|
GlobalTimescale = clamp(pausePacket->timescale, 0.0f, 1024.f);
|
||||||
} else if (auto serverInfoPacket = as<ServerInfoPacket>(packet)) {
|
} else if (auto serverInfoPacket = as<ServerInfoPacket>(packet)) {
|
||||||
m_serverInfo = ServerInfo{serverInfoPacket->players, serverInfoPacket->maxPlayers};
|
m_serverInfo = ServerInfo{serverInfoPacket->players, serverInfoPacket->maxPlayers};
|
||||||
} else if (!m_systemWorldClient->handleIncomingPacket(packet)) {
|
} else if (!m_systemWorldClient->handleIncomingPacket(packet)) {
|
||||||
|
@ -143,8 +143,19 @@ void UniverseServer::setPause(bool pause) {
|
|||||||
else
|
else
|
||||||
m_universeClock->start();
|
m_universeClock->start();
|
||||||
|
|
||||||
for (auto p : m_clients)
|
for (auto& p : m_clients)
|
||||||
m_connectionServer->sendPackets(p.first, {make_shared<PausePacket>(*m_pause)});
|
m_connectionServer->sendPackets(p.first, {make_shared<PausePacket>(*m_pause, GlobalTimescale)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniverseServer::setTimescale(float timescale) {
|
||||||
|
ReadLocker clientsLocker(m_clientsLock);
|
||||||
|
GlobalTimescale = timescale;
|
||||||
|
for (auto& p : m_clients)
|
||||||
|
m_connectionServer->sendPackets(p.first, {make_shared<PausePacket>(*m_pause, GlobalTimescale)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniverseServer::setTickRate(float tickRate) {
|
||||||
|
ServerGlobalTimestep = 1.0f / tickRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WorldId> UniverseServer::activeWorlds() const {
|
List<WorldId> UniverseServer::activeWorlds() const {
|
||||||
@ -1677,7 +1688,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe<HostA
|
|||||||
|
|
||||||
m_connectionServer->sendPackets(clientId, {
|
m_connectionServer->sendPackets(clientId, {
|
||||||
make_shared<ConnectSuccessPacket>(clientId, m_universeSettings->uuid(), m_celestialDatabase->baseInformation()),
|
make_shared<ConnectSuccessPacket>(clientId, m_universeSettings->uuid(), m_celestialDatabase->baseInformation()),
|
||||||
make_shared<UniverseTimeUpdatePacket>(m_universeClock->time())
|
make_shared<UniverseTimeUpdatePacket>(m_universeClock->time()),
|
||||||
|
make_shared<PausePacket>(*m_pause, GlobalTimescale)
|
||||||
});
|
});
|
||||||
|
|
||||||
setPvp(clientId, false);
|
setPvp(clientId, false);
|
||||||
@ -1701,8 +1713,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe<HostA
|
|||||||
bool useReviveWarp = true;
|
bool useReviveWarp = true;
|
||||||
if (reviveWarp.world.is<InstanceWorldId>()) {
|
if (reviveWarp.world.is<InstanceWorldId>()) {
|
||||||
String instance = reviveWarp.world.get<InstanceWorldId>().instance;
|
String instance = reviveWarp.world.get<InstanceWorldId>().instance;
|
||||||
Json worldConfig = Root::singleton().assets()->json("/instance_worlds.config").get(instance);
|
auto worldConfig = Root::singleton().assets()->json("/instance_worlds.config").opt(instance);
|
||||||
if (!worldConfig.getBool("persistent", false))
|
if (!worldConfig || !worldConfig->getBool("persistent", false))
|
||||||
useReviveWarp = false;
|
useReviveWarp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ public:
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void setPause(bool pause);
|
void setPause(bool pause);
|
||||||
|
void setTimescale(float timescale);
|
||||||
|
void setTickRate(float tickRate);
|
||||||
|
|
||||||
List<WorldId> activeWorlds() const;
|
List<WorldId> activeWorlds() const;
|
||||||
bool isWorldActive(WorldId const& worldId) const;
|
bool isWorldActive(WorldId const& worldId) const;
|
||||||
|
@ -207,7 +207,7 @@ void WorldServerThread::run() {
|
|||||||
double storageInterval = root.assets()->json("/universe_server.config:worldStorageInterval").toDouble() / 1000.0;
|
double storageInterval = root.assets()->json("/universe_server.config:worldStorageInterval").toDouble() / 1000.0;
|
||||||
Timer storageTimer = Timer::withTime(storageInterval);
|
Timer storageTimer = Timer::withTime(storageInterval);
|
||||||
|
|
||||||
TickRateApproacher tickApproacher(1.0 / ServerGlobalTimestep, updateMeasureWindow);
|
TickRateApproacher tickApproacher(1.0f / ServerGlobalTimestep, updateMeasureWindow);
|
||||||
double fidelityScore = 0.0;
|
double fidelityScore = 0.0;
|
||||||
WorldServerFidelity automaticFidelity = WorldServerFidelity::Medium;
|
WorldServerFidelity automaticFidelity = WorldServerFidelity::Medium;
|
||||||
|
|
||||||
@ -217,6 +217,7 @@ void WorldServerThread::run() {
|
|||||||
LogMap::set(strf("server_{}_update", m_worldId), strf("{:4.2f}Hz", tickApproacher.rate()));
|
LogMap::set(strf("server_{}_update", m_worldId), strf("{:4.2f}Hz", tickApproacher.rate()));
|
||||||
|
|
||||||
update(fidelity);
|
update(fidelity);
|
||||||
|
tickApproacher.setTargetTickRate(1.0f / ServerGlobalTimestep);
|
||||||
tickApproacher.tick();
|
tickApproacher.tick();
|
||||||
|
|
||||||
if (storageTimer.timeUp()) {
|
if (storageTimer.timeUp()) {
|
||||||
|
@ -51,7 +51,7 @@ int main(int argc, char** argv) {
|
|||||||
if (auto jUpdateRate = configuration->get("updateRate")) {
|
if (auto jUpdateRate = configuration->get("updateRate")) {
|
||||||
updateRate = jUpdateRate.toFloat();
|
updateRate = jUpdateRate.toFloat();
|
||||||
ServerGlobalTimestep = GlobalTimestep = 1.0f / updateRate;
|
ServerGlobalTimestep = GlobalTimestep = 1.0f / updateRate;
|
||||||
Logger::info("Configured tickrate is {:4.2f}hz", updateRate);
|
Logger::info("Configured tick rate is {:4.2f}hz", updateRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniverseServerUPtr server = make_unique<UniverseServer>(root->toStoragePath("universe"));
|
UniverseServerUPtr server = make_unique<UniverseServer>(root->toStoragePath("universe"));
|
||||||
|
Loading…
Reference in New Issue
Block a user