From dd52188e53e690f8eb872421f8a4c3bcc5699133 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:39:11 +1100 Subject: [PATCH] add sky setting overrides to celestial.flyShip, pass net rules to packet read/write --- source/core/StarDataStream.cpp | 2 + source/core/StarDataStream.hpp | 3 +- source/core/StarNetCompatibility.cpp | 2 +- source/game/StarNetPacketSocket.cpp | 39 ++--- source/game/StarNetPacketSocket.hpp | 10 +- source/game/StarNetPackets.cpp | 156 +++++++++--------- source/game/StarNetPackets.hpp | 48 +++--- source/game/StarSky.cpp | 28 +++- source/game/StarSky.hpp | 4 +- source/game/StarSkyParameters.cpp | 9 +- source/game/StarSkyParameters.hpp | 1 + source/game/StarSkyRenderData.cpp | 2 +- source/game/StarSkyRenderData.hpp | 2 +- source/game/StarUniverseClient.cpp | 6 +- source/game/StarUniverseClient.hpp | 2 +- source/game/StarUniverseServer.cpp | 27 +-- source/game/StarUniverseServer.hpp | 6 +- source/game/StarWorldServer.cpp | 11 +- source/game/StarWorldServer.hpp | 6 +- .../scripting/StarCelestialLuaBindings.cpp | 4 +- source/rendering/StarEnvironmentPainter.cpp | 12 +- 21 files changed, 194 insertions(+), 186 deletions(-) diff --git a/source/core/StarDataStream.cpp b/source/core/StarDataStream.cpp index 3a4ed0c..7097d63 100644 --- a/source/core/StarDataStream.cpp +++ b/source/core/StarDataStream.cpp @@ -6,6 +6,8 @@ namespace Star { +unsigned const CurrentStreamVersion = 3; + DataStream::DataStream() : m_byteOrder(ByteOrder::BigEndian), m_nullTerminatedStrings(false), diff --git a/source/core/StarDataStream.hpp b/source/core/StarDataStream.hpp index abcbff4..d5f9bcb 100644 --- a/source/core/StarDataStream.hpp +++ b/source/core/StarDataStream.hpp @@ -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); diff --git a/source/core/StarNetCompatibility.cpp b/source/core/StarNetCompatibility.cpp index fdd53fb..94e1ca5 100644 --- a/source/core/StarNetCompatibility.cpp +++ b/source/core/StarNetCompatibility.cpp @@ -2,6 +2,6 @@ namespace Star { -VersionNumber const OpenProtocolVersion = 2; +VersionNumber const OpenProtocolVersion = 3; } \ No newline at end of file diff --git a/source/game/StarNetPacketSocket.cpp b/source/game/StarNetPacketSocket.cpp index 4caeea0..b6320fa 100644 --- a/source/game/StarNetPacketSocket.cpp +++ b/source/game/StarNetPacketSocket.cpp @@ -62,9 +62,8 @@ Maybe PacketSocket::incomingStats() const { Maybe 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 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 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 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 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 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 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(false); outBuffer.writeData(packetBuffer.ptr(), packetBuffer.size()); @@ -387,13 +380,11 @@ void P2PPacketSocket::sendPackets(List 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 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()); } diff --git a/source/game/StarNetPacketSocket.hpp b/source/game/StarNetPacketSocket.hpp index c2c06fa..7c3e7ac 100644 --- a/source/game/StarNetPacketSocket.hpp +++ b/source/game/StarNetPacketSocket.hpp @@ -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 incomingStats() const; virtual Maybe 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 incomingStats() const override; Maybe outgoingStats() const override; - - void setLegacy(bool legacy) override; private: TcpPacketSocket(TcpSocketPtr socket); diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index b8605ed..44d1e21 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -85,8 +85,10 @@ EnumMap 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,13 +208,10 @@ 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); - ds.write(info); + if (!netRules.isLegacy()) + ds.write(info); } ConnectSuccessPacket::ConnectSuccessPacket() {} @@ -339,23 +338,18 @@ 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); - timescale = 1.0f; + 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); - ds.write(timescale); + if (!netRules.isLegacy()) + ds.write(timescale); } void PausePacket::readJson(Json const& json) { @@ -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(); + if (!netRules.isLegacy()) + ds.read(info); } -void ClientConnectPacket::read(DataStream& ds) { - readLegacy(ds); - 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,11 +428,8 @@ void ClientConnectPacket::writeLegacy(DataStream& ds) const { ds.write(shipUpgrades); ds.write(introComplete); ds.write(account); -} - -void ClientConnectPacket::write(DataStream& ds) const { - writeLegacy(ds); - ds.write(info); + if (!netRules.isLegacy()) + ds.write(info); } ClientDisconnectRequestPacket::ClientDisconnectRequestPacket() {} @@ -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) { - // Packets can't be empty, read the trash data - ds.read(); - time = 0; +void PingPacket::read(DataStream& ds, NetCompatibilityRules netRules) { + if (netRules.isLegacy()) { + // Packets can't be empty, read the trash data + ds.read(); + time = 0; + } else { + ds.readVlqI(time); + } } -void PingPacket::read(DataStream& ds) { - ds.readVlqI(time); -} - - -void PingPacket::writeLegacy(DataStream& ds) const { - // Packets can't be empty, write some trash data - ds.write(false); -} - -void PingPacket::write(DataStream& ds) const { - ds.writeVlqI(time); +void PingPacket::write(DataStream& ds, NetCompatibilityRules netRules) const { + if (netRules.isLegacy()) { + // Packets can't be empty, write some trash data + ds.write(false); + } 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) { - // Packets can't be empty, read the trash data - ds.read(); - time = 0; + +void PongPacket::read(DataStream& ds, NetCompatibilityRules netRules) { + if (netRules.isLegacy()) { + // Packets can't be empty, read the trash data + ds.read(); + time = 0; + } else { + ds.readVlqI(time); + } + } -void PongPacket::read(DataStream& ds) { - ds.readVlqI(time); -} - -void PongPacket::writeLegacy(DataStream& ds) const { - // Packets can't be empty, write some trash data - ds.write(false); -} - -void PongPacket::write(DataStream& ds) const { - ds.writeVlqI(time); +void PongPacket::write(DataStream& ds, NetCompatibilityRules netRules) const { + if (netRules.isLegacy()) { + // Packets can't be empty, write some trash data + ds.write(false); + } else { + ds.writeVlqI(time); + } } StepUpdatePacket::StepUpdatePacket() : remoteTime(0.0) {} StepUpdatePacket::StepUpdatePacket(double remoteTime) : remoteTime(remoteTime) {} -void StepUpdatePacket::readLegacy(DataStream& ds) { - auto steps = ds.readVlqU(); - remoteTime = double(steps) / 60.0; + +void StepUpdatePacket::read(DataStream& ds, NetCompatibilityRules netRules) { + if (netRules.isLegacy()) { + auto steps = ds.readVlqU(); + remoteTime = double(steps) / 60.0; + } else { + ds.read(remoteTime); + } } -void StepUpdatePacket::read(DataStream& ds) { - ds.read(remoteTime); -} - -void StepUpdatePacket::writeLegacy(DataStream& ds) const { - ds.writeVlqU((uint64_t)round(remoteTime * 60.0)); -} - -void StepUpdatePacket::write(DataStream& ds) const { - ds.write(remoteTime); +void StepUpdatePacket::write(DataStream& ds, NetCompatibilityRules netRules) const { + if (netRules.isLegacy()) { + ds.writeVlqU((uint64_t)round(remoteTime * 60.0)); + } else { + ds.write(remoteTime); + } } SystemWorldStartPacket::SystemWorldStartPacket() {} diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index fc43212..4002e90 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -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 { 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 { 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 { 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 { struct FlyShipPacket : PacketBase { 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 { @@ -614,10 +610,8 @@ struct PongPacket : PacketBase { 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 { 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 { 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; }; diff --git a/source/game/StarSky.cpp b/source/game/StarSky.cpp index 51e5b73..9b3363d 100644 --- a/source/game/StarSky.cpp +++ b/source/game/StarSky.cpp @@ -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 dest) { @@ -63,7 +63,7 @@ void Sky::stopFlyingAt(Maybe dest) { void Sky::jumpTo(SkyParameters skyParameters) { m_skyParameters = skyParameters; - m_skyParametersUpdated = true; + skyParametersUpdated(); } pair 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(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")); +} + } diff --git a/source/game/StarSky.hpp b/source/game/StarSky.hpp index 6065a9d..dcb3383 100644 --- a/source/game/StarSky.hpp +++ b/source/game/StarSky.hpp @@ -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); @@ -117,6 +117,8 @@ private: float speedupTime() const; float slowdownTime() const; + void skyParametersUpdated(); + Json m_settings; SkyParameters m_skyParameters; bool m_skyParametersUpdated; diff --git a/source/game/StarSkyParameters.cpp b/source/game/StarSkyParameters.cpp index 3eddce5..e2ed885 100644 --- a/source/game/StarSkyParameters.cpp +++ b/source/game/StarSkyParameters.cpp @@ -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(spaceLevel)}, {"surfaceLevel", jsonFromMaybe(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) { diff --git a/source/game/StarSkyParameters.hpp b/source/game/StarSkyParameters.hpp index 50b476f..35d4284 100644 --- a/source/game/StarSkyParameters.hpp +++ b/source/game/StarSkyParameters.hpp @@ -45,6 +45,7 @@ struct SkyParameters { Maybe spaceLevel; Maybe surfaceLevel; String sunType; + Json settings; }; DataStream& operator>>(DataStream& ds, SkyParameters& sky); diff --git a/source/game/StarSkyRenderData.cpp b/source/game/StarSkyRenderData.cpp index 53a2c4f..54db722 100644 --- a/source/game/StarSkyRenderData.cpp +++ b/source/game/StarSkyRenderData.cpp @@ -6,7 +6,7 @@ namespace Star { -StringList SkyRenderData::starTypes() const { +StringList const& SkyRenderData::starTypes() const { if (type == SkyType::Warp) return hyperStarList; else diff --git a/source/game/StarSkyRenderData.hpp b/source/game/StarSkyRenderData.hpp index 0e004b0..8d47282 100644 --- a/source/game/StarSkyRenderData.hpp +++ b/source/game/StarSkyRenderData.hpp @@ -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 diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 427cecb..b4edae4 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -124,7 +124,7 @@ Maybe UniverseClient::connect(UniverseConnection connection, bool allowA } } } - connection.packetSocket().setLegacy(legacyServer); + connection.packetSocket().setNetRules(compatibilityRules); auto clientConnect = make_shared(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(system, destination)); +void UniverseClient::flyShip(Vec3I const& system, SystemLocation const& destination, Json const& settings) { + m_connection->pushSingle(make_shared(system, destination, settings)); } CelestialDatabasePtr UniverseClient::celestialDatabase() const { diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp index 9452cf6..b951e25 100644 --- a/source/game/StarUniverseClient.hpp +++ b/source/game/StarUniverseClient.hpp @@ -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; diff --git a/source/game/StarUniverseServer.cpp b/source/game/StarUniverseServer.cpp index fa728fb..9ce097e 100644 --- a/source/game/StarUniverseServer.cpp +++ b/source/game/StarUniverseServer.cpp @@ -288,7 +288,7 @@ void UniverseServer::clientWarpPlayer(ConnectionId clientId, WarpAction action, m_pendingPlayerWarps[clientId] = pair(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> const& p) { + eraseWhere(m_pendingFlights, [this](pair> 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(packet)) { - clientFlyShip(clientId, flyShip->system, flyShip->location); + clientFlyShip(clientId, flyShip->system, flyShip->location, flyShip->settings); } else if (auto chatSend = as(packet)) { RecursiveMutexLocker locker(m_mainLock); @@ -1554,7 +1555,8 @@ void UniverseServer::acceptConnection(UniverseConnection connection, MaybecompressionMode() != PacketCompressionMode::Enabled; - connection.packetSocket().setLegacy(legacyClient); + if (legacyClient) + connection.packetSocket().setNetRules(LegacyVersion); auto protocolResponse = make_shared(); protocolResponse->setCompressionMode(PacketCompressionMode::Enabled); // Signal that we're OpenStarbound @@ -1681,8 +1683,9 @@ void UniverseServer::acceptConnection(UniverseConnection connection, Maybe 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> m_pendingPlayerWarps; - HashMap, Maybe>> m_queuedFlights; - HashMap> m_pendingFlights; + HashMap, Maybe>> m_queuedFlights; + HashMap> m_pendingFlights; HashMap m_pendingArrivals; HashMap m_pendingDisconnections; HashMap>> m_pendingCelestialRequests; diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index c313771..0c2a089 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -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(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) { diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index 21c8e9f..63414f7 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -50,6 +50,7 @@ class WorldServer : public World { public: typedef LuaMessageHandlingComponent>> ScriptComponent; typedef shared_ptr ScriptComponentPtr; + typedef function 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 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 m_worldPropertyListeners; Maybe> m_newPlanetType; diff --git a/source/game/scripting/StarCelestialLuaBindings.cpp b/source/game/scripting/StarCelestialLuaBindings.cpp index 2123bf7..03a989f 100644 --- a/source/game/scripting/StarCelestialLuaBindings.cpp +++ b/source/game/scripting/StarCelestialLuaBindings.cpp @@ -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(); diff --git a/source/rendering/StarEnvironmentPainter.cpp b/source/rendering/StarEnvironmentPainter.cpp index b5c514e..d95d968 100644 --- a/source/rendering/StarEnvironmentPainter.cpp +++ b/source/rendering/StarEnvironmentPainter.cpp @@ -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,8 +85,8 @@ 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]; - primitives.emplace_back(std::in_place_type_t(), texture, screenPos * pixelRatio - Vec2F(texture->size()) / 2, 1.0, color, 0.0f); + if (auto const& texture = m_starTextures[star.second.first * sky.starFrames + starFrame]) + primitives.emplace_back(std::in_place_type_t(), 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);