add sky setting overrides to celestial.flyShip, pass net rules to packet read/write

This commit is contained in:
Kae 2024-12-05 15:39:11 +11:00
parent 3fc12923ce
commit dd52188e53
21 changed files with 194 additions and 186 deletions

View File

@ -6,6 +6,8 @@
namespace Star {
unsigned const CurrentStreamVersion = 3;
DataStream::DataStream()
: m_byteOrder(ByteOrder::BigEndian),
m_nullTerminatedStrings(false),

View File

@ -6,6 +6,7 @@
namespace Star {
STAR_EXCEPTION(DataStreamException, IOException);
extern unsigned const CurrentStreamVersion;
// Writes complex types to bytes in a portable big-endian fashion.
class DataStream {
@ -13,8 +14,6 @@ public:
DataStream();
virtual ~DataStream() = default;
static unsigned const CurrentStreamVersion = 2;
// DataStream defaults to big-endian order for all primitive types
ByteOrder byteOrder() const;
void setByteOrder(ByteOrder byteOrder);

View File

@ -2,6 +2,6 @@
namespace Star {
VersionNumber const OpenProtocolVersion = 2;
VersionNumber const OpenProtocolVersion = 3;
}

View File

@ -62,9 +62,8 @@ Maybe<PacketStats> PacketSocket::incomingStats() const {
Maybe<PacketStats> PacketSocket::outgoingStats() const {
return {};
}
void PacketSocket::setLegacy(bool legacy) { m_legacy = legacy; }
bool PacketSocket::legacy() const { return m_legacy; }
void PacketSocket::setNetRules(NetCompatibilityRules netRules) { m_netRules = netRules; }
NetCompatibilityRules PacketSocket::netRules() const { return m_netRules; }
void CompressedPacketSocket::setCompressionStreamEnabled(bool enabled) { m_useCompressionStream = enabled; }
bool CompressedPacketSocket::compressionStreamEnabled() const { return m_useCompressionStream; }
@ -155,7 +154,8 @@ void TcpPacketSocket::sendPackets(List<PacketPtr> packets) {
PacketPtr& packet = it.next();
auto packetType = packet->type();
DataStreamBuffer packetBuffer;
packet->write(packetBuffer);
packetBuffer.setStreamCompatibilityVersion(netRules());
packet->write(packetBuffer, netRules());
outBuffer.write(packetType);
outBuffer.writeVlqI((int)packetBuffer.size());
outBuffer.writeData(packetBuffer.ptr(), packetBuffer.size());
@ -168,13 +168,11 @@ void TcpPacketSocket::sendPackets(List<PacketPtr> packets) {
PacketCompressionMode currentCompressionMode = it.peekNext()->compressionMode();
DataStreamBuffer packetBuffer;
packetBuffer.setStreamCompatibilityVersion(netRules());
while (it.hasNext()
&& it.peekNext()->type() == currentType
&& it.peekNext()->compressionMode() == currentCompressionMode) {
if (legacy())
it.next()->writeLegacy(packetBuffer);
else
it.next()->write(packetBuffer);
it.next()->write(packetBuffer, netRules());
}
// Packets must read and write actual data, because this is used to
@ -239,6 +237,7 @@ List<PacketPtr> TcpPacketSocket::receivePackets() {
m_incomingStats.mix(packetType, packetSize, !compressionStreamEnabled());
DataStreamExternalBuffer packetStream(ds.ptr() + ds.pos(), packetSize);
packetStream.setStreamCompatibilityVersion(netRules());
ByteArray uncompressed;
if (packetCompressed) {
uncompressed = uncompressData(packetStream.ptr(), packetSize, PacketSizeLimit);
@ -255,10 +254,7 @@ List<PacketPtr> TcpPacketSocket::receivePackets() {
}
PacketPtr packet = createPacket(packetType);
packet->setCompressionMode(packetCompressed ? PacketCompressionMode::Enabled : PacketCompressionMode::Disabled);
if (legacy())
packet->readLegacy(packetStream);
else
packet->read(packetStream);
packet->read(packetStream, netRules());
packets.append(std::move(packet));
} while (!packetStream.atEnd());
}
@ -347,10 +343,6 @@ Maybe<PacketStats> TcpPacketSocket::outgoingStats() const {
return m_outgoingStats.stats();
}
void TcpPacketSocket::setLegacy(bool legacy) {
PacketSocket::setLegacy(legacy);
}
TcpPacketSocket::TcpPacketSocket(TcpSocketPtr socket) : m_socket(std::move(socket)) {}
P2PPacketSocketUPtr P2PPacketSocket::open(P2PSocketUPtr socket) {
@ -373,8 +365,9 @@ void P2PPacketSocket::sendPackets(List<PacketPtr> packets) {
while (it.hasNext()) {
PacketType currentType = it.peekNext()->type();
DataStreamBuffer packetBuffer;
packetBuffer.setStreamCompatibilityVersion(netRules());
while (it.hasNext() && it.peekNext()->type() == currentType)
it.next()->write(packetBuffer);
it.next()->write(packetBuffer, netRules());
outBuffer.write(currentType);
outBuffer.write<bool>(false);
outBuffer.writeData(packetBuffer.ptr(), packetBuffer.size());
@ -387,13 +380,11 @@ void P2PPacketSocket::sendPackets(List<PacketPtr> packets) {
PacketCompressionMode currentCompressionMode = it.peekNext()->compressionMode();
DataStreamBuffer packetBuffer;
packetBuffer.setStreamCompatibilityVersion(netRules());
while (it.hasNext()
&& it.peekNext()->type() == currentType
&& it.peekNext()->compressionMode() == currentCompressionMode) {
if (legacy())
it.next()->writeLegacy(packetBuffer);
else
it.next()->write(packetBuffer);
it.next()->write(packetBuffer, netRules());
}
// Packets must read and write actual data, because this is used to
@ -440,13 +431,11 @@ List<PacketPtr> P2PPacketSocket::receivePackets() {
m_incomingStats.mix(packetType, packetSize, !compressionStreamEnabled());
DataStreamExternalBuffer packetStream(packetBytes);
packetStream.setStreamCompatibilityVersion(netRules());
do {
PacketPtr packet = createPacket(packetType);
packet->setCompressionMode(packetCompressed ? PacketCompressionMode::Enabled : PacketCompressionMode::Disabled);
if (legacy())
packet->readLegacy(packetStream);
else
packet->read(packetStream);
packet->read(packetStream, netRules());
packets.append(std::move(packet));
} while (!packetStream.atEnd());
}

View File

@ -5,6 +5,7 @@
#include "StarP2PNetworkingService.hpp"
#include "StarNetPackets.hpp"
#include "StarZSTDCompression.hpp"
#include "StarNetCompatibility.hpp"
namespace Star {
@ -75,10 +76,11 @@ public:
virtual Maybe<PacketStats> incomingStats() const;
virtual Maybe<PacketStats> outgoingStats() const;
virtual void setLegacy(bool legacy);
virtual bool legacy() const;
virtual void setNetRules(NetCompatibilityRules netRules);
virtual NetCompatibilityRules netRules() const;
private:
bool m_legacy = false;
NetCompatibilityRules m_netRules;
};
class CompressedPacketSocket : public PacketSocket {
@ -142,8 +144,6 @@ public:
Maybe<PacketStats> incomingStats() const override;
Maybe<PacketStats> outgoingStats() const override;
void setLegacy(bool legacy) override;
private:
TcpPacketSocket(TcpSocketPtr socket);

View File

@ -85,8 +85,10 @@ EnumMap<NetCompressionMode> const NetCompressionModeNames {
Packet::~Packet() {}
void Packet::readLegacy(DataStream& ds) { read(ds); }
void Packet::writeLegacy(DataStream& ds) const { write(ds); }
void Packet::read(DataStream& ds, NetCompatibilityRules netRules) { read(ds); }
void Packet::read(DataStream& ds) {}
void Packet::write(DataStream& ds, NetCompatibilityRules netRules) const { write(ds); }
void Packet::write(DataStream& ds) const {}
void Packet::readJson(Json const& json) {}
Json Packet::writeJson() const { return JsonObject{}; }
@ -206,12 +208,9 @@ void ProtocolResponsePacket::read(DataStream& ds) {
}
}
void ProtocolResponsePacket::writeLegacy(DataStream& ds) const {
void ProtocolResponsePacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
ds.write(allowed);
}
void ProtocolResponsePacket::write(DataStream& ds) const {
writeLegacy(ds);
if (!netRules.isLegacy())
ds.write(info);
}
@ -339,22 +338,17 @@ PausePacket::PausePacket() {}
PausePacket::PausePacket(bool pause, float timescale) : pause(pause), timescale(timescale) {}
void PausePacket::readLegacy(DataStream& ds) {
void PausePacket::read(DataStream& ds, NetCompatibilityRules netRules) {
ds.read(pause);
if (!netRules.isLegacy())
ds.read(timescale);
else
timescale = 1.0f;
}
void PausePacket::read(DataStream& ds) {
readLegacy(ds);
ds.read(timescale);
}
void PausePacket::writeLegacy(DataStream& ds) const {
void PausePacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
ds.write(pause);
}
void PausePacket::write(DataStream& ds) const {
writeLegacy(ds);
if (!netRules.isLegacy())
ds.write(timescale);
}
@ -409,7 +403,8 @@ ClientConnectPacket::ClientConnectPacket(ByteArray assetsDigest, bool allowAsset
playerName(std::move(playerName)), playerSpecies(std::move(playerSpecies)), shipChunks(std::move(shipChunks)),
shipUpgrades(std::move(shipUpgrades)), introComplete(std::move(introComplete)), account(std::move(account)), info(std::move(info)) {}
void ClientConnectPacket::readLegacy(DataStream& ds) {
void ClientConnectPacket::read(DataStream& ds, NetCompatibilityRules netRules) {
ds.read(assetsDigest);
ds.read(allowAssetsMismatch);
ds.read(playerUuid);
@ -419,15 +414,11 @@ void ClientConnectPacket::readLegacy(DataStream& ds) {
ds.read(shipUpgrades);
ds.read(introComplete);
ds.read(account);
info = Json();
}
void ClientConnectPacket::read(DataStream& ds) {
readLegacy(ds);
if (!netRules.isLegacy())
ds.read(info);
}
void ClientConnectPacket::writeLegacy(DataStream& ds) const {
void ClientConnectPacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
ds.write(assetsDigest);
ds.write(allowAssetsMismatch);
ds.write(playerUuid);
@ -437,10 +428,7 @@ void ClientConnectPacket::writeLegacy(DataStream& ds) const {
ds.write(shipUpgrades);
ds.write(introComplete);
ds.write(account);
}
void ClientConnectPacket::write(DataStream& ds) const {
writeLegacy(ds);
if (!netRules.isLegacy())
ds.write(info);
}
@ -484,16 +472,20 @@ void PlayerWarpPacket::write(DataStream& ds) const {
FlyShipPacket::FlyShipPacket() {}
FlyShipPacket::FlyShipPacket(Vec3I system, SystemLocation location) : system(std::move(system)), location(std::move(location)) {}
FlyShipPacket::FlyShipPacket(Vec3I system, SystemLocation location, Json settings) : system(std::move(system)), location(std::move(location)), settings(std::move(settings)) {}
void FlyShipPacket::read(DataStream& ds) {
void FlyShipPacket::read(DataStream& ds, NetCompatibilityRules netRules) {
ds.read(system);
ds.read(location);
if (netRules.version() >= 3)
ds.read(settings);
}
void FlyShipPacket::write(DataStream& ds) const {
void FlyShipPacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
ds.write(system);
ds.write(location);
if (netRules.version() >= 3)
ds.write(settings);
}
ChatSendPacket::ChatSendPacket() : sendMode(ChatSendMode::Broadcast) {}
@ -944,24 +936,23 @@ void WorldStartAcknowledgePacket::write(DataStream& ds) const {
PingPacket::PingPacket() {}
PingPacket::PingPacket(int64_t time) : time(time) {}
void PingPacket::readLegacy(DataStream& ds) {
void PingPacket::read(DataStream& ds, NetCompatibilityRules netRules) {
if (netRules.isLegacy()) {
// Packets can't be empty, read the trash data
ds.read<bool>();
time = 0;
}
void PingPacket::read(DataStream& ds) {
} else {
ds.readVlqI(time);
}
}
void PingPacket::writeLegacy(DataStream& ds) const {
void PingPacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
if (netRules.isLegacy()) {
// Packets can't be empty, write some trash data
ds.write<bool>(false);
}
void PingPacket::write(DataStream& ds) const {
} else {
ds.writeVlqI(time);
}
}
EntityCreatePacket::EntityCreatePacket(EntityType entityType, ByteArray storeData, ByteArray firstNetState, EntityId entityId)
@ -1265,44 +1256,47 @@ void FindUniqueEntityResponsePacket::write(DataStream& ds) const {
PongPacket::PongPacket() {}
PongPacket::PongPacket(int64_t time) : time(time) {}
void PongPacket::readLegacy(DataStream& ds) {
void PongPacket::read(DataStream& ds, NetCompatibilityRules netRules) {
if (netRules.isLegacy()) {
// Packets can't be empty, read the trash data
ds.read<bool>();
time = 0;
}
void PongPacket::read(DataStream& ds) {
} else {
ds.readVlqI(time);
}
}
void PongPacket::writeLegacy(DataStream& ds) const {
void PongPacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
if (netRules.isLegacy()) {
// Packets can't be empty, write some trash data
ds.write<bool>(false);
}
void PongPacket::write(DataStream& ds) const {
} else {
ds.writeVlqI(time);
}
}
StepUpdatePacket::StepUpdatePacket() : remoteTime(0.0) {}
StepUpdatePacket::StepUpdatePacket(double remoteTime) : remoteTime(remoteTime) {}
void StepUpdatePacket::readLegacy(DataStream& ds) {
void StepUpdatePacket::read(DataStream& ds, NetCompatibilityRules netRules) {
if (netRules.isLegacy()) {
auto steps = ds.readVlqU();
remoteTime = double(steps) / 60.0;
}
void StepUpdatePacket::read(DataStream& ds) {
} else {
ds.read(remoteTime);
}
}
void StepUpdatePacket::writeLegacy(DataStream& ds) const {
void StepUpdatePacket::write(DataStream& ds, NetCompatibilityRules netRules) const {
if (netRules.isLegacy()) {
ds.writeVlqU((uint64_t)round(remoteTime * 60.0));
}
void StepUpdatePacket::write(DataStream& ds) const {
} else {
ds.write(remoteTime);
}
}
SystemWorldStartPacket::SystemWorldStartPacket() {}

View File

@ -134,10 +134,10 @@ struct Packet {
virtual PacketType type() const = 0;
virtual void readLegacy(DataStream& ds);
virtual void read(DataStream& ds) = 0;
virtual void writeLegacy(DataStream& ds) const;
virtual void write(DataStream& ds) const = 0;
virtual void read(DataStream& ds, NetCompatibilityRules netRules);
virtual void read(DataStream& ds);
virtual void write(DataStream& ds, NetCompatibilityRules netRules) const;
virtual void write(DataStream& ds) const;
virtual void readJson(Json const& json);
virtual Json writeJson() const;
@ -172,8 +172,7 @@ struct ProtocolResponsePacket : PacketBase<PacketType::ProtocolResponse> {
ProtocolResponsePacket(bool allowed = false, Json info = {});
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
bool allowed;
Json info;
@ -281,10 +280,8 @@ struct PausePacket : PacketBase<PacketType::Pause> {
PausePacket();
PausePacket(bool pause, float timescale = 1.0f);
void readLegacy(DataStream& ds) override;
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
void readJson(Json const& json) override;
Json writeJson() const override;
@ -313,10 +310,8 @@ struct ClientConnectPacket : PacketBase<PacketType::ClientConnect> {
String playerSpecies, WorldChunks shipChunks, ShipUpgrades shipUpgrades, bool introComplete,
String account, Json info = {});
void readLegacy(DataStream& ds) override;
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
ByteArray assetsDigest;
bool allowAssetsMismatch;
@ -360,13 +355,14 @@ struct PlayerWarpPacket : PacketBase<PacketType::PlayerWarp> {
struct FlyShipPacket : PacketBase<PacketType::FlyShip> {
FlyShipPacket();
FlyShipPacket(Vec3I system, SystemLocation location);
FlyShipPacket(Vec3I system, SystemLocation location, Json settings = {});
void read(DataStream& ds) override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
Vec3I system;
SystemLocation location;
Json settings;
};
struct ChatSendPacket : PacketBase<PacketType::ChatSend> {
@ -614,10 +610,8 @@ struct PongPacket : PacketBase<PacketType::Pong> {
PongPacket();
PongPacket(int64_t time);
void readLegacy(DataStream& ds) override;
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
int64_t time = 0;
};
@ -733,10 +727,8 @@ struct PingPacket : PacketBase<PacketType::Ping> {
PingPacket();
PingPacket(int64_t time);
void readLegacy(DataStream& ds) override;
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
int64_t time = 0;
};
@ -879,10 +871,8 @@ struct StepUpdatePacket : PacketBase<PacketType::StepUpdate> {
StepUpdatePacket();
StepUpdatePacket(double remoteTime);
void readLegacy(DataStream& ds) override;
void read(DataStream& ds) override;
void writeLegacy(DataStream& ds) const override;
void write(DataStream& ds) const override;
void read(DataStream& ds, NetCompatibilityRules netRules) override;
void write(DataStream& ds, NetCompatibilityRules netRules) const override;
double remoteTime;
};

View File

@ -13,11 +13,7 @@
namespace Star {
Sky::Sky() {
m_settings = Root::singleton().assets()->json("/sky.config");
m_starFrames = m_settings.queryInt("stars.frames");
m_starList = jsonToStringList(m_settings.query("stars.list"));
m_hyperStarList = jsonToStringList(m_settings.query("stars.hyperlist"));
skyParametersUpdated();
m_netInit = false;
@ -38,7 +34,7 @@ Sky::Sky() {
Sky::Sky(SkyParameters const& skyParameters, bool inOrbit) : Sky() {
m_skyParameters = skyParameters;
m_skyParametersUpdated = true;
skyParametersUpdated();
if (inOrbit)
m_skyType = SkyType::Orbital;
@ -46,7 +42,7 @@ Sky::Sky(SkyParameters const& skyParameters, bool inOrbit) : Sky() {
m_skyType = m_skyParameters.skyType;
}
void Sky::startFlying(bool enterHyperspace, bool startInWarp) {
void Sky::startFlying(bool enterHyperspace, bool startInWarp, Json settings) {
if (startInWarp)
m_flyingType = FlyingType::Warp;
else
@ -55,6 +51,10 @@ void Sky::startFlying(bool enterHyperspace, bool startInWarp) {
m_flyingTimer = 0;
m_enterHyperspace = enterHyperspace;
m_startInWarp = startInWarp;
if (settings.isType(Json::Type::Object)) {
m_skyParameters.settings = settings;
skyParametersUpdated();
}
}
void Sky::stopFlyingAt(Maybe<SkyParameters> dest) {
@ -63,7 +63,7 @@ void Sky::stopFlyingAt(Maybe<SkyParameters> dest) {
void Sky::jumpTo(SkyParameters skyParameters) {
m_skyParameters = skyParameters;
m_skyParametersUpdated = true;
skyParametersUpdated();
}
pair<ByteArray, uint64_t> Sky::writeUpdate(uint64_t fromVersion, NetCompatibilityRules rules) {
@ -531,8 +531,10 @@ void Sky::writeNetStates() {
}
void Sky::readNetStates() {
if (m_skyParametersNetState.pullUpdated())
if (m_skyParametersNetState.pullUpdated()) {
m_skyParameters = SkyParameters(DataStreamBuffer::deserialize<Json>(m_skyParametersNetState.get()));
skyParametersUpdated();
}
m_skyType = (SkyType)m_skyTypeNetState.get();
m_time = m_timeNetState.get();
@ -651,4 +653,12 @@ float Sky::slowdownTime() const {
return m_settings.queryFloat("slowdownTime");
}
void Sky::skyParametersUpdated() {
m_skyParametersUpdated = true;
m_settings = jsonMerge(Root::singleton().assets()->json("/sky.config"), m_skyParameters.settings);
m_starFrames = m_settings.queryInt("stars.frames");
m_starList = jsonToStringList(m_settings.query("stars.list"));
m_hyperStarList = jsonToStringList(m_settings.query("stars.hyperlist"));
}
}

View File

@ -23,7 +23,7 @@ public:
Sky(SkyParameters const& skyParameters, bool inOrbit);
// Controls the space sky "flight" system
void startFlying(bool enterHyperspace, bool startInWarp);
void startFlying(bool enterHyperspace, bool startInWarp, Json settings = {});
// Stops flying animation copying the new pertinant sky data from the given
// sky, as though the sky as moved to a new world.
void stopFlyingAt(Maybe<SkyParameters> SkyParameters);
@ -117,6 +117,8 @@ private:
float speedupTime() const;
float slowdownTime() const;
void skyParametersUpdated();
Json m_settings;
SkyParameters m_skyParameters;
bool m_skyParametersUpdated;

View File

@ -7,7 +7,7 @@
namespace Star {
SkyParameters::SkyParameters() : seed(), skyType(SkyType::Barren), skyColoring(makeRight(Color::Black)) {}
SkyParameters::SkyParameters() : seed(), skyType(SkyType::Barren), skyColoring(makeRight(Color::Black)), settings(JsonObject()) {}
SkyParameters::SkyParameters(CelestialCoordinate const& coordinate, CelestialDatabasePtr const& celestialDatabase)
: SkyParameters() {
@ -113,6 +113,8 @@ SkyParameters::SkyParameters(Json const& config) : SkyParameters() {
surfaceLevel = config.optFloat("surfaceLevel");
sunType = config.getString("sunType", "");
settings = config.get("settings", JsonObject());
}
Json SkyParameters::toJson() const {
@ -155,6 +157,7 @@ Json SkyParameters::toJson() const {
{"spaceLevel", jsonFromMaybe<float>(spaceLevel)},
{"surfaceLevel", jsonFromMaybe<float>(surfaceLevel)},
{"sunType", sunType},
{"settings", settings}
};
}
@ -170,6 +173,8 @@ void SkyParameters::read(DataStream& ds) {
ds >> spaceLevel;
ds >> surfaceLevel;
ds >> sunType;
if (ds.streamCompatibilityVersion() >= 3)
ds >> settings;
}
void SkyParameters::write(DataStream& ds) const {
@ -184,6 +189,8 @@ void SkyParameters::write(DataStream& ds) const {
ds << spaceLevel;
ds << surfaceLevel;
ds << sunType;
if (ds.streamCompatibilityVersion() >= 3)
ds << settings;
}
void SkyParameters::readVisitableParameters(VisitableWorldParametersConstPtr visitableParameters) {

View File

@ -45,6 +45,7 @@ struct SkyParameters {
Maybe<float> spaceLevel;
Maybe<float> surfaceLevel;
String sunType;
Json settings;
};
DataStream& operator>>(DataStream& ds, SkyParameters& sky);

View File

@ -6,7 +6,7 @@
namespace Star {
StringList SkyRenderData::starTypes() const {
StringList const& SkyRenderData::starTypes() const {
if (type == SkyType::Warp)
return hyperStarList;
else

View File

@ -32,7 +32,7 @@ struct SkyRenderData {
Color bottomRectColor;
Color flashColor;
StringList starTypes() const;
StringList const& starTypes() const;
// Star and orbiter positions here are in view space, from (0, 0) to viewSize

View File

@ -124,7 +124,7 @@ Maybe<String> UniverseClient::connect(UniverseConnection connection, bool allowA
}
}
}
connection.packetSocket().setLegacy(legacyServer);
connection.packetSocket().setNetRules(compatibilityRules);
auto clientConnect = make_shared<ClientConnectPacket>(Root::singleton().assets()->digest(), allowAssetsMismatch, m_mainPlayer->uuid(), m_mainPlayer->name(),
m_mainPlayer->species(), m_playerStorage->loadShipData(m_mainPlayer->uuid()), m_mainPlayer->shipUpgrades(),
m_mainPlayer->log()->introComplete(), account);
@ -426,8 +426,8 @@ void UniverseClient::warpPlayer(WarpAction const& warpAction, bool animate, Stri
m_pendingWarp = warpAction;
}
void UniverseClient::flyShip(Vec3I const& system, SystemLocation const& destination) {
m_connection->pushSingle(make_shared<FlyShipPacket>(system, destination));
void UniverseClient::flyShip(Vec3I const& system, SystemLocation const& destination, Json const& settings) {
m_connection->pushSingle(make_shared<FlyShipPacket>(system, destination, settings));
}
CelestialDatabasePtr UniverseClient::celestialDatabase() const {

View File

@ -61,7 +61,7 @@ public:
bool canTeleport() const;
void warpPlayer(WarpAction const& warpAction, bool animate = true, String const& animationType = "default", bool deploy = false);
void flyShip(Vec3I const& system, SystemLocation const& destination);
void flyShip(Vec3I const& system, SystemLocation const& destination, Json const& settings = {});
CelestialDatabasePtr celestialDatabase() const;

View File

@ -288,7 +288,7 @@ void UniverseServer::clientWarpPlayer(ConnectionId clientId, WarpAction action,
m_pendingPlayerWarps[clientId] = pair<WarpAction, bool>(std::move(action), std::move(deploy));
}
void UniverseServer::clientFlyShip(ConnectionId clientId, Vec3I const& system, SystemLocation const& location) {
void UniverseServer::clientFlyShip(ConnectionId clientId, Vec3I const& system, SystemLocation const& location, Json const& settings) {
RecursiveMutexLocker locker(m_mainLock);
ReadLocker clientsLocker(m_clientsLock);
@ -300,7 +300,7 @@ void UniverseServer::clientFlyShip(ConnectionId clientId, Vec3I const& system, S
return;
if (system == Vec3I()) {
m_pendingFlights.set(clientId, {Vec3I(), {}}); // find starter world
m_pendingFlights.set(clientId, make_tuple(Vec3I(), SystemLocation(), settings)); // find starter world
return;
}
@ -315,7 +315,7 @@ void UniverseServer::clientFlyShip(ConnectionId clientId, Vec3I const& system, S
// don't switch systems while already flying
if (!m_pendingArrivals.contains(clientId) || sameSystem)
m_pendingFlights.set(clientId, {system, location});
m_pendingFlights.set(clientId, make_tuple(system, location, settings));
}
WorldId UniverseServer::clientWorld(ConnectionId clientId) const {
@ -892,10 +892,11 @@ void UniverseServer::flyShips() {
}
}
eraseWhere(m_pendingFlights, [this](pair<ConnectionId const, pair<Vec3I, SystemLocation>> const& p) {
eraseWhere(m_pendingFlights, [this](pair<ConnectionId const, tuple<Vec3I, SystemLocation, Json>> const& p) {
ConnectionId clientId = p.first;
Vec3I system = p.second.first;
SystemLocation location = p.second.second;
Vec3I system = get<0>(p.second);
SystemLocation location = get<1>(p.second);
Json settings = get<2>(p.second);
auto clientContext = m_clients.value(clientId);
if (!clientContext)
@ -935,7 +936,7 @@ void UniverseServer::flyShips() {
clientContext->setSystemWorld({});
if (location)
m_queuedFlights.set(clientId, {{system, location}, {}});
m_queuedFlights.set(clientId, {make_tuple(system, location, settings), {}});
destination = CelestialCoordinate(system);
}
@ -946,8 +947,8 @@ void UniverseServer::flyShips() {
Logger::info("Flying ship for player {} to {}", clientId, destination);
bool startInWarp = system == Vec3I();
clientShip->executeAction([interstellar, startInWarp](WorldServerThread*, WorldServer* worldServer) {
worldServer->startFlyingSky(interstellar, startInWarp);
clientShip->executeAction([interstellar, startInWarp, settings](WorldServerThread*, WorldServer* worldServer) {
worldServer->startFlyingSky(interstellar, startInWarp, settings);
});
clientContext->setShipCoordinate(CelestialCoordinate(system));
@ -1507,7 +1508,7 @@ void UniverseServer::packetsReceived(UniverseConnectionServer*, ConnectionId cli
clientWarpPlayer(clientId, warpAction->action, warpAction->deploy);
} else if (auto flyShip = as<FlyShipPacket>(packet)) {
clientFlyShip(clientId, flyShip->system, flyShip->location);
clientFlyShip(clientId, flyShip->system, flyShip->location, flyShip->settings);
} else if (auto chatSend = as<ChatSendPacket>(packet)) {
RecursiveMutexLocker locker(m_mainLock);
@ -1554,7 +1555,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe<HostA
}
bool legacyClient = protocolRequest->compressionMode() != PacketCompressionMode::Enabled;
connection.packetSocket().setLegacy(legacyClient);
if (legacyClient)
connection.packetSocket().setNetRules(LegacyVersion);
auto protocolResponse = make_shared<ProtocolResponsePacket>();
protocolResponse->setCompressionMode(PacketCompressionMode::Enabled); // Signal that we're OpenStarbound
@ -1681,8 +1683,9 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe<HostA
if (Json brand = info.get("brand", "custom"))
connectionLog += strf(" ({} client)", brand.toString());
if (info.getBool("legacy", false))
connection.packetSocket().setLegacy(legacyClient = true);
netRules.setVersion(LegacyVersion);
}
connection.packetSocket().setNetRules(netRules);
Logger::log(LogLevel::Info, connectionLog.utf8Ptr());

View File

@ -83,7 +83,7 @@ public:
RpcThreadPromise<Json> sendWorldMessage(WorldId const& worldId, String const& message, JsonArray const& args = {});
void clientWarpPlayer(ConnectionId clientId, WarpAction action, bool deploy = false);
void clientFlyShip(ConnectionId clientId, Vec3I const& system, SystemLocation const& location);
void clientFlyShip(ConnectionId clientId, Vec3I const& system, SystemLocation const& location, Json const& settings = {});
WorldId clientWorld(ConnectionId clientId) const;
CelestialCoordinate clientShipCoordinate(ConnectionId clientId) const;
@ -243,8 +243,8 @@ private:
TeamManagerPtr m_teamManager;
HashMap<ConnectionId, pair<WarpAction, bool>> m_pendingPlayerWarps;
HashMap<ConnectionId, pair<pair<Vec3I, SystemLocation>, Maybe<double>>> m_queuedFlights;
HashMap<ConnectionId, pair<Vec3I, SystemLocation>> m_pendingFlights;
HashMap<ConnectionId, pair<tuple<Vec3I, SystemLocation, Json>, Maybe<double>>> m_queuedFlights;
HashMap<ConnectionId, tuple<Vec3I, SystemLocation, Json>> m_pendingFlights;
HashMap<ConnectionId, CelestialCoordinate> m_pendingArrivals;
HashMap<ConnectionId, String> m_pendingDisconnections;
HashMap<ConnectionId, List<WorkerPoolPromise<CelestialResponse>>> m_pendingCelestialRequests;

View File

@ -853,6 +853,10 @@ void WorldServer::setSpawningEnabled(bool spawningEnabled) {
m_spawner.setActive(spawningEnabled);
}
void WorldServer::setPropertyListener(String const& propertyName, WorldPropertyListener listener) {
m_worldPropertyListeners[propertyName] = listener;
}
TileModificationList WorldServer::validTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) const {
return WorldImpl::splitTileModifications(m_entityMap, modificationList, allowEntityOverlap, m_tileGetterFunction, [this](Vec2I pos, TileModification) {
return !isTileProtected(pos);
@ -2202,14 +2206,17 @@ void WorldServer::setProperty(String const& propertyName, Json const& property)
for (auto const& pair : m_clientInfo)
pair.second->outgoingPackets.append(make_shared<UpdateWorldPropertiesPacket>(JsonObject{ {propertyName, property} }));
}
auto listener = m_worldPropertyListeners.find(propertyName);
if (listener != m_worldPropertyListeners.end())
listener->second(property);
}
void WorldServer::timer(float delay, WorldAction worldAction) {
m_timers.append({delay, worldAction});
}
void WorldServer::startFlyingSky(bool enterHyperspace, bool startInWarp) {
m_sky->startFlying(enterHyperspace, startInWarp);
void WorldServer::startFlyingSky(bool enterHyperspace, bool startInWarp, Json settings) {
m_sky->startFlying(enterHyperspace, startInWarp, settings);
}
void WorldServer::stopFlyingSkyAt(SkyParameters const& destination) {

View File

@ -50,6 +50,7 @@ class WorldServer : public World {
public:
typedef LuaMessageHandlingComponent<LuaUpdatableComponent<LuaWorldComponent<LuaBaseComponent>>> ScriptComponent;
typedef shared_ptr<ScriptComponent> ScriptComponentPtr;
typedef function<void(Json const&)> WorldPropertyListener;
// Create a new world with the given template, writing new storage file.
WorldServer(WorldTemplatePtr const& worldTemplate, IODevicePtr storage);
@ -108,7 +109,7 @@ public:
Maybe<Json> receiveMessage(ConnectionId fromConnection, String const& message, JsonArray const& args);
void startFlyingSky(bool enterHyperspace, bool startInWarp);
void startFlyingSky(bool enterHyperspace, bool startInWarp, Json settings = {});
void stopFlyingSkyAt(SkyParameters const& destination);
void setOrbitalSky(SkyParameters const& destination);
@ -231,6 +232,8 @@ public:
void setSpawningEnabled(bool spawningEnabled);
void setPropertyListener(String const& propertyName, WorldPropertyListener listener);
// Write all active sectors to disk without unloading them
void sync();
// Copy full world to in memory representation
@ -347,6 +350,7 @@ private:
bool m_adjustPlayerStart;
bool m_respawnInWorld;
JsonObject m_worldProperties;
StringMap<WorldPropertyListener> m_worldPropertyListeners;
Maybe<pair<String, String>> m_newPlanetType;

View File

@ -30,9 +30,9 @@ LuaCallbacks LuaBindings::makeCelestialCallbacks(UniverseClient* client) {
return client->currentSky()->inHyperspace();
});
callbacks.registerCallback("flyShip", [client,systemWorld](Vec3I const& system, Json const& destination) {
callbacks.registerCallback("flyShip", [client,systemWorld](Vec3I const& system, Json const& destination, Json const& settings) {
auto location = jsonToSystemLocation(destination);
client->flyShip(system, location);
client->flyShip(system, location, settings);
});
callbacks.registerCallback("flying", [systemWorld]() {
return systemWorld->flying();

View File

@ -39,9 +39,6 @@ void EnvironmentPainter::update(float dt) {
}
void EnvironmentPainter::renderStars(float pixelRatio, Vec2F const& screenSize, SkyRenderData const& sky) {
if (!sky.settings)
return;
float nightSkyAlpha = 1.0f - min(sky.dayLevel, sky.skyAlpha);
if (nightSkyAlpha <= 0.0f)
return;
@ -58,6 +55,9 @@ void EnvironmentPainter::renderStars(float pixelRatio, Vec2F const& screenSize,
setupStars(sky);
}
if (!sky.settings || sky.starFrames == 0 || sky.starTypes().empty())
return;
float screenBuffer = sky.settings.queryFloat("stars.screenBuffer");
PolyF field = PolyF(RectF::withSize(viewMin, Vec2F(viewSize)).padded(screenBuffer));
@ -85,7 +85,7 @@ void EnvironmentPainter::renderStars(float pixelRatio, Vec2F const& screenSize,
Vec2F screenPos = transform.transformVec2(star.first);
if (viewRect.contains(screenPos)) {
size_t starFrame = (size_t)(sky.epochTime + star.second.second) % sky.starFrames;
auto const& texture = m_starTextures[star.second.first * sky.starFrames + starFrame];
if (auto const& texture = m_starTextures[star.second.first * sky.starFrames + starFrame])
primitives.emplace_back(std::in_place_type_t<RenderQuad>(), texture, screenPos * pixelRatio - Vec2F(texture->size()) / 2, 1.0, color, 0.0f);
}
}
@ -455,7 +455,7 @@ void EnvironmentPainter::setupStars(SkyRenderData const& sky) {
if (!sky.settings)
return;
StringList starTypes = sky.starTypes();
StringList const& starTypes = sky.starTypes();
size_t starTypesSize = starTypes.size();
m_starTextures.resize(starTypesSize * sky.starFrames);